diff --git a/CMakeLists.txt b/CMakeLists.txt
index 588fb6817..697a056cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -418,6 +418,7 @@ set(memgraph_src_files
     ${src_dir}/utils/string/transform.cpp
     ${src_dir}/utils/string/join.cpp
     ${src_dir}/utils/string/file.cpp
+    ${src_dir}/utils/iterator/iterator_base.cpp
     ${src_dir}/query_engine/util.cpp
     ${src_dir}/communication/bolt/v1/bolt.cpp
     ${src_dir}/communication/bolt/v1/states.cpp
diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp
index e201b9d61..7c03e49c9 100644
--- a/include/barrier/barrier.hpp
+++ b/include/barrier/barrier.hpp
@@ -25,6 +25,7 @@ class EdgeIterator;
 
 // TYPED ITERATORS
 class VertexAccessIterator;
+class EdgeAccessIterator;
 class OutEdgesIterator;
 class InEdgesIterator;
 
@@ -63,8 +64,8 @@ using label_ref_t = ReferenceWrapper<const Label>;
 // Original class should have Sized barrier class if it can't be Unsized.
 // Sized barrier classes should:
 // --Have same name as original class.
-// --Inherit Sized class from common.hpp as private. Blueprint:
-//      class class_name: Sized<size_of_t,aligment_of_t>
+// --Inherit Sized class from common.hpp as public. Blueprint:
+//      class class_name: public Sized<size_of_t,aligment_of_t>
 // --Sized template arguments must be hardcoded numbers equal to sizeof(T) and
 //   alignof(T) where T is original class.
 // --It should have undefined public constructor which is specialized in .cpp
@@ -82,7 +83,7 @@ using label_ref_t = ReferenceWrapper<const Label>;
 // --It should specify public methods which can be called on the original class.
 //
 // Blueprint:
-// class class_name : private Sized<,>
+// class class_name : public Sized<,>
 // {
 // public:
 //     template <class T>
@@ -247,6 +248,8 @@ public:
 
     VertexAccessor vertex_insert();
 
+    EdgeAccessIterator edge_access();
+
     Option<const EdgeAccessor> edge_find(const Id &id);
 
     EdgeAccessor edge_insert(VertexAccessor const &from,
@@ -278,7 +281,8 @@ public:
     void abort();
 };
 
-class VertexIterator : private Sized<8, 8>
+class VertexIterator : public Sized<8, 8>,
+                       public IteratorBase<const VertexAccessor>
 {
 public:
     template <class T>
@@ -290,11 +294,14 @@ public:
     VertexIterator &operator=(const VertexIterator &other) = delete;
     VertexIterator &operator=(VertexIterator &&other) = delete;
 
-    Option<const VertexAccessor> next();
+    Option<const VertexAccessor> next() final;
+
+    Count count() final;
 };
 
 // TODO: Find reasons of such great size ant try to decrease it.
-class VertexAccessIterator : private Sized<552, 8>
+class VertexAccessIterator : public Sized<560, 8>,
+                             public IteratorBase<const VertexAccessor>
 {
 public:
     template <class T>
@@ -306,10 +313,32 @@ public:
     VertexAccessIterator &operator=(const VertexAccessIterator &other) = delete;
     VertexAccessIterator &operator=(VertexAccessIterator &&other) = delete;
 
-    Option<const VertexAccessor> next();
+    Option<const VertexAccessor> next() final;
+
+    Count count() final;
 };
 
-class OutEdgesIterator : private Sized<40, 8>
+// TODO: Find reasons of such great size ant try to decrease it.
+class EdgeAccessIterator : public Sized<560, 8>,
+                           public IteratorBase<const EdgeAccessor>
+{
+public:
+    template <class T>
+    EdgeAccessIterator(T &&d);
+
+    EdgeAccessIterator(const EdgeAccessIterator &other) = delete;
+    EdgeAccessIterator(EdgeAccessIterator &&other);
+    ~EdgeAccessIterator();
+    EdgeAccessIterator &operator=(const EdgeAccessIterator &other) = delete;
+    EdgeAccessIterator &operator=(EdgeAccessIterator &&other) = delete;
+
+    Option<const EdgeAccessor> next() final;
+
+    Count count() final;
+};
+
+class OutEdgesIterator : public Sized<48, 8>,
+                         public IteratorBase<const EdgeAccessor>
 {
 public:
     template <class T>
@@ -321,10 +350,13 @@ public:
     OutEdgesIterator &operator=(const OutEdgesIterator &other) = delete;
     OutEdgesIterator &operator=(OutEdgesIterator &&other) = delete;
 
-    Option<const EdgeAccessor> next();
+    Option<const EdgeAccessor> next() final;
+
+    Count count() final;
 };
 
-class InEdgesIterator : private Sized<56, 8>
+class InEdgesIterator : public Sized<64, 8>,
+                        public IteratorBase<const EdgeAccessor>
 {
 public:
     template <class T>
@@ -336,10 +368,12 @@ public:
     InEdgesIterator &operator=(const InEdgesIterator &other) = delete;
     InEdgesIterator &operator=(InEdgesIterator &&other) = delete;
 
-    Option<const EdgeAccessor> next();
+    Option<const EdgeAccessor> next() final;
+
+    Count count() final;
 };
 
-class EdgeIterator : private Sized<8, 8>
+class EdgeIterator : public Sized<8, 8>, public IteratorBase<const EdgeAccessor>
 {
 public:
     template <class T>
@@ -351,7 +385,9 @@ public:
     EdgeIterator &operator=(const EdgeIterator &other) = delete;
     EdgeIterator &operator=(EdgeIterator &&other) = delete;
 
-    Option<const EdgeAccessor> next();
+    Option<const EdgeAccessor> next() final;
+
+    Count count() final;
 };
 
 class VertexPropertyKey : private Sized<8, 8>
@@ -442,10 +478,10 @@ public:
     void write_success_empty();
     void write_ignored();
     void write_fields(const std::vector<std::string> &fields);
-    void write_field(const std::string& field);
+    void write_field(const std::string &field);
     void write_list_header(size_t size);
     void write_record();
-    void write_meta(const std::string& type);
+    void write_meta(const std::string &type);
     void send();
     void chunk();
 };
