public static void tokenize(CharSequence text, Collection<Rfc822Token> out) {
        StringBuilder name = new StringBuilder();
        StringBuilder address = new StringBuilder();
        StringBuilder comment = new StringBuilder();

        int i = 0;
        int cursor = text.length();

        while (i < cursor) {
            char c = text.charAt(i);

            if (c == ',' || c == ';') {
                i++;

                while (i < cursor && text.charAt(i) == ' ') {
                    i++;
                }

                crunch(name);

                if (address.length() > 0) {
                    out.add(new Rfc822Token(name.toString(),
                                            address.toString(),
                                            comment.toString()));
                } else if (name.length() > 0) {
                    out.add(new Rfc822Token(null,
                                            name.toString(),
                                            comment.toString()));
                }

                name.setLength(0);
                address.setLength(0);
                comment.setLength(0);
            } else if (c == '"') {
                i++;

                while (i < cursor) {
                    c = text.charAt(i);

                    if (c == '"') {
                        i++;
                        break;
                    } else if (c == '\\') {
                        if (i + 1 < cursor) {
                            name.append(text.charAt(i + 1));
                        }
                        i += 2;
                    } else {
                        name.append(c);
                        i++;
                    }
                }
            } else if (c == '(') {
                int level = 1;
                i++;

                while (i < cursor && level > 0) {
                    c = text.charAt(i);

                    if (c == ')') {
                        if (level > 1) {
                            comment.append(c);
                        }

                        level--;
                        i++;
                    } else if (c == '(') {
                        comment.append(c);
                        level++;
                        i++;
                    } else if (c == '\\') {
                        if (i + 1 < cursor) {
                            comment.append(text.charAt(i + 1));
                        }
                        i += 2;
                    } else {
                        comment.append(c);
                        i++;
                    }
                }
            } else if (c == '<') {
                i++;

                while (i < cursor) {
                    c = text.charAt(i);

                    if (c == '>') {
                        i++;
                        break;
                    } else {
                        address.append(c);
                        i++;
                    }
                }
            } else if (c == ' ') {
                name.append('\0');
                i++;
            } else {
                name.append(c);
                i++;
            }
        }

        crunch(name);

        if (address.length() > 0) {
            out.add(new Rfc822Token(name.toString(),
                                    address.toString(),
                                    comment.toString()));
        } else if (name.length() > 0) {
            out.add(new Rfc822Token(null,
                                    name.toString(),
                                    comment.toString()));
        }
    }
public static void tokenize ( CharSequence text , Collection < Rfc822Token > out ) { StringBuilder name = new StringBuilder ( ) ; StringBuilder address = new StringBuilder ( ) ; StringBuilder comment = new StringBuilder ( ) ; int i = 0 ; int cursor = text . length ( ) ; while ( i < cursor ) { char c = text . charAt ( i ) ; if ( c == ',' || c == ';' ) { i ++ ; while ( i < cursor && text . charAt ( i ) == ' ' ) { i ++ ; } crunch ( name ) ; if ( address . length ( ) > 0 ) { out . add ( new Rfc822Token ( name . toString ( ) , address . toString ( ) , comment . toString ( ) ) ) ; } else if ( name . length ( ) > 0 ) { out . add ( new Rfc822Token ( null , name . toString ( ) , comment . toString ( ) ) ) ; } name . setLength ( 0 ) ; address . setLength ( 0 ) ; comment . setLength ( 0 ) ; } else if ( c == '"' ) { i ++ ; while ( i < cursor ) { c = text . charAt ( i ) ; if ( c == '"' ) { i ++ ; break ; } else if ( c == '\\' ) { if ( i + 1 < cursor ) { name . append ( text . charAt ( i + 1 ) ) ; } i += 2 ; } else { name . append ( c ) ; i ++ ; } } } else if ( c == '(' ) { int level = 1 ; i ++ ; while ( i < cursor && level > 0 ) { c = text . charAt ( i ) ; if ( c == ')' ) { if ( level > 1 ) { comment . append ( c ) ; } level -- ; i ++ ; } else if ( c == '(' ) { comment . append ( c ) ; level ++ ; i ++ ; } else if ( c == '\\' ) { if ( i + 1 < cursor ) { comment . append ( text . charAt ( i + 1 ) ) ; } i += 2 ; } else { comment . append ( c ) ; i ++ ; } } } else if ( c == '<' ) { i ++ ; while ( i < cursor ) { c = text . charAt ( i ) ; if ( c == '>' ) { i ++ ; break ; } else { address . append ( c ) ; i ++ ; } } } else if ( c == ' ' ) { name . append ( '\0' ) ; i ++ ; } else { name . append ( c ) ; i ++ ; } } crunch ( name ) ; if ( address . length ( ) > 0 ) { out . add ( new Rfc822Token ( name . toString ( ) , address . toString ( ) , comment . toString ( ) ) ) ; } else if ( name . length ( ) > 0 ) { out . add ( new Rfc822Token ( null , name . toString ( ) , comment . toString ( ) ) ) ; } }
This constructor will try to take a string like
"Foo Bar (something) &lt;foo\@google.com&gt;,
blah\@google.com (something)"
and convert it into one or more Rfc822Tokens, output into the supplied
collection.

It does *not* decode MIME encoded-words; charset conversion
must already have taken place if necessary.
It will try to be tolerant of broken syntax instead of
returning an error.