/* classes/include/Ipv4PrefixPatricia.hh.  Generated automatically by configure.  */
//===========================================================================
//  $Name: arts++-1-1-a8 $
//  $Id: Ipv4PrefixPatricia.hh.in,v 1.12 2000/01/21 12:21:59 dwm Exp $
//
//  Daniel W. McRobb
//  CAIDA
//  December 1998
//===========================================================================

extern "C" {
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
  
#include "caida_t.h"
}

#include <vector>
#include <utility>

#include "Ipv4Network.hh"

#define WORDS_BIGENDIAN 1

//--------------------------------------------------------------------------
//!  Some constants to make erase() members a tad bit more readable.
//--------------------------------------------------------------------------
static const uint8_t   k_nodeSelfLinkLeft      = 0x01;
static const uint8_t   k_nodeSelfLinkRight     = 0x02;
static const uint8_t   k_nodeUpwardLinkLeft    = 0x03;
static const uint8_t   k_nodeUpwardLinkRight   = 0x04;
static const uint8_t   k_nodeDownwardLinkLeft  = 0x05;
static const uint8_t   k_nodeDownwardLinkRight = 0x06;

//----------------------------------------------------------------------------
//                          template <class Type>                          
//                          class Ipv4PrefixPatricia                         
//----------------------------------------------------------------------------
//!  This template class implements a Patricia tree keyed by IPv4 
//!  address. It is particularly useful for storing any type of data keyed 
//!  by IP address.  Because it's Patricia, exact match searches are 
//!  relatively speedy.  So are longest-match searches.
/*!
 *  The interfaces here are very STL-like, but there are some
 *  compromises for performance.  The most significant is the find()
 *  member.  While it returns an iterator, it's not a true iterator; you
 *  can't increment or decrement it because it doesn't contain the
 *  necessary information for tree traversal.  This has not been an
 *  issue when using this class; I guess I almost never call find()
 *  and then call an increment operator on the iterator.  In any case,
 *  the performance gain of skipping the stack-building overhead for
 *  returning a true iterator is significant, and searching is very
 *  common in my use of this class.
 *
 *  begin(), end(), rbegin() and rend() work as expected.  They 
 *  return an iterator (or a reverse_iterator) which can be incremented 
 *  to walk the whole tree in order of key value.  Hence you can use the
 *   typical 'for (iter = tree.begin(); iter != tree.end(); iter++)' loop 
 *  to walk the whole tree.  This is generally slow (due to the iterator
 *  maintenace while walking the tree) and shouldn't be done often if
 *  performance is a major concern.  Instead, you can use the visit()
 *  member when you want to perform some action on the whole tree; it's
 *  recursive and does not require iterator overhead.
 *
 *  operator [] works just like it does for STL's <map>: be careful, 
 *  it will insert if the key was not found.  This permits using it on the
 *  left hand side of a statement for assignment of a value in the tree.
 *
 *  erase() members work as expected, removing a key/value from the
 *  tree.
 *
 *  Finally, note that I haven't implemented prefix increment or
 *  any decrement operators for the iterators.  They're not difficult,
 *  I just haven't had a need for them yet.
 *
 *  Daniel W. McRobb
 *  CAIDA
 *  December 1998
 */
//----------------------------------------------------------------------------
template <class Type>
class Ipv4PrefixPatricia
{
public:
  //--------------------------------------------------------------------------
  //  Some useful typedefs.
  //--------------------------------------------------------------------------
  typedef Ipv4Network                  key_type;
  
  typedef Type                         data_type;
  
  typedef pair<const key_type, Type>   rep_type;

  typedef pair<const key_type, const Type>  const_rep_type;
  
  //--------------------------------------------------------------------------
  //                           class VlsmListEntry                           
  //--------------------------------------------------------------------------
  //!  This class encapsulates the storage of each entry in the tree.
  //!  It looks much like a pair<key_type,Type>.
  //--------------------------------------------------------------------------
  class VlsmListEntry : public pair<key_type,Type>
  {
  public:
    //------------------------------------------------------------------------
    //                             VlsmListEntry()                             
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    VlsmListEntry()
    {
      Type  initialValue;
      
      this->first.net = 0;
      this->first.maskLen = 32;
      this->second = initialValue;
    }
    
    //------------------------------------------------------------------------
    //          VlsmListEntry(const key_type key, const Type & value)          
    //........................................................................
    //!  constructor accepting a key and value.
    //------------------------------------------------------------------------
    VlsmListEntry(const key_type key, const Type & value) 
    {
      this->first =  key;
      this->second = value;
    }

    //------------------------------------------------------------------------
    //              VlsmListEntry(const VlsmListEntry & vlsmEntry) 
    //........................................................................
    //!  copy constructor
    //------------------------------------------------------------------------
    VlsmListEntry(const VlsmListEntry & vlsmEntry)
    {
      this->first = vlsmEntry.first;
      this->second = vlsmEntry.second;
    }
    
    //------------------------------------------------------------------------
    //       VlsmListEntry & operator = (const VlsmListEntry & vlsmEntry) 
    //........................................................................
    //  
    //------------------------------------------------------------------------
    VlsmListEntry & operator = (const VlsmListEntry & vlsmEntry)
    {
      this->first = vlsmEntry.first;
      this->second = vlsmEntry.second;
      return(*this);
    }
  };

  //--------------------------------------------------------------------------
  //!  value_type typedef
  //--------------------------------------------------------------------------
  typedef VlsmListEntry  value_type;
  
  
  //--------------------------------------------------------------------------
  //              class VlsmList : public vector<VlsmListEntry>              
  //--------------------------------------------------------------------------
  //!  This class is just a vector<VlsmListEntry> with the addition of
  //!  a specialized constructor.  Internally we use this class to hold
  //!  our VlsmListEntry objects which contain our key/value pairs.
  //--------------------------------------------------------------------------
  class VlsmList : public vector<VlsmListEntry>
  {
  public:
    //------------------------------------------------------------------------
    //             VlsmList(const key_type key, const Type & value)            
    //........................................................................
    //!  constructor accepting a key and value.
    //------------------------------------------------------------------------
    VlsmList(const key_type key, const Type & value)
    {
      VlsmListEntry newEntry(key,value);
      this->push_back(newEntry);
    }