diff --git a/include/barrier/common.hpp b/include/barrier/common.hpp
index 75b2bdbe6..1873988f7 100644
--- a/include/barrier/common.hpp
+++ b/include/barrier/common.hpp
@@ -121,6 +121,18 @@ protected:
                       "Border class aligment mismatch");
     }
 
+public:
+    typename std::aligned_storage<size_B, alignment_B>::type &_data_ref()
+    {
+        return data;
+    }
+
+    typename std::aligned_storage<size_B, alignment_B>::type const &
+    _data_ref_const() const
+    {
+        return data;
+    }
+
 private:
     // Here is the aligned storage which imitates size and aligment of object of
     // original class from memgraph.
diff --git a/include/barrier/trans.hpp b/include/barrier/trans.hpp
index af7c8ad76..1e474903f 100644
--- a/include/barrier/trans.hpp
+++ b/include/barrier/trans.hpp
@@ -5,13 +5,15 @@
 // This is the place for imports from memgraph .hpp
 #include "communication/bolt/v1/serialization/bolt_serializer.hpp"
 #include "communication/bolt/v1/serialization/record_stream.hpp"
-#include "io/network/socket.hpp"
 #include "database/db.hpp"
 #include "database/db_accessor.hpp"
+#include "io/network/socket.hpp"
 #include "storage/edge_type/edge_type.hpp"
 #include "storage/edge_x_vertex.hpp"
 #include "storage/label/label.hpp"
 
+// This is the place for imports from memgraph .cpp
+
 // **************************** HELPER DEFINES *******************************//
 // Creates 8 functions for transformation of refereces between types x and y.
 // Where x is a border type.
@@ -26,6 +28,21 @@
     y *trans(x *l) { return ptr_as<y>(l); }                                    \
     y const *trans(x const *l) { return ptr_as<y const>(l); }
 
+// Creates 4 functions for transformation of refereces between types x and y.
+// Where x is a sized border type.
+// DANGEROUS
+#define TRANSFORM_REF_SIZED(x, y)                                              \
+    y &trans(x &l) { return ref_as<y>(l._data_ref()); }                        \
+    y const &trans(x const &l)                                                 \
+    {                                                                          \
+        return ref_as<y const>(l._data_ref_const());                           \
+    }                                                                          \
+    y *trans(x *l) { return ptr_as<y>(&(l->_data_ref())); }                    \
+    y const *trans(x const *l)                                                 \
+    {                                                                          \
+        return ptr_as<y const>(&(l->_data_ref_const()));                       \
+    }
+
 // Creates 8 functions for transformation of refereces between types x and y.
 // Where both x and y are templates over T. Where x is a border type.
 // DANGEROUS
@@ -126,6 +143,9 @@
 using vertex_access_iterator_t =
     decltype(((::DbAccessor *)(std::nullptr_t()))->vertex_access());
 
+using edge_access_iterator_t =
+    decltype(((::DbAccessor *)(std::nullptr_t()))->edge_access());
+
 using out_edge_iterator_t =
     decltype(((::VertexAccessor *)(std::nullptr_t()))->out());
 
