diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index eff2894c194703220ab51d2a5ffd455f517b84bc..ecf74dfecea0e4b2e8b7e4c79f1c6168f231efe3 100644
--- a/libwccl/CMakeLists.txt
+++ b/libwccl/CMakeLists.txt
@@ -70,7 +70,6 @@ SET(libwccl_STAT_SRC
 	ops/match/conditions/optionalmatch.cpp
 	ops/match/conditions/repeatedmatch.cpp
 	ops/match/conditions/tokencondition.cpp
-	ops/match/matchoperator.cpp
 	ops/matchrule.cpp
 	ops/rulesequence.cpp
 	ops/tagaction.cpp
diff --git a/libwccl/ops/match/applyoperator.cpp b/libwccl/ops/match/applyoperator.cpp
index 9a5a9878b185a8ea5a4e254539354779d8fc70c2..9e9816ad85dfe0c9b1aa937f22a6bacfcc918c45 100644
--- a/libwccl/ops/match/applyoperator.cpp
+++ b/libwccl/ops/match/applyoperator.cpp
@@ -1,48 +1,55 @@
 #include <libwccl/ops/match/applyoperator.h>
-#include <libwccl/values/matchvector.h>
+#include <libwccl/values/match.h>
+#include <libwccl/ops/match/conditions/conjconditions.h>
+#include <libwccl/ops/match/matchaction.h>
 #include <libpwrutils/foreach.h>
 
 namespace Wccl {
 
 ApplyOperator::ApplyOperator(
 	const VariableAccessor<Match>& matches,
-	const boost::shared_ptr<const MatchOperator>& match_op,
+	const boost::shared_ptr<const ConjConditions>& match_conditions,
 	const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > >& actions,
-	const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > >& conditions)
-		: _matches(matches),
-		  _match_op(match_op),
-		  _actions(actions),
-		  _conditions(conditions)
+	const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > >& apply_conditions)
+		: matches_(matches),
+		  match_conditions_(match_conditions),
+		  actions_(actions),
+		  apply_conditions_(apply_conditions)
 {
-	BOOST_ASSERT(_match_op);
-	BOOST_ASSERT(actions->size() > 0);
+	BOOST_ASSERT(match_conditions_);
+	BOOST_ASSERT(actions_->size() > 0);
 }
 
 void ApplyOperator::execute(const ActionExecContext &context) const
 {
 	MatchVector* matches =
 		dynamic_cast<MatchVector*>(
-			&context.variables()->get_fast(_matches)->get_value());
+			&context.variables()->get_fast(matches_)->get_value());
 	BOOST_ASSERT(matches);
 	context.sentence_context().goto_start();
 	while(context.sentence_context().is_current_inside()) {
 		int orig_pos = context.sentence_context().get_position();
 		// Set initial value for $m:_M variable for this iteration and launch the match:
 		matches->clear();
-		boost::shared_ptr<Match> match = _match_op->apply(context);
-		// Execute the actions only if match isn't empty and all post-conditions are met:
-		bool should_act = !match->empty();
-		for(size_t i = 0; should_act && i < _conditions->size(); ++i) {
-			should_act = (*_conditions)[i]->apply(context)->get_value();
-		}
-		if (should_act) {
-			matches->append(match); // the match goes to $m:_M[0]
-			foreach (const boost::shared_ptr<MatchAction>& action, *_actions) {
-				action->execute(context);
+		MatchResult match = match_conditions_->apply(context);
+		// Execute the actions only if there was a match and all post-conditions are met:
+		if (!match.matched()) {
+			// no match - advance current position by 1.
+			context.sentence_context().set_position(orig_pos + 1);
+		} else {
+			// there was a match - check conditions of apply
+			bool should_act = true;
+			for(size_t i = 0; should_act && i < apply_conditions_->size(); ++i) {
+				should_act = (*apply_conditions_)[i]->apply(context)->get_value();
+			}
+			if (should_act) {
+				matches->append(match.get_match()); // the match goes to $m:_M[0]
+				foreach (const boost::shared_ptr<MatchAction>& action, *actions_) {
+					action->execute(context);
+				}
 			}
 		}
-		// Inner operators (match and its conditions) are responsible for properly
-		// advancing current sentence position.
+		// Inner operators are responsible for properly advancing current sentence position.
 		BOOST_ASSERT(context.sentence_context().get_position() > orig_pos);
 	}
 }
@@ -50,23 +57,23 @@ void ApplyOperator::execute(const ActionExecContext &context) const
 std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const
 {
 	std::ostringstream ostream;
-	ostream << name() << "(" << _match_op->to_string(tagset) << ", ";
-	if (!_conditions->empty()) {
+	ostream << name() << "(match" << match_conditions_->to_string(tagset) << ", ";
+	if (!apply_conditions_->empty()) {
 		ostream << "cond(";
-		for(size_t i = 0; i < _conditions->size(); ++i) {
+		for(size_t i = 0; i < apply_conditions_->size(); ++i) {
 			if (i != 0) {
 				ostream << ", ";
 			}
-			ostream << (*_conditions)[i]->to_string(tagset);
+			ostream << (*apply_conditions_)[i]->to_string(tagset);
 		}
 		ostream << "), ";
 	}
 	ostream << "actions(";
-	for(size_t i = 0; i < _actions->size(); ++i) {
+	for(size_t i = 0; i < actions_->size(); ++i) {
 		if (i != 0) {
 			ostream << ", ";
 		}
-		ostream << (*_actions)[i]->to_string(tagset);
+		ostream << (*actions_)[i]->to_string(tagset);
 	}
 	ostream << "))";
 	return ostream.str();
@@ -74,23 +81,23 @@ std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const
 
 std::ostream& ApplyOperator::write_to(std::ostream &ostream) const
 {
-	ostream << name() << "(" << *_match_op << ", ";
-	if (!_conditions->empty()) {
+	ostream << name() << "(match" << *match_conditions_ << ", ";
+	if (!apply_conditions_->empty()) {
 		ostream << "cond(";
-		for(size_t i = 0; i < _conditions->size(); ++i) {
+		for(size_t i = 0; i < apply_conditions_->size(); ++i) {
 			if (i != 0) {
 				ostream << ", ";
 			}
-			ostream << *(*_conditions)[i];
+			ostream << *(*apply_conditions_)[i];
 		}
 		ostream << "), ";
 	}
 	ostream << "actions(";
-	for(size_t i = 0; i < (*_actions).size(); ++i) {
+	for(size_t i = 0; i < (*actions_).size(); ++i) {
 		if (i != 0) {
 			ostream << ", ";
 		}
-		ostream << *(*_actions)[i];
+		ostream << *(*actions_)[i];
 	}
 	ostream << "))";
 	return ostream;
diff --git a/libwccl/ops/match/applyoperator.h b/libwccl/ops/match/applyoperator.h
index d90aadc20dbc981bda82ba878f65acc7ebef6443..f685c72a023f49d278afc73b2ff2c518cf3ca944 100644
--- a/libwccl/ops/match/applyoperator.h
+++ b/libwccl/ops/match/applyoperator.h
@@ -3,12 +3,10 @@
 
 #include <libwccl/ops/functions/bool/predicates/logicalpredicate.h>
 
-#include <libwccl/ops/match/matchoperator.h>
-#include <libwccl/ops/match/matchaction.h>
-
-
 namespace Wccl {
 
+class ConjConditions;
+class MatchAction;
 /**
  * Operator that realizes "apply" functionality for match rules
  */
@@ -18,15 +16,15 @@ public:
 	typedef LogicalPredicate::BoolFunctionPtrVector BoolFunctionPtrVector;
 	/**
 	  * @param matches Accessor to the "$m:_M" variable
-	  * @param match_op "match" operator for apply
-	  * @param actions "actions" section of apply, should not be empty
-	  * @param conditions "cond" section of apply, empty by default
+	  * @param match_conditions "match" sections of apply; conditions for finding matches
+	  * @param actions "actions" section of apply, should not be empty; actions to apply on matches
+	  * @param conditions "cond" section of apply, empty by default; conditions for applying the actions
 	  */
 	ApplyOperator(
 			const VariableAccessor<Match>& matches,
-			const boost::shared_ptr<const MatchOperator>& match_op,
+			const boost::shared_ptr<const ConjConditions>& match_conditions,
 			const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > >& actions,
-			const boost::shared_ptr<const BoolFunctionPtrVector>& conditions
+			const boost::shared_ptr<const BoolFunctionPtrVector>& apply_conditions
 				= boost::shared_ptr<const BoolFunctionPtrVector>(new BoolFunctionPtrVector()));
 
 	/**
@@ -58,10 +56,10 @@ protected:
 	std::ostream& write_to(std::ostream& ostream) const;
 
 private:
-	const VariableAccessor<Match> _matches;
-	const boost::shared_ptr<const MatchOperator> _match_op;
-	const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > > _actions;
-	const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > > _conditions;
+	const VariableAccessor<Match> matches_;
+	const boost::shared_ptr<const ConjConditions> match_conditions_;
+	const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > > actions_;
+	const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > > apply_conditions_;
 };
 
 } /* end ns Wccl */
diff --git a/libwccl/ops/match/matchoperator.cpp b/libwccl/ops/match/matchoperator.cpp
deleted file mode 100644
index 26a46e047f40563008818d31d37cc786887d0c94..0000000000000000000000000000000000000000
--- a/libwccl/ops/match/matchoperator.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <libwccl/ops/match/matchoperator.h>
-#include <sstream>
-
-namespace Wccl {
-
-boost::shared_ptr<Match> MatchOperator::apply(const ActionExecContext& context) const
-{
-	int orig_pos = context.sentence_context().get_position();
-	MatchResult res = _conditions->apply(context);
-	if(res.matched()) {
-		return res.get_match();
-	}
-	context.sentence_context().set_position(orig_pos + 1);
-	return boost::make_shared<Match>();
-}
-
-std::string MatchOperator::to_string(const Corpus2::Tagset& tagset) const
-{
-	std::ostringstream ostream;
-	ostream << name() << _conditions->to_string(tagset);
-	return ostream.str();
-}
-
-std::ostream& MatchOperator::write_to(std::ostream &ostream) const
-{
-	return ostream << name() << *_conditions;
-}
-
-} /* end ns Wccl */
diff --git a/libwccl/ops/match/matchoperator.h b/libwccl/ops/match/matchoperator.h
deleted file mode 100644
index 000c38c89c81447378d204c461ec3b08c95bce23..0000000000000000000000000000000000000000
--- a/libwccl/ops/match/matchoperator.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef LIBWCCL_OPS_MATCH_MATCHOPERATOR_H
-#define LIBWCCL_OPS_MATCH_MATCHOPERATOR_H
-
-#include <libwccl/ops/match/conditions/conjconditions.h>
-
-namespace Wccl {
-
-/**
- * Operator that realizes "match" functionality for match rules
- */
-class MatchOperator : public Expression
-{
-public:
-	MatchOperator(const boost::shared_ptr<ConjConditions>& conditions)
-		: _conditions(conditions) {
-		BOOST_ASSERT(_conditions);
-	}
-
-	/**
-	 * @returns Name of the operator.
-	 */
-	std::string name() const {
-		return "match";
-	}
-
-	/**
-	 * @returns String representation of the Action
-	 */
-	std::string to_string(const Corpus2::Tagset& tagset) const;
-
-	/**
-	 * Applies the operator to the given context.
-	 * @returns Vector of matches corresponding to match conditions,
-	 * if all conditions were met. In such case current sentence position
-	 * points to one position ahead of matched tokens.
-	 * Empty MatchVector is returned if any of the conditions was not met.
-	 * In such case current Position in sentence is advanced by 1.
-	 * @param context Execution context - current sentence and Variables to operate on
-	 */
-	boost::shared_ptr<Match> apply(const ActionExecContext& context) const;
-
-protected:
-	/**
-	 * Writes string representation of the operator 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_MATCHOPERATOR_H
diff --git a/libwccl/parser/grammar.g b/libwccl/parser/grammar.g
index 5ce65c46b90c91cf2ef44016bb29f5885473bbe0..d06ac7f16a48bfd6c97185ba0da039670d43bd66 100644
--- a/libwccl/parser/grammar.g
+++ b/libwccl/parser/grammar.g
@@ -2008,42 +2008,28 @@ match_apply_operator
 	returns [boost::shared_ptr<ApplyOperator> ret_op]
 {
 	VariableAccessor<Match> matches = vars.create_accessor<Match>("_M");;
-	boost::shared_ptr<const MatchOperator> match_op;
+	boost::shared_ptr<ConjConditions> match_cond;
 	boost::shared_ptr<std::vector<boost::shared_ptr<MatchAction> > > actions;
 	boost::shared_ptr<std::vector<boost::shared_ptr<Function<Bool> > > > conditions;
-
 }
 	: "apply" LPAREN 
-		match_op = match_operator[tagset, vars] COMMA
+		"match" LPAREN match_cond = match_condition [tagset,vars] RPAREN COMMA
 		("cond"   LPAREN conditions = bool_operator_comma_sep [tagset, vars] RPAREN COMMA)?
 		"actions" LPAREN actions    =  match_action_comma_sep [tagset, vars] RPAREN
 		RPAREN {
 			if (conditions) {
 				ret_op.reset(
-					new ApplyOperator(matches, match_op, actions, conditions)
+					new ApplyOperator(matches, match_cond, actions, conditions)
 				);
 			}
 			else {
 				ret_op.reset(
-					new ApplyOperator(matches, match_op, actions)
+					new ApplyOperator(matches, match_cond, actions)
 				);
 			}
 		}
 ;
 
-// Match operator: match(match_conditions)
-// Returns boost::shared_ptr<MatchOperator>
-match_operator
-	[const Corpus2::Tagset& tagset, Variables& vars]
-	returns [boost::shared_ptr<MatchOperator> op]
-{
-	boost::shared_ptr<ConjConditions> match_cond;
-}
-	: "match" LPAREN match_cond = match_condition [tagset,vars] RPAREN {
-		op.reset(new MatchOperator(match_cond));
-	}
-;
-
 // Match conditions. Wrapper for vector of the match conditions
 match_condition
 	[const Corpus2::Tagset& tagset, Variables& vars]