diff --git a/alib2data/src/graph/directed/AdjacencyListDirectedGraph.cpp b/alib2data/src/graph/directed/AdjacencyListDirectedGraph.cpp
index ccdbdda61b93268462af46761677a47c2e9a5edb..be31ad52549ba415866d7d22f88305612add018a 100644
--- a/alib2data/src/graph/directed/AdjacencyListDirectedGraph.cpp
+++ b/alib2data/src/graph/directed/AdjacencyListDirectedGraph.cpp
@@ -27,6 +27,16 @@ std::set<DirectedEdge> AdjacencyListDirectedGraph::allEdges() const
 	return edges;
 }
 
+bool AdjacencyListDirectedGraph::hasNode(const Node &node) const
+{
+	return adj.find(node) != adj.end();
+}
+
+bool AdjacencyListDirectedGraph::hasEdge(const DirectedEdge &edge) const
+{
+	return edges.find(edge) != edges.end();
+}
+
 bool AdjacencyListDirectedGraph::hasEdge(const Node &from, const Node &to) const
 {
 	auto search = adj.find(from);
diff --git a/alib2data/src/graph/directed/AdjacencyListDirectedGraph.h b/alib2data/src/graph/directed/AdjacencyListDirectedGraph.h
index 4586e96cd80d2e96f86887e9d9e7ba8f104debdc..7ccfe90762351152eb61b60149c8b66a6461dcc4 100644
--- a/alib2data/src/graph/directed/AdjacencyListDirectedGraph.h
+++ b/alib2data/src/graph/directed/AdjacencyListDirectedGraph.h
@@ -29,6 +29,9 @@ public:
 	std::set<Node> allNodes() const override;
 	std::set<DirectedEdge> allEdges() const override;
 
+	bool hasNode(const Node &node) const override;
+	bool hasEdge(const DirectedEdge &edge) const override;
+
 	bool hasEdge(const Node &from, const Node &to) const override;
 	std::set<DirectedEdge> findEdges(const Node &from, const Node &to) const override;
 
diff --git a/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.cpp b/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.cpp
index e0cfed03b5cc284094e53518dad51295569a4e7c..0f1598b82adf2e8341a80b0dc46eed311bf1cb72 100644
--- a/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.cpp
+++ b/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.cpp
@@ -19,6 +19,16 @@ std::set<DirectedEdge> AdjacencyMatrixDirectedGraph::allEdges() const
 	return edges;
 }
 
+bool AdjacencyMatrixDirectedGraph::hasNode(const Node &node) const
+{
+	return adj.find(node) != adj.end();
+}
+
+bool AdjacencyMatrixDirectedGraph::hasEdge(const DirectedEdge &edge) const
+{
+	return edges.find(edge) != edges.end();
+}
+
 bool AdjacencyMatrixDirectedGraph::hasEdge(const Node &from, const Node &to) const
 {
 	auto search = adj.find(from);
diff --git a/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.h b/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.h
index 5dc9aa4adce0a08d65bcc78f90ae8fa342f3549b..277147dbee584beb60bbc2426483361cd4ab8db4 100644
--- a/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.h
+++ b/alib2data/src/graph/directed/AdjacencyMatrixDirectedGraph.h
@@ -33,6 +33,9 @@ public:
 	std::set<Node> allNodes() const override;
 	std::set<DirectedEdge> allEdges() const override;
 
+	bool hasNode(const Node &node) const override;
+	bool hasEdge(const DirectedEdge &edge) const override;
+
 	bool hasEdge(const Node &from, const Node &to) const override;
 	std::set<DirectedEdge> findEdges(const Node &from, const Node &to) const override;
 
diff --git a/alib2data/src/graph/directed/DirectedGraph.cpp b/alib2data/src/graph/directed/DirectedGraph.cpp
index 525826bcbf5697e670bc96712f2fe81bbccec7c9..af07c466a6cbfb4c6262b7ce46d4c61744b2ebd5 100644
--- a/alib2data/src/graph/directed/DirectedGraph.cpp
+++ b/alib2data/src/graph/directed/DirectedGraph.cpp
@@ -72,6 +72,16 @@ std::set<Node> DirectedGraph::getNodes() const
 	return impl->allNodes();
 }
 