    VlsmList(const key_type key)
    {
      Type  newValue;
      VlsmListEntry newEntry(key,newValue);
      this->push_back(newEntry);
    }
  };
  
  
  //--------------------------------------------------------------------------
  //  Ipv4PrefixPatricia class variables
  //--------------------------------------------------------------------------
  VlsmList                    vlsmVect;
  Ipv4PrefixPatricia<Type>   *lft;      //  tree node left branch
  Ipv4PrefixPatricia<Type>   *rgt;      //  tree node right branch
  Ipv4PrefixPatricia<Type>   *parent;   //  tree node parent
  uint32_t                    bit;      //  bit to check when traversing tree
  

  //--------------------------------------------------------------------------
  //                           class StackEntry                              
  //--------------------------------------------------------------------------
  //!  This class is just a helper class; it is used to hold a stack
  //!  entry inside an iterator when doing in-order tree traversal.  To
  //!  implement the in-order iterator, we can't use recurion and hence
  //!  we emulate it with a stack (basically do what the compiler would
  //!  do for recursion).
  //--------------------------------------------------------------------------
  class StackEntry
  {
  public:
    //------------------------------------------------------------------------
    //  class variables
    //------------------------------------------------------------------------
    Ipv4PrefixPatricia<Type>            *nodePtr;
    vector<VlsmListEntry>::iterator    vlsmIter;
    bool                               wentLeft;
    bool                               wentRight;
    
    //------------------------------------------------------------------------
    //                          StackEntry()                                 
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    StackEntry()
    {
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
      this->vlsmIter = (vector<VlsmListEntry>::iterator)0;
      this->wentLeft = false;
      this->wentRight = false;
    }

    //------------------------------------------------------------------------
    //                StackEntry(const StackEntry & stackEntry) 
    //........................................................................
    //!  copy constructor
    //------------------------------------------------------------------------
    StackEntry(const StackEntry & stackEntry)
    {
      this->nodePtr = stackEntry.nodePtr;
      this->wentLeft = stackEntry.wentLeft;
      this->wentRight = stackEntry.wentRight;
      this->vlsmIter = stackEntry.vlsmIter;
    }
    
    //------------------------------------------------------------------------
    //                         ~StackEntry()                                 
    //........................................................................
    //!  destructor
    //------------------------------------------------------------------------
    ~StackEntry()
    {
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
      this->vlsmIter = (vector<VlsmListEntry>::iterator)0;
    }
    
    //-------------------------------------------------------------------------
    //       StackEntry & operator = (const StackEntry & stackEntry)       
    //.........................................................................
    //!  Copies one StackEntry to another.
    //-------------------------------------------------------------------------
    StackEntry & operator = (const StackEntry & stackEntry)
    {
      this->nodePtr = stackEntry.nodePtr;
      this->wentLeft = stackEntry.wentLeft;
      this->wentRight = stackEntry.wentRight;
      this->vlsmIter = stackEntry.vlsmIter;
      return(*this);
    }
    
    //-------------------------------------------------------------------------
    //            operator == (const StackEntry & stackEntry) const            
    //.........................................................................
    //!  operator ==
    //-------------------------------------------------------------------------
    bool operator == (const StackEntry & stackEntry) const
    {
      return(this->nodePtr == stackEntry.nodePtr &&
             this->wentLeft == stackEntry.wentLeft &&
             this->wentRight == stackEntry.wentRight &&
             this->vlsmIter == stackEntry.vlsmIter);
    }
  };
  
  //--------------------------------------------------------------------------
  //                            class iterator                               
  //--------------------------------------------------------------------------
  //!  This class is used to represent a tree iterator.  It is returned
  //!  by the begin(), end() and find() functions, and may be used to
  //!  step through the tree in order of key value.
  //--------------------------------------------------------------------------
  class iterator
  {
  public:
    vector<StackEntry>            nodeStack;
    Ipv4PrefixPatricia<Type>     *nodePtr;
    bool                          end;
    VlsmList::iterator            vlsmIter;
    
    //------------------------------------------------------------------------
    //                                iterator()                               
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    iterator()
    {
      this->end = false;
    }
    
    //------------------------------------------------------------------------
    //                     iterator(const iterator & iter) 
    //........................................................................
    //!  copy constructor
    //------------------------------------------------------------------------
    iterator(const iterator & iter)
    {
      this->nodeStack = iter.nodeStack;
      this->nodePtr = iter.nodePtr;
      this->vlsmIter = iter.vlsmIter;
      this->end = iter.end;
    }
    
    //------------------------------------------------------------------------
    //                  iterator(Ipv4PrefixPatricia<Type> *head)           
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    iterator(Ipv4PrefixPatricia<Type> *head)
    {
      this->end = false;
    }
    
    //------------------------------------------------------------------------
    //                           virtual ~iterator() 
    //........................................................................
    //!  destructor
    //------------------------------------------------------------------------
    virtual ~iterator()
    {
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    }
    
    //------------------------------------------------------------------------
    //         virtual iterator & operator = (const iterator & iter)
    //........................................................................
    //!  operator =
    //------------------------------------------------------------------------
    virtual iterator & operator = (const iterator & iter)
    {
      this->nodeStack = iter.nodeStack;
      this->nodePtr = iter.nodePtr;
      this->vlsmIter = iter.vlsmIter;
      this->end = iter.end;
      
      return(*this);
    }
    
