diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 4159f73..5bbbc15 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -24,336 +24,29 @@
 #include "ccnx-face.h"
 #include "ccnx-interest-header.h"
 
-#include "ns3/node.h"
-#include "ns3/assert.h"
-#include "ns3/names.h"
-#include "ns3/log.h"
+#include "ccnx-name-components.h"
+#include "ccnx-fib-impl.h"
 
-#define NDN_RTO_ALPHA 0.125
-#define NDN_RTO_BETA 0.25
-#define NDN_RTO_K 4
+#include "ns3/node.h"
+#include "ns3/names.h"
 
 #include <boost/ref.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/lambda/bind.hpp>
 namespace ll = boost::lambda;
 
-NS_LOG_COMPONENT_DEFINE ("CcnxFib");
-
 namespace ns3 {
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxFib);
-
-//////////////////////////////////////////////////////////////////////
-// Helpers
-//////////////////////////////////////////////////////////////////////
-namespace __ccnx_private {
-
-struct CcnxFibFaceMetricByFace
-{
-  typedef CcnxFibFaceMetricContainer::type::index<i_face>::type
-  type;
-};
-
-}
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-    
 using namespace __ccnx_private;
 
-TypeId 
-CcnxFib::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::CcnxFib")
-    .SetParent<Object> ()
-    .SetGroupName ("Ccnx")
-    .AddConstructor<CcnxFib> ()
-
-  ;
-  return tid;
-}
-
-/////////////////////////////////////////////////////////////////////
-
-void
-CcnxFibFaceMetric::UpdateRtt (const Time &rttSample)
-{
-  // const Time & this->m_rttSample
-  
-  //update srtt and rttvar (RFC 2988)
-  if (m_sRtt.IsZero ())
-    {
-      //first RTT measurement
-      NS_ASSERT_MSG (m_rttVar.IsZero (), "SRTT is zero, but variation is not");
-      
-      m_sRtt = rttSample;
-      m_rttVar = Time (m_sRtt / 2.0);
-    }
-  else
-    {
-      m_rttVar = Time ((1 - NDN_RTO_BETA) * m_rttVar + NDN_RTO_BETA * Abs(m_sRtt - rttSample));
-      m_sRtt = Time ((1 - NDN_RTO_ALPHA) * m_sRtt + NDN_RTO_ALPHA * rttSample);
-    }
-}
-
-/////////////////////////////////////////////////////////////////////
-
-void
-CcnxFibEntry::UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample)
-{
-  CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
-  NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
-                 "Update status can be performed only on existing faces of CcxnFibEntry");
-
-  m_faces.modify (record,
-                  ll::bind (&CcnxFibFaceMetric::UpdateRtt, ll::_1, sample));
-
-  // reordering random access index same way as by metric index
-  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
-}
-
-void
-CcnxFibEntry::UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
-{
-  NS_LOG_FUNCTION (this << boost::cref(*face) << status);
-
-  CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
-  NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
-                 "Update status can be performed only on existing faces of CcxnFibEntry");
-
-  m_faces.modify (record,
-                  (&ll::_1)->*&CcnxFibFaceMetric::m_status = status);
-
-  // reordering random access index same way as by metric index
-  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
-}
-
-void
-CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
-{
-  NS_LOG_FUNCTION (this);
-  NS_ASSERT_MSG (face != NULL, "Trying to Add or Update NULL face");
-
-  CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
-  if (record == m_faces.get<i_face> ().end ())
-    {
-      m_faces.insert (CcnxFibFaceMetric (face, metric));
-    }
-  else
-  {
-    // don't update metric to higher value
-    if (record->m_routingCost > metric || record->m_status == CcnxFibFaceMetric::NDN_FIB_RED)
-      {
-        m_faces.modify (record,
-                        (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
-
-        m_faces.modify (record,
-                        (&ll::_1)->*&CcnxFibFaceMetric::m_status = CcnxFibFaceMetric::NDN_FIB_YELLOW);
-      }
-  }
-  
-  // reordering random access index same way as by metric index
-  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
-}
-
-void
-CcnxFibEntry::Invalidate ()
-{
-  for (CcnxFibFaceMetricByFace::type::iterator face = m_faces.begin ();
-       face != m_faces.end ();
-       face++)
-    {
-      m_faces.modify (face,
-                      (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = std::numeric_limits<uint16_t>::max ());
-
-      m_faces.modify (face,
-                      (&ll::_1)->*&CcnxFibFaceMetric::m_status = CcnxFibFaceMetric::NDN_FIB_RED);
-    }
-}
-
-const CcnxFibFaceMetric &
-CcnxFibEntry::FindBestCandidate (uint32_t skip/* = 0*/) const
-{
-  if (m_faces.size () == 0) throw CcnxFibEntry::NoFaces ();
-  skip = skip % m_faces.size();
-  return m_faces.get<i_nth> () [skip];
-}
-
-
-CcnxFib::CcnxFib ()
-{
-}
-
-void
-CcnxFib::NotifyNewAggregate ()
-{
-  if (m_node == 0)
-      m_node = this->GetObject<Node>();
-  Object::NotifyNewAggregate ();
-}
-
-void 
-CcnxFib::DoDispose (void)
-{
-  m_fib.clear ();
-  m_node = 0;
-  Object::DoDispose ();
-}
-
-
-CcnxFibEntryContainer::type::iterator
-CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
-{
-  const CcnxNameComponents &name = interest.GetName ();
-  for (size_t componentsCount = name.GetComponents ().size ()+1;
-       componentsCount > 0;
-       componentsCount--)
-    {
-      CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
-      CcnxFibEntryContainer::type::iterator match = m_fib.find (subPrefix);
-      if (match != m_fib.end())
-        return match;
-    }
-  
-  return m_fib.end ();
-}
-
-
-CcnxFibEntryContainer::type::iterator
-CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
-{
-  return Add (Create<CcnxNameComponents> (prefix), face, metric);
-}
-  
-CcnxFibEntryContainer::type::iterator
-CcnxFib::Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric)
-{
-// CcnxFibFaceMetric
-  NS_LOG_FUNCTION(this->GetObject<Node> ()->GetId () << boost::cref(*prefix) << boost::cref(*face) << metric);
-  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
-  if (entry == m_fib.end ())
-    {
-      entry = m_fib.insert (m_fib.end (), CcnxFibEntry (prefix));
-      // insert new
-    }
-
-  NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
-  m_fib.modify (entry,
-                ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
-    
-  return entry;
-}
-
-void
-CcnxFib::Remove (const Ptr<const CcnxNameComponents> &prefix)
-{
-  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
-  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
-  if (entry != m_fib.end ())
-    m_fib.erase (entry);
-}
-
-void
-CcnxFib::Invalidate (const Ptr<const CcnxNameComponents> &prefix)
-{
-  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
-
-  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
-  if (entry == m_fib.end ())
-    return; // nothing to invalidate
-
-  m_fib.modify (entry,
-                ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
-}
-
-void
-CcnxFib::InvalidateAll ()
-{
-  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId ());
-
-  for (CcnxFibEntryContainer::type::iterator entry = m_fib.begin ();
-       entry != m_fib.end ();
-       entry ++)
-    {
-      m_fib.modify (entry,
-                    ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
-    }
-}
-
-void
-CcnxFib::Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face)
-{
-  NS_LOG_FUNCTION (this);
-
-  m_fib.modify (m_fib.iterator_to (entry),
-                ll::bind (&CcnxFibEntry::RemoveFace, ll::_1, face));
-  if (entry.m_faces.size () == 0)
-    {
-      m_fib.erase (m_fib.iterator_to (entry));
-    }
-}
-
-void
-CcnxFib::RemoveFromAll (Ptr<CcnxFace> face)
-{
-  NS_LOG_FUNCTION (this);
-
-  for_each (m_fib.begin (), m_fib.end (), 
-            ll::bind (static_cast< void (CcnxFib::*) (const CcnxFibEntry &, Ptr<CcnxFace>) > (&CcnxFib::Remove),
-                      this, ll::_1, face));
-}
-
-
 std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
 {
-  os << "Node " << Names::FindName (fib.m_node) << "\n";
+  os << "Node " << Names::FindName (fib.GetObject<Node>()) << "\n";
   os << "  Dest prefix      Interfaces(Costs)                  \n";
   os << "+-------------+--------------------------------------+\n";
-  
-  for (CcnxFibEntryContainer::type::iterator entry = fib.m_fib.begin ();
-       entry != fib.m_fib.end ();
-       entry++)
-    {
-      os << entry->GetPrefix () << "\t" << *entry << "\n";
-    }
+
+  fib.Print (os);
   return os;
 }
 
-std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
-{
-  for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
-         entry.m_faces.get<i_nth> ().begin ();
-       metric != entry.m_faces.get<i_nth> ().end ();
-       metric++)
-    {
-      if (metric != entry.m_faces.get<i_nth> ().begin ())
-        os << ", ";
-
-      os << *metric;
-    }
-  return os;
-}
-
-std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
-{
-  static const std::string statusString[] = {"","g","y","r"};
-
-  os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << "," << metric.m_face->GetMetric () << ")";
-  return os;
-}
-
-// void CcnxFib::resetProbing()
-// {
-//     for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
-//         VALUE(fib).needsProbing = true;
-// }
-
-// void CcnxFib::updateInterfaceStatus( int interface, int status )
-// {
-// 	for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
-// 	{
-// 		VALUE(fib).updateStatus( interface, status );
-// 	}
-// }
-
 } // namespace ns3
