short addUtf8(String k)
    {
        int theIndex = itsUtf8Hash.get(k, -1);
        if (theIndex == -1) {
            int strLen = k.length();
            boolean tooBigString;
            if (strLen > MAX_UTF_ENCODING_SIZE) {
                tooBigString = true;
            } else {
                tooBigString = false;
                // Ask for worst case scenario buffer when each char takes 3
                // bytes
                ensure(1 + 2 + strLen * 3);
                int top = itsTop;

                itsPool[top++] = CONSTANT_Utf8;
                top += 2; // skip length

                char[] chars = cfw.getCharBuffer(strLen);
                k.getChars(0, strLen, chars, 0);

                for (int i = 0; i != strLen; i++) {
                    int c = chars[i];
                    if (c != 0 && c <= 0x7F) {
                        itsPool[top++] = (byte)c;
                    } else if (c > 0x7FF) {
                        itsPool[top++] = (byte)(0xE0 | (c >> 12));
                        itsPool[top++] = (byte)(0x80 | ((c >> 6) & 0x3F));
                        itsPool[top++] = (byte)(0x80 | (c & 0x3F));
                    } else {
                        itsPool[top++] = (byte)(0xC0 | (c >> 6));
                        itsPool[top++] = (byte)(0x80 | (c & 0x3F));
                    }
                }

                int utfLen = top - (itsTop + 1 + 2);
                if (utfLen > MAX_UTF_ENCODING_SIZE) {
                    tooBigString = true;
                } else {
                    // Write back length
                    itsPool[itsTop + 1] = (byte)(utfLen >>> 8);
                    itsPool[itsTop + 2] = (byte)utfLen;

                    itsTop = top;
                    theIndex = itsTopIndex++;
                    itsUtf8Hash.put(k, theIndex);
                }
            }
            if (tooBigString) {
                throw new IllegalArgumentException("Too big string");
            }
        }
        return (short)theIndex;
    }