@@ -155,13 +175,16 @@ TRANSFORM_REF(VertexPropertyKey,
               ::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
 TRANSFORM_REF(EdgePropertyKey,
               ::EdgePropertyFamily::PropertyType::PropertyFamilyKey);
-TRANSFORM_REF(VertexIterator,
-              std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
-TRANSFORM_REF(EdgeIterator,
-              std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
-TRANSFORM_REF(VertexAccessIterator, vertex_access_iterator_t);
-TRANSFORM_REF(OutEdgesIterator, out_edge_iterator_t);
-TRANSFORM_REF(InEdgesIterator, in_edge_iterator_t);
+
+// ITERATORS
+TRANSFORM_REF_SIZED(VertexIterator,
+                    std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
+TRANSFORM_REF_SIZED(EdgeIterator,
+                    std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
+TRANSFORM_REF_SIZED(VertexAccessIterator, vertex_access_iterator_t);
+TRANSFORM_REF_SIZED(EdgeAccessIterator, edge_access_iterator_t);
+TRANSFORM_REF_SIZED(OutEdgesIterator, out_edge_iterator_t);
+TRANSFORM_REF_SIZED(InEdgesIterator, in_edge_iterator_t);
 
 template <class T>
 TRANSFORM_REF_TEMPLATED(VertexIndex<T>, VertexIndexBase<T>);
@@ -189,19 +212,22 @@ TRANSFORM_VALUE(EdgePropertyKey,
 TRANSFORM_VALUE(VertexPropertyKey,
                 ::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
 TRANSFORM_VALUE_ONE(VertexAccessIterator, vertex_access_iterator_t);
-MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t);
+// MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t);
+TRANSFORM_VALUE_ONE(EdgeAccessIterator, edge_access_iterator_t);
+// MOVE_CONSTRUCTOR_FORCED(EdgeAccessIterator, edge_access_iterator_t);
 TRANSFORM_VALUE_ONE(OutEdgesIterator, out_edge_iterator_t);
-MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
+// MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
 TRANSFORM_VALUE_ONE(InEdgesIterator, in_edge_iterator_t);
-MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
+// MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
 TRANSFORM_VALUE_ONE(VertexIterator,
                     std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
-MOVE_CONSTRUCTOR_FORCED(VertexIterator,
-                        std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
+// MOVE_CONSTRUCTOR_FORCED(VertexIterator,
+//                         std::unique_ptr<IteratorBase<const
+//                         ::VertexAccessor>>);
 TRANSFORM_VALUE_ONE(EdgeIterator,
                     std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
-MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
-                        std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
+// MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
+//                         std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
 
 template <class T>
 TRANSFORM_VALUE_ONE_RAW(
diff --git a/include/data_structures/concurrent/common.hpp b/include/data_structures/concurrent/common.hpp
index 4ec9e7c16..35b1e3408 100644
--- a/include/data_structures/concurrent/common.hpp
+++ b/include/data_structures/concurrent/common.hpp
@@ -62,6 +62,8 @@ public:
 
     ~AccessorBase() {}
 
+    size_t size() { return accessor.size(); };
+
     list_it begin() { return accessor.begin(); }
 
     list_it_con begin() const { return accessor.cbegin(); }
diff --git a/include/data_structures/concurrent/concurrent_list.hpp b/include/data_structures/concurrent/concurrent_list.hpp
index 87d414f49..8f16a504b 100644
--- a/include/data_structures/concurrent/concurrent_list.hpp
+++ b/include/data_structures/concurrent/concurrent_list.hpp
@@ -281,6 +281,8 @@ public:
 
     ConstIterator cend() { return ConstIterator(); }
 
+    std::size_t size() { return count.load(std::memory_order_consume); }
+
 private:
     std::atomic<std::size_t> count{0};
     std::atomic<Node *> head{nullptr};
diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp
index 8614a341a..8df93dfb8 100644
--- a/include/database/db_accessor.hpp
+++ b/include/database/db_accessor.hpp
@@ -69,6 +69,14 @@ public:
     VertexAccessor vertex_insert();
 
     // ******************* EDGE METHODS
+    auto edge_access()
+    {
+        return iter::make_map(
+            iter::make_iter(this->db_transaction.db.graph.edges.access()),
+            [&](auto e) -> auto {
+                return EdgeAccessor(&(e->second), db_transaction);
+            });
+    }
 
     Option<const EdgeAccessor> edge_find(const Id &id);
 
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index f50d7c0c4..191cca8de 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -4,6 +4,7 @@
 #include <map>
 
 #include "barrier/barrier.hpp"
+#include "utils/iterator/iterator_base.cpp"
 
 using namespace std;
 
@@ -20,8 +21,7 @@ auto load_queries(Db &db)
 
         auto vertex_accessor = t.vertex_insert();
         vertex_accessor.set(prop_key, args[0]);
-        t.commit();
-        return true;
+        return t.commit();
     };
     queries[11597417457737499503u] = create_node;
 
@@ -34,8 +34,7 @@ auto load_queries(Db &db)
         vertex_accessor.set(prop_key, args[0]);
         vertex_accessor.add_label(label);
         // cout_properties(vertex_accessor.properties());
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto create_account = [&db](const properties_t &args) {
@@ -53,8 +52,7 @@ auto load_queries(Db &db)
         vertex_accessor.set(prop_created, args[3]);
         vertex_accessor.add_label(label);
         // cout_properties(vertex_accessor.properties());
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto find_node_by_internal_id = [&db](const properties_t &args) {
@@ -71,8 +69,7 @@ auto load_queries(Db &db)
         for (auto label_ref : vertex_accessor.labels()) {
             // cout << label_ref.get() << endl;
         }
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto create_edge = [&db](const properties_t &args) {
@@ -89,13 +86,13 @@ auto load_queries(Db &db)
 
         edge_accessor.edge_type(edge_type);
 
-        t.commit();
+        bool ret = t.commit();
 
         // cout << edge_accessor.edge_type() << endl;
 
         // cout_properties(edge_accessor.properties());
 
-        return true;
+        return ret;
     };
 
     auto find_edge_by_internal_id = [&db](const properties_t &args) {
@@ -119,9 +116,7 @@ auto load_queries(Db &db)
         cout << "TO:" << endl;
         // cout_properties(to->data.props);
 
-        t.commit();
-
-        return true;
+        return t.commit();
     };
 
     auto update_node = [&db](const properties_t &args) {
@@ -135,9 +130,7 @@ auto load_queries(Db &db)
         v.set(prop_name, args[1]);
         // cout_properties(v.properties());
 
-        t.commit();
-
-        return true;
+        return t.commit();
     };
 
     // MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,
@@ -158,21 +151,17 @@ auto load_queries(Db &db)
         auto &IS = t.type_find_or_create("IS");
         r.edge_type(IS);
 
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     // MATCH (n) RETURN n
     auto match_all_nodes = [&db](const properties_t &args) {
         DbAccessor t(db);
 
-        iter::for_all(t.vertex_access(), [&](auto vertex) {
-            if (vertex.fill()) {
-                cout << vertex.id() << endl;
-            }
-        });
+        t.vertex_access().fill().for_all(
+            [&](auto vertex) { cout << vertex.id() << endl; });
 
-        return t.commit(), true;
+        return t.commit();
     };
 
     // MATCH (n:LABEL) RETURN n
@@ -183,12 +172,123 @@ auto load_queries(Db &db)
         auto prop_key = t.vertex_property_key("name", Flags::String);
 
         cout << "VERTICES" << endl;
-        iter::for_all(label.index().for_range(t),
-                      [&](auto a) { cout << a.at(prop_key) << endl; });
+        label.index().for_range(t).for_all(
+            [&](auto a) { cout << a.at(prop_key) << endl; });
 
-        return t.commit(), true;
+        return t.commit();
     };
 
+    // MATCH (n) DELETE n
+    auto match_all_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        t.vertex_access().fill().for_all([&](auto a) { a.remove(); });
+
+        return t.commit();
+    };
+
+    // MATCH (n:LABEL) DELETE n
+    auto match_label_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &label = t.label_find_or_create("LABEL");
+
+        label.index().for_range(t).for_all([&](auto a) { a.remove(); });
+
+        return t.commit();
+    };
+
+    // MATCH (n) WHERE ID(n) = id DELETE n
+    auto match_id_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto ov = t.vertex_find(args[0]->as<Int64>().value);
+        if (!option_fill(ov)) return t.commit(), false;
+
+        auto v = ov.take();
+        v.remove();
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r]-() WHERE ID(r) = id DELETE r
+    auto match_edge_id_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto ov = t.edge_find(args[0]->as<Int64>().value);
+        if (!option_fill(ov)) return t.commit(), false;
+
+        auto v = ov.take();
+        v.remove();
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r]-() DELETE r
+    auto match_edge_all_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        t.edge_access().fill().for_all([&](auto a) { a.remove(); });
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r:TYPE]-() DELETE r
+    auto match_edge_type_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+
+        type.index().for_range(t).for_all([&](auto a) { a.remove(); });
+
+        return t.commit();
+    };
+
+    // MATCH (n)-[:TYPE]->(m) WHERE ID(n) = id RETURN m
+    auto match_id_type_return = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+
+        auto ov = t.vertex_find(args[0]->as<Int64>().value);
+        if (!option_fill(ov)) return t.commit(), false;
+        auto v = ov.take();
+
+        auto results = v.out().fill().type(type).to();
+
+        // Example of Print resoult.
+        // results.for_all([&](auto va) {
+        //     va is VertexAccessor
+        //     PRINT
+        // });
+
+        return t.commit();
+    };
+
+    // MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN m
+    auto match_name_type_return = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+
+        auto it_type = type.index().for_range(t);
+        auto it_vertex = t.vertex_access();
+
+        // if(it_type.count().max>it_vertex.count().max){
+        //
+        // }
+
+        return t.commit();
+    };
+
+    // Blueprint:
+    // auto  = [&db](const properties_t &args) {
+    //     DbAccessor t(db);
+    //
+    //
+    //     return t.commit();
+    // };
+
     queries[15284086425088081497u] = match_all_nodes;
     queries[4857652843629217005u] = match_by_label;
     queries[15648836733456301916u] = create_edge_v2;
@@ -199,6 +299,13 @@ auto load_queries(Db &db)
     queries[11198568396549106428u] = find_node_by_internal_id;
     queries[8320600413058284114u] = find_edge_by_internal_id;
     queries[6813335159006269041u] = update_node;
+    queries[10506105811763742758u] = match_all_delete;
+    queries[13742779491897528506u] = match_label_delete;
+    queries[11349462498691305864u] = match_id_delete;
+    queries[6963549500479100885u] = match_edge_id_delete;
+    queries[14897166600223619735u] = match_edge_all_delete;
+    queries[16888549834923624215u] = match_edge_type_delete;
+    queries[11675960684124428508u] = match_id_type_return;
 
     return queries;
 }
diff --git a/include/storage/model/edge_list.hpp b/include/storage/model/edge_list.hpp
index ac53ab4db..cf139a4e5 100644
--- a/include/storage/model/edge_list.hpp
+++ b/include/storage/model/edge_list.hpp
@@ -27,6 +27,8 @@ public:
 
     void clear() { edges.clear(); }
 
+    std::size_t size() { return edges.size(); }
+
 private:
     std::vector<EdgeRecord *> edges;
 };