    //------------------------------------------------------------------------
    //                   iterator & operator ++ (int foo)
    //........................................................................
    //!  Postfix ++ operator.  Moves the iterator the next entry in the
    //!  tree and returns the iterator.  Returns end() when the iterator
    //!  is at the end of the tree (one past the last tree entry).
    //------------------------------------------------------------------------
    iterator & operator ++ (int foo)
    {
      vector<StackEntry>::iterator       stackIter;
      uint32_t                           bitNum;
      Ipv4PrefixPatricia<Type>          *leftNode;
      Ipv4PrefixPatricia<Type>          *rightNode;
      
      this->vlsmIter++;
      
      if (! (this->vlsmIter == this->nodePtr->vlsmVect.end())) {
        return(*this);
      }
      
      while (this->nodeStack.size() > 0) {
        stackIter = this->nodeStack.end() - 1;
        bitNum = (*stackIter).nodePtr->bit;
        leftNode  = (*stackIter).nodePtr->lft;
        rightNode = (*stackIter).nodePtr->rgt;
        
        if ((*stackIter).wentLeft == false) {
          (*stackIter).wentLeft = true;
          if (leftNode->bit < bitNum) {
            StackEntry  newStackEntry;
            newStackEntry.nodePtr = leftNode;
            newStackEntry.vlsmIter = leftNode->vlsmVect.begin();
            this->nodeStack.push_back(newStackEntry);
            continue;
          }
          else {
            if (leftNode->bit != 32) {
              this->nodePtr = leftNode;
              this->vlsmIter = leftNode->vlsmVect.begin();
              return(*this);
            }
          }
        }
        
        if ((*stackIter).wentRight == false) {
          (*stackIter).wentRight = true;
          if (rightNode->bit < bitNum) {
            StackEntry  newStackEntry;
            newStackEntry.nodePtr = rightNode;
            newStackEntry.vlsmIter = leftNode->vlsmVect.begin();
            (*this).nodeStack.push_back(newStackEntry);
            continue;
          }
          else {
            if (rightNode->bit != 32) {
              this->nodePtr = rightNode;
              this->vlsmIter = rightNode->vlsmVect.begin();
              return(*this);
            }
          }
        }
        
        (*this).nodeStack.pop_back();
      }
      
      this->end = true;
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
      return(*this);
    }
    
    //------------------------------------------------------------------------
    //                    iterator & operator -- (int)
    //........................................................................
    //!  NOT IMPLEMENTED
    //------------------------------------------------------------------------
    iterator & operator -- (int)
    {
      cerr << "operator -- (int) not implemented for"
           << " Ipv4PrefixPatricia::iterator class!" << endl;
      abort();
    }
    
    //------------------------------------------------------------------------
    //          virtual rep_type & operator * ()
    //........................................................................
    //!  Dereference operator.  Returns a reference to the key/value
    //!  pointed to by the iterator.  Note that the first entry in the
    //!  returned pair is const; we don't want someone to be able to
    //!  modify the key value via the iterator, it could break the tree
    //!  and the iterator itself!
    //------------------------------------------------------------------------
    virtual rep_type & operator * ()
    {
      return((rep_type &)(*this->vlsmIter));
    }
    
    virtual const rep_type & operator * () const
    {
      return((rep_type &)(*this->vlsmIter));
    }

    //------------------------------------------------------------------------
    //                   operator != (const iterator & iter) const
    //........................................................................
    //!  operator !=
    //------------------------------------------------------------------------
    bool operator != (const iterator & iter) const
    {
      return(this->nodePtr != iter.nodePtr);
    }
    
    //------------------------------------------------------------------------
    //                   operator == (const iterator & iter) const
    //........................................................................
    //!  operator ==
    //------------------------------------------------------------------------
    bool operator == (const iterator & iter) const
    {
      return(this->nodeStack == iter.nodeStack &&
             this->nodePtr == iter.nodePtr &&
             this->end == iter.end);
    }
    
  };


  //--------------------------------------------------------------------------
  //                          class reverse_iterator                         
  //--------------------------------------------------------------------------
  //!  This class is just like our iterator class, but permits reverse
  //!  traversal of the tree.  It is returned by rbegin() and rend(),
  //!  and allows the typical reverse traversal loop:
  /*!  \verbatim
       for (riter = tree.rbegin(); riter != tree.rend(); riter++) {
         ...
       }
       \endverbatim
   */
  //--------------------------------------------------------------------------
  class reverse_iterator
  {
  public:
    vector<StackEntry>           nodeStack;
    Ipv4PrefixPatricia<Type>    *nodePtr;
    VlsmList::reverse_iterator   vlsmIter;
    bool                         end;
    
    //------------------------------------------------------------------------
    //                            reverse_iterator()                           
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    reverse_iterator()
    {
      this->end = false;
    }
    
    //------------------------------------------------------------------------
    //           reverse_iterator(Ipv4PrefixPatricia<Type> *head)
    //........................................................................
    //!  constructor
    //------------------------------------------------------------------------
    reverse_iterator(Ipv4PrefixPatricia<Type> *head)
    {
      this->end = false;
    }
    
    //------------------------------------------------------------------------
    //                       virtual ~reverse_iterator() 
    //........................................................................
    //!  destructor
    //------------------------------------------------------------------------
    virtual ~reverse_iterator()
    {
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    }
    
    //------------------------------------------------------------------------
    //     reverse_iterator & operator = (const reverse_iterator & iter)
    //........................................................................
    //!  Copies a reverse_iterator.
    //------------------------------------------------------------------------
    reverse_iterator & operator = (const reverse_iterator & iter)
    {
      this->nodeStack = iter.nodeStack;
      this->nodePtr   = iter.nodePtr;
      this->vlsmIter  = iter.vlsmIter;
      this->end       = iter.end;
      
      return(*this);
    }
    
    //------------------------------------------------------------------------
    //                 reverse_iterator & operator ++ (int foo)                
    //........................................................................
    //!  Postfix ++ operator.
    //------------------------------------------------------------------------
    reverse_iterator & operator ++ (int foo)
    {
      vector<StackEntry>::iterator       stackIter;
      uint32_t                           bitNum;
      Ipv4PrefixPatricia<Type>          *leftNode;
      Ipv4PrefixPatricia<Type>          *rightNode;
      
      this->vlsmIter++;
      if (! (this->vlsmIter == this->nodePtr->vlsmVect.rend()))
        return(*this);
      
      while (this->nodeStack.size() > 0) {
        stackIter = this->nodeStack.end() - 1;
        bitNum = (*stackIter).nodePtr->bit;
        leftNode  = (*stackIter).nodePtr->lft;
        rightNode = (*stackIter).nodePtr->rgt;
        
        if ((*stackIter).wentRight == false) {
          (*stackIter).wentRight = true;
          if (rightNode->bit < bitNum) {
            StackEntry  newStackEntry;
            newStackEntry.nodePtr = rightNode;
            (*this).nodeStack.push_back(newStackEntry);
            continue;
          }
          else {
            if (rightNode->bit != 32) {
              this->nodePtr = rightNode;
              this->vlsmIter = rightNode->vlsmVect.rbegin();
              return(*this);
            }
          }
        }
        
        if ((*stackIter).wentLeft == false) {
          (*stackIter).wentLeft = true;
          if (leftNode->bit < bitNum) {
            StackEntry  newStackEntry;
            newStackEntry.nodePtr = leftNode;
            this->nodeStack.push_back(newStackEntry);
            continue;
          }
          else {
            if (leftNode->bit != 32) {
              this->nodePtr = leftNode;
              this->vlsmIter = leftNode->vlsmVect.rbegin();
              return(*this);
            }
          }
        }
        
        (*this).nodeStack.pop_back();
      }
      
      this->nodePtr = (Ipv4PrefixPatricia<Type> *)0;
      this->end = true;
      return(*this);
    }
    
