diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp
index 6520c0cf7..fe848c88d 100644
--- a/include/barrier/barrier.hpp
+++ b/include/barrier/barrier.hpp
@@ -145,7 +145,7 @@ public:
 
     VertexAccessor update() const;
 
-    bool remove() const;
+    void remove() const;
 
     const Property &at(VertexPropertyFamily &key) const;
 
@@ -204,7 +204,7 @@ public:
 
     EdgeAccessor update() const;
 
-    bool remove() const;
+    void remove() const;
 
     const Property &at(EdgePropertyFamily &key) const;
 
diff --git a/include/mvcc/version_list.hpp b/include/mvcc/version_list.hpp
index 2b7046548..0523559b6 100644
--- a/include/mvcc/version_list.hpp
+++ b/include/mvcc/version_list.hpp
@@ -178,12 +178,11 @@ public:
         return remove(record, t), true;
     }
 
-    bool remove(T *record, tx::Transaction &t)
+    void remove(T *record, tx::Transaction &t)
     {
         assert(record != nullptr);
         lock_and_validate(record, t);
         record->mark_deleted(t);
-        return true;
     }
 
     const Id id;
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index 303b664d2..6424b745a 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -271,13 +271,111 @@ auto load_queries(Db &db)
         DbAccessor t(db);
 
         auto &type = t.type_find_or_create("TYPE");
+        auto prop_name = t.vertex_property_key("name", args[0]->flags);
 
-        auto it_type = type.index().for_range(t);
-        auto it_vertex = t.vertex_access();
+        Option<const EdgeAccessor> r;
 
-        // TODO
-        // if (it_type.count().max > it_vertex.count().max) {
-        // }
+        auto it_type = type.index()
+                           .for_range(t)
+                           .clone_to(r) // Savepoint
+                           .from()      // Backtracing
+                           .has_property(prop_name, *args[0].get())
+                           .replace(r); // Load savepoint
+
+        auto it_vertex = t.vertex_access()
+                             .fill()
+                             .has_property(prop_name, *args[0].get())
+                             .out()
+                             .type(type);
+
+        if (it_type.count() > it_vertex.count()) {
+            // Going through vertices wiil probably be faster
+            it_vertex.to().for_all([&](auto m) {
+                // PRINT m
+            });
+
+        } else {
+            // Going through edges wiil probably be faster
+            it_type.to().for_all([&](auto m) {
+                // PRINT m
+            });
+        }
+
+        return t.commit();
+    };
+
+    // MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN n,m
+    auto match_name_type_return_cross = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+        auto prop_name = t.vertex_property_key("name", args[0]->flags);
+
+        Option<const VertexAccessor> n;
+        Option<const EdgeAccessor> r;
+
+        auto it_type = type.index()
+                           .for_range(t)
+                           .clone_to(r) // Savepoint
+                           .from()      // Backtracing
+                           .has_property(prop_name, *args[0].get())
+                           .clone_to(n) // Savepoint
+                           .replace(r); // Load savepoint
+
+        auto it_vertex = t.vertex_access()
+                             .fill()
+                             .has_property(prop_name, *args[0].get())
+                             .clone_to(n) // Savepoint
+                             .out()
+                             .type(type);
+
+        if (it_type.count() > it_vertex.count()) {
+            // Going through vertices wiil probably be faster
+            it_vertex.to().for_all([&](auto m) {
+                // PRINT n,m
+            });
+
+        } else {
+            // Going through edges wiil probably be faster
+            it_type.to().for_all([&](auto m) {
+                // PRINT n,m
+            });
+        }
+
+        return t.commit();
+    };
+
+    // MATCH (n:LABEL)-[:TYPE]->(m) RETURN n
+    auto match_label_type_return = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+        auto &label = t.label_find_or_create("LABEL");
+
+        Option<const VertexAccessor> bt;
+
+        auto it_type = type.index().for_range(t).from().label(label);
+
+        auto it_vertex = t.vertex_access()
+                             .fill()
+                             .label(label)
+                             .clone_to(bt) // Savepoint
+                             .out()
+                             .type(type)
+                             .replace(bt); // Load savepoint
+
+        if (it_type.count() > it_vertex.count()) {
+            // Going through vertices wiil probably be faster
+            it_vertex.for_all([&](auto n) {
+                // PRINT n
+            });
+
+        } else {
+            // Going through edges wiil probably be faster
+            it_type.for_all([&](auto n) {
+                // PRINT n
+            });
+        }
 
         return t.commit();
     };
