Fighting off python bindings and repairing ccnx_fib visualizer plugin
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 2a2b50f..a828ce4 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -1328,6 +1328,8 @@
     cls.add_constructor([param('ns3::CcnxPitEntryIncomingFace const &', 'arg0')])
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::CcnxPitEntryIncomingFace(ns3::Ptr<ns3::CcnxFace> face) [constructor]
     cls.add_constructor([param('ns3::Ptr< ns3::CcnxFace >', 'face')])
+    ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::CcnxPitEntryIncomingFace() [constructor]
+    cls.add_constructor([])
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::m_arrivalTime [variable]
     cls.add_instance_attribute('m_arrivalTime', 'ns3::Time', is_const=False)
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::m_face [variable]
@@ -3054,6 +3056,11 @@
                    'ns3::TypeId', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## object.h (module 'core'): ns3::Ptr<ns3::CcnxFib> ns3::Object::GetObject() const [member function]
+    cls.add_method('GetObject', 
+                   'ns3::Ptr< ns3::CcnxFib >', 
+                   [], 
+                   is_const=True, template_parameters=['ns3::CcnxFib'])
     ## object.h (module 'core'): static ns3::TypeId ns3::Object::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -4360,6 +4367,21 @@
                    'ns3::Ptr< ns3::CcnxFibEntry >', 
                    [param('ns3::Ptr< ns3::CcnxNameComponents const > const &', 'prefix'), param('ns3::Ptr< ns3::CcnxFace >', 'face'), param('int32_t', 'metric')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::Begin() [member function]
+    cls.add_method('Begin', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::End() [member function]
+    cls.add_method('End', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): static ns3::Ptr<ns3::CcnxFib> ns3::CcnxFib::GetCcnxFib(ns3::Ptr<ns3::Object> node) [member function]
+    cls.add_method('GetCcnxFib', 
+                   'ns3::Ptr< ns3::CcnxFib >', 
+                   [param('ns3::Ptr< ns3::Object >', 'node')], 
+                   is_static=True)
     ## ccnx-fib.h (module 'ndnSIM'): static ns3::TypeId ns3::CcnxFib::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -4375,6 +4397,11 @@
                    'ns3::Ptr< ns3::CcnxFibEntry >', 
                    [param('ns3::CcnxInterestHeader const &', 'interest')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::Next(ns3::Ptr<const ns3::CcnxFibEntry> item) [member function]
+    cls.add_method('Next', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [param('ns3::Ptr< ns3::CcnxFibEntry const >', 'item')], 
+                   is_pure_virtual=True, is_virtual=True)
     ## ccnx-fib.h (module 'ndnSIM'): void ns3::CcnxFib::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index 2a2b50f..a828ce4 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -1328,6 +1328,8 @@
     cls.add_constructor([param('ns3::CcnxPitEntryIncomingFace const &', 'arg0')])
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::CcnxPitEntryIncomingFace(ns3::Ptr<ns3::CcnxFace> face) [constructor]
     cls.add_constructor([param('ns3::Ptr< ns3::CcnxFace >', 'face')])
+    ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::CcnxPitEntryIncomingFace() [constructor]
+    cls.add_constructor([])
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::m_arrivalTime [variable]
     cls.add_instance_attribute('m_arrivalTime', 'ns3::Time', is_const=False)
     ## ccnx-pit-entry-incoming-face.h (module 'ndnSIM'): ns3::CcnxPitEntryIncomingFace::m_face [variable]
@@ -3054,6 +3056,11 @@
                    'ns3::TypeId', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## object.h (module 'core'): ns3::Ptr<ns3::CcnxFib> ns3::Object::GetObject() const [member function]
+    cls.add_method('GetObject', 
+                   'ns3::Ptr< ns3::CcnxFib >', 
+                   [], 
+                   is_const=True, template_parameters=['ns3::CcnxFib'])
     ## object.h (module 'core'): static ns3::TypeId ns3::Object::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -4360,6 +4367,21 @@
                    'ns3::Ptr< ns3::CcnxFibEntry >', 
                    [param('ns3::Ptr< ns3::CcnxNameComponents const > const &', 'prefix'), param('ns3::Ptr< ns3::CcnxFace >', 'face'), param('int32_t', 'metric')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::Begin() [member function]
+    cls.add_method('Begin', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::End() [member function]
+    cls.add_method('End', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): static ns3::Ptr<ns3::CcnxFib> ns3::CcnxFib::GetCcnxFib(ns3::Ptr<ns3::Object> node) [member function]
+    cls.add_method('GetCcnxFib', 
+                   'ns3::Ptr< ns3::CcnxFib >', 
+                   [param('ns3::Ptr< ns3::Object >', 'node')], 
+                   is_static=True)
     ## ccnx-fib.h (module 'ndnSIM'): static ns3::TypeId ns3::CcnxFib::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -4375,6 +4397,11 @@
                    'ns3::Ptr< ns3::CcnxFibEntry >', 
                    [param('ns3::CcnxInterestHeader const &', 'interest')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ccnx-fib.h (module 'ndnSIM'): ns3::Ptr<const ns3::CcnxFibEntry> ns3::CcnxFib::Next(ns3::Ptr<const ns3::CcnxFibEntry> item) [member function]
+    cls.add_method('Next', 
+                   'ns3::Ptr< ns3::CcnxFibEntry const >', 
+                   [param('ns3::Ptr< ns3::CcnxFibEntry const >', 'item')], 
+                   is_pure_virtual=True, is_virtual=True)
     ## ccnx-fib.h (module 'ndnSIM'): void ns3::CcnxFib::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 249954f..31ff9b2 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -63,7 +63,7 @@
   m_ccnxFactory.        SetTypeId ("ns3::CcnxL3Protocol");
   m_strategyFactory.    SetTypeId ("ns3::CcnxFloodingStrategy");
   m_contentStoreFactory.SetTypeId ("ns3::CcnxContentStoreLru");
-  m_fibFactory.         SetTypeId ("ns3::CcnxFib");
+  m_fibFactory.         SetTypeId ("ns3::CcnxFibImpl");
   m_pitFactory.         SetTypeId ("ns3::CcnxPit");
 }
     
diff --git a/model/ccnx-fib-impl.cc b/model/ccnx-fib-impl.cc
index 9f9394e..6453bc6 100644
--- a/model/ccnx-fib-impl.cc
+++ b/model/ccnx-fib-impl.cc
@@ -43,8 +43,8 @@
 TypeId 
 CcnxFibImpl::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::CcnxFib") // cheating ns3 object system
-    .SetParent<Object> ()
+  static TypeId tid = TypeId ("ns3::CcnxFibImpl") // cheating ns3 object system
+    .SetParent<CcnxFib> ()
     .SetGroupName ("Ccnx")
     .AddConstructor<CcnxFibImpl> ()
   ;
@@ -193,4 +193,47 @@
     }
 }
 
+CcnxFib::const_iterator
+CcnxFibImpl::Begin ()
+{
+  super::parent_trie::const_recursive_iterator item (super::getTrie ());
+  super::parent_trie::const_recursive_iterator end (0);
+  for (; item != end; item++)
+    {
+      if (item->payload () == 0) continue;
+      break;
+    }
+
+  if (item == end)
+    return End ();
+  else
+    return item->payload ();
+}
+
+CcnxFib::const_iterator
+CcnxFibImpl::End ()
+{
+  return 0;
+}
+
+CcnxFib::const_iterator
+CcnxFibImpl::Next (CcnxFib::const_iterator from)
+{
+  if (from == 0) return 0;
+  
+  super::parent_trie::const_recursive_iterator item (*StaticCast<const CcnxFibEntryImpl> (from)->to_iterator ());
+  super::parent_trie::const_recursive_iterator end (0);
+  for (item++; item != end; item++)
+    {
+      if (item->payload () == 0) continue;
+      break;
+    }
+
+  if (item == end)
+    return End ();
+  else
+    return item->payload ();
+}
+
+
 } // namespace ns3
diff --git a/model/ccnx-fib-impl.h b/model/ccnx-fib-impl.h
index 071c07d..a9b9efc 100644
--- a/model/ccnx-fib-impl.h
+++ b/model/ccnx-fib-impl.h
@@ -88,80 +88,35 @@
    */
   CcnxFibImpl ();
 
-  /**
-   * \brief Perform longest prefix match
-   *
-   * \todo Implement exclude filters
-   *
-   * \param interest Interest packet header
-   * \returns If entry found a valid iterator will be returned, otherwise end ()
-   */
-  CcnxFib::iterator
+  virtual CcnxFib::iterator
   LongestPrefixMatch (const CcnxInterestHeader &interest) const;
   
-  /**
-   * \brief Add or update FIB entry
-   *
-   * If the entry exists, metric will be updated. Otherwise, new entry will be created
-   *
-   * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
-   *
-   * @param name	Prefix
-   * @param face	Forwarding face
-   * @param metric	Routing metric
-   */
-  CcnxFib::iterator
+  virtual CcnxFib::iterator
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
 
-  /**
-   * \brief Add or update FIB entry using smart pointer to prefix
-   *
-   * If the entry exists, metric will be updated. Otherwise, new entry will be created
-   *
-   * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
-   *
-   * @param name	Smart pointer to prefix
-   * @param face	Forwarding face
-   * @param metric	Routing metric
-   */
-  CcnxFib::iterator
+  virtual CcnxFib::iterator
   Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric);
 
-  /**
-   * @brief Remove FIB entry
-   *
-   * ! ATTENTION ! Use with caution.  All PIT entries referencing the corresponding FIB entry will become invalid.
-   * So, simulation may crash.
-   *
-   * @param name	Smart pointer to prefix
-   */
-  void
+  virtual void
   Remove (const Ptr<const CcnxNameComponents> &prefix);
 
-  // /**
-  //  * @brief Invalidate FIB entry ("Safe" version of Remove)
-  //  *
-  //  * All faces for the entry will be assigned maximum routing metric and NDN_FIB_RED status   
-  //  * @param name	Smart pointer to prefix
-  //  */
-  // void
-  // Invalidate (const Ptr<const CcnxNameComponents> &prefix);
-
-  /**
-   * @brief Invalidate all FIB entries
-   */
-  void
+  virtual void
   InvalidateAll ();
   
-  /**
-   * @brief Remove all references to a face from FIB.  If for some enty that face was the only element,
-   * this FIB entry will be removed.
-   */
-  void
+  virtual void
   RemoveFromAll (Ptr<CcnxFace> face);
 
-  void
+  virtual void
   Print (std::ostream &os) const;
+
+  virtual CcnxFib::const_iterator
+  Begin ();
+
+  virtual CcnxFib::const_iterator
+  End ();
+
+  virtual CcnxFib::const_iterator
+  Next (CcnxFib::const_iterator item);
   
   /**
    * @brief Modify element in container
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index c8153fc..f98839d 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -42,7 +42,11 @@
 TypeId 
 CcnxFib::GetTypeId (void)
 {
-  return CcnxFibImpl::GetTypeId ();
+  static TypeId tid = TypeId ("ns3::CcnxFib") // cheating ns3 object system
+    .SetParent<Object> ()
+    .SetGroupName ("Ccnx")
+  ;
+  return tid;
 }
 
 std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 4d4c7f7..0a24db9 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -38,7 +38,7 @@
 {
 public:
   typedef ns3::Ptr<CcnxFibEntry> iterator; // not sure, but let's see what will happen
-  typedef ns3::Ptr<CcnxFibEntry> const_iterator;
+  typedef ns3::Ptr<const CcnxFibEntry> const_iterator;
 
   /**
    * \brief Interface ID
@@ -133,16 +133,27 @@
    */
   virtual void
   Print (std::ostream &os) const = 0;
-  
-  // /**
-  //  * @brief Modify element in container
-  //  */
-  // template<typename Modifier>
-  // virtual bool
-  // modify (iterator position, Modifier mod) = 0;
-  // // {
-  // //   return this->m_fib.modify (position, mod);
-  // // }
+
+  /**
+   * @brief Return first element of FIB (no order guaranteed)
+   */
+  virtual const_iterator
+  Begin () = 0;
+
+  /**
+   * @brief Return item next after last (no order guaranteed)
+   */
+  virtual const_iterator
+  End () = 0;
+
+  /**
+   * @brief Advance the iterator
+   */
+  virtual const_iterator
+  Next (const_iterator item) = 0;
+
+  static inline Ptr<CcnxFib>
+  GetCcnxFib (Ptr<Object> node);
   
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
@@ -153,7 +164,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
- 
+
+Ptr<CcnxFib>
+CcnxFib::GetCcnxFib (Ptr<Object> node)
+{
+  return node->GetObject<CcnxFib> ();
+}
+
 } // namespace ns3
 
 #endif	/* NDN_FIB_H */