    //------------------------------------------------------------------------
    //                    reverse_iterator & operator -- ()                    
    //........................................................................
    //!  NOT IMPLEMENTED
    //------------------------------------------------------------------------
    reverse_iterator & operator -- ()
    {
      cerr << "operator -- (int) not implemented for"
           << " Ipv4PrefixPatricia::reverse_iterator class!" << endl;
      abort();
    }
    
    //------------------------------------------------------------------------
    //             virtual rep_type & operator * () const
    //........................................................................
    //!  Dereference operator.  Returns a reference to the key/value
    //!  pointed to by the reverse_iterator.  Note that the first entry
    //!  in the returned pair is const; we don't want someone to be able
    //!  to modify the key value via the reverse_iterator, it could break
    //!  the tree and the reverse_iterator itself!
    //------------------------------------------------------------------------
    virtual rep_type & operator * () const
    {
      return((rep_type &)(*this->vlsmIter));
    }
    
    //------------------------------------------------------------------------
    //         bool operator != (const reverse_iterator & iter) const
    //........................................................................
    //!  
    //------------------------------------------------------------------------
    bool operator != (const reverse_iterator & iter) const
    {
      return(// this->nodeStack != iter.nodeStack ||
             // this->end != iter.end ||
             this->nodePtr != iter.nodePtr);
    }
    
    //------------------------------------------------------------------------
    //       bool operator == (const reverse_iterator & iter) const
    //........................................................................
    //
    //------------------------------------------------------------------------
    bool operator == (const reverse_iterator & iter) const
    {
      return(this->nodeStack == iter.nodeStack &&
             this->nodePtr == iter.nodePtr &&
             this->end == iter.end);
    }
    
  };

  //--------------------------------------------------------------------------
  //                  Ipv4PrefixPatricia() : value(0,Type())                  
  //..........................................................................
  //!  constructor
  //--------------------------------------------------------------------------
  Ipv4PrefixPatricia() : vlsmVect(key_type(0,32),Type())
  {
    this->bit = 32;
    this->parent = (Ipv4PrefixPatricia<Type> *)0;
    this->lft = this;
    this->rgt = this;
    this->_size = 0;
  }
  
  //--------------------------------------------------------------------------
  //                Ipv4PrefixPatricia(const value_type& Value)                
  //                    : value(Value.first,Value.second)                    
  //..........................................................................
  //!  Constructor accepting an initial key and value.  Note that all we do
  //!  here is initialize our vlsmVect via the initializer list.
  //--------------------------------------------------------------------------
  Ipv4PrefixPatricia(const value_type& Value) 
      : vlsmVect(Value.first,Value.second)
  {
  }

  //--------------------------------------------------------------------------
  //     Ipv4PrefixPatricia & 
  //     operator = (Ipv4PrefixPatricia<Type> & ipv4PrefixPatricia) 
  //..........................................................................
  //!  overloaded = operator to deep-copy an Ipv4PrefixPatricia<Type>.
  //--------------------------------------------------------------------------
  Ipv4PrefixPatricia &
  operator = (Ipv4PrefixPatricia<Type> & ipv4PrefixPatricia)
  {
    Ipv4PrefixPatricia<Type>::iterator  rhsIter;
    for (rhsIter = ipv4PrefixPatricia.begin();
         rhsIter != ipv4PrefixPatricia.end(); rhsIter++) {
      (*this)[(*rhsIter).first] = (*rhsIter).second;
    }
    return(*this);
  }
  
  //--------------------------------------------------------------------------
  //                             iterator begin()                            
  //..........................................................................
  //!  Builds and returns an iterator pointing to the first entry (by key
  //!  value) in the tree.  You may increment the return iterator (using the
  //!  postfix ++ operator) to step through the tree in order (by key value),
  //!  using the typical for (iter = tree.begin(); iter != tree.end(); iter++)
  //!  loop.
  //--------------------------------------------------------------------------
  iterator begin()
  {
    StackEntry                        stackEntry;
    iterator                          retIter;
    vector<StackEntry>::iterator      stackIter;
    Ipv4PrefixPatricia<Type>         *leftNode;
    Ipv4PrefixPatricia<Type>         *rightNode;
    uint32_t                          bitNum;
    
    stackEntry.nodePtr   = this;
    stackEntry.wentLeft  = false;
    stackEntry.wentRight = false;
    
    retIter.nodeStack.push_back(stackEntry);
    
    while (retIter.nodeStack.size() > 0) {
      stackIter = retIter.nodeStack.end() - 1;
      bitNum = (*stackIter).nodePtr->bit;
      leftNode  = (*stackIter).nodePtr->lft;
      rightNode = (*stackIter).nodePtr->rgt;
      
      if ((*stackIter).wentLeft == false) {
        
        (*stackIter).wentLeft = true;
        
        if (leftNode->bit < bitNum) {
          StackEntry  newStackEntry;
          newStackEntry.nodePtr = leftNode;
          newStackEntry.vlsmIter = leftNode->vlsmVect.begin();
          retIter.nodeStack.push_back(newStackEntry);
          continue;
        }
        else {
          if (leftNode->bit != 32) {
            retIter.nodePtr = leftNode;
            retIter.end = false;
            retIter.vlsmIter = leftNode->vlsmVect.begin();
            return(retIter);
          }
        }
      }
      
      if ((*stackIter).wentRight == false) {
        (*stackIter).wentRight = true;
        if (rightNode->bit < bitNum) {
          StackEntry  newStackEntry;
          newStackEntry.nodePtr = rightNode;
          newStackEntry.vlsmIter = rightNode->vlsmVect.begin();
          retIter.nodeStack.push_back(newStackEntry);
          continue;
        }
        else {
          if (rightNode->bit != 32) {
            retIter.nodePtr = rightNode;
            retIter.end = false;
            retIter.vlsmIter = rightNode->vlsmVect.begin();
            return(retIter);
          }
        }
      }
      retIter.nodeStack.pop_back();
    }
    retIter.end = true;
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    
    return(retIter);
  }
  