@@ -307,6 +405,9 @@ auto load_queries(Db &db)
     queries[14897166600223619735u] = match_edge_all_delete;
     queries[16888549834923624215u] = match_edge_type_delete;
     queries[11675960684124428508u] = match_id_type_return;
+    queries[1554436524951961398u] = match_name_type_return;
+    queries[8537338362659537296u] = match_name_type_return_cross;
+    queries[8918221081398321263u] = match_label_type_return;
 
     return queries;
 }
diff --git a/include/storage/edge_accessor.hpp b/include/storage/edge_accessor.hpp
index 05d266290..197cf378d 100644
--- a/include/storage/edge_accessor.hpp
+++ b/include/storage/edge_accessor.hpp
@@ -15,19 +15,23 @@ class Edges;
 // There exists circular dependecy with VertexAccessor.
 class EdgeAccessor : public RecordAccessor<TypeGroupEdge, EdgeAccessor>
 {
+    friend VertexAccessor;
+
 public:
     using RecordAccessor::RecordAccessor;
     typedef Edge record_t;
     typedef EdgeRecord record_list_t;
 
     // Removes self and disconects vertices from it.
-    bool remove() const;
+    void remove() const;
 
     void edge_type(EdgeType const &edge_type);
 
     const EdgeType &edge_type() const;
 
+    // EdgeAccessor doesnt need to be filled
     VertexAccessor from() const;
 
+    // EdgeAccessor doesnt need to be filled
     VertexAccessor to() const;
 };
diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp
index 9a8e80fb8..a818f4324 100644
--- a/include/storage/record_accessor.hpp
+++ b/include/storage/record_accessor.hpp
@@ -146,7 +146,7 @@ public:
     }
 
 protected:
-    bool remove() const;
+    void remove() const;
 
     T *record{nullptr};
     vlist_t *const vlist;
diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp
index 7b73e8cb3..e9d6b216e 100644
--- a/include/storage/vertex_accessor.hpp
+++ b/include/storage/vertex_accessor.hpp
@@ -17,8 +17,8 @@ public:
     typedef Vertex record_t;
     typedef VertexRecord record_list_t;
 
-    // Removes only self.
-    bool remove() const { return RecordAccessor::remove(); }
+    // Removes self and all edges connected to it.
+    void remove() const;
 
     size_t out_degree() const;
 
diff --git a/include/utils/iterator/count.hpp b/include/utils/iterator/count.hpp
index 20016970f..074f4a44d 100644
--- a/include/utils/iterator/count.hpp
+++ b/include/utils/iterator/count.hpp
@@ -1,8 +1,10 @@
 #pragma once
 
+#include "utils/total_ordering.hpp"
+
 // Represents number of to be returned elements from iterator. Where acutal
 // number is probably somwhere in [min,max].
-class Count
+class Count : public TotalOrdering<Count>
 {
 
 public:
@@ -16,6 +18,18 @@ public:
         return *this;
     }
 
+    size_t avg() const { return ((max - min) >> 1) + min; }
+
+    friend constexpr bool operator<(const Count &lhs, const Count &rhs)
+    {
+        return lhs.avg() < rhs.avg();
+    }
+
+    friend constexpr bool operator==(const Count &lhs, const Count &rhs)
+    {
+        return lhs.avg() == rhs.avg();
+    }
+
     size_t min;
     size_t max;
 };