+bool DirectedGraph::hasNode(const Node &node) const
+{
+	return impl->hasNode(node);
+}
+
+bool DirectedGraph::hasEdge(const DirectedEdge &edge) const
+{
+	return impl->hasEdge(edge);
+}
+
 std::set<DirectedEdge> DirectedGraph::getEdges() const
 {
 	return impl->allEdges();
diff --git a/alib2data/src/graph/directed/DirectedGraph.h b/alib2data/src/graph/directed/DirectedGraph.h
index 306605437b3e74807a256a854e14e1af4e42f6b1..0844695284751cc0ffa3ee0c367b358a1dd7128a 100644
--- a/alib2data/src/graph/directed/DirectedGraph.h
+++ b/alib2data/src/graph/directed/DirectedGraph.h
@@ -32,6 +32,9 @@ public:
 	std::set<Node> getNodes() const;
 	std::set<DirectedEdge> getEdges() const;
 
+	bool hasNode(const Node &node) const;
+	bool hasEdge(const DirectedEdge &edge) const;
+
 	bool hasEdge(const Node &from, const Node &to) const;
 	std::set<DirectedEdge> findEdges(const Node &from, const Node &to) const;
 
diff --git a/alib2data/src/graph/directed/IDirectedGraph.h b/alib2data/src/graph/directed/IDirectedGraph.h
index c142659996b83b4d593f1dd0fd26712f673a4366..163c376b0b61ca046e3020d3830b96595f7dcec0 100644
--- a/alib2data/src/graph/directed/IDirectedGraph.h
+++ b/alib2data/src/graph/directed/IDirectedGraph.h
@@ -16,6 +16,9 @@ public:
 	virtual std::set<Node> allNodes() const = 0;
 	virtual std::set<DirectedEdge> allEdges() const = 0;
 
+	virtual bool hasNode(const Node &node) const = 0;
+	virtual bool hasEdge(const DirectedEdge &edge) const = 0;
+
 	virtual bool hasEdge(const Node &from, const Node &to) const = 0;
 	virtual std::set<DirectedEdge> findEdges(const Node &from, const Node &to) const = 0;
 
diff --git a/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.cpp b/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.cpp
index 7d5fb88aeb6abb7eecc2438c588ff889cefc5f79..4f98050aac27073f7d85e91ebb51e75b73cbf66d 100644
--- a/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.cpp
+++ b/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.cpp
@@ -20,6 +20,16 @@ std::set<UndirectedEdge> AdjacencyListUndirectedGraph::allEdges() const
 	return edges;
 }
 