  //--------------------------------------------------------------------------
  //                        reverse_iterator rbegin()                        
  //..........................................................................
  //!  Builds and returns a reverse_iterator pointing to the last entry
  //!  (by key value) in the tree.  You may increment the returned
  //!  reverse_iterator (using the postfix ++ operator) to step through
  //!  the tree in reverse order (by key value), using the typical
  //!  for (revIter = tree.rbegin(); revIter != tree.rend(); revIter++)
  //!  loop.
  //--------------------------------------------------------------------------
  reverse_iterator rbegin()
  {
    StackEntry                        stackEntry;
    reverse_iterator                  retIter;
    vector<StackEntry>::iterator      stackIter;
    Ipv4PrefixPatricia<Type>         *leftNode;
    Ipv4PrefixPatricia<Type>         *rightNode;
    uint32_t                          bitNum;
    
    stackEntry.nodePtr   = this;
    stackEntry.wentLeft  = false;
    stackEntry.wentRight = false;
    
    retIter.nodeStack.push_back(stackEntry);
    
    while (retIter.nodeStack.size() > 0) {
      stackIter = retIter.nodeStack.end() - 1;
      bitNum = (*stackIter).nodePtr->bit;
      leftNode  = (*stackIter).nodePtr->lft;
      rightNode = (*stackIter).nodePtr->rgt;
      
      if ((*stackIter).wentRight == false) {
        (*stackIter).wentRight = true;
        if (rightNode->bit < bitNum) {
          StackEntry  newStackEntry;
          newStackEntry.nodePtr = rightNode;
          retIter.nodeStack.push_back(newStackEntry);
          continue;
        }
        else {
          if (rightNode->bit != 32) {
            retIter.nodePtr = rightNode;
            retIter.end = false;
            retIter.vlsmIter = rightNode->vlsmVect.rbegin();
            return(retIter);
          }
        }
      }
      
      if ((*stackIter).wentLeft == false) {
        (*stackIter).wentLeft = true;
        if (leftNode->bit < bitNum) {
          StackEntry  newStackEntry;
          newStackEntry.nodePtr = leftNode;
          retIter.nodeStack.push_back(newStackEntry);
          continue;
        }
        else {
          if (leftNode->bit != 32) {
            retIter.nodePtr = leftNode;
            retIter.end = false;
            retIter.vlsmIter = leftNode->vlsmVect.rbegin();
            return(retIter);
          }
        }
      }
      
      retIter.nodeStack.pop_back();
    }
    
    retIter.end = true;
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    
    return(retIter);
  }
  
  //--------------------------------------------------------------------------
  //                          inline iterator end()                          
  //..........................................................................
  //!  Returns an iterator that indicates the end of the tree.
  //!  This can be used just like you'd use end() in an STL container,
  //!  except it can't be decremented meanigfully.  i.e. it's really only
  //!  useful when you're using the forward iterator to walk through
  //!  the tree or you're checking the return of find() or LongestMatch().
  //--------------------------------------------------------------------------
  inline iterator end()
  {
    iterator  retIter;
    retIter.end = true;
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    return(retIter);
  }
  
  //--------------------------------------------------------------------------
  //                         reverse_iterator rend()                         
  //..........................................................................
  //!  Returns a reverse_iterator that indicates the reverse end of the
  //!  tree.  This can be used just like you'd use rend() in an STL
  //!  container, except it can't be decremented meanigfully.  i.e. it's
  //!  really only useful when you're using the forward iterator to walk
  //!  through the tree or you're checking the return of find() or
  //!  LongestMatch().
  //--------------------------------------------------------------------------
  reverse_iterator rend()
  {
    reverse_iterator retIter;
    retIter.end = true;
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    return(retIter);
  }
  
  //--------------------------------------------------------------------------
  //              inline iterator find(const key_type & keyVal)             
  //..........................................................................
  //!  Searches the tree for an entry whose key exactly matches keyVal.
  //!  Returns an iterator pointing to the tree entry if a match was
  //!  found, else returns end().
  //!  Note that you can NOT increment or decrement the returned iterator!
  //!  For performance reasons, we don't return a true iterator; you should
  //!  only use the dereference operator (*) and the first and second
  //!  members in the returned iterator, just like you would with an STL
  //!  map iterator.
  //--------------------------------------------------------------------------
  inline iterator find(const key_type & keyVal)
  {
    iterator                          retIter;
    Ipv4PrefixPatricia<Type>           *treeNode, *nextNode;
    vector<VlsmListEntry>::iterator   vlsmIter;
    
    treeNode = this;
    nextNode = treeNode->lft;
    
    while (treeNode->bit > nextNode->bit) {
      treeNode = nextNode;
      nextNode =
        (bitset(keyVal.net,nextNode->bit)) ? nextNode->rgt : nextNode->lft;
    }
    
    for (vlsmIter = nextNode->vlsmVect.begin();
         vlsmIter != nextNode->vlsmVect.end(); vlsmIter++) {
      if (keyVal == (*vlsmIter).first) {
        retIter.nodePtr = nextNode;
        retIter.vlsmIter = vlsmIter;
        retIter.end = false;
        return(retIter);
      }
    }
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    retIter.end = true;
    
    return(retIter);
    
  }
  
