diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index 75bcc153864b0b9d1ff8eb77983f5c1b12b39cf5..d57040aeadb012a4e442566f21dbba35a4011442 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/oneof.cpp
 	ops/match/conditions/optionalmatch.cpp
 	ops/match/conditions/repeatedmatch.cpp
 	ops/match/conditions/tokencondition.cpp
diff --git a/libwccl/ops/match/conditions/oneof.cpp b/libwccl/ops/match/conditions/oneof.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78c3544c0656ddb6d828c3a6623a6943cbb66b4a
--- /dev/null
+++ b/libwccl/ops/match/conditions/oneof.cpp
@@ -0,0 +1,54 @@
+#include <libwccl/ops/match/conditions/oneof.h>
+#include <libwccl/values/matchvector.h>
+#include <sstream>
+#include <libpwrutils/foreach.h>
+
+namespace Wccl {
+
+OneOf::OneOf(const boost::shared_ptr<std::vector<ConjConditions> >& variants)
+	: _variants(variants)
+{
+	BOOST_ASSERT(_variants);
+	BOOST_ASSERT(!_variants->empty());
+}
+
+MatchResult OneOf::apply(const ActionExecContext& context) const
+{
+	int orig_pos = context.sentence_context().get_position();
+	foreach(const ConjConditions& variant, *_variants) {
+		MatchResult res = variant.apply(context);
+		if (res.matched()) {
+			return res;
+		}
+		context.sentence_context().set_position(orig_pos);
+	}
+	return MatchResult();
+}
+
+std::string OneOf::to_string(const Corpus2::Tagset& tagset) const
+{
+	std::ostringstream ostream;
+	ostream << name() << "(";
+	for (size_t i = 0; i < _variants->size(); ++i) {
+		if (i != 0) {
+			ostream << ", ";
+		}
+		ostream << "variant" << _variants->at(i).to_string(tagset);
+	}
+	ostream << ")";
+	return ostream.str();
+}
+
+std::ostream& OneOf::write_to(std::ostream& ostream) const
+{
+	ostream << name() << "(";
+	for (size_t i = 0; i < _variants->size(); ++i) {
+		if (i != 0) {
+			ostream << ", ";
+		}
+		ostream << "variant" << _variants->at(i);
+	}
+	return ostream << ")";
+}
+
+} /* end ns Wccl */
diff --git a/libwccl/ops/match/conditions/oneof.h b/libwccl/ops/match/conditions/oneof.h
new file mode 100644
index 0000000000000000000000000000000000000000..0aba4762638cf33c594401be71a2adfbba19572a
--- /dev/null
+++ b/libwccl/ops/match/conditions/oneof.h
@@ -0,0 +1,51 @@
+#ifndef LIBWCCL_OPS_MATCH_CONDITIONS_ONEOF_H
+#define LIBWCCL_OPS_MATCH_CONDITIONS_ONEOF_H
+
+#include <libwccl/ops/match/conditions/conjconditions.h>
+
+namespace Wccl {
+
+/**
+ * Class for "oneof" condition of match
+ */
+class OneOf : public MatchCondition
+{
+public:
+	OneOf(const boost::shared_ptr<std::vector<ConjConditions> >& variants);
+
+	/**
+	 * @returns Name of the condition.
+	 */
+	std::string name() const {
+		return "oneof";
+	}
+	/**
+	 * Applies the condition to the given execution context.
+	 * Inner match variants are executed one by one until a "true" one is found.
+	 * Once a "true" variant is found, it is returned with "true" MatchResult.
+	 * If there was no "true" match variant, "false" is returned instead.
+	 * If a match is found, the current sentence Position is increased
+	 * as to point one token after all the matched tokens, otherwise
+	 * it stays unchanged.
+	 */
+	MatchResult apply(const ActionExecContext& context) const;
+
+	/**
+	 * @returns String representation of the MatchCondition
+	 */
+	std::string to_string(const Corpus2::Tagset& tagset) const;
+
+protected:
+	/**
+	 * Writes string representation of the MatchCondition 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<std::vector<ConjConditions> > _variants;
+};
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_MATCH_CONDITIONS_ONEOF_H