diff --git a/include/graph_t.hpp b/include/graph_t.hpp
index 0f50eddb2a40a713b1b1d8c97393109b718257bb..c344b9db14d96b1364ee0027f5321533f850392f 100644
--- a/include/graph_t.hpp
+++ b/include/graph_t.hpp
@@ -85,6 +85,26 @@ public:
         }
     }
 
+    Graph deep_copy() const {
+        Graph copy;
+        for (const auto& [id, node] : nodes) {
+            copy.nodes[id] = Node{id, std::make_shared<ND>(*node.data)};
+        }
+
+        for (const auto& [id, edge] : edges) {
+            copy.edges[id] = Edge{id, edge.source_id, edge.dest_id, std::make_shared<ED>(*edge.data)};
+        }
+
+        for (const auto& [source, dests] : dests) {
+            copy.dests[source] = std::vector<int>();
+            for (auto d : dests) {
+                copy.dests[source].push_back(d);
+            }
+        }
+
+        return copy;
+    }
+
     inline int add_node(const ND &m) {
       Node node;
       node.node_id = id_counter;
diff --git a/test/test_gnt b/test/test_gnt
index 8718ac9df67514b3a9dba05abe8e99c413997174..b7b96454415882952f6369a935d33f5e7f0c64b8 100755
Binary files a/test/test_gnt and b/test/test_gnt differ
diff --git a/test/test_gnt.cpp b/test/test_gnt.cpp
index 0bb33457289c8c6095496fa81389a924931483c7..f701b8c37618c6f87ecc950f3fec9216505a0ca0 100644
--- a/test/test_gnt.cpp
+++ b/test/test_gnt.cpp
@@ -179,3 +179,71 @@ SCENARIO("Decorators", "[graph t]")
         }
     }
 }
+
+// Test deep copy
+SCENARIO("Deep copy", "[graph t]")
+{
+    GIVEN("A graph with some items") {
+        Graph<string, EdgeProps> g;
+        int a = g.add_node("A");
+        int b = g.add_node("B");
+        int c = g.add_node("C");
+        int d = g.add_node("D");
+        EdgeProps _ab, _ac, _bd, _cd;
+        _ab.set_string("msg-ab");
+        _ac.set_string("msg-ac");
+        _bd.set_string("msg-bd");
+        _cd.set_string("msg-cd");
+        _ab.set_length(1.0);
+        _ac.set_length(2.0);
+        _bd.set_length(3.0);
+        _cd.set_length(4.0);
+        int ab = g.add_edge(_ab, a,b);
+        int ac = g.add_edge(_ac, a,c);
+        int bd = g.add_edge(_bd, b,d);
+        int cd = g.add_edge(_cd, c,d);
+
+        REQUIRE(*g.get_node_data(a) == "A");
+        REQUIRE(*g.get_node_data(b) == "B");
+        REQUIRE(*g.get_node_data(c) == "C");
+        REQUIRE(*g.get_node_data(d) == "D");
+
+        REQUIRE(ab == 0);
+        REQUIRE(ac == 1);
+
+        EdgeProps __ab = *g.get_edge_data(ab);
+        EdgeProps __ac = *g.get_edge_data(ac);
+        EdgeProps __cd = *g.get_edge_data(cd);
+        EdgeProps __bd = *g.get_edge_data(bd);
+        REQUIRE(__ab.get_string() == "msg-ab");
+        REQUIRE(__ac.get_string() == "msg-ac");
+        REQUIRE(__cd.get_string() == "msg-cd");
+        REQUIRE(__bd.get_string() == "msg-bd");
+
+        vector<int> succ_a = {b, c};
+        REQUIRE(g.get_successors(a) == succ_a);
+        vector<int> succ_b = {d};
+        REQUIRE(g.get_successors(b) == succ_b);
+        vector<int> prec_d = {b, c};
+        REQUIRE(g.get_predecessors(d) == prec_d);
+
+        WHEN("Copying the graph") {
+            Graph g1(g);
+            THEN ("We obtain the same graph, with the same indexes") {
+                REQUIRE(g1.get_predecessors(d) == prec_d);
+            }
+        }
+
+        WHEN("Changing the copy") {
+            Graph g2(g);
+            EdgeProps _bc;
+            _bc.set_string("msg-bc");
+            _bc.set_length(5.0);
+            g2.add_edge(_bc, b,c);
+            THEN ("The original is not changed") {
+                REQUIRE(g.get_successors(b).size() == 1);
+                REQUIRE(g2.get_successors(b).size() == 2);
+            }
+        }
+    }
+}