  //--------------------------------------------------------------------------
  //         inline iterator LongestMatch(const ipv4addr_t & ipv4addr)
  //..........................................................................
  //!  This member function permits searching for a longest-match IP
  //!  address.  It returns an iterator pointing to the matching entry if
  //!  a match is found, else returns end().
  //!  Note that you can NOT increment or decrement the returned iterator!
  //!  For performance reasons, we don't return a true iterator; you should
  //!  only use the dereference operator (*) and the first and second
  //!  members in the returned iterator, just like you would with an STL
  //!  map iterator.
  //--------------------------------------------------------------------------
  inline iterator LongestMatch(const ipv4addr_t & ipv4addr)
  {
    iterator                          retIter;
    Ipv4PrefixPatricia<Type>           *treeNode, *nextNode;
    vector<VlsmListEntry>::iterator   vlsmIter;
    
    treeNode = this;
    nextNode = treeNode->lft;
    
    while (treeNode->bit > nextNode->bit) {
      treeNode = nextNode;
      nextNode =
        (bitset(ipv4addr,nextNode->bit)) ? nextNode->rgt : nextNode->lft;
    }
    
    for (vlsmIter = nextNode->vlsmVect.begin();
         vlsmIter != nextNode->vlsmVect.end(); vlsmIter++) {
      if ((*vlsmIter).first.Matches(ipv4addr)) {
        retIter.nodePtr = nextNode;
        retIter.vlsmIter = vlsmIter;
        retIter.end = false;
        return(retIter);
      }
    }

    while (nextNode->parent && nextNode->bit != 32) {
      nextNode = nextNode->parent;
      if ((ipv4addr & nextNode->vlsmVect[0].first.net)
          == nextNode->vlsmVect[0].first.net) {
        for (vlsmIter = nextNode->vlsmVect.begin();
             vlsmIter != nextNode->vlsmVect.end(); vlsmIter++) {
          if ((*vlsmIter).first.Matches(ipv4addr) &&
              (*vlsmIter).first.net != 0) {
            retIter.nodePtr = nextNode;
            retIter.vlsmIter = vlsmIter;
            retIter.end = false;
            return(retIter);
          }
        }
      }
    }
    
    retIter.nodePtr = (Ipv4PrefixPatricia<Type> *)0;
    retIter.end = true;
    
    return(retIter);
  }
  
  //--------------------------------------------------------------------------
  //                       const uint32_t size() const                       
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  const uint32_t size() const
  {
    return(this->_size);
  }

  //--------------------------------------------------------------------------
  //               Type & operator [] (const key_type & keyVal)              
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  Type & operator [] (const key_type & keyVal)
  {
    return (*((insert(value_type(keyVal, Type()))).first)).second;
  }

  //--------------------------------------------------------------------------
  //           pair<iterator,bool> & insert(const value_type & value)
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  pair<iterator,bool> & insert(const value_type & value)
  {
    static pair<Ipv4PrefixPatricia<Type>::iterator,bool>  retVal;
    
    retVal = _insert(value);
    if (retVal.second) {
      _size++;
    }
    return(retVal);
  }
  
  //--------------------------------------------------------------------------
  //     inline void                               
  //     visit(void (*visitFunc)(Ipv4PrefixPatricia<Type> & value, void *), 
  //           void *other)                        
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  inline void
  visit(void (*visitFunc)(VlsmList::iterator & value, void *),
        void *other)
  {
    _visit(this->lft,visitFunc,other,33);
  }

  //-------------------------------------------------------------------------
  //                   bool erase(const key_type & keyVal)                   
  //.........................................................................
  //!  Erases the tree entry with key equal to keyVal.  Returns true if
  //!  node was found (and hence deleted), else returns false.
  //-------------------------------------------------------------------------
  bool erase(const key_type & keyVal)
  {
    Ipv4PrefixPatricia<Type>           *unode, *dnode;
    uint8_t                             u2dLinkType;
    
    unode = this;
    dnode = unode->lft;

    while (unode->bit > dnode->bit) {
      unode = dnode;
      if (bitset(keyVal.net,dnode->bit)) {
        dnode = dnode->rgt;
      }
      else {
        dnode = dnode->lft;
      }
    }

    if (keyVal.net != dnode->vlsmVect[0].first.net) {
      return(false);
    }

    bool                  foundVlsmEntry = false;
    VlsmList::iterator    vlsmDeleteIter;
    
    for (vlsmDeleteIter = dnode->vlsmVect.begin();
         vlsmDeleteIter != dnode->vlsmVect.end(); vlsmDeleteIter++) {
      if ((*vlsmDeleteIter).first == keyVal) {
        foundVlsmEntry = true;
        break;
      }
    }

    if (!foundVlsmEntry) {
      return(false);
    }

    //  Now I need to do the actual deletion.  If the vlsm list has
    //  more than one entry, I just remove the vlsm list entry.
    //  Otherwise I also need to remove the tree node.

    if (dnode->vlsmVect.size() > 1) {
      dnode->vlsmVect.erase(vlsmDeleteIter);
      this->_size--;
      return(true);
    }
    
    if (unode == dnode) {
      if (unode->lft == dnode) {
        u2dLinkType = k_nodeSelfLinkLeft;
      }
      else {
        u2dLinkType = k_nodeSelfLinkRight;
      }
    }
    else {
      if (unode->lft == dnode) {
        u2dLinkType = k_nodeUpwardLinkLeft;
      }
      else {
        u2dLinkType = k_nodeUpwardLinkRight;
      }
    }

    switch (u2dLinkType) 
    {
      case k_nodeSelfLinkLeft:
        if (unode->parent->lft == unode) {
          unode->parent->lft = unode->rgt;
        }
        else {
          unode->parent->rgt = unode->rgt;
        }
        unode->rgt->parent = unode->parent;
        delete(dnode);
        break;
        
      case k_nodeSelfLinkRight:
        if (unode->parent->lft == unode) {
          unode->parent->lft = unode->lft;
        }
        else {
          unode->parent->rgt = unode->lft;
        }
        unode->lft->parent = unode->parent;
        delete(dnode);
        break;
        
      case k_nodeUpwardLinkLeft:
        unode->lft = dnode->lft;
        if (unode->rgt != unode) {
          if (unode->parent->lft == unode) {
            unode->parent->lft = unode->rgt;
          }
          else {
            unode->parent->rgt = unode->rgt;
          }
        }
        unode->rgt->parent = unode->parent;
        unode->rgt = dnode->rgt;
        unode->parent = dnode->parent;
        if (dnode->parent->lft == dnode)
          dnode->parent->lft = unode;
        else
          dnode->parent->rgt = unode;
        unode->bit = dnode->bit;
        if (dnode->rgt->bit < dnode->bit)
          dnode->rgt->parent = unode;
        if (dnode->lft->bit < dnode->bit)
          dnode->lft->parent = unode;
        delete(dnode);
        break;
        
      case k_nodeUpwardLinkRight:
        unode->rgt = dnode->rgt;
        if (unode->lft != unode) {
          if (unode->parent->lft == unode) {
            unode->parent->lft = unode->lft;
          }
          else {
            unode->parent->rgt = unode->lft;
          }
        }
        unode->lft->parent = unode->parent;
        unode->lft = dnode->lft;
        unode->parent = dnode->parent;
        if (dnode->parent->lft == dnode)
          dnode->parent->lft = unode;
        else
          dnode->parent->rgt = unode;
        unode->bit = dnode->bit;
        if (dnode->rgt->bit < dnode->bit)
          dnode->rgt->parent = unode;
        if (dnode->lft->bit < dnode->bit)
          dnode->lft->parent = unode;
        delete(dnode);
        break;
        
      default:
        break;
    }
    
    this->_size--;
    
    return(true);
  }