+bool AdjacencyListUndirectedGraph::hasNode(const Node &node) const
+{
+	return adj.find(node) != adj.end();
+}
+
+bool AdjacencyListUndirectedGraph::hasEdge(const UndirectedEdge &edge) const
+{
+	return edges.find(edge) != edges.end();
+}
+
 bool AdjacencyListUndirectedGraph::hasEdge(const Node &first, const Node &second) const
 {
 	auto search = adj.find(first);
diff --git a/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.h b/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.h
index 6c4605bbfa60b6863af8b32caee90dd141a59077..066ee6636dcb70bc01bddfb8123076b28d4df562 100644
--- a/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.h
+++ b/alib2data/src/graph/undirected/AdjacencyListUndirectedGraph.h
@@ -32,6 +32,9 @@ public:
 	std::set<Node> allNodes() const override;
 	std::set<UndirectedEdge> allEdges() const override;
 
+	bool hasNode(const Node &node) const override;
+	bool hasEdge(const UndirectedEdge &edge) const override;
+
 	bool hasEdge(const Node &first, const Node &second) const override;
 	std::set<UndirectedEdge> findEdges(const Node &first, const Node &second) const override;
 
diff --git a/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.cpp b/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.cpp
index 49c50ba2e3977dd1e32d10721d728264685d4801..a1d42d092176fce490483a25b2e451546a7cb248 100644
--- a/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.cpp
+++ b/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.cpp
@@ -29,6 +29,16 @@ bool AdjacencyMatrixUndirectedGraph::hasEdge(const Node &first, const Node &seco
 	return search->second.find(second) != search->second.end();
 }
 
+bool AdjacencyMatrixUndirectedGraph::hasNode(const Node &node) const
+{
+	return adj.find(node) != adj.end();
+}
+
+bool AdjacencyMatrixUndirectedGraph::hasEdge(const UndirectedEdge &edge) const
+{
+	return edges.find(edge) != edges.end();
+}
+
 std::set<UndirectedEdge> AdjacencyMatrixUndirectedGraph::findEdges(const Node &first, const Node &second) const
 {
 	std::set<UndirectedEdge> out;
diff --git a/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.h b/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.h
index a877b030ab61ed92dbd946618f3ffb77a9989017..a920d3dfa4c82acda851307903d7c422b0aa5f96 100644
--- a/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.h
+++ b/alib2data/src/graph/undirected/AdjacencyMatrixUndirectedGraph.h
@@ -35,6 +35,9 @@ public:
 	std::set<Node> allNodes() const override;
 	std::set<UndirectedEdge> allEdges() const override;
 
+	bool hasNode(const Node &node) const override;
+	bool hasEdge(const UndirectedEdge &edge) const override;
+
 	bool hasEdge(const Node &first, const Node &second) const override;
 	std::set<UndirectedEdge> findEdges(const Node &first, const Node &second) const override;
 
diff --git a/alib2data/src/graph/undirected/IUndirectedGraph.h b/alib2data/src/graph/undirected/IUndirectedGraph.h
index 51c6574ba3168b670e9232a091a3d67fa8a2103a..3e0ad5aacc23c201ba2ff71579aefc48ec9f86d5 100644
--- a/alib2data/src/graph/undirected/IUndirectedGraph.h
+++ b/alib2data/src/graph/undirected/IUndirectedGraph.h
@@ -16,6 +16,9 @@ public:
 	virtual std::set<Node> allNodes() const = 0;
 	virtual std::set<UndirectedEdge> allEdges() const = 0;
 
+	virtual bool hasNode(const Node &node) const = 0;
+	virtual bool hasEdge(const UndirectedEdge &edge) const = 0;
+
 	virtual bool hasEdge(const Node &first, const Node &second) const = 0;
 	virtual std::set<UndirectedEdge> findEdges(const Node &first, const Node &second) const = 0;
 
diff --git a/alib2data/src/graph/undirected/UndirectedGraph.cpp b/alib2data/src/graph/undirected/UndirectedGraph.cpp
index bf0d409aa9eda1fe41ff4bc2868c63eedc865d50..4209cf1674ebfc5a4783795c3abc8b998c851ac8 100644
--- a/alib2data/src/graph/undirected/UndirectedGraph.cpp
+++ b/alib2data/src/graph/undirected/UndirectedGraph.cpp
@@ -77,6 +77,16 @@ std::set<UndirectedEdge> UndirectedGraph::getEdges() const
 	return impl->allEdges();
 }
 
+bool UndirectedGraph::hasNode(const Node &node) const
+{
+	return impl->hasNode(node);
+}
+
+bool UndirectedGraph::hasEdge(const UndirectedEdge &edge) const
+{
+	return impl->hasEdge(edge);
+}
+
 bool UndirectedGraph::hasEdge(const Node &from, const Node &to) const
 {
 	return impl->hasEdge(from, to);
diff --git a/alib2data/src/graph/undirected/UndirectedGraph.h b/alib2data/src/graph/undirected/UndirectedGraph.h
index ed6cdc68ae47497fc07447d4b2afeb6a251dc9a1..8476e4d970da18c58af4892c0b1e34cbf50b9a1c 100644
--- a/alib2data/src/graph/undirected/UndirectedGraph.h
+++ b/alib2data/src/graph/undirected/UndirectedGraph.h
@@ -32,6 +32,9 @@ public:
 	std::set<Node> getNodes() const;
 	std::set<UndirectedEdge> getEdges() const;
 
+	bool hasNode(const Node &node) const;
+	bool hasEdge(const UndirectedEdge &edge) const;
+
 	bool hasEdge(const Node &from, const Node &to) const;
 	std::set<UndirectedEdge> findEdges(const Node &from, const Node &to) const;
 
diff --git a/alib2data/test-src/graph/GraphTest.cpp b/alib2data/test-src/graph/GraphTest.cpp
index 0fcd966d54f9dab3e282169083b3d65926cbc4fc..52132ffe5d52c45eac9998dd9db4c4480ec674ae 100644
--- a/alib2data/test-src/graph/GraphTest.cpp
+++ b/alib2data/test-src/graph/GraphTest.cpp
@@ -71,6 +71,11 @@ void GraphTest::testAddEdgeValue()
 	RUN_TEST(testAddEdgeValue_impl);
 }
 
+void GraphTest::testHasNodeAndEdge()
+{
+	RUN_TEST(testHasNodeAndEdge_impl);
+}
+
 void GraphTest::testCopyConstruct_impl(graph::REPRESENTATION representation)
 {
 	// Common
@@ -711,3 +716,98 @@ void GraphTest::testAddEdgeValue_impl(graph::REPRESENTATION representation)
 	CPPUNIT_ASSERT_EQUAL(2, ug.getEdgeValue(ue6));
 }
 
+void GraphTest::testHasNodeAndEdge_impl(graph::REPRESENTATION representation)
+{
+	// Common
+	graph::Node n1("n1");
+	graph::Node n2("n2");
+	graph::Node n3("n3");
+	graph::Node n4("n4");
+	graph::Node n5("n5");
+	graph::Node n6("n6");
+
+	// Directed
+	graph::DirectedEdge de1(n1, n2);
+	graph::DirectedEdge de2(n1, n3);
+	graph::DirectedEdge de3(n1, n4);
+	graph::DirectedEdge de4(n1, n5);
+	graph::DirectedEdge de5(n2, n5);
+	graph::DirectedEdge de6(n5, n6);
+
+	graph::DirectedGraph dg(representation);
+	dg.addEdge(de1, 2);
+	dg.addEdge(de2, 2);
+	dg.addEdge(de3, 1);
+	dg.addEdge(de4, 6);
+	dg.addEdge(de5, 3);
+	dg.addEdge(de6, 2);
+
+	CPPUNIT_ASSERT_EQUAL_INT(6, dg.getNodes().size());
+	CPPUNIT_ASSERT_EQUAL_INT(6, dg.getEdges().size());
+
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n1));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n2));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n3));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n4));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n5));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasNode(n6));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasNode(graph::Node("n7")));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasNode(graph::Node("n8")));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasNode(graph::Node("n9")));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasNode(graph::Node("n10")));
+
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de1));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de2));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de3));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de4));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de5));
+	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(de6));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(graph::DirectedEdge(n1, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(graph::DirectedEdge(n2, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(graph::DirectedEdge(n3, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(graph::DirectedEdge(n4, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(graph::DirectedEdge(n1, n2, "a")));
+
+	// Undirected
+	graph::UndirectedEdge ue1(n1, n2);
+	graph::UndirectedEdge ue2(n1, n3);
+	graph::UndirectedEdge ue3(n1, n4);
+	graph::UndirectedEdge ue4(n1, n5);
+	graph::UndirectedEdge ue5(n2, n5);
+	graph::UndirectedEdge ue6(n5, n6);
+
+	graph::UndirectedGraph ug(representation);
+	ug.addEdge(ue1, 2);
+	ug.addEdge(ue2, 2);
+	ug.addEdge(ue3, 1);
+	ug.addEdge(ue4, 6);
+	ug.addEdge(ue5, 3);
+	ug.addEdge(ue6, 2);
+
+	CPPUNIT_ASSERT_EQUAL_INT(6, ug.getNodes().size());
+	CPPUNIT_ASSERT_EQUAL_INT(6, ug.getEdges().size());
+
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n1));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n2));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n3));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n4));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n5));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasNode(n6));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasNode(graph::Node("n7")));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasNode(graph::Node("n8")));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasNode(graph::Node("n9")));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasNode(graph::Node("n10")));
+
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue1));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue2));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue3));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue4));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue5));
+	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(ue6));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(graph::UndirectedEdge(n1, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(graph::UndirectedEdge(n2, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(graph::UndirectedEdge(n3, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(graph::UndirectedEdge(n4, n6)));
+	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(graph::UndirectedEdge(n1, n2, "a")));
+}
+
diff --git a/alib2data/test-src/graph/GraphTest.h b/alib2data/test-src/graph/GraphTest.h
index 50d9472e84411096a72e245100c2461f0ec6d0b3..3ee02ff14f9947435502431199e8657f11d757b8 100644
--- a/alib2data/test-src/graph/GraphTest.h
+++ b/alib2data/test-src/graph/GraphTest.h
@@ -20,6 +20,7 @@ class GraphTest : public CppUnit::TestFixture
 	CPPUNIT_TEST(testNeighborEdges);
 	CPPUNIT_TEST(testHasEdge);
 	CPPUNIT_TEST(testAddEdgeValue);
+	CPPUNIT_TEST(testHasNodeAndEdge);
 	CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -35,6 +36,7 @@ public:
 	void testNeighborEdges();
 	void testHasEdge();
 	void testAddEdgeValue();
+	void testHasNodeAndEdge();
 
 	void testCopyConstruct_impl(graph::REPRESENTATION representation);
 	void testEqual_impl(graph::REPRESENTATION representation);
@@ -48,6 +50,7 @@ public:
 	void testNeighborEdges_impl(graph::REPRESENTATION representation);
 	void testHasEdge_impl(graph::REPRESENTATION representation);
 	void testAddEdgeValue_impl(graph::REPRESENTATION representation);
+	void testHasNodeAndEdge_impl(graph::REPRESENTATION representation);
 };
 
 #endif	// GRAPH_TEST_H_