diff --git a/include/storage/model/edge_map.hpp b/include/storage/model/edge_map.hpp
index 5460e3e18..d1d9b0035 100644
--- a/include/storage/model/edge_map.hpp
+++ b/include/storage/model/edge_map.hpp
@@ -28,6 +28,8 @@ public:
 
     void clear() { edges.clear(); }
 
+    std::size_t size() { return edges.size(); }
+
 private:
     RhHashMultiMap<VertexRecord *, EdgeRecord> edges;
 };
diff --git a/include/utils/iterator/count.hpp b/include/utils/iterator/count.hpp
new file mode 100644
index 000000000..20016970f
--- /dev/null
+++ b/include/utils/iterator/count.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+// Represents number of to be returned elements from iterator. Where acutal
+// number is probably somwhere in [min,max].
+class Count
+{
+
+public:
+    Count(size_t exact) : min(exact), max(exact) {}
+
+    Count(size_t min, size_t max) : min(min), max(max) {}
+
+    Count &min_zero()
+    {
+        min = 0;
+        return *this;
+    }
+
+    size_t min;
+    size_t max;
+};
diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp
new file mode 100644
index 000000000..f0c430309
--- /dev/null
+++ b/include/utils/iterator/filter.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which filters values T returned by I iterator if OP returns true for
+// them.
+// T - type of return value
+// I - iterator type
+// OP - type of filter function. OP: T& -> bool
+template <class T, class I, class OP>
+class Filter : public IteratorBase<T>
+{
+
+public:
+    Filter() = delete;
+
+    // Filter operation is designed to be used in chained calls which operate on
+    // a
+    // iterator. Filter will in that usecase receive other iterator by value and
+    // std::move is a optimization for it.
+    Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    // Return values for which filter return true.
+    Option<T> next() final
+    {
+        auto item = Option<T>();
+        do {
+            item = iter.next();
+            if (!item.is_present()) {
+                return Option<T>();
+            }
+        } while (!op(item.get()));
+
+        return std::move(item);
+    }
+
+    Count count() final { return iter.count().min_zero(); }
+
+private:
+    I iter;
+    OP op;
+};
+
+template <class I, class OP>
+auto make_filter(I &&iter, OP &&op)
+{
+    // Compiler cant deduce type T. decltype is here to help with it.
+    return Filter<decltype(iter.next().take()), I, OP>(std::move(iter),
+                                                       std::move(op));
+}
+}
diff --git a/include/utils/iterator/for_all.hpp b/include/utils/iterator/for_all.hpp
index 043f2c882..d68344aff 100644
--- a/include/utils/iterator/for_all.hpp
+++ b/include/utils/iterator/for_all.hpp
@@ -25,4 +25,17 @@ void for_all(std::unique_ptr<I> &&iter, C &&consumer)
         e = iter->next();
     }
 }