  //--------------------------------------------------------------------------
  //                    bool erase(const iterator & iter)                    
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  bool erase(const iterator & iter)
  {
    Ipv4PrefixPatricia<Type>  *unode, *dnode;
    const key_type             keyVal = (*iter).first;
    uint8_t                    u2dLinkType;
    
    unode = this;
    dnode = unode->lft;

    while (unode->bit > dnode->bit) {
      unode = dnode;
      if (bitset(keyVal.net,dnode->bit)) {
        dnode = dnode->rgt;
      }
      else {
        dnode = dnode->lft;
      }
    }

    if (keyVal.net != dnode->vlsmVect[0].first.net) {
      return(false);
    }

    bool                  foundVlsmEntry = false;
    VlsmList::iterator    vlsmDeleteIter;
    
    for (vlsmDeleteIter = dnode->vlsmVect.begin();
         vlsmDeleteIter != dnode->vlsmVect.end(); vlsmDeleteIter++) {
      if ((*vlsmDeleteIter).first == keyVal) {
        foundVlsmEntry = true;
        break;
      }
    }

    if (!foundVlsmEntry) {
      return(false);
    }

    //  Now I need to do the actual deletion.  If the vlsm list has
    //  more than one entry, I just remove the vlsm list entry.
    //  Otherwise I also need to remove the tree node.

    if (dnode->vlsmVect.size() > 1) {
      dnode->vlsmVect.erase(vlsmDeleteIter);
      this->_size--;
      return(true);
    }

    if (unode == dnode) {
      if (unode->lft == dnode) {
        u2dLinkType = k_nodeSelfLinkLeft;
      }
      else {
        u2dLinkType = k_nodeSelfLinkRight;
      }
    }
    else {
      if (unode->lft == dnode) {
        u2dLinkType = k_nodeUpwardLinkLeft;
      }
      else {
        u2dLinkType = k_nodeUpwardLinkRight;
      }
    }

    switch (u2dLinkType) 
    {
      case k_nodeSelfLinkLeft:
        if (unode->parent->lft == unode) {
          unode->parent->lft = unode->rgt;
        }
        else {
          unode->parent->rgt = unode->rgt;
        }
        unode->rgt->parent = unode->parent;
        delete(dnode);
        break;
        
      case k_nodeSelfLinkRight:
        if (unode->parent->lft == unode) {
          unode->parent->lft = unode->lft;
        }
        else {
          unode->parent->rgt = unode->lft;
        }
        unode->lft->parent = unode->parent;
        delete(dnode);
        break;
        
      case k_nodeUpwardLinkLeft:
        unode->lft = dnode->lft;
        if (unode->rgt != unode) {
          if (unode->parent->lft == unode) {
            unode->parent->lft = unode->rgt;
          }
          else {
            unode->parent->rgt = unode->rgt;
          }
        }
        unode->rgt->parent = unode->parent;
        unode->rgt = dnode->rgt;
        unode->parent = dnode->parent;
        if (dnode->parent->lft == dnode)
          dnode->parent->lft = unode;
        else
          dnode->parent->rgt = unode;
        unode->bit = dnode->bit;
        if (dnode->rgt->bit < dnode->bit)
          dnode->rgt->parent = unode;
        if (dnode->lft->bit < dnode->bit)
          dnode->lft->parent = unode;
        delete(dnode);
        break;
        
      case k_nodeUpwardLinkRight:
        unode->rgt = dnode->rgt;
        if (unode->lft != unode) {
          if (unode->parent->lft == unode) {
            unode->parent->lft = unode->lft;
          }
          else {
            unode->parent->rgt = unode->lft;
          }
        }
        unode->lft->parent = unode->parent;
        unode->lft = dnode->lft;
        unode->parent = dnode->parent;
        if (dnode->parent->lft == dnode)
          dnode->parent->lft = unode;
        else
          dnode->parent->rgt = unode;
        unode->bit = dnode->bit;
        if (dnode->rgt->bit < dnode->bit)
          dnode->rgt->parent = unode;
        if (dnode->lft->bit < dnode->bit)
          dnode->lft->parent = unode;
        delete(dnode);
        break;
        
      default:
        break;
    }
    
    return(true);
  }

  //-------------------------------------------------------------------------
  //     uint32_t erase(const iterator & start, const iterator & finish)     
  //.........................................................................
  //  
  //-------------------------------------------------------------------------
  uint32_t erase(const iterator & start, const iterator & finish)
  {
    vector<key_type>             keyVector;
    vector<key_type>::iterator   keyVectorIter;
    iterator                     iter;
    uint32_t                     numErased = 0;
    
    for (iter = start; iter != finish; iter++) {
      keyVector.push_back((*iter).first);
    }

    for (keyVectorIter = keyVector.begin(); keyVectorIter != keyVector.end();
         keyVectorIter++) {
      if (this->erase(*keyVectorIter) == true) {
        numErased++;
      }
    }
    return(numErased);
  }

