#include <catch2/catch.hpp>

#include "sax/SaxComposeInterface.h"
#include "sax/SaxParseInterface.h"

#include "rte/formal/FormalRTE.h"
#include "rte/formal/FormalRTEElements.h"

#include <rte/xml/FormalRTE.h>

#include "rte/RTE.h"

#include "factory/XmlDataFactory.hpp"

TEST_CASE ( "RTE", "[unit][data][rte]" ) {
	SECTION ( "Copy constructor" ) {
		{
			/*
			 * rte::UnboundedRTE rte;
			 * rte.setAlphabet({DefaultSymbolType("1"), DefaultSymbolType("2"), DefaultSymbolType("3")});
			 * rte::UnboundedRTESymbol l1 = rte::UnboundedRTESymbol("1");
			 * rte::UnboundedRTESymbol l2 = rte::UnboundedRTESymbol("2");
			 *
			 * rte::UnboundedRTEConcatenation con = rte::UnboundedRTEConcatenation();
			 * con.appendElement(l1);
			 * con.appendElement(l2);
			 *
			 * rte::UnboundedRTEIteration ite = rte::UnboundedRTEIteration(l1);
			 *
			 * rte::UnboundedRTEAlternation alt = rte::UnboundedRTEAlternation();
			 * alt.appendElement(con);
			 * alt.appendElement(ite);
			 *
			 * rte.setRTE(alt);
			 *
			 * rte::UnboundedRTE rte2(rte);
			 *
			 * CHECK( rte == rte2 );
			 *
			 * rte::UnboundedRTE rte3(std::move(rte));
			 *
			 * CHECK( rte2 == rte3 );
			 */
		}
		{
			const common::ranked_symbol < > symb_a2 ( DefaultSymbolType ( 'a' ), 2 );
			const common::ranked_symbol < > symb_b0 ( DefaultSymbolType ( 'b' ), 0 );
			const common::ranked_symbol < > symb_c0 ( DefaultSymbolType ( 'c' ), 0 );
			const common::ranked_symbol < > symb_y0 ( DefaultSymbolType ( 'y' ), 0 );
			const common::ranked_symbol < > symb_z0 ( DefaultSymbolType ( 'z' ), 0 );

			rte::FormalRTE < > rte;
			rte.setAlphabetSymbols ( { symb_a2, symb_b0, symb_c0 } );
			rte.setConstantSymbols ( { symb_y0, symb_z0 } );

			rte::FormalRTESymbolAlphabet < DefaultSymbolType > b = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_b0, { } );
			rte::FormalRTESymbolAlphabet < DefaultSymbolType > c = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_c0, { } );
			rte::FormalRTESymbolSubst < DefaultSymbolType > y = rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_y0 );
			rte::FormalRTESymbolSubst < DefaultSymbolType > z = rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_z0 );

			rte::FormalRTEAlternation < DefaultSymbolType > alt = rte::FormalRTEAlternation < DefaultSymbolType > ( b, c );

			ext::ptr_vector < rte::FormalRTEElement < DefaultSymbolType > > children;
			children.push_back ( std::move ( y ) );
			children.push_back ( std::move ( z ) );
			rte::FormalRTESymbolAlphabet < DefaultSymbolType > a = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_a2, std::move ( children ) );

			rte::FormalRTEIteration < DefaultSymbolType > iter = rte::FormalRTEIteration < DefaultSymbolType > ( a, rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_y0 ) );
			rte::FormalRTESubstitution < DefaultSymbolType > subst = rte::FormalRTESubstitution < DefaultSymbolType > ( iter, alt, rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_z0 ) );
			rte.setRTE ( rte::FormalRTEStructure < DefaultSymbolType > ( subst ) );

			rte::FormalRTE < > frte2 ( rte );
			CHECK ( rte == frte2 );

			rte::FormalRTE < > frte3 ( std::move ( rte ) );
			CHECK ( frte2 == frte3 );
		}
	}

	SECTION ( "Xml Parser" ) {
		const common::ranked_symbol < > symb_a2 ( DefaultSymbolType ( 'a' ), 2 );
		const common::ranked_symbol < > symb_b0 ( DefaultSymbolType ( 'b' ), 0 );
		const common::ranked_symbol < > symb_c0 ( DefaultSymbolType ( 'c' ), 0 );
		const common::ranked_symbol < > symb_d1 ( DefaultSymbolType ( 'd' ), 1 );
		const common::ranked_symbol < > symb_y0 ( DefaultSymbolType ( 'y' ), 0 );
		const common::ranked_symbol < > symb_z0 ( DefaultSymbolType ( 'z' ), 0 );

		rte::FormalRTE < > rte;

		rte.setAlphabetSymbols ( { symb_a2, symb_b0, symb_c0, symb_d1 } );
		rte.setConstantSymbols ( { symb_y0, symb_z0 } );

		rte::FormalRTESymbolAlphabet < DefaultSymbolType > b = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_b0, { } );
		rte::FormalRTESymbolAlphabet < DefaultSymbolType > c = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_c0, { } );
		rte::FormalRTESymbolSubst < DefaultSymbolType > y = rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_y0 );
		rte::FormalRTESymbolSubst < DefaultSymbolType > z = rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_z0 );

		rte::FormalRTEAlternation < DefaultSymbolType > alt = rte::FormalRTEAlternation < DefaultSymbolType > ( b, c );

		ext::ptr_vector < rte::FormalRTEElement < DefaultSymbolType > > children_a;
		children_a.push_back ( std::move ( y ) );
		children_a.push_back ( std::move ( z ) );
		rte::FormalRTESymbolAlphabet < DefaultSymbolType > a = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_a2, std::move ( children_a ) );

		ext::ptr_vector < rte::FormalRTEElement < DefaultSymbolType > > children_d;
		children_d.push_back ( std::move ( a ) );
		rte::FormalRTESymbolAlphabet < DefaultSymbolType > d = rte::FormalRTESymbolAlphabet < DefaultSymbolType > ( symb_d1, children_d );

		rte::FormalRTEIteration < DefaultSymbolType > iter = rte::FormalRTEIteration < DefaultSymbolType > ( d, rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_y0 ) );
		rte::FormalRTESubstitution < DefaultSymbolType > subst = rte::FormalRTESubstitution < DefaultSymbolType > ( iter, alt, rte::FormalRTESymbolSubst < DefaultSymbolType > ( symb_z0 ) );
		rte.setRTE ( rte::FormalRTEStructure < DefaultSymbolType > ( subst ) );

		factory::XmlDataFactory::toStdout ( rte );
		{
			ext::deque < sax::Token > tokens = factory::XmlDataFactory::toTokens ( rte );
			std::string tmp = sax::SaxComposeInterface::composeMemory ( tokens );

			ext::deque < sax::Token > tokens2 = sax::SaxParseInterface::parseMemory ( tmp );
			rte::FormalRTE < > rte2 = factory::XmlDataFactory::fromTokens ( std::move ( tokens2 ) );

			CHECK ( rte == rte2 );
		}
		{
			std::string tmp = factory::XmlDataFactory::toString ( rte );
			rte::FormalRTE < > rte2 = factory::XmlDataFactory::fromString ( tmp );

			CHECK ( rte == rte2 );
		}
	}

	SECTION ( "Order" ) {
		{
			/*
			 * rte::UnboundedRTESymbol s1("1");
			 * rte::UnboundedRTEEmpty e1;
			 * rte::UnboundedRTEEpsilon e2;
			 * rte::UnboundedRTEIteration i1(s1);
			 * rte::UnboundedRTEConcatenation a1;
			 * a1.appendElement(s1);
			 * a1.appendElement(s1);
			 * rte::UnboundedRTEAlternation c1;
			 * c1.appendElement(s1);
			 * c1.appendElement(s1);
			 *
			 * rte::UnboundedRTE alt1(a1);
			 * rte::UnboundedRTE con1(c1);
			 * rte::UnboundedRTE ite1(i1);
			 * rte::UnboundedRTE emp1(e1);
			 * rte::UnboundedRTE eps1(e2);
			 * rte::UnboundedRTE sym1(s1);
			 *
			 * CPPUNIT_EXCLUSIVE_OR(alt1 < con1, con1 < alt1);
			 * CPPUNIT_EXCLUSIVE_OR(alt1 < ite1, ite1 < alt1);
			 * CPPUNIT_EXCLUSIVE_OR(alt1 < emp1, emp1 < alt1);
			 * CPPUNIT_EXCLUSIVE_OR(alt1 < eps1, eps1 < alt1);
			 * CPPUNIT_EXCLUSIVE_OR(alt1 < sym1, sym1 < alt1);
			 *
			 * CPPUNIT_EXCLUSIVE_OR(con1 < ite1, ite1 < con1);
			 * CPPUNIT_EXCLUSIVE_OR(con1 < emp1, emp1 < con1);
			 * CPPUNIT_EXCLUSIVE_OR(con1 < eps1, eps1 < con1);
			 * CPPUNIT_EXCLUSIVE_OR(con1 < sym1, sym1 < con1);
			 *
			 * CPPUNIT_EXCLUSIVE_OR(ite1 < emp1, emp1 < ite1);
			 * CPPUNIT_EXCLUSIVE_OR(ite1 < eps1, eps1 < ite1);
			 * CPPUNIT_EXCLUSIVE_OR(ite1 < sym1, sym1 < ite1);
			 *
			 * CPPUNIT_EXCLUSIVE_OR(emp1 < eps1, eps1 < emp1);
			 * CPPUNIT_EXCLUSIVE_OR(emp1 < sym1, sym1 < emp1);
			 *
			 * CPPUNIT_EXCLUSIVE_OR(eps1 < sym1, sym1 < eps1);
			 *
			 * CPPUNIT_IMPLY( alt1 < con1 && con1 < ite1, alt1 < ite1 );
			 * CPPUNIT_IMPLY( alt1 < con1 && con1 < emp1, alt1 < emp1 );
			 * CPPUNIT_IMPLY( alt1 < con1 && con1 < eps1, alt1 < eps1 );
			 * CPPUNIT_IMPLY( alt1 < con1 && con1 < sym1, alt1 < sym1 );
			 *
			 * CPPUNIT_IMPLY( alt1 < ite1 && ite1 < con1, alt1 < con1 );
			 * CPPUNIT_IMPLY( alt1 < ite1 && ite1 < emp1, alt1 < emp1 );
			 * CPPUNIT_IMPLY( alt1 < ite1 && ite1 < eps1, alt1 < eps1 );
			 * CPPUNIT_IMPLY( alt1 < ite1 && ite1 < sym1, alt1 < sym1 );
			 *
			 * CPPUNIT_IMPLY( alt1 < emp1 && emp1 < con1, alt1 < con1 );
			 * CPPUNIT_IMPLY( alt1 < emp1 && emp1 < ite1, alt1 < ite1 );
			 * CPPUNIT_IMPLY( alt1 < emp1 && emp1 < eps1, alt1 < eps1 );
			 * CPPUNIT_IMPLY( alt1 < emp1 && emp1 < sym1, alt1 < sym1 );
			 *
			 * CPPUNIT_IMPLY( alt1 < eps1 && eps1 < con1, alt1 < con1 );
			 * CPPUNIT_IMPLY( alt1 < eps1 && eps1 < ite1, alt1 < ite1 );
			 * CPPUNIT_IMPLY( alt1 < eps1 && eps1 < emp1, alt1 < emp1 );
			 * CPPUNIT_IMPLY( alt1 < eps1 && eps1 < sym1, alt1 < sym1 );
			 *
			 * CPPUNIT_IMPLY( alt1 < sym1 && sym1 < con1, alt1 < con1 );
			 * CPPUNIT_IMPLY( alt1 < sym1 && sym1 < ite1, alt1 < ite1 );
			 * CPPUNIT_IMPLY( alt1 < sym1 && sym1 < emp1, alt1 < emp1 );
			 * CPPUNIT_IMPLY( alt1 < sym1 && sym1 < eps1, alt1 < eps1 );
			 *
			 *
			 *
			 * CPPUNIT_IMPLY( con1 < alt1 && alt1 < ite1, con1 < ite1 );
			 * CPPUNIT_IMPLY( con1 < alt1 && alt1 < emp1, con1 < emp1 );
			 * CPPUNIT_IMPLY( con1 < alt1 && alt1 < eps1, con1 < eps1 );
			 * CPPUNIT_IMPLY( con1 < alt1 && alt1 < sym1, con1 < sym1 );
			 *
			* CPPUNIT_IMPLY( con1 < ite1 && ite1 < alt1, con1 < alt1 );
			* CPPUNIT_IMPLY( con1 < ite1 && ite1 < emp1, con1 < emp1 );
			* CPPUNIT_IMPLY( con1 < ite1 && ite1 < eps1, con1 < eps1 );
			* CPPUNIT_IMPLY( con1 < ite1 && ite1 < sym1, con1 < sym1 );
			*
				* CPPUNIT_IMPLY( con1 < emp1 && emp1 < alt1, con1 < alt1 );
			* CPPUNIT_IMPLY( con1 < emp1 && emp1 < ite1, con1 < ite1 );
			* CPPUNIT_IMPLY( con1 < emp1 && emp1 < eps1, con1 < eps1 );
			* CPPUNIT_IMPLY( con1 < emp1 && emp1 < sym1, con1 < sym1 );
			*
				* CPPUNIT_IMPLY( con1 < eps1 && eps1 < alt1, con1 < alt1 );
			* CPPUNIT_IMPLY( con1 < eps1 && eps1 < ite1, con1 < ite1 );
			* CPPUNIT_IMPLY( con1 < eps1 && eps1 < emp1, con1 < emp1 );
			* CPPUNIT_IMPLY( con1 < eps1 && eps1 < sym1, con1 < sym1 );
			*
				* CPPUNIT_IMPLY( con1 < sym1 && sym1 < alt1, con1 < alt1 );
			* CPPUNIT_IMPLY( con1 < sym1 && sym1 < ite1, con1 < ite1 );
			* CPPUNIT_IMPLY( con1 < sym1 && sym1 < emp1, con1 < emp1 );
			* CPPUNIT_IMPLY( con1 < sym1 && sym1 < eps1, con1 < eps1 );
			*
				*
				*
				* CPPUNIT_IMPLY( ite1 < alt1 && alt1 < con1, ite1 < con1 );
			* CPPUNIT_IMPLY( ite1 < alt1 && alt1 < emp1, ite1 < emp1 );
			* CPPUNIT_IMPLY( ite1 < alt1 && alt1 < eps1, ite1 < eps1 );
			* CPPUNIT_IMPLY( ite1 < alt1 && alt1 < sym1, ite1 < sym1 );
			*
				* CPPUNIT_IMPLY( ite1 < con1 && con1 < alt1, ite1 < alt1 );
			* CPPUNIT_IMPLY( ite1 < con1 && con1 < emp1, ite1 < emp1 );
			* CPPUNIT_IMPLY( ite1 < con1 && con1 < eps1, ite1 < eps1 );
			* CPPUNIT_IMPLY( ite1 < con1 && con1 < sym1, ite1 < sym1 );
			*
				* CPPUNIT_IMPLY( ite1 < emp1 && emp1 < alt1, ite1 < alt1 );
			* CPPUNIT_IMPLY( ite1 < emp1 && emp1 < con1, ite1 < con1 );
			* CPPUNIT_IMPLY( ite1 < emp1 && emp1 < eps1, ite1 < eps1 );
			* CPPUNIT_IMPLY( ite1 < emp1 && emp1 < sym1, ite1 < sym1 );
			*
				* CPPUNIT_IMPLY( ite1 < eps1 && eps1 < alt1, ite1 < alt1 );
			* CPPUNIT_IMPLY( ite1 < eps1 && eps1 < con1, ite1 < con1 );
			* CPPUNIT_IMPLY( ite1 < eps1 && eps1 < emp1, ite1 < emp1 );
			* CPPUNIT_IMPLY( ite1 < eps1 && eps1 < sym1, ite1 < sym1 );
			*
				* CPPUNIT_IMPLY( ite1 < sym1 && sym1 < alt1, ite1 < alt1 );
			* CPPUNIT_IMPLY( ite1 < sym1 && sym1 < con1, ite1 < con1 );
			* CPPUNIT_IMPLY( ite1 < sym1 && sym1 < emp1, ite1 < emp1 );
			* CPPUNIT_IMPLY( ite1 < sym1 && sym1 < eps1, ite1 < eps1 );
			*
				*
				*
				* CPPUNIT_IMPLY( emp1 < alt1 && alt1 < con1, emp1 < con1 );
			* CPPUNIT_IMPLY( emp1 < alt1 && alt1 < ite1, emp1 < ite1 );
			* CPPUNIT_IMPLY( emp1 < alt1 && alt1 < eps1, emp1 < eps1 );
			* CPPUNIT_IMPLY( emp1 < alt1 && alt1 < sym1, emp1 < sym1 );
			*
				* CPPUNIT_IMPLY( emp1 < con1 && con1 < alt1, emp1 < alt1 );
			* CPPUNIT_IMPLY( emp1 < con1 && con1 < ite1, emp1 < ite1 );
			* CPPUNIT_IMPLY( emp1 < con1 && con1 < eps1, emp1 < eps1 );
			* CPPUNIT_IMPLY( emp1 < con1 && con1 < sym1, emp1 < sym1 );
			*
				* CPPUNIT_IMPLY( emp1 < ite1 && ite1 < alt1, emp1 < alt1 );
			* CPPUNIT_IMPLY( emp1 < ite1 && ite1 < con1, emp1 < con1 );
			* CPPUNIT_IMPLY( emp1 < ite1 && ite1 < eps1, emp1 < eps1 );
			* CPPUNIT_IMPLY( emp1 < ite1 && ite1 < sym1, emp1 < sym1 );
			*
				* CPPUNIT_IMPLY( emp1 < eps1 && eps1 < alt1, emp1 < alt1 );
			* CPPUNIT_IMPLY( emp1 < eps1 && eps1 < con1, emp1 < con1 );
			* CPPUNIT_IMPLY( emp1 < eps1 && eps1 < ite1, emp1 < ite1 );
			* CPPUNIT_IMPLY( emp1 < eps1 && eps1 < sym1, emp1 < sym1 );
			*
				* CPPUNIT_IMPLY( emp1 < sym1 && sym1 < alt1, emp1 < alt1 );
			* CPPUNIT_IMPLY( emp1 < sym1 && sym1 < con1, emp1 < con1 );
			* CPPUNIT_IMPLY( emp1 < sym1 && sym1 < ite1, emp1 < ite1 );
			* CPPUNIT_IMPLY( emp1 < sym1 && sym1 < eps1, emp1 < eps1 );
			*
				*
				*
				* CPPUNIT_IMPLY( eps1 < alt1 && alt1 < con1, eps1 < con1 );
			* CPPUNIT_IMPLY( eps1 < alt1 && alt1 < ite1, eps1 < ite1 );
			* CPPUNIT_IMPLY( eps1 < alt1 && alt1 < emp1, eps1 < emp1 );
			* CPPUNIT_IMPLY( eps1 < alt1 && alt1 < sym1, eps1 < sym1 );
			*
				* CPPUNIT_IMPLY( eps1 < con1 && con1 < alt1, eps1 < alt1 );
			* CPPUNIT_IMPLY( eps1 < con1 && con1 < ite1, eps1 < ite1 );
			* CPPUNIT_IMPLY( eps1 < con1 && con1 < emp1, eps1 < emp1 );
			* CPPUNIT_IMPLY( eps1 < con1 && con1 < sym1, eps1 < sym1 );
			*
				* CPPUNIT_IMPLY( eps1 < ite1 && ite1 < alt1, eps1 < alt1 );
			* CPPUNIT_IMPLY( eps1 < ite1 && ite1 < con1, eps1 < con1 );
			* CPPUNIT_IMPLY( eps1 < ite1 && ite1 < emp1, eps1 < emp1 );
			* CPPUNIT_IMPLY( eps1 < ite1 && ite1 < sym1, eps1 < sym1 );
			*
				* CPPUNIT_IMPLY( eps1 < emp1 && emp1 < alt1, eps1 < alt1 );
			* CPPUNIT_IMPLY( eps1 < emp1 && emp1 < con1, eps1 < con1 );
			* CPPUNIT_IMPLY( eps1 < emp1 && emp1 < ite1, eps1 < ite1 );
			* CPPUNIT_IMPLY( eps1 < emp1 && emp1 < sym1, eps1 < sym1 );
			*
				* CPPUNIT_IMPLY( eps1 < sym1 && sym1 < alt1, eps1 < alt1 );
			* CPPUNIT_IMPLY( eps1 < sym1 && sym1 < con1, eps1 < con1 );
			* CPPUNIT_IMPLY( eps1 < sym1 && sym1 < ite1, eps1 < ite1 );
			* CPPUNIT_IMPLY( eps1 < sym1 && sym1 < emp1, eps1 < emp1 );
			*
				*
				*
				* CPPUNIT_IMPLY( sym1 < alt1 && alt1 < con1, sym1 < con1 );
			* CPPUNIT_IMPLY( sym1 < alt1 && alt1 < ite1, sym1 < ite1 );
			* CPPUNIT_IMPLY( sym1 < alt1 && alt1 < emp1, sym1 < emp1 );
			* CPPUNIT_IMPLY( sym1 < alt1 && alt1 < eps1, sym1 < eps1 );
			*
				* CPPUNIT_IMPLY( sym1 < con1 && con1 < alt1, sym1 < alt1 );
			* CPPUNIT_IMPLY( sym1 < con1 && con1 < ite1, sym1 < ite1 );
			* CPPUNIT_IMPLY( sym1 < con1 && con1 < emp1, sym1 < emp1 );
			* CPPUNIT_IMPLY( sym1 < con1 && con1 < eps1, sym1 < eps1 );
			*
				* CPPUNIT_IMPLY( sym1 < ite1 && ite1 < alt1, sym1 < alt1 );
			* CPPUNIT_IMPLY( sym1 < ite1 && ite1 < con1, sym1 < con1 );
			* CPPUNIT_IMPLY( sym1 < ite1 && ite1 < emp1, sym1 < emp1 );
			* CPPUNIT_IMPLY( sym1 < ite1 && ite1 < eps1, sym1 < eps1 );
			*
				* CPPUNIT_IMPLY( sym1 < emp1 && emp1 < alt1, sym1 < alt1 );
			* CPPUNIT_IMPLY( sym1 < emp1 && emp1 < con1, sym1 < con1 );
			* CPPUNIT_IMPLY( sym1 < emp1 && emp1 < ite1, sym1 < ite1 );
			* CPPUNIT_IMPLY( sym1 < emp1 && emp1 < eps1, sym1 < eps1 );
			*
				* CPPUNIT_IMPLY( sym1 < eps1 && eps1 < alt1, sym1 < alt1 );
			* CPPUNIT_IMPLY( sym1 < eps1 && eps1 < con1, sym1 < con1 );
			* CPPUNIT_IMPLY( sym1 < eps1 && eps1 < ite1, sym1 < ite1 );
			* CPPUNIT_IMPLY( sym1 < eps1 && eps1 < emp1, sym1 < emp1 );
			*/
		}
		{
			/*
			 * rte::UnboundedRTESymbol s1("1");
			 * rte::UnboundedRTESymbol s2("2");
			 * rte::UnboundedRTESymbol s3("3");
			 *
			 * rte::UnboundedRTEEmpty e1;
			 * rte::UnboundedRTEEpsilon e2;
			 *
			 * rte::UnboundedRTEIteration i1(s1);
			 * rte::UnboundedRTEIteration i2(s2);
			 * rte::UnboundedRTEIteration i3(s3);
			 *
			 * rte::UnboundedRTEAlternation a1;
			 * a1.appendElement(s1);
			 * a1.appendElement(s1);
			 * rte::UnboundedRTEAlternation a2;
			 * a2.appendElement(s1);
			 * a2.appendElement(s2);
			 * rte::UnboundedRTEAlternation a3;
			 * a3.appendElement(s1);
			 * a3.appendElement(s3);
			 * rte::UnboundedRTEAlternation a4;
			 * a4.appendElement(s2);
			 * a4.appendElement(s1);
			 * rte::UnboundedRTEAlternation a5;
			 * a5.appendElement(s2);
			 * a5.appendElement(s2);
			 * rte::UnboundedRTEAlternation a6;
			 * a6.appendElement(s2);
			 * a6.appendElement(s3);
			 * rte::UnboundedRTEAlternation a7;
			 * a7.appendElement(s3);
			 * a7.appendElement(s1);
			 * rte::UnboundedRTEAlternation a8;
			 * a8.appendElement(s3);
			 * a8.appendElement(s2);
			 * rte::UnboundedRTEAlternation a9;
			 * a9.appendElement(s3);
			 * a9.appendElement(s3);
			 *
			 * rte::UnboundedRTEConcatenation c1;
			 * c1.appendElement(s1);
			 * c1.appendElement(s1);
			 * rte::UnboundedRTEConcatenation c2;
			 * c2.appendElement(s1);
			 * c2.appendElement(s2);
			 * rte::UnboundedRTEConcatenation c3;
			 * c3.appendElement(s1);
			 * c3.appendElement(s3);
			 * rte::UnboundedRTEConcatenation c4;
			 * c4.appendElement(s2);
			 * c4.appendElement(s1);
			 * rte::UnboundedRTEConcatenation c5;
			 * c5.appendElement(s2);
			 * c5.appendElement(s2);
			 * rte::UnboundedRTEConcatenation c6;
			 * c6.appendElement(s2);
			 * c6.appendElement(s3);
			 * rte::UnboundedRTEConcatenation c7;
			 * c7.appendElement(s3);
			 * c7.appendElement(s1);
			 * rte::UnboundedRTEConcatenation c8;
			 * c8.appendElement(s3);
			 * c8.appendElement(s2);
			 * rte::UnboundedRTEConcatenation c9;
			 * c9.appendElement(s3);
			 * c9.appendElement(s3);
			 *
			 * rte::UnboundedRTE alt1(a1);
			 * rte::UnboundedRTE alt2(a2);
			 * rte::UnboundedRTE alt3(a3);
			* rte::UnboundedRTE alt4(a4);
			* rte::UnboundedRTE alt5(a5);
			* rte::UnboundedRTE alt6(a6);
			* rte::UnboundedRTE alt7(a7);
			* rte::UnboundedRTE alt8(a8);
			* rte::UnboundedRTE alt9(a9);
			*
				* rte::UnboundedRTE con1(c1);
			* rte::UnboundedRTE con2(c2);
			* rte::UnboundedRTE con3(c3);
			* rte::UnboundedRTE con4(c4);
			* rte::UnboundedRTE con5(c5);
			* rte::UnboundedRTE con6(c6);
			* rte::UnboundedRTE con7(c7);
			* rte::UnboundedRTE con8(c8);
			* rte::UnboundedRTE con9(c9);
			*
				* rte::UnboundedRTE ite1(i1);
			* rte::UnboundedRTE ite2(i2);
			* rte::UnboundedRTE ite3(i3);
			*
				* rte::UnboundedRTE emp1(e1);
			* rte::UnboundedRTE eps1(e2);
			*
				* rte::UnboundedRTE sym1(s1);
			* rte::UnboundedRTE sym2(s2);
			* rte::UnboundedRTE sym3(s3);
			*
				*
				*
				* CHECK(alt1 == alt1);
			* CHECK(alt1 < alt2);
			* CHECK(alt1 < alt3);
			* CHECK(alt1 < alt4);
			* CHECK(alt1 < alt5);
			* CHECK(alt1 < alt6);
			* CHECK(alt1 < alt7);
			* CHECK(alt1 < alt8);
			* CHECK(alt1 < alt9);
			*
				* CHECK(alt2 > alt1);
			* CHECK(alt2 == alt2);
			* CHECK(alt2 < alt3);
			* CHECK(alt2 < alt4);
			* CHECK(alt2 < alt5);
			* CHECK(alt2 < alt6);
			* CHECK(alt2 < alt7);
			* CHECK(alt2 < alt8);
			* CHECK(alt2 < alt9);
			*
				* CHECK(alt3 > alt1);
			* CHECK(alt3 > alt2);
			* CHECK(alt3 == alt3);
			* CHECK(alt3 < alt4);
			* CHECK(alt3 < alt5);
			* CHECK(alt3 < alt6);
			* CHECK(alt3 < alt7);
			* CHECK(alt3 < alt8);
			* CHECK(alt3 < alt9);
			*
				* CHECK(alt4 > alt1);
			* CHECK(alt4 > alt2);
			* CHECK(alt4 > alt3);
			* CHECK(alt4 == alt4);
			* CHECK(alt4 < alt5);
			* CHECK(alt4 < alt6);
			* CHECK(alt4 < alt7);
			* CHECK(alt4 < alt8);
			* CHECK(alt4 < alt9);
			*
				* CHECK(alt5 > alt1);
			* CHECK(alt5 > alt2);
			* CHECK(alt5 > alt3);
			* CHECK(alt5 > alt4);
			* CHECK(alt5 == alt5);
			* CHECK(alt5 < alt6);
			* CHECK(alt5 < alt7);
			* CHECK(alt5 < alt8);
			* CHECK(alt5 < alt9);
			*
				* CHECK(alt6 > alt1);
			* CHECK(alt6 > alt2);
			* CHECK(alt6 > alt3);
			* CHECK(alt6 > alt4);
			* CHECK(alt6 > alt5);
			* CHECK(alt6 == alt6);
			* CHECK(alt6 < alt7);
			* CHECK(alt6 < alt8);
			* CHECK(alt6 < alt9);
			*
				* CHECK(alt7 > alt1);
			* CHECK(alt7 > alt2);
			* CHECK(alt7 > alt3);
			* CHECK(alt7 > alt4);
			* CHECK(alt7 > alt5);
			* CHECK(alt7 > alt6);
			* CHECK(alt7 == alt7);
			* CHECK(alt7 < alt8);
			* CHECK(alt7 < alt9);
			*
				* CHECK(alt8 > alt1);
			* CHECK(alt8 > alt2);
			* CHECK(alt8 > alt3);
			* CHECK(alt8 > alt4);
			* CHECK(alt8 > alt5);
			* CHECK(alt8 > alt6);
			* CHECK(alt8 > alt7);
			* CHECK(alt8 == alt8);
			* CHECK(alt8 < alt9);
			*
				* CHECK(alt9 > alt1);
			* CHECK(alt9 > alt2);
			* CHECK(alt9 > alt3);
			* CHECK(alt9 > alt4);
			* CHECK(alt9 > alt5);
			* CHECK(alt9 > alt6);
			* CHECK(alt9 > alt7);
			* CHECK(alt9 > alt8);
			* CHECK(alt9 == alt9);
			*
				*
				*
				* CHECK(con1 == con1);
			* CHECK(con1 < con2);
			* CHECK(con1 < con3);
			* CHECK(con1 < con4);
			* CHECK(con1 < con5);
			* CHECK(con1 < con6);
			* CHECK(con1 < con7);
			* CHECK(con1 < con8);
			* CHECK(con1 < con9);
			*
				* CHECK(con2 > con1);
			* CHECK(con2 == con2);
			* CHECK(con2 < con3);
			* CHECK(con2 < con4);
			* CHECK(con2 < con5);
			* CHECK(con2 < con6);
			* CHECK(con2 < con7);
			* CHECK(con2 < con8);
			* CHECK(con2 < con9);
			*
				* CHECK(con3 > con1);
			* CHECK(con3 > con2);
			* CHECK(con3 == con3);
			* CHECK(con3 < con4);
			* CHECK(con3 < con5);
			* CHECK(con3 < con6);
			* CHECK(con3 < con7);
			* CHECK(con3 < con8);
			* CHECK(con3 < con9);
			*
				* CHECK(con4 > con1);
			* CHECK(con4 > con2);
			* CHECK(con4 > con3);
			* CHECK(con4 == con4);
			* CHECK(con4 < con5);
			* CHECK(con4 < con6);
			* CHECK(con4 < con7);
			* CHECK(con4 < con8);
			* CHECK(con4 < con9);
			*
				* CHECK(con5 > con1);
			* CHECK(con5 > con2);
			* CHECK(con5 > con3);
			* CHECK(con5 > con4);
			* CHECK(con5 == con5);
			* CHECK(con5 < con6);
			* CHECK(con5 < con7);
			* CHECK(con5 < con8);
			* CHECK(con5 < con9);
			*
				* CHECK(con6 > con1);
			* CHECK(con6 > con2);
			* CHECK(con6 > con3);
			* CHECK(con6 > con4);
			* CHECK(con6 > con5);
			* CHECK(con6 == con6);
			* CHECK(con6 < con7);
			* CHECK(con6 < con8);
			* CHECK(con6 < con9);
			*
				* CHECK(con7 > con1);
			* CHECK(con7 > con2);
			* CHECK(con7 > con3);
			* CHECK(con7 > con4);
			* CHECK(con7 > con5);
			* CHECK(con7 > con6);
			* CHECK(con7 == con7);
			* CHECK(con7 < con8);
			* CHECK(con7 < con9);
			*
				* CHECK(con8 > con1);
			* CHECK(con8 > con2);
			* CHECK(con8 > con3);
			* CHECK(con8 > con4);
			* CHECK(con8 > con5);
			* CHECK(con8 > con6);
			* CHECK(con8 > con7);
			* CHECK(con8 == con8);
			* CHECK(con8 < con9);
			*
				* CHECK(con9 > con1);
			* CHECK(con9 > con2);
			* CHECK(con9 > con3);
			* CHECK(con9 > con4);
			* CHECK(con9 > con5);
			* CHECK(con9 > con6);
			* CHECK(con9 > con7);
			* CHECK(con9 > con8);
			* CHECK(con9 == con9);
			*
				*
				* CHECK(ite1 == ite1);
			* CHECK(ite1 < ite2);
			* CHECK(ite1 < ite3);
			*
				* CHECK(ite2 > ite1);
			* CHECK(ite2 == ite2);
			* CHECK(ite2 < ite3);
			*
				* CHECK(ite3 > ite1);
			* CHECK(ite3 > ite2);
			* CHECK(ite3 == ite3);
			*
				*
				*
				* CHECK(emp1 == emp1);
			*
				*
				*
				* CHECK(eps1 == eps1);
			*
				*
				*
				* CHECK(sym1 == sym1);
			* CHECK(sym1 < sym2);
			* CHECK(sym1 < sym3);
			*
				* CHECK(sym2 > sym1);
			* CHECK(sym2 == sym2);
			* CHECK(sym2 < sym3);
			*
				* CHECK(sym3 > sym1);
			* CHECK(sym3 > sym2);
			* CHECK(sym3 == sym3);
			*/
		}
	}
}