diff --git a/include/utils/iterator/flat_map.hpp b/include/utils/iterator/flat_map.hpp
new file mode 100644
index 000000000..9fc748740
--- /dev/null
+++ b/include/utils/iterator/flat_map.hpp
@@ -0,0 +1,77 @@
+#pragma once
+
+namespace iter
+{
+
+// Class which maps values returned by I iterator into iterators of type J
+// ,which
+// return value of type T, with function OP.
+// function.
+// T - type of return value
+// I - iterator type
+// J - iterator type returned from OP
+// OP - type of mapper function
+template <class T, class I, class J, class OP>
+class FlatMap : public IteratorBase<T>
+{
+
+public:
+    FlatMap() = delete;
+
+    // FlatMap operation is designed to be used in chained calls which operate
+    // on a
+    // iterator. FlatMap will in that usecase receive other iterator by value
+    // and
+    // std::move is a optimization for it.
+    FlatMap(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    FlatMap(FlatMap &&m)
+        : iter(std::move(m.iter)), op(std::move(m.op)),
+          sub_iter(std::move(m.sub_iter))
+    {
+    }
+
+    ~FlatMap() final {}
+
+    Option<T> next() final
+    {
+        do {
+            if (!sub_iter.is_present()) {
+                auto item = iter.next();
+                if (item.is_present()) {
+                    sub_iter = Option<J>(op(item.take()));
+                } else {
+                    return Option<T>();
+                }
+            }
+
+            auto item = sub_iter.get().next();
+            if (item.is_present()) {
+                return std::move(item);
+            } else {
+                sub_iter.take();
+            }
+        } while (true);
+    }
+
+    Count count() final
+    {
+        // TODO: Correct count, are at least correcter
+        return iter.count();
+    }
+
+private:
+    I iter;
+    Option<J> sub_iter;
+    OP op;
+};
+
+template <class I, class OP>
+auto make_flat_map(I &&iter, OP &&op)
+{
+    // Compiler cant deduce type T and J. decltype is here to help with it.
+    return FlatMap<decltype(op(iter.next().take()).next().take()), I,
+                   decltype(op(iter.next().take())), OP>(std::move(iter),
+                                                         std::move(op));
+}
+}
diff --git a/include/utils/iterator/inspect.hpp b/include/utils/iterator/inspect.hpp
new file mode 100644
index 000000000..8fba73b37
--- /dev/null
+++ b/include/utils/iterator/inspect.hpp
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which inspects values returned by I iterator before passing thenm as
+// result.
+// function.
+// T - type of return value
+// I - iterator type
+// OP - type of inspector function. OP: T&->void
+template <class T, class I, class OP>
+class Inspect : public IteratorBase<T>
+{
+
+public:
+    Inspect() = delete;
+
+    // Inspect operation is designed to be used in chained calls which operate
+    // on a
+    // iterator. Inspect will in that usecase receive other iterator by value
+    // and
+    // std::move is a optimization for it.
+    Inspect(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    Inspect(Inspect &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
+
+    ~Inspect() final {}
+
+    Option<T> next() final
+    {
+        auto item = iter.next();
+        if (item.is_present()) {
+            op(item.get());
+            return std::move(item);
+        } else {
+            return Option<T>();
+        }
+    }
+
+    Count count() final { return iter.count(); }
+
+private:
+    I iter;
+    OP op;
+};
+
+template <class I, class OP>
+auto make_inspect(I &&iter, OP &&op)
+{
+    // Compiler cant deduce type T. decltype is here to help with it.
+    return Inspect<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 fb9d41655..44091046b 100644
--- a/include/utils/iterator/iterator.hpp
+++ b/include/utils/iterator/iterator.hpp
@@ -3,9 +3,12 @@
 #include "utils/iterator/accessor.hpp"
 #include "utils/iterator/count.hpp"
 #include "utils/iterator/filter.hpp"
+#include "utils/iterator/flat_map.hpp"
 #include "utils/iterator/for_all.hpp"
+#include "utils/iterator/inspect.hpp"
 #include "utils/iterator/iterator_accessor.hpp"
 #include "utils/iterator/iterator_base.hpp"
 #include "utils/iterator/lambda_iterator.hpp"
+#include "utils/iterator/limited_map.hpp"
 #include "utils/iterator/map.hpp"
 #include "utils/iterator/range_iterator.hpp"
diff --git a/include/utils/iterator/iterator_base.hpp b/include/utils/iterator/iterator_base.hpp
index b11906673..019aeb5f2 100644
--- a/include/utils/iterator/iterator_base.hpp
+++ b/include/utils/iterator/iterator_base.hpp
@@ -15,6 +15,15 @@ auto make_filter(I &&iter, OP &&op);
 
 template <class I, class C>
 void for_all(I &&iter, C &&consumer);
+
+template <class I, class OP>
+auto make_flat_map(I &&iter, OP &&op);
+
+template <class I, class OP>
+auto make_inspect(I &&iter, OP &&op);
+
+template <class I, class OP>
+auto make_limited_map(I &&iter, OP &&op);
 }
 
 // Base iterator for next() kind iterator.
@@ -43,12 +52,64 @@ public:
             std::move(*this), std::move(op));
     }
 
+    // Replaces every item with item taken from n if it exists.
+    template <class R>
+    auto replace(Option<R> &n)
+    {
+        return iter::make_limited_map<decltype(std::move(*this))>(
+            std::move(*this), [&](auto v) mutable { return std::move(n); });
+    }
+
     // Maps with call to method to() and filters with call to fill.
     auto to()
     {
         return map([](auto er) { return er.to(); }).fill();
     }
 
+    // Maps with call to method from() and filters with call to fill.
+    auto from()
+    {
+        return map([](auto er) { return er.from(); }).fill();
+    }
+
+    // Combines out iterators into one iterator.
+    auto out()
+    {
+        return iter::make_flat_map<decltype(std::move(*this))>(
+            std::move(*this), [](auto vr) { return vr.out().fill(); });
+    }
+
+    // Filters with label on from vertex.
+    template <class LABEL>
+    auto from_label(LABEL const &label)
+    {
+        return filter([&](auto &ra) {
+            auto va = ra.from();
+            return va.fill() && va.has_label(label);
+        });
+    }
+
+    // Filters with property under given key
+    template <class KEY, class PROP>
+    auto has_property(KEY &key, PROP const &prop)
+    {
+        return filter([&](auto &va) { return va.at(key) == prop; });
+    }
+
+    // Copy-s all pasing value to t before they are returned.
+    // auto clone_to(Option<T> &t)
+    // {
+    //     return iter::make_inspect<decltype(std::move(*this))>(
+    //         std::move(*this), [&](auto &v) { t = Option<T>(v); });
+    // }
+
+    // Copy-s pasing value to t before they are returned.
+    auto clone_to(Option<const T> &t)
+    {
+        return iter::make_inspect<decltype(std::move(*this))>(
+            std::move(*this), [&](auto &v) mutable { t = Option<const T>(v); });
+    }
+
     // Filters with call to method fill()
     auto fill()
     {
@@ -62,6 +123,13 @@ public:
         return filter([&](auto &ra) { return ra.edge_type() == type; });
     }
 
+    // Filters with label.
+    template <class LABEL>
+    auto label(LABEL const &label)
+    {
+        return filter([&](auto &va) { return va.has_label(label); });
+    }
+
     // Filters out vertices which are connected.
     auto isolated()
     {
diff --git a/include/utils/iterator/limited_map.hpp b/include/utils/iterator/limited_map.hpp
new file mode 100644
index 000000000..83d4402e4
--- /dev/null
+++ b/include/utils/iterator/limited_map.hpp
@@ -0,0 +1,56 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which maps values returned by I iterator into value of type T with OP
+// function and ends when op return empty optional.
+// T - type of return value
+// I - iterator type
+// OP - type of mapper function. OP: V -> Option<T>
+template <class T, class I, class OP>
+class LimitedMap : public IteratorBase<T>
+{
+
+public:
+    LimitedMap() = delete;
+
+    // LimitedMap operation is designed to be used in chained calls which
+    // operate on a
+    // iterator. LimitedMap will in that usecase receive other iterator by value
+    // and
+    // std::move is a optimization for it.
+    LimitedMap(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    LimitedMap(LimitedMap &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
+
+    ~LimitedMap() final {}
+
+    Option<T> next() final
+    {
+        auto item = iter.next();
+        if (item.is_present()) {
+            return op(item.take());
+        } else {
+            return Option<T>();
+        }
+    }
+
+    Count count() final { return iter.count(); }
+
+private:
+    I iter;
+    OP op;
+};
+
+template <class I, class OP>
+auto make_limited_map(I &&iter, OP &&op)
+{
+    // Compiler cant deduce type T. decltype is here to help with it.
+    return LimitedMap<decltype(op(iter.next().take()).take()), I, OP>(
+        std::move(iter), std::move(op));
+}
+}
diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp
index 3c1702dac..65fc1f710 100644
--- a/src/barrier/barrier.cpp
+++ b/src/barrier/barrier.cpp
@@ -282,7 +282,7 @@ const Id &VertexAccessor::id() const { return HALF_CALL(id()); }
 
 VertexAccessor VertexAccessor::update() const { return CALL(update()); }
 
-bool VertexAccessor::remove() const { return HALF_CALL(remove()); }
+void VertexAccessor::remove() const { HALF_CALL(remove()); }
 
 const Property &VertexAccessor::at(VertexPropertyFamily &key) const
 {
@@ -372,7 +372,7 @@ const Id &EdgeAccessor::id() const { return HALF_CALL(id()); }
 
 EdgeAccessor EdgeAccessor::update() const { return CALL(update()); }
 
-bool EdgeAccessor::remove() const { return HALF_CALL(remove()); }
+void EdgeAccessor::remove() const { HALF_CALL(remove()); }
 
 const Property &EdgeAccessor::at(EdgePropertyFamily &key) const
 {
diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp
index 8e5c91e64..15031a9af 100644
--- a/src/storage/edge_accessor.cpp
+++ b/src/storage/edge_accessor.cpp
@@ -2,24 +2,19 @@
 
 #include "storage/vertex_record.hpp"
 
-bool EdgeAccessor::remove() const
+void EdgeAccessor::remove() const
 {
-    if (RecordAccessor::remove()) {
-        auto from_v = from();
-        bool f_from = from_v.fill();
-        assert(f_from);
+    RecordAccessor::remove();
+    auto from_v = from();
+    bool f_from = from_v.fill();
+    assert(f_from);
 
-        auto to_v = to();
-        bool f_to = to_v.fill();
-        assert(f_to);
+    auto to_v = to();
+    bool f_to = to_v.fill();
+    assert(f_to);
 
-        from_v.update().record->data.out.remove(vlist);
-        to_v.update().record->data.in.remove(vlist);
-
-        return true;
-    } else {
-        return false;
-    }
+    from_v.update().record->data.out.remove(vlist);
+    to_v.update().record->data.in.remove(vlist);
 }
 
 void EdgeAccessor::edge_type(const EdgeType &edge_type)
diff --git a/src/storage/record_accessor.cpp b/src/storage/record_accessor.cpp
index fdbb25a77..3f62e8ad4 100644
--- a/src/storage/record_accessor.cpp
+++ b/src/storage/record_accessor.cpp
@@ -13,11 +13,11 @@
 // }
 
 template <class T, class Derived>
-bool RecordAccessor<T, Derived>::remove() const
+void RecordAccessor<T, Derived>::remove() const
 {
     assert(!empty());
 
-    return vlist->remove(record, db.trans);
+    vlist->remove(record, db.trans);
 }
 
 template class RecordAccessor<TypeGroupEdge, EdgeAccessor>;
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index 6b17464ff..06347c24c 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -48,3 +48,23 @@ bool VertexAccessor::in_contains(VertexAccessor const &other) const
 {
     return record->data.in.contains(other.vlist);
 }
+
+void VertexAccessor::remove() const
+{
+    RecordAccessor::remove();
+
+    for (auto evr : record->data.out) {
+        auto ea = EdgeAccessor(evr, db);
+        ea.vlist->remove(db.trans);
+        auto to_v = ea.to();
+        to_v.fill();
+        to_v.update().record->data.in.remove(ea.vlist);
+    }
+    for (auto evr : record->data.in) {
+        auto ea = EdgeAccessor(evr, db);
+        ea.vlist->remove(db.trans);
+        auto from_v = ea.from();
+        from_v.fill();
+        from_v.update().record->data.out.remove(ea.vlist);
+    }
+}