+
+template <class I, class C>
+void find(I iter, C &&consumer)
+{
+    auto e = iter.next();
+    while (e.is_present()) {
+
+        if (consumer(e.take())) {
+            return;
+        }
+        e = iter.next();
+    }
+}
 }
diff --git a/include/utils/iterator/iterator.hpp b/include/utils/iterator/iterator.hpp
index 93e48a67d..fb9d41655 100644
--- a/include/utils/iterator/iterator.hpp
+++ b/include/utils/iterator/iterator.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
 #include "utils/iterator/accessor.hpp"
+#include "utils/iterator/count.hpp"
+#include "utils/iterator/filter.hpp"
 #include "utils/iterator/for_all.hpp"
 #include "utils/iterator/iterator_accessor.hpp"
 #include "utils/iterator/iterator_base.hpp"
diff --git a/include/utils/iterator/iterator_accessor.hpp b/include/utils/iterator/iterator_accessor.hpp
index 54ef77eda..2acd960d3 100644
--- a/include/utils/iterator/iterator_accessor.hpp
+++ b/include/utils/iterator/iterator_accessor.hpp
@@ -17,12 +17,13 @@ public:
     IteratorAccessor() = delete;
 
     IteratorAccessor(A &&acc)
-        : begin(std::move(acc.begin())), acc(std::forward<A>(acc))
+        : begin(std::move(acc.begin())), acc(std::forward<A>(acc)), returned(0)
     {
     }
 
     IteratorAccessor(IteratorAccessor &&other)
