/**
         *  Test key prefix membership in this trie (prefix search using key)
         *
         * @param prefix  key prefix to search
         * @return true if trie contains key prefix
         */
        public bool ContainsKeyPrefix(string prefix)
        {
            if (prefix == null)
            {
                throw new ArgumentNullException("Prefix key can not be null");
            }

            // An empty string is a prefix of everything
            if (prefix.Equals(""))
            {
                return(true);
            }

            // Find nearest node
            PatriciaNode <V> nearest = FindNearestNode(prefix);

            // If no nearest node exist, there isn't any prefix match either
            if (nearest == null)
            {
                return(false);
            }

            // The nearest is the root, so no match
            if (nearest.Key == null)
            {
                return(false);
            }

            // Test prefix match
            return(nearest.Key.StartsWith(prefix));
        }
        /**
         * Get value associated with specified key in this trie
         *
         * @param key  key to retrieve value for
         * @return value or null if non-existent
         */
        private V Get(string key)
        {
            // Keys can not be null
            if (key == null)
            {
                throw new ArgumentNullException("Key can not be null");
            }
            // Empty keys are stored in the root
            if (key.Equals(""))
            {
                if (root.Right == null)
                {
                    return(default(V));
                }
                else
                {
                    return(root.Right.Value);
                }
            }

            // Find nearest node
            PatriciaNode <V> nearest = FindNearestNode(key);

            // If the nearest node matches key, we have a match
            if (key.Equals(nearest.Key))
            {
                return(nearest.Value);
            }
            else
            {
                return(default(V));
            }
        }
 private void EntriesR(PatriciaNode <V> node, int bit, Dictionary <string, V> entries)
 {
     if (node.Bit <= bit)
     {
         return;
     }
     else
     {
         EntriesR(node.Left, node.Bit, entries);
         EntriesR(node.Right, node.Bit, entries);
         entries[node.Key] = node.Value;
     }
 }
 private void KeysR(PatriciaNode <V> node, int bit, HashSet <string> keys)
 {
     if (node.Bit <= bit)
     {
         return;
     }
     else
     {
         KeysR(node.Left, node.Bit, keys);
         KeysR(node.Right, node.Bit, keys);
         keys.Add(node.Key);
     }
 }
 private void ValuesR(PatriciaNode <V> node, int bit, List <V> list)
 {
     if (node.Bit <= bit)
     {
         return;
     }
     else
     {
         ValuesR(node.Left, node.Bit, list);
         ValuesR(node.Right, node.Bit, list);
         list.Add(node.Value);
     }
 }
        /**
         * Finds the closest node in the trie matching key
         *
         * @param key  key to look up
         * @return closest node, null null
         */
        private PatriciaNode <V> FindNearestNode(string key)
        {
            PatriciaNode <V> current = root.Left;
            PatriciaNode <V> parent  = root;

            while (parent.Bit < current.Bit)
            {
                parent = current;
                if (!keyMapper.IsSet(current.Bit, key))
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }
            return(current);
        }
        /**
         * Puts value into trie identifiable by key into this trie (key should be non-null)
         *
         * @param key  key to associate with value
         * @param value  value be inserted
         * @return value inserted
         * @throws NullPointerException in case key is null
         */
        private V Put(string key, V value)
        {
            // Keys can not be null
            if (key == null)
            {
                throw new ArgumentNullException("Key can not be null");
            }

            // Empty keys are stored in the root
            if (key.Equals(""))
            {
                PatriciaNode <V> nodeP = new PatriciaNode <V>(key, value, -1);
                nodeP.Value = value;
                root.Right  = nodeP;
                entries++;
                return(value);
            }

            // Find nearest node
            PatriciaNode <V> nearest = FindNearestNode(key);

            // Key already exist, replace value and return
            if (key.Equals(nearest.Key))
            {
                nearest.Value = value;
                return(value);
            }

            // Find differing bit and create new node to insert
            int bit = FindFirstDifferingBit(key, nearest.Key);
            PatriciaNode <V> node = new PatriciaNode <V>(key, value, bit);

            // Insert new node
            InsertNode(node);

            entries++;

            return(value);
        }
        /**
         * Inserts a node into this trie
         *
         * @param node  node to insert
         */
        private void InsertNode(PatriciaNode <V> node)
        {
            PatriciaNode <V> current = root.Left;
            PatriciaNode <V> parent  = root;

            while (parent.Bit < current.Bit && current.Bit < node.Bit)
            {
                parent = current;
                if (!keyMapper.IsSet(current.Bit, node.Key))
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }

            if (!keyMapper.IsSet(node.Bit, node.Key))
            {
                node.Left  = node;
                node.Right = current;
            }
            else
            {
                node.Left  = current;
                node.Right = node;
            }

            if (!keyMapper.IsSet(parent.Bit, node.Key))
            {
                parent.Left = node;
            }
            else
            {
                parent.Right = node;
            }
        }
 public void Clear()
 {
     root      = new PatriciaNode <V>(null, default(V), -1);
     root.Left = root;
     entries   = 0;
 }