diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1086b0df..e41ecc27f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -407,6 +407,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 748358c54..7c03e49c9 100644
--- a/include/barrier/barrier.hpp
+++ b/include/barrier/barrier.hpp
@@ -64,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
@@ -83,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>
@@ -281,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>
@@ -293,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>
@@ -309,11 +313,14 @@ public:
     VertexAccessIterator &operator=(const VertexAccessIterator &other) = delete;
     VertexAccessIterator &operator=(VertexAccessIterator &&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 EdgeAccessIterator : private Sized<552, 8>
+class EdgeAccessIterator : public Sized<560, 8>,
+                           public IteratorBase<const EdgeAccessor>
 {
 public:
     template <class T>
@@ -325,10 +332,13 @@ public:
     EdgeAccessIterator &operator=(const EdgeAccessIterator &other) = delete;
     EdgeAccessIterator &operator=(EdgeAccessIterator &&other) = delete;
 
-    Option<const EdgeAccessor> next();
+    Option<const EdgeAccessor> next() final;
+
+    Count count() final;
 };
 
-class OutEdgesIterator : private Sized<40, 8>
+class OutEdgesIterator : public Sized<48, 8>,
+                         public IteratorBase<const EdgeAccessor>
 {
 public:
     template <class T>
@@ -340,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>
@@ -355,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>
@@ -370,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>
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 2aa927d98..1e474903f 100644
--- a/include/barrier/trans.hpp
+++ b/include/barrier/trans.hpp
@@ -12,6 +12,8 @@
 #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
@@ -158,14 +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(EdgeAccessIterator, edge_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>);
@@ -193,21 +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);
+// 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/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index 8d1a0c86b..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;
 
@@ -157,11 +158,8 @@ auto load_queries(Db &db)
     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();
     };
@@ -174,8 +172,8 @@ 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();
     };
@@ -184,11 +182,7 @@ auto load_queries(Db &db)
     auto match_all_delete = [&db](const properties_t &args) {
         DbAccessor t(db);
 
-        iter::for_all(t.vertex_access(), [&](auto a) {
-            if (a.fill()) {
-                a.remove();
-            }
-        });
+        t.vertex_access().fill().for_all([&](auto a) { a.remove(); });
 
         return t.commit();
     };
@@ -199,11 +193,7 @@ auto load_queries(Db &db)
 
         auto &label = t.label_find_or_create("LABEL");
 
-        iter::for_all(label.index().for_range(t), [&](auto a) {
-            if (a.fill()) {
-                a.remove();
-            }
-        });
+        label.index().for_range(t).for_all([&](auto a) { a.remove(); });
 
         return t.commit();
     };
@@ -238,11 +228,7 @@ auto load_queries(Db &db)
     auto match_edge_all_delete = [&db](const properties_t &args) {
         DbAccessor t(db);
 
-        iter::for_all(t.edge_access(), [&](auto a) {
-            if (a.fill()) {
-                a.remove();
-            }
-        });
+        t.edge_access().fill().for_all([&](auto a) { a.remove(); });
 
         return t.commit();
     };
@@ -253,26 +239,46 @@ auto load_queries(Db &db)
 
         auto &type = t.type_find_or_create("TYPE");
 
-        iter::for_all(type.index().for_range(t), [&](auto a) {
-            if (a.fill()) {
-                a.remove();
-            }
-        });
+        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_type_id_return = [&db](const properties_t &args) {
+    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 resoults = iter::make_f`
+        auto results = v.out().fill().type(type).to();
 
-                        return t.commit();
+        // 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:
@@ -299,6 +305,7 @@ auto load_queries(Db &db)
     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
index fc908f19c..f0c430309 100644
--- a/include/utils/iterator/filter.hpp
+++ b/include/utils/iterator/filter.hpp
@@ -6,12 +6,11 @@
 namespace iter
 {
 
-// Class which filters values returned by I iterator into value of type T with
-// OP
-// function.
+// 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 mapper function
+// OP - type of filter function. OP: T& -> bool
 template <class T, class I, class OP>
 class Filter : public IteratorBase<T>
 {
@@ -25,30 +24,32 @@ public:
     // std::move is a optimization for it.
     Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
 
-    Filter(Filter &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
-
-    ~Filter() final {}
-
+    // Return values for which filter return true.
     Option<T> next() final
     {
-        auto item = iter.next();
-        if (item.is_present()) {
-            return Option<T>(op(item.take()));
-        } else {
-            return Option<T>();
-        }
+        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_map(I &&iter, OP &&op)
+auto make_filter(I &&iter, OP &&op)
 {
     // Compiler cant deduce type T. decltype is here to help with it.
-    return Filter<decltype(op(iter.next().take())), I, OP>(std::move(iter),
-                                                           std::move(op));
+    return Filter<decltype(iter.next().take()), I, OP>(std::move(iter),
+                                                       std::move(op));
 }
 }
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/src/barrier/barrier.cpp b/src/barrier/barrier.cpp
index a2630d0a3..717e1fedf 100644
--- a/src/barrier/barrier.cpp
+++ b/src/barrier/barrier.cpp
@@ -437,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);
 
@@ -445,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);
 
@@ -453,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);
 
@@ -461,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);
 
@@ -469,6 +477,8 @@ 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);
 
@@ -477,6 +487,8 @@ Option<const EdgeAccessor> EdgeAccessIterator::next()
     return HALF_CALL(next()).map<const EdgeAccessor>();
 }
 
+Count EdgeAccessIterator::count() { return HALF_CALL(count()); }
+
 // ************************* VertexPropertyKey
 DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey);
 
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));
+}