diff --git a/libwccl/ops/match/actions/markmatch.cpp b/libwccl/ops/match/actions/markmatch.cpp
index 9c987a2f9144198e4b88ca959ebb26d9a6226183..27933f151ae8afd92ce0985565df49a3043ac4ca 100644
--- a/libwccl/ops/match/actions/markmatch.cpp
+++ b/libwccl/ops/match/actions/markmatch.cpp
@@ -18,20 +18,26 @@ void MarkMatch::execute(const ActionExecContext& context) const
 	boost::shared_ptr<const Match> match_from = match_from_->apply(context);
 	boost::shared_ptr<const Match> match_to =
 		(match_from_.get() == match_to_.get()) ? match_from : match_to_->apply(context);
+	boost::shared_ptr<const Match> head_match =
+		(match_from_.get() == head_match_.get()) ? match_from : head_match_->apply(context);
 
 	int abs_left = match_from->first_token(as).get_value();
-	int abs_right = match_to->last_token(as).get_value();
 	if (abs_left < 0) {
 		throw WcclError("Received starting match that points outside sentence.");
 	}
+
+	int abs_right = match_to->last_token(as).get_value();
 	if (abs_right >= sc.size()) {
 		throw WcclError("Received ending match that points outside sentence.");
 	}
 	if (abs_left > abs_right) {
 		throw WcclError("Received starting match points after the received ending match.");
 	}
-	// TODO: what about head in this mark from match actions? Mark from tag actions does have it.
-	int abs_head = abs_left;
+
+	int abs_head = head_match->first_token(as).get_value();
+	if (abs_head < abs_left || abs_head > abs_right) {
+		throw WcclError("Received head match points outside range defined by start and end matches.");
+	}
 
 	if (!as->has_channel(chan_name_)) {
 		as->create_channel(chan_name_);
diff --git a/libwccl/ops/match/actions/markmatch.h b/libwccl/ops/match/actions/markmatch.h
index 9f5b6e51377854d08181154898cfc7d3c0a3971e..024af6decd0188bdf5016901c61c75ce3b2a407a 100644
--- a/libwccl/ops/match/actions/markmatch.h
+++ b/libwccl/ops/match/actions/markmatch.h
@@ -12,13 +12,30 @@ public:
 	MarkMatch(
 			const boost::shared_ptr<Function<Match> >& match_from,
 			const boost::shared_ptr<Function<Match> >& match_to,
+			const boost::shared_ptr<Function<Match> >& head_match,
 			const std::string& annotation_name)
 		: match_from_(match_from),
 		  match_to_(match_to),
+		  head_match_(head_match),
 		  chan_name_(annotation_name)
 	{
 		BOOST_ASSERT(match_from_);
 		BOOST_ASSERT(match_to_);
+		BOOST_ASSERT(head_match_);
+	}
+
+	MarkMatch(
+			const boost::shared_ptr<Function<Match> >& match_from,
+			const boost::shared_ptr<Function<Match> >& match_to,
+			const std::string& annotation_name)
+		: match_from_(match_from),
+		  match_to_(match_to),
+		  head_match_(match_from),
+		  chan_name_(annotation_name)
+	{
+		BOOST_ASSERT(match_from_);
+		BOOST_ASSERT(match_to_);
+		BOOST_ASSERT(head_match_);
 	}
 
 	MarkMatch(
@@ -26,10 +43,12 @@ public:
 			const std::string& annotation_name)
 		: match_from_(match_from_to),
 		  match_to_(match_from_to),
+		  head_match_(match_from_to),
 		  chan_name_(annotation_name)
 	{
 		BOOST_ASSERT(match_from_);
 		BOOST_ASSERT(match_to_);
+		BOOST_ASSERT(head_match_);
 	}
 	/**
 	 * @returns Name of the action.
@@ -59,6 +78,7 @@ protected:
 private:
 	const boost::shared_ptr<Function<Match> >& match_from_;
 	const boost::shared_ptr<Function<Match> >& match_to_;
+	const boost::shared_ptr<Function<Match> >& head_match_;
 	const std::string chan_name_;
 };
 
diff --git a/libwccl/parser/grammar.g b/libwccl/parser/grammar.g
index ba4f99c0fdb5fba5a1f0acfe110e574891085b6a..9bea7459323dd907b6dd87c11b3c0ec026a1e118 100644
--- a/libwccl/parser/grammar.g
+++ b/libwccl/parser/grammar.g
@@ -1947,10 +1947,13 @@ match_mark_action
 {
 	boost::shared_ptr<Function<Match> > match_to;
 	boost::shared_ptr<Function<Match> > match_from;
+	boost::shared_ptr<Function<Match> > head_match;
 }
 	: "mark" LPAREN 
 			match_from = match_fit[tagset, vars] COMMA
-			(match_to  = match_fit[tagset, vars] COMMA) ?
+			( match_to  = match_fit[tagset, vars] COMMA
+				( head_match = match_fit[tagset, vars] COMMA )?
+			)?
 			annotation_name : STRING
 		RPAREN {
 			if (!match_to) {
@@ -1959,11 +1962,20 @@ match_mark_action
 						match_from,
 						((antlr::Token*)annotation_name)->getText()));
 			} else {
-				m_act.reset(
-					new MarkMatch(
-						match_from,
-						match_to,
-						((antlr::Token*)annotation_name)->getText()));
+				if (!head_match) {
+					m_act.reset(
+						new MarkMatch(
+							match_from,
+							match_to,
+							((antlr::Token*)annotation_name)->getText()));
+				} else {
+					m_act.reset(
+						new MarkMatch(
+							match_from,
+							match_to,
+							head_match,
+							((antlr::Token*)annotation_name)->getText()));
+				}
 			}
 		}
 ;