private void detachImpl(Env env, StringValue hash)
        {
            ObjectEntry entry = _objMap.remove(hash);

            if (entry == null)
            {
                return;
            }

            ObjectEntry prev = entry.getPrev();
            ObjectEntry next = entry.getNext();

            if (prev != null)
            {
                prev.setNext(next);
            }

            if (next != null)
            {
                next.setPrev(prev);
            }

            if (entry == _tail)
            {
                _tail = entry.getPrev();
            }

            if (entry == _head)
            {
                _head = entry.getNext();
            }
        }
        public override StringValue serialize(Env env)
        {
            ArrayValue array = new ArrayValueImpl();

            StringValue objStr   = env.createString("obj");
            StringValue valueStr = env.createString("inf");

            ObjectEntry entry = _head;

            while (entry != null)
            {
                ArrayValue inner = new ArrayValueImpl();

                inner.put(objStr, entry.getObject());
                inner.put(valueStr, entry.getValue());

                array.append(inner);

                entry = entry.getNext();
            }

            string str = VariableModule.serialize(env, array);

            return(env.createString(str));
        }
        public void addAll(Env env, SplObjectStorage storage)
        {
            ObjectEntry entry = storage._head;

            while (entry != null)
            {
                attachImpl(env, entry.getHash(), entry.getObject(), entry.getValue());

                entry = entry.getNext();
            }
        }
        public void removeAllExcept(Env env, SplObjectStorage storage)
        {
            ArrayList <ObjectEntry> toRemoveList = new ArrayList <ObjectEntry>();

            ObjectEntry entry = _head;

            while (entry != null)
            {
                if (storage._objMap.containsKey(entry.getHash()))
                {
                }
                else
                {
                    toRemoveList.add(entry);
                }

                entry = entry.getNext();
            }

            for (ObjectEntry listEntry : toRemoveList)
            {
                detachImpl(env, listEntry.getHash());
            }
        }