diff --git a/model/ccnx-pit-entry-incoming-face.cc b/model/ccnx-pit-entry-incoming-face.cc
index 0c65549..23f3c40 100644
--- a/model/ccnx-pit-entry-incoming-face.cc
+++ b/model/ccnx-pit-entry-incoming-face.cc
@@ -31,4 +31,21 @@
 {
 }
 
+CcnxPitEntryIncomingFace::CcnxPitEntryIncomingFace ()
+  : m_face (0)
+  , m_arrivalTime (0)
+{
+}
+
+/**
+ * @brie Copy operator
+ */
+CcnxPitEntryIncomingFace &
+CcnxPitEntryIncomingFace::operator = (CcnxPitEntryIncomingFace &other)
+{
+  m_face = other.m_face;
+  m_arrivalTime = other.m_arrivalTime;
+  return *this;
+}
+
 } // namespace ns3
diff --git a/model/ccnx-pit-entry-incoming-face.h b/model/ccnx-pit-entry-incoming-face.h
index 61cb4e6..f88ad8a 100644
--- a/model/ccnx-pit-entry-incoming-face.h
+++ b/model/ccnx-pit-entry-incoming-face.h
@@ -47,6 +47,16 @@
   CcnxPitEntryIncomingFace (Ptr<CcnxFace> face);
 
   /**
+   * @brief Default constructor, necessary for Python bindings, but should not be used anywhere else.
+   */
+  CcnxPitEntryIncomingFace ();
+  /**
+   * @brie Copy operator
+   */
+  CcnxPitEntryIncomingFace &
+  operator = (CcnxPitEntryIncomingFace &other);
+
+  /**
    * @brief Compare two CcnxPitEntryIncomingFace
    */
   bool operator== (const CcnxPitEntryIncomingFace &dst) { return *m_face==*(dst.m_face); }