private boolean add(final long id) {
        if (size == Integer.MAX_VALUE) {
            throw new IllegalArgumentException("cannot grow beyond size Integer.MAX_VALUE");
        }

        // put the new entry in the first array
        al[0][0] = id;

        // determine the first empty array
        int bp = size++; // treat size as bitpattern
        int idx = 1;
        int n = 1;

        pa[0] = 1;
        pa[1] = 1;

        while ((bp & 1) == 1) {
            bp >>= 1;
            pa[idx++] = n;
            n <<= 1;
        }

        // create it if not existant
        if (al[idx] == null) {
            al[idx] = new long[n];
            vla[idx] = new Object[n];
        }

        // now merge the contents of arrays 0...idx-1 into idx
        while (n > 0) {
            long maxId = 0;
            int maxIdx = -1;

            for (int i = 0; i < idx; i++) {
                final int p = pa[i];
                if (p > 0) {
                    final long currentId = al[i][p - 1];
                    if (maxIdx < 0 || currentId > maxId) {
                        maxIdx = i;
                        maxId = currentId;
                    }
                }
            }

            // current maximum found, copy to target array
            if (n < al[idx].length && maxId == al[idx][n]) {
                throw new IllegalArgumentException("duplicate key found in late check: " + maxId);
            }
            --n;
            al[idx][n] = maxId;
            vla[idx][n] = vla[maxIdx][pa[maxIdx] - 1];

            --pa[maxIdx];
        }

        // de-allocate empty arrays of a certain size (fix at 64kByte)
        while (idx-- > maxKeepExponent) {
            al[idx] = null;
            vla[idx] = null;
        }

        return false;
    }
@return the number of entries in this map
main/src/main/java/cgeo/geocaching/brouter/util/CompactLongMap.java