diff --git a/helper/lfid/remove-loops.cpp b/helper/lfid/remove-loops.cpp
new file mode 100644
index 0000000..90062d1
--- /dev/null
+++ b/helper/lfid/remove-loops.cpp
@@ -0,0 +1,348 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#include "remove-loops.hpp"
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <queue>
+
+#include "ns3/abort.h"
+#include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+using std::set;
+using AllNodeFib = AbstractFib::AllNodeFib;
+
+/**
+ * Fill directed graph only with edges existing in the FIB.
+ */
+void
+getDigraphFromFib(DiGraph& dg, const AllNodeFib& allNodeFIB, const int dstId)
+{
+
+  // 1. Erase All Arcs:
+  dg.clear();
+
+  // 2. Add Arcs from FIB
+  for (const auto& node : allNodeFIB) {
+    int nodeId = node.first;
+    if (dstId == nodeId) {
+      continue;
+    }
+
+    for (const auto& fibNh : node.second.getNexthops(dstId)) {
+      NS_ABORT_UNLESS(fibNh.getType() <= NextHopType::UPWARD);
+      boost::add_edge(static_cast<uint64_t>(nodeId), static_cast<uint64_t>(fibNh.getNexthopId()), 1, dg);
+    }
+  }
+}
+
+class NodePrio {
+public:
+  NodePrio(int nodeId, int remainingNh, set<FibNextHop> nhSet)
+    : m_nodeId{nodeId}
+    , m_remainingNh{remainingNh}
+    , m_uwSet{nhSet}
+  {
+    NS_ABORT_UNLESS(remainingNh > 0 && m_uwSet.size() > 0);
+    NS_ABORT_UNLESS(static_cast<int>(m_uwSet.size()) < remainingNh);
+  }
+
+  int
+  getId() const
+  {
+    return m_nodeId;
+  }
+
+  int
+  getRemainingUw() const
+  {
+    return static_cast<int>(m_uwSet.size());
+  }
+
+  /**
+   * Order by Remamining UW NHs, Highest DeltaCost, and then id.
+   */
+  bool
+  operator<(const NodePrio& other) const
+  {
+    return std::make_tuple(m_remainingNh, getHighestCostUw(), m_nodeId)
+           < std::make_tuple(other.m_remainingNh, other.getHighestCostUw(), other.m_nodeId);
+  }
+
+  // Setters:
+  FibNextHop
+  popHighestCostUw()
+  {
+    const FibNextHop& tmp = getHighestCostUw();
+    eraseUw(tmp);
+    return tmp;
+  }
+
+  void
+  reduceRemainingNh()
+  {
+    m_remainingNh--;
+    // Check that remaining nexthops >= remaining uw nexthops.
+    NS_ABORT_UNLESS(m_remainingNh > 0 && m_remainingNh > getRemainingUw());
+  }
+
+private:
+  void
+  eraseUw(FibNextHop nh)
+  {
+    NS_ABORT_UNLESS(m_uwSet.size() > 0);
+    auto success = m_uwSet.erase(nh);
+    NS_ABORT_UNLESS(success == 1);
+  }
+
+  FibNextHop
+  getHighestCostUw() const
+  {
+    NS_ABORT_UNLESS(m_uwSet.size() > 0);
+    NS_ABORT_UNLESS(std::prev(m_uwSet.end()) != m_uwSet.end());
+    return *(std::prev(m_uwSet.end()));
+  }
+
+private:
+  int m_nodeId;
+  int m_remainingNh;
+  set<FibNextHop> m_uwSet;
+
+  friend std::ostream&
+  operator<<(std::ostream&, const NodePrio& node);
+};
+
+std::ostream&
+operator<<(std::ostream& os, const NodePrio& node)
+{
+  return os << "Id: " << node.m_nodeId << ", remaining NH: " << node.m_remainingNh
+            << ", remaining UW: " << node.getRemainingUw() << " ";
+}
+
+int
+removeLoops(AllNodeFib& allNodeFIB, bool printOutput)
+{
+  int removedLoopCounter = 0;
+  int upwardCounter = 0;
+
+  const int NUM_NODES{static_cast<int>(allNodeFIB.size())};
+
+  // Build graph with boost graph library:
+  DiGraph dg{};
+
+  // Add all Arcs that fit into FIB. // O(n)
+  for (int dstId = 0; dstId < NUM_NODES; dstId++) {
+    // 1. Get DiGraph from Fib //
+    getDigraphFromFib(dg, allNodeFIB, dstId);
+
+    // NodeId -> set<UwNexthops>
+    std::priority_queue<NodePrio> q;
+
+    // 2. Put nodes in the queue, ordered by # remaining nexthops, then CostDelta // O(n^2)
+    for (const auto& node : allNodeFIB) {
+      int nodeId{node.first};
+      const AbstractFib& fib{node.second};
+      if (nodeId == dstId) {
+        continue;
+      }
+
+      const auto& uwNhSet = fib.getUpwardNexthops(dstId);
+      if (!uwNhSet.empty()) {
+        upwardCounter += uwNhSet.size();
+
+        int fibSize{fib.numEnabledNhPerDst(dstId)};
+        // NodePrio tmpNode {nodeId, fibSize, uwNhSet};
+        q.emplace(nodeId, fibSize, uwNhSet);
+      }
+    }
+
+    // 3. Iterate PriorityQueue //
+    while (!q.empty()) {
+      NodePrio node = q.top();
+      q.pop();
+
+      int nodeId = node.getId();
+      int nhId = node.popHighestCostUw().getNexthopId();
+
+      // Remove opposite of Uphill link
+      //      int arcId1 {getArcId(arcMap, nhId, nodeId)};
+      auto res = boost::edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), dg);
+
+      auto arc = res.first;
+      bool arcExists = res.second;
+
+      if (arcExists) {
+        boost::remove_edge(arc, dg);
+      }
+
+      // 2. Loop Check: Is the current node still reachable for the uphill nexthop?
+      // Uses BFS:
+      // bool willLoop = bfs(dg).run(dg.nodeFromId(nhId), dg.nodeFromId(nodeId)); // O(m^2n)
+
+      std::vector<int> dists(num_vertices(dg));
+
+      auto weightmap = get(boost::edge_weight, dg);
+
+      const auto& x = boost::edges(dg);
+      for (auto e = x.first; e != x.second; e++) {
+        int weight = get(weightmap, *e);
+        NS_ABORT_UNLESS(weight == 1); // Only use uniform weights.
+      }
+
+      // TODO: Could be replaced by BFS/DFS to improve speed.
+      dijkstra_shortest_paths(dg, static_cast<uint64_t>(nhId),
+                              distance_map(
+                                boost::make_iterator_property_map(dists.begin(), get(boost::vertex_index, dg))));
+
+      bool willLoop = (dists.at(static_cast<size_t>(nodeId)) < (std::numeric_limits<int>::max() - 1));
+
+      // Uphill nexthop loops back to original node
+      if (willLoop) {
+        node.reduceRemainingNh();
+        removedLoopCounter++;
+
+        // Erase FIB entry
+        allNodeFIB.at(node.getId()).erase(dstId, nhId);
+
+        auto res2 = boost::edge(static_cast<uint64_t>(node.getId()), static_cast<uint64_t>(nhId), dg);
+        auto arc2 = res2.first;
+        NS_ABORT_UNLESS(res.second);
+
+        boost::remove_edge(arc2, dg);
+      }
+
+      // Add opposite of UW link back:
+      if (arcExists) {
+        boost::add_edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), 1, dg);
+      }
+
+      // If not has further UW nexthops: Requeue.
+      if (node.getRemainingUw() > 0) {
+        q.push(node);
+      }
+    }
+  }
+
+  if (printOutput) {
+    std::cout << "Found " << upwardCounter << " UW nexthops, Removed " << removedLoopCounter
+              << " Looping UwNhs, Remaining: " << upwardCounter - removedLoopCounter << " NHs\n";
+  }
+  NS_ABORT_UNLESS((upwardCounter - removedLoopCounter) >= 0);
+
+  return removedLoopCounter;
+}
+
+int
+removeDeadEnds(AllNodeFib& allNodeFIB, bool printOutput)
+{
+  int NUM_NODES{static_cast<int>(allNodeFIB.size())};
+  int checkedUwCounter{0};
+  int uwCounter{0};
+  int totalCounter{0};
+  int removedDeadendCounter{0};
+
+  for (int dstId = 0; dstId < NUM_NODES; dstId++) {
+    // NodeId -> FibNexthops (Order important)
+    set<std::pair<int, FibNextHop>> nhSet;
+
+    // 1. Put all uwNexthops in set<NodeId, FibNexhtop>:
+    for (const auto& node : allNodeFIB) {
+      int nodeId{node.first};
+      if (nodeId == dstId) {
+        continue;
+      }
+
+      totalCounter += node.second.getNexthops(dstId).size();
+
+      const auto& uwNhSet = node.second.getUpwardNexthops(dstId);
+      uwCounter += uwNhSet.size();
+      for (const FibNextHop& fibNh : uwNhSet) {
+        nhSet.emplace(nodeId, fibNh);
+      }
+    }
+
+    // FibNexthops ordered by (costDelta, cost, nhId).
+    // Start with nexthop with highest cost:
+    while (!nhSet.empty()) {
+      checkedUwCounter++;
+
+      // Pop from queue:
+      const auto& nhPair = nhSet.begin();
+      NS_ABORT_UNLESS(nhPair != nhSet.end());
+      nhSet.erase(nhPair);
+
+      int nodeId = nhPair->first;
+      const FibNextHop& nh = nhPair->second;
+      AbstractFib& fib = allNodeFIB.at(nodeId);
+
+      if (nh.getNexthopId() == dstId) {
+        continue;
+      }
+
+      int reverseEntries{allNodeFIB.at(nh.getNexthopId()).numEnabledNhPerDst(dstId)};
+
+      // Must have at least one FIB entry.
+      NS_ABORT_UNLESS(reverseEntries > 0);
+
+      // If it has exactly 1 entry -> Is downward back through the upward nexthop!
+      // Higher O-Complexity below:
+      if (reverseEntries <= 1) {
+        removedDeadendCounter++;
+
+        // Erase NhEntry from FIB:
+        fib.erase(dstId, nh.getNexthopId());
+
+        // Push into Queue: All NhEntries that lead to m_nodeId!
+        const auto& nexthops = fib.getNexthops(dstId);
+
+        for (const auto& ownNhs : nexthops) {
+          if (ownNhs.getType() == NextHopType::DOWNWARD && ownNhs.getNexthopId() != dstId) {
+            const auto& reverseNh = allNodeFIB.at(ownNhs.getNexthopId()).getNexthops(dstId);
+
+            for (const auto& y : reverseNh) {
+              if (y.getNexthopId() == nodeId) {
+                NS_ABORT_UNLESS(y.getType() == NextHopType::UPWARD);
+                nhSet.emplace(ownNhs.getNexthopId(), y);
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (printOutput) {
+    std::cout << "Checked " << checkedUwCounter << " Upward NHs, Removed " << removedDeadendCounter
+              << " Deadend UwNhs, Remaining: " << uwCounter - removedDeadendCounter << " UW NHs, "
+              << totalCounter - removedDeadendCounter << " total nexthops\n";
+  }
+
+  return removedDeadendCounter;
+}
+
+} // namespace ndn
+} // namespace ns3
