diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index a88b82f82b500d3ab9011421916e1f295374fcb7..320dbd262b77e9addc9e7db690bdee5fe1619a6b 100644
--- a/libwccl/CMakeLists.txt
+++ b/libwccl/CMakeLists.txt
@@ -28,6 +28,7 @@ endif(WIN32)
 SET(libwccl_STAT_SRC
 	exception.cpp
 	ops/formatters.cpp
+	ops/functions/bool/iteration.cpp
 	ops/functions/bool/predicate.cpp
 	ops/functions/bool/predicates/and.cpp
 	ops/functions/bool/predicates/logicalpredicate.cpp
diff --git a/libwccl/ops/functions/bool/iteration.cpp b/libwccl/ops/functions/bool/iteration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd9c97c6f0d1637289f4e55f70d409009a9ce580
--- /dev/null
+++ b/libwccl/ops/functions/bool/iteration.cpp
@@ -0,0 +1,59 @@
+#include <libwccl/ops/functions/bool/iteration.h>
+#include <libwccl/ops/functions/bool/predicate.h>
+
+
+namespace Wccl {
+
+#ifndef _MSC_VER
+const int Iteration::MatchAll;
+#endif
+
+Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context) const
+{
+	const boost::shared_ptr<const Position>& range_begin = range_begin_expr_->apply(context);
+	const boost::shared_ptr<const Position>& range_end = range_end_expr_->apply(context);
+	const boost::shared_ptr<Position>& iter_var = context.variables()->get_fast(iter_var_acc_);
+
+	const SentenceContext& sc = context.sentence_context();
+
+	int abs_begin = sc.get_abs_position(*range_begin);
+	int abs_end = sc.get_abs_position(*range_end);
+
+	// Proceed only if range positions are not "nowhere".
+	if (abs_begin != Position::Nowhere && abs_end != Position::Nowhere) {
+		// Trim range to sentence boundaries
+		if (abs_begin < 0) {
+			abs_begin = 0;
+		}
+		if (abs_end >= sc.size()) {
+			abs_end = sc.size() - 1;
+		}
+		int range_size = abs_begin - abs_end + 1;
+		// Proceed only if range isn't empty
+		if (range_size > 0) {
+			int n = (match_count_ == MatchAll) ? range_size : match_count_;
+			// Proceed only if the range actually has enough positions to match
+			if (n <= range_size) {
+				if (direction_ == Forward) {
+					if (iterate(abs_begin, abs_end, 1, *iter_var, context)) {
+						return Predicate::True(context);
+					}
+				}
+				if (iterate(abs_end, abs_begin, -1, *iter_var, context)) {
+					return Predicate::True(context);
+				}
+			}
+		}
+	}
+	// In case of failure, set iteration variable to Nowhere and return False
+	iter_var->set_value(Position::Nowhere);
+	return Predicate::False(context);
+}
+
+bool Iteration::iterate(int start, int stop, int step, Position &p, const FunExecContext &context) const
+{
+	//TODO: implement
+	return false;
+}
+
+} /* end ns Wccl */
diff --git a/libwccl/ops/functions/bool/iteration.h b/libwccl/ops/functions/bool/iteration.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b27b9f79f4d5af6d7b3f190e06b685ae2efcd4e
--- /dev/null
+++ b/libwccl/ops/functions/bool/iteration.h
@@ -0,0 +1,66 @@
+#ifndef LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H
+#define LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H
+
+#include <libwccl/ops/function.h>
+#include <libwccl/values/bool.h>
+#include <libwccl/values/position.h>
+
+namespace Wccl {
+
+/**
+ * Abstract base class for a class of operators that iterate over a range.
+ */
+class Iteration : public Function<Bool> {
+public:
+	typedef boost::shared_ptr<Function<Position> > PosFunctionPtr;
+	typedef boost::shared_ptr<Function<Bool> > BoolFunctionPtr;
+	static const int MatchAll = boost::integer_traits<int>::const_min;
+	typedef enum Direction
+	{
+		Forward,
+		Backward
+	} Direction;
+
+protected:
+
+	Iteration(
+		const PosFunctionPtr& range_begin_expr,
+		const PosFunctionPtr& range_end_expr,
+		const VariableAccessor<Position>& iter_var_acc,
+		const BoolFunctionPtr& condition_expr,
+		int match_count = MatchAll,
+		Direction direction = Forward)
+		: range_begin_expr_(range_begin_expr),
+		  range_end_expr_(range_end_expr),
+		  iter_var_acc_(iter_var_acc),
+		  condition_expr_(condition_expr),
+		  match_count_(match_count),
+		  direction_(direction)
+	{
+		BOOST_ASSERT(range_begin_expr_);
+		BOOST_ASSERT(range_end_expr_);
+		BOOST_ASSERT(condition_expr_);
+		BOOST_ASSERT(match_count == MatchAll || match_count > 0);
+	}
+
+	/**
+	 * Evaluate argument expression and assign the result to underlying variable.
+	 * @returns True.
+	 */
+	BaseRetValPtr apply_internal(const FunExecContext& context) const;
+
+	const PosFunctionPtr& range_begin_expr_;
+	const PosFunctionPtr& range_end_expr_;
+	const VariableAccessor<Position> iter_var_acc_;
+	const BoolFunctionPtr& condition_expr_;
+	const int match_count_;
+	const Direction direction_;
+
+private:
+	bool iterate(int start, int stop, int step, Position& p, const FunExecContext& context) const;
+};
+
+
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H