public String intern(char[] ch, int start, int length) {
        int index = 0;
        int hash = 0;
        Object[] bucket;

        // Generate a hash code. This is a widely used string hash,
        // often attributed to Brian Kernighan.
        for (int i = start; i < start + length; i++) {
            hash = 31 * hash + ch[i];
        }
        hash = (hash & 0x7fffffff) % SYMBOL_TABLE_LENGTH;

        // Get the bucket -- consists of {array,String} pairs
        if ((bucket = symbolTable[hash]) == null) {
            // first string in this bucket
            bucket = new Object[8];

            // Search for a matching tuple, and
            // return the string if we find one.
        } else {
            while (index < bucket.length) {
                char[] chFound = (char[]) bucket[index];

                // Stop when we hit an empty entry.
                if (chFound == null) {
                    break;
                }

                // If they're the same length, check for a match.
                if (chFound.length == length) {
                    for (int i = 0; i < chFound.length; i++) {
                        // continue search on failure
                        if (ch[start + i] != chFound[i]) {
                            break;
                        } else if (i == length - 1) {
                            // That's it, we have a match!
                            return (String) bucket[index + 1];
                        }
                    }
                }
                index += 2;
            }
            // Not found -- we'll have to add it.

            // Do we have to grow the bucket?
            bucket = (Object[]) extendArray(bucket, bucket.length, index);
        }
        symbolTable[hash] = bucket;

        // OK, add it to the end of the bucket -- "local" interning.
        // Intern "globally" to let applications share interning benefits.
        // That is, "!=" and "==" work on our strings, not just equals().
        String s = new String(ch, start, length).intern();
        bucket[index] = s.toCharArray();
        bucket[index + 1] = s;
        return s;
    }
Create an interned string from a character array. &AElig;lfred uses this
method to create an interned version of all names and name tokens, so
that it can test equality with <code>==</code> instead of
<code>String.equals ()</code>.

<p>
This is much more efficient than constructing a non-interned string
first, and then interning it.

@param ch
           an array of characters for building the string.
@param start
           the starting position in the array.
@param length
           the number of characters to place in the string.
@return an interned string.
@see #intern (String)
@see java.lang.String#intern
src/nu/validator/gnu/xml/aelfred2/XmlParser.java