### Question:
ISO8601Duration implements SemanticString { public static ISO8601Duration newInstance(String iso8601DurationString) throws ParseException { if (iso8601DurationString == null || iso8601DurationString.length() == 0) { return null; } int curPos = 0; int endPos = iso8601DurationString.length(); int durationSign = 1; int years = 0; int months = 0; int days = 0; int hours = 0; int minutes = 0; double fractionalSeconds = 0.0; if (iso8601DurationString.charAt(curPos) == '-') { durationSign = -1; curPos++; } if (iso8601DurationString.charAt(curPos) != 'P') { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + POSITION_STRING + curPos, curPos); } curPos++; if (curPos >= endPos) { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + "\": No duration components following P", curPos); } int lastChunkOrder = 0; boolean sawT = false; while (curPos < endPos) { if (iso8601DurationString.charAt(curPos) == 'T') { if (sawT) { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + POSITION_STRING + curPos + ": saw multiple T separators", curPos); } else { sawT = true; } curPos++; } else { DurationChunk durationChunk = DurationChunk.nextChunk(iso8601DurationString, curPos); int chunkOrder = getChunkOrder(sawT, durationChunk.getChunkName()); if (chunkOrder <= 0) { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + POSITION_STRING + curPos + ": invalid component", curPos); } else if (chunkOrder <= lastChunkOrder) { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + POSITION_STRING + curPos + ": out of order component", curPos); } lastChunkOrder = chunkOrder; if (durationChunk.getChunkName() != 'S' && !durationChunk.isIntValue()) { throw new ParseException(INVALID_DURATION_STRING + iso8601DurationString + POSITION_STRING + curPos + ": expected int value", curPos); } switch(durationChunk.getChunkName()) { case 'Y': years = durationChunk.getIntValue(); break; case 'M': if (!sawT) { months = durationChunk.getIntValue(); } else { minutes = durationChunk.getIntValue(); } break; case 'D': days = durationChunk.getIntValue(); break; case 'H': hours = durationChunk.getIntValue(); break; case 'S': fractionalSeconds = durationChunk.getChunkValue(); break; default: assert(false); break; } curPos += durationChunk.getLength(); } } return new ISO8601Duration(durationSign, years, months, days, hours, minutes, fractionalSeconds); } ISO8601Duration(int durationSignIn, int yearsIn, int monthsIn, int daysIn, int hoursIn, int minutesIn, double secondsIn); static ISO8601Duration newInstance(String iso8601DurationString); int getDurationSign(); int getYears(); int getMonths(); int getDays(); int getHours(); int getMinutes(); int getSeconds(); int getMillis(); double getFractionalSecs(); @Override int hashCode(); @Override boolean equals(Object obj); @Override String stringValue(); @Override String toString();  }### Answer:
@Test(expected = ParseException.class) public void testParse00() throws ParseException { ISO8601Duration.newInstance("p"); }
@Test(expected = ParseException.class) public void testParse01() throws ParseException { ISO8601Duration.newInstance("P"); }
@Test(expected = ParseException.class) public void testParse02() throws ParseException { ISO8601Duration.newInstance("P3Y6M4DT12H30M5L"); }