diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index 2b63e4b476862ad188009f6ab6c2eff759b9122d..a48ace24e94e3070271de973b33860a2b36c2f7e 100644
--- a/libwccl/CMakeLists.txt
+++ b/libwccl/CMakeLists.txt
@@ -55,6 +55,7 @@ SET(libwccl_STAT_SRC
 	ops/functions/tset/getsymbols.cpp
 	ops/functions/tset/getsymbolsinrange.cpp
 	ops/match/conditions/conjconditions.cpp
+	ops/match/conditions/repeatedmatch.cpp
 	ops/match/conditions/tokencondition.cpp
 	ops/match/applyoperator.cpp
 	ops/match/matchoperator.cpp
diff --git a/libwccl/ops/match/conditions/repeatedmatch.cpp b/libwccl/ops/match/conditions/repeatedmatch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a43fb47617e06d3e379a2576f6caf0aaf731dadb
--- /dev/null
+++ b/libwccl/ops/match/conditions/repeatedmatch.cpp
@@ -0,0 +1,43 @@
+#include <libwccl/ops/match/conditions/repeatedmatch.h>
+#include <libwccl/values/matchvector.h>
+#include <sstream>
+
+namespace Wccl {
+
+RepeatedMatch::RepeatedMatch(const boost::shared_ptr<ConjConditions>& conditions)
+	: _conditions(conditions)
+{
+	BOOST_ASSERT(_conditions);
+}
+
+MatchResult RepeatedMatch::apply(boost::shared_ptr<Position> iter_pos, const FunExecContext& context) const
+{
+	boost::shared_ptr<MatchVector> match(new MatchVector());
+	int orig_pos = iter_pos->get_value();
+	MatchResult res = _conditions->apply(iter_pos, context);
+	if (res.matched()) {
+		do {
+			match->append(res.get_match());
+			res = _conditions->apply(iter_pos, context);
+		} while (res.matched());
+		return MatchResult(match);
+	}
+	else {
+		iter_pos->set_value(orig_pos);
+		return MatchResult();
+	}
+}
+
+std::string RepeatedMatch::to_string(const Corpus2::Tagset& tagset) const
+{
+	std::ostringstream ostream;
+	ostream << name() << _conditions->to_string(tagset);
+	return ostream.str();
+}
+
+std::ostream& RepeatedMatch::write_to(std::ostream& ostream) const
+{
+	return ostream << name() << *_conditions;
+}
+
+} /* end ns Wccl */
diff --git a/libwccl/ops/match/conditions/repeatedmatch.h b/libwccl/ops/match/conditions/repeatedmatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..b26230ceadd9039eb36e5bdd62bf3b20dd5cc7ba
--- /dev/null
+++ b/libwccl/ops/match/conditions/repeatedmatch.h
@@ -0,0 +1,54 @@
+#ifndef LIBWCCL_OPS_MATCH_CONDITIONS_REPEATEDMATCH_H
+#define LIBWCCL_OPS_MATCH_CONDITIONS_REPEATEDMATCH_H
+
+#include <libwccl/ops/match/conditions/conjconditions.h>
+
+namespace Wccl {
+
+/**
+ * Class for "repeat" condition of match
+ */
+class RepeatedMatch : public MatchCondition
+{
+public:
+	RepeatedMatch(const boost::shared_ptr<ConjConditions>& conditions);
+
+	/**
+	 * @returns Name of the condition.
+	 */
+	std::string name() const {
+		return "repeat";
+	}
+	/**
+	 * Applies the condition to the given execution context.
+	 * Inner conditions are executed repeatedly as long as matching is successful.
+	 * If there were any successful matches, the result consists of "true"
+	 * and the MatchVector constructed out of individual match vectors coming
+	 * from each successful repetition.
+	 * If there was no match, "false" is returned along with a default Match.
+	 * If match is found, the current iter Position "$_" is increased
+	 * as to point one token after all the matched tokens, otherwise
+	 * it stays unchanged.
+	 */
+	MatchResult apply(boost::shared_ptr<Position> iter_pos, const FunExecContext& context) const;
+
+	/**
+	 * @returns String representation of the Action
+	 */
+	std::string to_string(const Corpus2::Tagset& tagset) const;
+
+protected:
+	/**
+	 * Writes string representation of the TokenCondition to
+	 * an output stream.
+	 * @returns Stream written to.
+	 * @note May be incomplete and/or containt internal info.
+	 */
+	std::ostream& write_to(std::ostream& ostream) const;
+private:
+	const boost::shared_ptr<ConjConditions> _conditions;
+};
+
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_MATCH_CONDITIONS_REPEATEDMATCH_H