-        : begin(std::move(other.begin)), acc(std::forward<A>(other.acc))
+        : begin(std::move(other.begin)), acc(std::forward<A>(other.acc)),
+          returned(other.returned)
     {
     }
 
@@ -37,15 +38,27 @@ public:
         if (begin != acc.end()) {
             auto ret = Option<T>(&(*(begin.operator->())));
             begin++;
+            returned++;
             return ret;
         } else {
             return Option<T>();
         }
     }
 
+    Count count() final
+    {
+        auto size = acc.size();
+        if (size > returned) {
+            return Count(0);
+        } else {
+            return Count(size - returned);
+        }
+    }
+
 private:
     I begin;
     A acc;
+    size_t returned;
 };
 
 // TODO: Join to make functions into one
diff --git a/include/utils/iterator/iterator_base.hpp b/include/utils/iterator/iterator_base.hpp
index 68403c548..d6feb5813 100644
--- a/include/utils/iterator/iterator_base.hpp
+++ b/include/utils/iterator/iterator_base.hpp
@@ -1,7 +1,10 @@
 #pragma once
 
+#include "utils/iterator/count.hpp"
 #include "utils/option.hpp"
 
+class EdgeType;
+
 // Base iterator for next() kind iterator.
 // T - type of return value
 template <class T>
@@ -11,4 +14,26 @@ public:
     virtual ~IteratorBase(){};
 
     virtual Option<T> next() = 0;
+
+    virtual Count count() { return Count(0, ~((size_t)0)); }
+
+    template <class OP>
+    auto map(OP &&op);
+
+    template <class OP>
+    auto filter(OP &&op);
+
+    // Maps with call to method to() and filters with call to fill.
+    auto to();
+
+    // Filters with call to method fill()
+    auto fill();
+
+    // Filters with type
+    template <class TYPE>
+    auto type(TYPE const &type);
+
+    // For all items calls OP.
+    template <class OP>
+    void for_all(OP &&op);
 };
diff --git a/include/utils/iterator/lambda_iterator.hpp b/include/utils/iterator/lambda_iterator.hpp
index 67dbccfb6..cd130af31 100644
--- a/include/utils/iterator/lambda_iterator.hpp
+++ b/include/utils/iterator/lambda_iterator.hpp
@@ -11,26 +11,36 @@ template <class T, class F>
 class LambdaIterator : public IteratorBase<T>
 {
 public:
-    LambdaIterator(F &&f) : func(std::move(f)) {}
+    LambdaIterator(F &&f, size_t count) : func(std::move(f)), _count(count) {}
 
-    LambdaIterator(LambdaIterator &&other) : func(std::move(other.func)) {}
+    LambdaIterator(LambdaIterator &&other)
+        : func(std::move(other.func)), _count(other._count)
+    {
+    }
 
     ~LambdaIterator() final {}
 
-    Option<T> next() final { return func(); }
+    Option<T> next() final
+    {
+        _count = _count > 0 ? _count - 1 : 0;
+        return func();
+    }
+
+    Count count() final { return Count(_count); }
 
 private:
     F func;
+    size_t _count;
 };
 
 // Wraps lambda which returns options as an iterator.
 template <class F>
-auto make_iterator(F &&f)
+auto make_iterator(F &&f, size_t count)
 {
     // Because function isn't receving or in any way using type T from
     // FunctionIterator compiler can't deduce it thats way there is decltype in
     // construction of FunctionIterator. Resoulting type of iter.next().take()
     // is T.
-    return LambdaIterator<decltype(f().take()), F>(std::move(f));
+    return LambdaIterator<decltype(f().take()), F>(std::move(f), count);
 }
 }
diff --git a/include/utils/iterator/map.hpp b/include/utils/iterator/map.hpp
index ddbc45700..53cf52f46 100644
--- a/include/utils/iterator/map.hpp
+++ b/include/utils/iterator/map.hpp
@@ -37,6 +37,8 @@ public:
         }
     }
 
+    Count count() final { return iter.count(); }
+
 private:
     I iter;
     OP op;
