diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp
new file mode 100644
index 000000000..2a45d23fe
--- /dev/null
+++ b/include/utils/iterator/filter.hpp
@@ -0,0 +1,49 @@
+#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
+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)) {}
+
+    Option<T> next() final
+    {
+        auto item = iter.next();
+        if (item.is_present() && op(item.get())) {
+            return std::move(item);
+        } else {
+            return Option<T>();
+        }
+    }
+
+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/iterator.hpp b/include/utils/iterator/iterator.hpp
index 93e48a67d..8a42b10ac 100644
--- a/include/utils/iterator/iterator.hpp
+++ b/include/utils/iterator/iterator.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "utils/iterator/accessor.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/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/tool.cpp b/poc/tool.cpp
index 616db34f2..a60ee9ae7 100644
--- a/poc/tool.cpp
+++ b/poc/tool.cpp
@@ -13,6 +13,7 @@
 #include "storage/record_accessor.cpp"
 #include "storage/vertex_accessor.cpp"
 #include "utils/command_line/arguments.hpp"
+#include "utils/iterator/query.hpp"
 
 using namespace std;
 
@@ -164,7 +165,7 @@ void oportunity_employe_company(
     const EdgeType &type_created, const EdgeType &type_works_in,
     const Label &label_company)
 {
-    iter::for_all_fill(va.in(), [&](auto opp_e) {
+    iter::for_all(va.in().fill(), [&](auto opp_e) {
         // cout << "                       oec.in()" << endl;
         from_fill(opp_e, type_created, [&](auto creator) {
             // cout << "                           type_created" << endl;