/*
 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef WTF_ListHashSet_h
#define WTF_ListHashSet_h

#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>

namespace WTF {

    // ListHashSet: Just like HashSet, this class provides a Set
    // interface - a collection of unique objects with O(1) insertion,
    // removal and test for containership. However, it also has an
    // order - iterating it will always give back values in the order
    // in which they are added.

    // Unlike iteration of most WTF Hash data structures, iteration is
    // guaranteed safe against mutation of the ListHashSet, except for
    // removal of the item currently pointed to by a given iterator.

    template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet;

    template<typename Value, size_t inlineCapacity, typename HashFunctions>
    void deleteAllValues(const ListHashSet<Value, inlineCapacity, HashFunctions>&);

    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator;
    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator;
    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator;
    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator;

    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode;
    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator;

    template<typename HashArg> struct ListHashSetNodeHashFunctions;
    template<typename HashArg> struct ListHashSetTranslator;

    template<typename ValueArg, size_t inlineCapacity = 256, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet {
        WTF_MAKE_FAST_ALLOCATED;
    private:
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;

        typedef HashTraits<Node*> NodeTraits;
        typedef ListHashSetNodeHashFunctions<HashArg> NodeHash;
        typedef ListHashSetTranslator<HashArg> BaseTranslator;

        typedef HashTable<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplType;
        typedef HashTableIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator;
        typedef HashTableConstIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplTypeConstIterator;

        typedef HashArg HashFunctions;

    public:
        typedef ValueArg ValueType;

        typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator;
        friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>;

        typedef ListHashSetReverseIterator<ValueType, inlineCapacity, HashArg> reverse_iterator;
        typedef ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg> const_reverse_iterator;
        friend class ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg>;

        typedef HashTableAddResult<iterator> AddResult;

        ListHashSet();
        ListHashSet(const ListHashSet&);
        ListHashSet& operator=(const ListHashSet&);
        ~ListHashSet();

        void swap(ListHashSet&);

        int size() const;
        int capacity() const;
        bool isEmpty() const;

        size_t sizeInBytes() const;

        iterator begin();
        iterator end();
        const_iterator begin() const;
        const_iterator end() const;

        reverse_iterator rbegin();
        reverse_iterator rend();
        const_reverse_iterator rbegin() const;
        const_reverse_iterator rend() const;

        ValueType& first();
        const ValueType& first() const;
        void removeFirst();

        ValueType& last();
        const ValueType& last() const;
        void removeLast();

        iterator find(const ValueType&);
        const_iterator find(const ValueType&) const;
        bool contains(const ValueType&) const;

        // An alternate version of find() that finds the object by hashing and comparing
        // with some other type, to avoid the cost of type conversion.
        // The HashTranslator interface is defined in HashSet.
        // FIXME: We should reverse the order of the template arguments so that callers
        // can just pass the translator let the compiler deduce T.
        template<typename T, typename HashTranslator> iterator find(const T&);
        template<typename T, typename HashTranslator> const_iterator find(const T&) const;
        template<typename T, typename HashTranslator> bool contains(const T&) const;

        // The return value of add is a pair of an iterator to the new value's location, 
        // and a bool that is true if an new entry was added.
        AddResult add(const ValueType&);

        // Add the value to the end of the collection. If the value was already in
        // the list, it is moved to the end.
        AddResult appendOrMoveToLast(const ValueType&);

        // Add the value to the beginning of the collection. If the value was already in
        // the list, it is moved to the beginning.
        AddResult prependOrMoveToFirst(const ValueType&);

        AddResult insertBefore(const ValueType& beforeValue, const ValueType& newValue);
        AddResult insertBefore(iterator, const ValueType&);

        void remove(const ValueType&);
        void remove(iterator);
        void clear();

    private:
        void unlink(Node*);
        void unlinkAndDelete(Node*);
        void appendNode(Node*);
        void prependNode(Node*);
        void insertNodeBefore(Node* beforeNode, Node* newNode);
        void deleteAllNodes();
        
        iterator makeIterator(Node*);
        const_iterator makeConstIterator(Node*) const;
        reverse_iterator makeReverseIterator(Node*);
        const_reverse_iterator makeConstReverseIterator(Node*) const;

        friend void deleteAllValues<>(const ListHashSet&);

        ImplType m_impl;
        Node* m_head;
        Node* m_tail;
        OwnPtr<NodeAllocator> m_allocator;
    };

    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator {
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;

        ListHashSetNodeAllocator() 
            : m_freeList(pool())
            , m_isDoneWithInitialFreeList(false)
        { 
            memset(m_pool.pool, 0, sizeof(m_pool.pool));
        }

        Node* allocate()
        { 
            Node* result = m_freeList;

            if (!result)
                return static_cast<Node*>(fastMalloc(sizeof(Node)));

            ASSERT(!result->m_isAllocated);

            Node* next = result->m_next;
            ASSERT(!next || !next->m_isAllocated);
            if (!next && !m_isDoneWithInitialFreeList) {
                next = result + 1;
                if (next == pastPool()) {
                    m_isDoneWithInitialFreeList = true;
                    next = 0;
                } else {
                    ASSERT(inPool(next));
                    ASSERT(!next->m_isAllocated);
                }
            }
            m_freeList = next;

            return result;
        }

        void deallocate(Node* node) 
        {
            if (inPool(node)) {
#ifndef NDEBUG
                node->m_isAllocated = false;
#endif
                node->m_next = m_freeList;
                m_freeList = node;
                return;
            }

            fastFree(node);
        }

        bool inPool(Node* node)
        {
            return node >= pool() && node < pastPool();
        }

    private:
        Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); }
        Node* pastPool() { return pool() + m_poolSize; }

        Node* m_freeList;
        bool m_isDoneWithInitialFreeList;
        static const size_t m_poolSize = inlineCapacity;
        union {
            char pool[sizeof(Node) * m_poolSize];
            double forAlignment;
        } m_pool;
    };

    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode {
        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;

        ListHashSetNode(ValueArg value)
            : m_value(value)
            , m_prev(0)
            , m_next(0)
#ifndef NDEBUG
            , m_isAllocated(true)
#endif
        {
        }

        void* operator new(size_t, NodeAllocator* allocator)
        {
            return allocator->allocate();
        }
        void destroy(NodeAllocator* allocator)
        {
            this->~ListHashSetNode();
            allocator->deallocate(this);
        }

        ValueArg m_value;
        ListHashSetNode* m_prev;
        ListHashSetNode* m_next;

#ifndef NDEBUG
        bool m_isAllocated;
#endif
    };

    template<typename HashArg> struct ListHashSetNodeHashFunctions {
        template<typename T> static unsigned hash(const T& key) { return HashArg::hash(key->m_value); }
        template<typename T> static bool equal(const T& a, const T& b) { return HashArg::equal(a->m_value, b->m_value); }
        static const bool safeToCompareToEmptyOrDeleted = false;
    };

    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator {
    private:
        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
        typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator;
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ValueArg ValueType;
        typedef ValueType& ReferenceType;
        typedef ValueType* PointerType;

        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;

        ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }

    public:
        ListHashSetIterator() { }

        // default copy, assignment and destructor are OK

        PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        iterator& operator++() { ++m_iterator; return *this; }

        // postfix ++ intentionally omitted

        iterator& operator--() { --m_iterator; return *this; }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; }
        bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; }

        operator const_iterator() const { return m_iterator; }

    private:
        Node* node() { return m_iterator.node(); }

        const_iterator m_iterator;
    };

    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator {
    private:
        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
        typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator;
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ValueArg ValueType;
        typedef const ValueType& ReferenceType;
        typedef const ValueType* PointerType;

        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
        friend class ListHashSetIterator<ValueArg, inlineCapacity, HashArg>;

        ListHashSetConstIterator(const ListHashSetType* set, Node* position)
            : m_set(set)
            , m_position(position)
        {
        }

    public:
        ListHashSetConstIterator()
        {
        }

        PointerType get() const
        {
            return &m_position->m_value;
        }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        const_iterator& operator++()
        {
            ASSERT(m_position != 0);
            m_position = m_position->m_next;
            return *this;
        }

        // postfix ++ intentionally omitted

        const_iterator& operator--()
        {
            ASSERT(m_position != m_set->m_head);
            if (!m_position)
                m_position = m_set->m_tail;
            else
                m_position = m_position->m_prev;
            return *this;
        }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const const_iterator& other) const
        {
            return m_position == other.m_position;
        }
        bool operator!=(const const_iterator& other) const
        {
            return m_position != other.m_position;
        }

    private:
        Node* node() { return m_position; }

        const ListHashSetType* m_set;
        Node* m_position;
    };

    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator {
    private:
        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
        typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator;
        typedef ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator;
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ValueArg ValueType;
        typedef ValueType& ReferenceType;
        typedef ValueType* PointerType;

        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;

        ListHashSetReverseIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }

    public:
        ListHashSetReverseIterator() { }

        // default copy, assignment and destructor are OK

        PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        reverse_iterator& operator++() { ++m_iterator; return *this; }

        // postfix ++ intentionally omitted

        reverse_iterator& operator--() { --m_iterator; return *this; }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const reverse_iterator& other) const { return m_iterator == other.m_iterator; }
        bool operator!=(const reverse_iterator& other) const { return m_iterator != other.m_iterator; }

        operator const_reverse_iterator() const { return m_iterator; }

    private:
        Node* node() { return m_iterator.node(); }

        const_reverse_iterator m_iterator;
    };

    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator {
    private:
        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
        typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator;
        typedef ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator;
        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
        typedef ValueArg ValueType;
        typedef const ValueType& ReferenceType;
        typedef const ValueType* PointerType;

        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
        friend class ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg>;

        ListHashSetConstReverseIterator(const ListHashSetType* set, Node* position)
            : m_set(set)
            , m_position(position)
        {
        }

    public:
        ListHashSetConstReverseIterator()
        {
        }

        PointerType get() const
        {
            return &m_position->m_value;
        }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        const_reverse_iterator& operator++()
        {
            ASSERT(m_position != 0);
            m_position = m_position->m_prev;
            return *this;
        }

        // postfix ++ intentionally omitted

        const_reverse_iterator& operator--()
        {
            ASSERT(m_position != m_set->m_tail);
            if (!m_position)
                m_position = m_set->m_head;
            else
                m_position = m_position->m_next;
            return *this;
        }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const const_reverse_iterator& other) const
        {
            return m_position == other.m_position;
        }
        bool operator!=(const const_reverse_iterator& other) const
        {
            return m_position != other.m_position;
        }

    private:
        Node* node() { return m_position; }

        const ListHashSetType* m_set;
        Node* m_position;
    };

    template<typename HashFunctions>
    struct ListHashSetTranslator {
        template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); }
        template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a->m_value, b); }
        template<typename T, typename U, typename V> static void translate(T*& location, const U& key, const V& allocator)
        {
            location = new (allocator) T(key);
        }
    };

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSet<T, inlineCapacity, U>::ListHashSet()
        : m_head(0)
        , m_tail(0)
        , m_allocator(adoptPtr(new NodeAllocator))
    {
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSet<T, inlineCapacity, U>::ListHashSet(const ListHashSet& other)
        : m_head(0)
        , m_tail(0)
        , m_allocator(adoptPtr(new NodeAllocator))
    {
        const_iterator end = other.end();
        for (const_iterator it = other.begin(); it != end; ++it)
            add(*it);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSet<T, inlineCapacity, U>& ListHashSet<T, inlineCapacity, U>::operator=(const ListHashSet& other)
    {
        ListHashSet tmp(other);
        swap(tmp);
        return *this;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::swap(ListHashSet& other)
    {
        m_impl.swap(other.m_impl);
        std::swap(m_head, other.m_head);
        std::swap(m_tail, other.m_tail);
        m_allocator.swap(other.m_allocator);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSet<T, inlineCapacity, U>::~ListHashSet()
    {
        deleteAllNodes();
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline int ListHashSet<T, inlineCapacity, U>::size() const
    {
        return m_impl.size(); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline int ListHashSet<T, inlineCapacity, U>::capacity() const
    {
        return m_impl.capacity(); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline bool ListHashSet<T, inlineCapacity, U>::isEmpty() const
    {
        return m_impl.isEmpty(); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    size_t ListHashSet<T, inlineCapacity, U>::sizeInBytes() const
    {
        size_t result = sizeof(*this) + sizeof(*m_allocator);
        result += sizeof(typename ImplType::ValueType) * m_impl.capacity();
        for (Node* node = m_head; node; node = node->m_next) {
            if (!m_allocator->inPool(node))
                result += sizeof(Node);
        }
        return result;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin()
    {
        return makeIterator(m_head); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::end()
    {
        return makeIterator(0);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::begin() const
    {
        return makeConstIterator(m_head); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::end() const
    {
        return makeConstIterator(0); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin()
    {
        return makeReverseIterator(m_tail); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rend()
    {
        return makeReverseIterator(0);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin() const
    {
        return makeConstReverseIterator(m_tail); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rend() const
    {
        return makeConstReverseIterator(0); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline T& ListHashSet<T, inlineCapacity, U>::first()
    {
        ASSERT(!isEmpty());
        return m_head->m_value;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::removeFirst()
    {
        ASSERT(!isEmpty());
        m_impl.remove(m_head);
        unlinkAndDelete(m_head);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline const T& ListHashSet<T, inlineCapacity, U>::first() const
    {
        ASSERT(!isEmpty());
        return m_head->m_value;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline T& ListHashSet<T, inlineCapacity, U>::last()
    {
        ASSERT(!isEmpty());
        return m_tail->m_value;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline const T& ListHashSet<T, inlineCapacity, U>::last() const
    {
        ASSERT(!isEmpty());
        return m_tail->m_value;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::removeLast()
    {
        ASSERT(!isEmpty());
        m_impl.remove(m_tail);
        unlinkAndDelete(m_tail);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value)
    {
        ImplTypeIterator it = m_impl.template find<BaseTranslator>(value);
        if (it == m_impl.end())
            return end();
        return makeIterator(*it); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) const
    {
        ImplTypeConstIterator it = m_impl.template find<BaseTranslator>(value);
        if (it == m_impl.end())
            return end();
        return makeConstIterator(*it);
    }

    template<typename Translator>
    struct ListHashSetTranslatorAdapter {
        template<typename T> static unsigned hash(const T& key) { return Translator::hash(key); }
        template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a->m_value, b); }
    };

    template<typename ValueType, size_t inlineCapacity, typename U>
    template<typename T, typename HashTranslator>
    inline typename ListHashSet<ValueType, inlineCapacity, U>::iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value)
    {
        ImplTypeConstIterator it = m_impl.template find<ListHashSetTranslatorAdapter<HashTranslator> >(value);
        if (it == m_impl.end())
            return end();
        return makeIterator(*it);
    }

    template<typename ValueType, size_t inlineCapacity, typename U>
    template<typename T, typename HashTranslator>
    inline typename ListHashSet<ValueType, inlineCapacity, U>::const_iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value) const
    {
        ImplTypeConstIterator it = m_impl.template find<ListHashSetTranslatorAdapter<HashTranslator> >(value);
        if (it == m_impl.end())
            return end();
        return makeConstIterator(*it);
    }

    template<typename ValueType, size_t inlineCapacity, typename U>
    template<typename T, typename HashTranslator>
    inline bool ListHashSet<ValueType, inlineCapacity, U>::contains(const T& value) const
    {
        return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator> >(value);
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const
    {
        return m_impl.template contains<BaseTranslator>(value);
    }

    template<typename T, size_t inlineCapacity, typename U>
    typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::add(const ValueType &value)
    {
        typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get());
        if (result.isNewEntry)
            appendNode(*result.iterator);
        return AddResult(makeIterator(*result.iterator), result.isNewEntry);
    }

    template<typename T, size_t inlineCapacity, typename U>
    typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::appendOrMoveToLast(const ValueType &value)
    {
        typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get());
        Node* node = *result.iterator;
        if (!result.isNewEntry)
            unlink(node);
        appendNode(node);
        return AddResult(makeIterator(*result.iterator), result.isNewEntry);
    }

    template<typename T, size_t inlineCapacity, typename U>
    typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::prependOrMoveToFirst(const ValueType &value)
    {
        typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get());
        Node* node = *result.iterator;
        if (!result.isNewEntry)
            unlink(node);
        prependNode(node);
        return AddResult(makeIterator(*result.iterator), result.isNewEntry);
    }

    template<typename T, size_t inlineCapacity, typename U>
    typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue)
    {
        typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(newValue, m_allocator.get());
        if (result.isNewEntry)
            insertNodeBefore(it.node(), *result.iterator);
        return AddResult(makeIterator(*result.iterator), result.isNewEntry);
    }

    template<typename T, size_t inlineCapacity, typename U>
    typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue)
    {
        return insertBefore(find(beforeValue), newValue); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::remove(iterator it)
    {
        if (it == end())
            return;
        m_impl.remove(it.node());
        unlinkAndDelete(it.node());
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::remove(const ValueType& value)
    {
        remove(find(value));
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void ListHashSet<T, inlineCapacity, U>::clear()
    {
        deleteAllNodes();
        m_impl.clear(); 
        m_head = 0;
        m_tail = 0;
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::unlink(Node* node)
    {
        if (!node->m_prev) {
            ASSERT(node == m_head);
            m_head = node->m_next;
        } else {
            ASSERT(node != m_head);
            node->m_prev->m_next = node->m_next;
        }

        if (!node->m_next) {
            ASSERT(node == m_tail);
            m_tail = node->m_prev;
        } else {
            ASSERT(node != m_tail);
            node->m_next->m_prev = node->m_prev;
        }
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node)
    {
        unlink(node);
        node->destroy(m_allocator.get());
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::appendNode(Node* node)
    {
        node->m_prev = m_tail;
        node->m_next = 0;

        if (m_tail) {
            ASSERT(m_head);
            m_tail->m_next = node;
        } else {
            ASSERT(!m_head);
            m_head = node;
        }

        m_tail = node;
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::prependNode(Node* node)
    {
        node->m_prev = 0;
        node->m_next = m_head;

        if (m_head)
            m_head->m_prev = node;
        else
            m_tail = node;

        m_head = node;
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode)
    {
        if (!beforeNode)
            return appendNode(newNode);
        
        newNode->m_next = beforeNode;
        newNode->m_prev = beforeNode->m_prev;
        if (beforeNode->m_prev)
            beforeNode->m_prev->m_next = newNode;
        beforeNode->m_prev = newNode;

        if (!newNode->m_prev)
            m_head = newNode;
    }

    template<typename T, size_t inlineCapacity, typename U>
    void ListHashSet<T, inlineCapacity, U>::deleteAllNodes()
    {
        if (!m_head)
            return;

        for (Node* node = m_head, *next = m_head->m_next; node; node = next, next = node ? node->m_next : 0)
            node->destroy(m_allocator.get());
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSetReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeReverseIterator(Node* position) 
    {
        return ListHashSetReverseIterator<T, inlineCapacity, U>(this, position); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSetConstReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstReverseIterator(Node* position) const
    { 
        return ListHashSetConstReverseIterator<T, inlineCapacity, U>(this, position); 
    }
    
    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position) 
    {
        return ListHashSetIterator<T, inlineCapacity, U>(this, position); 
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline ListHashSetConstIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstIterator(Node* position) const
    { 
        return ListHashSetConstIterator<T, inlineCapacity, U>(this, position); 
    }
    template<bool, typename ValueType, typename HashTableType>
    void deleteAllValues(HashTableType& collection)
    {
        typedef typename HashTableType::const_iterator iterator;
        iterator end = collection.end();
        for (iterator it = collection.begin(); it != end; ++it)
            delete (*it)->m_value;
    }

    template<typename T, size_t inlineCapacity, typename U>
    inline void deleteAllValues(const ListHashSet<T, inlineCapacity, U>& collection)
    {
        deleteAllValues<true, typename ListHashSet<T, inlineCapacity, U>::ValueType>(collection.m_impl);
    }

} // namespace WTF

using WTF::ListHashSet;

#endif /* WTF_ListHashSet_h */
