@Override public ContactInfo readValue() throws IOException { ContactInfo result = null; skipSpaces(); if (peek() != -1) { result = new ContactInfo(); if (peek() == '"') { result.setDisplayName(readQuotedString()); skipSpaces(); result.setReference(new Reference(readReference())); } else if (peek() == '<') { result.setReference(new Reference(readReference())); } else if (HeaderUtils.isTokenChar(peek())) { // Read value until end or value or parameter separator StringBuilder sb = null; int next = read(); while ((next != -1) && !isComma(next) && !isSemiColon(next)) { if (sb == null) { sb = new StringBuilder(); } sb.append((char) next); next = read(); } // Remove trailing spaces if (sb != null) { for (int i = sb.length() - 1; (i >= 0) && isLinearWhiteSpace(sb.charAt(i)); i--) { sb.deleteCharAt(i); } } // Unread the separator if (isComma(next) || isSemiColon(next)) { unread(); } // The last token is the reference int index = sb.lastIndexOf(" "); if (index != -1) { if (sb.charAt(index + 1) == '<') { if (sb.charAt(sb.length() - 1) == '>') { result.setReference(new Reference(sb.substring(index + 2, sb.length() - 1))); } else { throw new IOException("Unexpected end of reference. Please check your value"); } } result.setDisplayName(sb.substring(0, index).trim()); } else { result.setReference(new Reference(sb.toString())); } } } // Read address parameters. if (skipParameterSeparator()) { Parameter param = readParameter(); while (param != null) { if ("q".equals(param.getName())) { result.setQuality(PreferenceReader.readQuality(param.getValue())); } else if ("expires".equals(param.getName())) { result.setExpires(param.getValue()); } else { addParameter(result, param); } if (skipParameterSeparator()) { param = readParameter(); } else { param = null; } } } return result; }