diff --git a/include/utils/iterator/query.hpp b/include/utils/iterator/query.hpp
new file mode 100644
index 000000000..b3fa64365
--- /dev/null
+++ b/include/utils/iterator/query.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "storage/vertex_accessor.hpp"
+#include "utils/iterator/iterator.hpp"
+#include "utils/option.hpp"
+
+namespace query_help
+{
+
+template <class A>
+bool fill(A &a)
+{
+    return a.fill();
+}
+};
+
+// Base iterator for next() kind iterator.
+// Vertex::Accessor - type of return value
+template <>
+class IteratorBase<Vertex::Accessor>
+{
+public:
+    virtual Option<Vertex::Accessor> next() = 0;
+
+    auto fill()
+    {
+        return iter::make_filter(std::move(*this), query_help::fill);
+    }
+};
diff --git a/poc/profile.hpp b/poc/profile.hpp
index 9e4548f21..0dea2abca 100644
--- a/poc/profile.hpp
+++ b/poc/profile.hpp
@@ -115,19 +115,6 @@ void for_all_fill(I iter, C &&consumer)
     }
 }
 
-template <class I, class C>
-void find(I iter, C &&consumer)
-{
-    auto e = iter.next();
-    while (e.is_present()) {
-
-        if (consumer(e.take())) {
-            return;
-        }
-        e = iter.next();
-    }
-}
-
 template <class I, class C>
 void find_fill(I iter, C &&consumer)
 {
diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp
index 7031230bd..717e1fedf 100644
--- a/src/barrier/barrier.cpp
+++ b/src/barrier/barrier.cpp
@@ -148,6 +148,8 @@ Option<const VertexAccessor> DbAccessor::vertex_find(const Id &id)
 
 VertexAccessor DbAccessor::vertex_insert() { return CALL(vertex_insert()); }
 
+EdgeAccessIterator DbAccessor::edge_access() { return CALL(edge_access()); }
+
 Option<const EdgeAccessor> DbAccessor::edge_find(const Id &id)
 {
     return HALF_CALL(edge_find(id)).map<const EdgeAccessor>();
@@ -435,6 +437,8 @@ Option<const VertexAccessor> VertexIterator::next()
     return HALF_CALL(get()->next()).map<const VertexAccessor>();
 }
 
+Count VertexIterator::count() { return HALF_CALL(get()->count()); }
+
 // ************************* EdgeIterator
 DESTRUCTOR(EdgeIterator, unique_ptr);
 
@@ -443,6 +447,8 @@ Option<const EdgeAccessor> EdgeIterator::next()
     return HALF_CALL(get()->next()).map<const EdgeAccessor>();
 }
 
+Count EdgeIterator::count() { return HALF_CALL(get()->count()); }
+
 // ************************* OutEdgesIterator
 DESTRUCTOR(OutEdgesIterator, out_edge_iterator_t);
 
@@ -451,6 +457,8 @@ Option<const EdgeAccessor> OutEdgesIterator::next()
     return HALF_CALL(next()).map<const EdgeAccessor>();
 }
 
+Count OutEdgesIterator::count() { return HALF_CALL(count()); }
+
 // ************************* InEdgesIterator
 DESTRUCTOR(InEdgesIterator, in_edge_iterator_t);
 
@@ -459,6 +467,8 @@ Option<const EdgeAccessor> InEdgesIterator::next()
     return HALF_CALL(next()).map<const EdgeAccessor>();
 }
 
+Count InEdgesIterator::count() { return HALF_CALL(count()); }
+
 // ************************* VertexAccessIterator
 DESTRUCTOR(VertexAccessIterator, vertex_access_iterator_t);
 
@@ -467,6 +477,18 @@ Option<const VertexAccessor> VertexAccessIterator::next()
     return HALF_CALL(next()).map<const VertexAccessor>();
 }
 
+Count VertexAccessIterator::count() { return HALF_CALL(count()); }
+
+// ************************* EdgeAccessIterator
+DESTRUCTOR(EdgeAccessIterator, edge_access_iterator_t);
+
+Option<const EdgeAccessor> EdgeAccessIterator::next()
+{
+    return HALF_CALL(next()).map<const EdgeAccessor>();
+}
+
+Count EdgeAccessIterator::count() { return HALF_CALL(count()); }
+
 // ************************* VertexPropertyKey
 DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey);
 
@@ -596,7 +618,7 @@ void RecordStream<Stream>::write_fields(const std::vector<std::string> &fields)
 }
 
 template <class Stream>
-void RecordStream<Stream>::write_field(const std::string& field)
+void RecordStream<Stream>::write_field(const std::string &field)
 {
     HALF_CALL(write_field(field));
 }
@@ -614,7 +636,7 @@ void RecordStream<Stream>::write_record()
 }
 
 template <class Stream>
-void RecordStream<Stream>::write_meta(const std::string& type)
+void RecordStream<Stream>::write_meta(const std::string &type)
 {
     HALF_CALL(write_meta(type));
 }