  //------------------------------------------------------------------------
  //                uint32_t bitset(uint32_t x, uint32_t k)
  //------------------------------------------------------------------------
  //!  Returns the kth most significant bit of an IP address.  NOTE WE
  //!  HANDLE OUR ENDIAN ISSUES HERE!  We do this because we want support
  //!  for inorder traversal of the trie by key in host byte order (IP
  //!  address), but we want the key values to be in network byte order.
  //------------------------------------------------------------------------
  uint32_t bitset(uint32_t x, uint32_t k)
  {
    uint32_t  rc;

    if (k != 32) {
      #if (WORDS_BIGENDIAN == 1)
        rc = (x >> k) & 0x01;
      #else
        rc = this->Ntohl(x);
        rc = (rc >> k) & 0x01;
      #endif
      return(rc);
    }
    return(0);
  }

  //-------------------------------------------------------------------------
  //             inline uint32_t Swab32(const uint32_t & keyVal)             
  //.........................................................................
  //  
  //-------------------------------------------------------------------------
  inline uint32_t Swab32(const uint32_t & keyVal)
  {
    return((((keyVal) & 0x000000ffUL) << 24) | 
           (((keyVal) & 0x0000ff00UL) <<  8) | 
           (((keyVal) & 0x00ff0000UL) >>  8) |
           (((keyVal) & 0xff000000UL) >> 24));
  }

  //-------------------------------------------------------------------------
  //              inline uint32_T Ntohl(const uint32_t & keyVal)             
  //.........................................................................
  //  
  //-------------------------------------------------------------------------
  inline uint32_t Ntohl(const uint32_t & keyVal)
  {
    #if (WORDS_BIGENDIAN == 1)
      return(keyVal);
    #else
      return(Swab32(keyVal));
    #endif
  }

  //--------------------------------------------------------------------------
  //              inline uint32_t Htonl(const uint32_t & keyVal)             
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  inline uint32_t Htonl(const uint32_t & keyVal)
  {
    #if (WORDS_BIGENDIAN == 1)
      return(keyVal);
    #else
      return(Swab32(keyVal));
    #endif
  }

private:
  uint32_t  _size;
  
  //--------------------------------------------------------------------------
  //       inline pair<iterator,bool> & _insert(const value_type & value)      
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  inline pair<iterator,bool> & _insert(const value_type & value)
  {
    Ipv4PrefixPatricia<Type> *p, *t, *x;
    uint32_t                  i = 32;
    VlsmList::iterator        vlsmIter;
    
    p = this;
    t = lft;
    
    while (p->bit > t->bit) {
      p = t;
      t = (bitset(value.first.net,t->bit)) ? t->rgt : t->lft;
    }
    
    if (value.first.net == t->vlsmVect[0].first.net) {
      //  node already exists in trie.
      for (vlsmIter = t->vlsmVect.begin(); vlsmIter != t->vlsmVect.end();
           vlsmIter++) {
        if ((*vlsmIter).first == value.first) {
          //  found entry in VLSM list.
          static pair<Ipv4PrefixPatricia<Type>::iterator,bool>  retVal;
          retVal.first.vlsmIter = vlsmIter;
          retVal.first.nodePtr = t;
          retVal.second = false;
          return(retVal);
        }
      }
      // We found the node in tree but not the VLSM entry.  Add the VLSM
      // entry.
      for (vlsmIter = t->vlsmVect.begin(); vlsmIter != t->vlsmVect.end();
           vlsmIter++) {
        if ((*vlsmIter).first.maskLen < value.first.maskLen) {
          break;
        }
      }
                
      static pair<Ipv4PrefixPatricia<Type>::iterator,bool>  retVal;
      retVal.first.vlsmIter = t->vlsmVect.insert(vlsmIter,value);
      retVal.first.nodePtr = t;
      retVal.second = true;
      return(retVal);
    }

    //  We need to create a new tree node.
    
    while (bitset(t->vlsmVect[0].first.net,i) == bitset(value.first.net,i)) {
      i--;
    }
    
    p = this;
    x = lft;
    while (p->bit > x->bit && x->bit > i) {
      p = x;
      x = (bitset(value.first.net,x->bit)) ? x->rgt : x->lft;
    }
    t = new Ipv4PrefixPatricia<Type>(value);
    // t = new Ipv4PrefixPatricia<Type>();
    // t->vlsmVect.push_back(value);
    t->bit = i;
    
    //  set left and right branches
    if (bitset(value.first.net,t->bit)) {
      t->rgt = t;
      t->lft = x;
    }
    else {
      t->lft = t;
      t->rgt = x;
    }

    if (t->rgt->bit < t->bit)
      t->rgt->parent = t;
    if (t->lft->bit < t->bit)
      t->lft->parent = t;

    //  point parent at new node
    if (bitset(value.first.net,p->bit))
      p->rgt = t;
    else
      p->lft = t;

    //  set parent
    t->parent = p;
    
    static pair<Ipv4PrefixPatricia<Type>::iterator,bool>  retVal;
    retVal.second = true;
    retVal.first.nodePtr = t;
    retVal.first.vlsmIter = t->vlsmVect.begin();
    retVal.first.end = false;
    return(retVal);
  }

  //--------------------------------------------------------------------------
  //     inline void                               
  //     _visit(Ipv4PrefixPatricia<Type> *head,      
  //            void (*visitFunc)(Ipv4PrefixPatricia<Type> & value, void *), 
  //            void *other, int bitNum)           
  //..........................................................................
  //  
  //--------------------------------------------------------------------------
  inline void
  _visit(Ipv4PrefixPatricia<Type> *head,
         void (*visitFunc)(VlsmList::iterator & value, void *),
         void *other, uint32_t bitNum)
  {
    Ipv4PrefixPatricia<Type> *p;
    Ipv4PrefixPatricia<Type> *leftNode;
    Ipv4PrefixPatricia<Type> *rightNode;
    VlsmList::iterator        vlsmIter;
    
    p = head;
    leftNode = head->lft;
    rightNode = head->rgt;

    if (p->bit >= bitNum) {
      for (vlsmIter = p->vlsmVect.begin(); vlsmIter != p->vlsmVect.end();
           vlsmIter++) {
        if (p->bit != 32) {
          visitFunc(vlsmIter,other);
        }
      }
      return;
    }

    //  visit the left branch
    _visit(leftNode,visitFunc,other,p->bit);

    //  visit the right branch
    _visit(rightNode,visitFunc,other,p->bit);

    return;
  }

};