@@ -632,7 +654,6 @@ void RecordStream<Stream>::chunk()
 }
 
 template class RecordStream<io::Socket>;
-
 }
 
 // **************************** ERROR EXAMPLES ****************************** //
diff --git a/src/storage/indexes/impl/nonunique_unordered_index.cpp b/src/storage/indexes/impl/nonunique_unordered_index.cpp
index d96f148ad..006ae702a 100644
--- a/src/storage/indexes/impl/nonunique_unordered_index.cpp
+++ b/src/storage/indexes/impl/nonunique_unordered_index.cpp
@@ -46,22 +46,26 @@ auto NonUniqueUnorderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
                                                     Border<K> from_v,
                                                     Border<K> to_v)
 {
-    return iter::make_iterator([
-        it = list.cbegin(), end = list.cend(), from = from_v, to = to_v, t = t_v
-    ]() mutable->auto {
-        while (it != end) {
-            const IndexRecord<T, K> &r = *it;
-            if (from < r.key && to > r.key &&
-                r.is_valid(t.db_transaction.trans)) {
-                const typename T::accessor_t acc = r.access(t.db_transaction);
+    return iter::make_iterator(
+        [
+          it = list.cbegin(), end = list.cend(), from = from_v, to = to_v,
+          t = t_v
+        ]() mutable->auto {
+            while (it != end) {
+                const IndexRecord<T, K> &r = *it;
+                if (from < r.key && to > r.key &&
+                    r.is_valid(t.db_transaction.trans)) {
+                    const typename T::accessor_t acc =
+                        r.access(t.db_transaction);
+                    it++;
+                    return make_option(std::move(acc));
+                }
                 it++;
-                return make_option(std::move(acc));
             }
-            it++;
-        }
 
-        return Option<const typename T::accessor_t>();
-    });
+            return Option<const typename T::accessor_t>();
+        },
+        list.size());
 }
 
 template <class T, class K>
diff --git a/src/storage/indexes/impl/unique_ordered_index.cpp b/src/storage/indexes/impl/unique_ordered_index.cpp
index a0de33592..dc2e6ec83 100644
--- a/src/storage/indexes/impl/unique_ordered_index.cpp
+++ b/src/storage/indexes/impl/unique_ordered_index.cpp
@@ -64,23 +64,28 @@ auto UniqueOrderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
     } else {
         assert(this->order() != None);
     }
+    // TODO: determine size on fact of border size.
+    auto size = acc.size();
 
-    return iter::make_iterator([
-        it = std::move(begin), b_end = std::move(end), t = t_v,
-        hold_acc = std::move(acc)
-    ]() mutable->auto {
-        while (b_end >= it->key) {
-            const IndexRecord<T, K> &r = *it;
-            if (r.is_valid(t.db_transaction.trans)) {
-                const typename T::accessor_t acc = r.access(t.db_transaction);
+    return iter::make_iterator(
+        [
+          it = std::move(begin), b_end = std::move(end), t = t_v,
+          hold_acc = std::move(acc)
+        ]() mutable->auto {
+            while (b_end >= it->key) {
+                const IndexRecord<T, K> &r = *it;
+                if (r.is_valid(t.db_transaction.trans)) {
+                    const typename T::accessor_t acc =
+                        r.access(t.db_transaction);
+                    it++;
+                    return make_option(std::move(acc));
+                }
                 it++;
-                return make_option(std::move(acc));
             }
-            it++;
-        }
 
-        return Option<const typename T::accessor_t>();
-    });
+            return Option<const typename T::accessor_t>();
+        },
+        size);
 }
 
 template <class T, class K>
diff --git a/src/utils/iterator/iterator_base.cpp b/src/utils/iterator/iterator_base.cpp
new file mode 100644
index 000000000..63615c825
--- /dev/null
+++ b/src/utils/iterator/iterator_base.cpp
@@ -0,0 +1,43 @@
+#include "utils/iterator/iterator.hpp"
+
+template <class T>
+template <class OP>
+auto IteratorBase<T>::map(OP &&op)
+{
+    return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
+                                                          std::move(op));
+}
+
+template <class T>
+template <class OP>
+auto IteratorBase<T>::filter(OP &&op)
+{
+    return iter::make_filter<decltype(std::move(*this)), OP>(std::move(*this),
+                                                             std::move(op));
+}
+
+template <class T>
+auto IteratorBase<T>::to()
+{
+    return map([](auto er) { return er.to(); }).fill();
+}
+
+template <class T>
+auto IteratorBase<T>::fill()
+{
+    return filter([](auto &ra) { return ra.fill(); });
+}
+
+template <class T>
+template <class TYPE>
+auto IteratorBase<T>::type(TYPE const &type)
+{
+    return filter([&](auto &ra) { return ra.edge_type() == type; });
+}
+
+template <class T>
+template <class OP>
+void IteratorBase<T>::for_all(OP &&op)
+{
+    iter::for_all(std::move(*this), std::move(op));
+}