diff --git a/alib2algo/src/automaton/convert/ToRTEStateElimination.cpp b/alib2algo/src/automaton/convert/ToRTEStateElimination.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5317429c933f329ace873f6ece898fcd299b01d7
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRTEStateElimination.cpp
@@ -0,0 +1,20 @@
+/*
+ * ToRTEStateElimination.cpp
+ *
+ *  Created on: 13. 3. 2019
+ *	  Author: Tomas Pecka
+ */
+
+#include "ToRTEStateElimination.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace automaton {
+
+namespace convert {
+
+auto ToRTEStateEliminationDFTA = registration::AbstractRegister< ToRTEStateElimination, rte::FormalRTE< ext::variant< DefaultSymbolType, DefaultStateType > >, const automaton::DFTA<>& > ( ToRTEStateElimination::convert, "automaton" );
+auto ToRTEStateEliminationNFTA = registration::AbstractRegister< ToRTEStateElimination, rte::FormalRTE< ext::variant< DefaultSymbolType, DefaultStateType > >, const automaton::NFTA<>& > ( ToRTEStateElimination::convert, "automaton" );
+
+} /* namespace convert */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/convert/ToRTEStateElimination.h b/alib2algo/src/automaton/convert/ToRTEStateElimination.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca79e54640812654894d15db844b6b61297f5776
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRTEStateElimination.h
@@ -0,0 +1,245 @@
+/*
+ * ToRTEStateElimination.h
+ *
+ * This file is part of Algorithms library toolkit.
+ * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
+
+ * Algorithms library toolkit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * Algorithms library toolkit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Created on: 13. 3. 2019
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef TO_RTE_STATE_ELIMINATION_H_
+#define TO_RTE_STATE_ELIMINATION_H_
+
+#include <algorithm>
+#include <numeric>
+
+#include <rte/formal/FormalRTE.h>
+
+#include <automaton/Automaton.h>
+#include <automaton/TA/DFTA.h>
+#include <automaton/TA/ExtendedNFTA.h>
+#include <automaton/TA/NFTA.h>
+
+#include <rte/formal/FormalRTEElements.h>
+
+#include <common/createUnique.hpp>
+
+#include <label/FinalStateLabel.h>
+
+#include <rte/simplify/RTEOptimize.h>
+
+namespace automaton {
+
+namespace convert {
+
+/**
+ * Converts a finite tree automaton to a regular tree expression using using the State Elimination algorithm (Travnicek: Not yet published)
+ * This algorithm returns the regular tree expression as rte::FormalRTE.
+ */
+class ToRTEStateElimination {
+public:
+    /**
+	 * Performs conversion.
+	 * @tparam T type of the finite tree automaton
+	 * @tparam SymbolType the type of symbol of the automaton's input ranked alphabet
+	 * @tparam StateType  the type of states of the automaton
+	 * @param automaton finite tree automaton to convert
+	 * @return formal regular tree expression equivalent to the original automaton
+	 */
+    template < class T, class SymbolType = DefaultSymbolType, class StateType = DefaultStateType >
+    static rte::FormalRTE< ext::variant< SymbolType, StateType > > convert ( const T& automaton );
+
+private:
+    /**
+	 * Helper function to create new final state in the automaton
+	 * @tparam SymbolType the type of symbol of the automaton's input ranked alphabet
+	 * @tparam StateType  the type of states of the automaton
+	 * @param automaton extended finite tree automaton
+	 */
+    template < class SymbolType, class StateType >
+    static void extendExtendedNFTA ( automaton::ExtendedNFTA< SymbolType, StateType >& automaton );
+
+    /**
+	 * Helper function for the elimination of a single state according to the algorithm.
+	 * @tparam SymbolType the type of symbol of the automaton's input ranked alphabet
+	 * @tparam StateType  the type of states of the automaton
+	 * @param extendedAutomaton automaton for the elimination
+	 * @param state a state to eliminate
+	 * @return the @p extendedAutomaton after the elimination of a state @state.
+	 */
+    template < class SymbolType, class StateType >
+    static automaton::ExtendedNFTA< SymbolType, StateType > eliminateState ( const automaton::ExtendedNFTA< SymbolType, StateType >& extendedAutomaton, const StateType& state );
+
+    /**
+	 * Helper function to create RTE alternation from several transition's rtexps
+	 * @tparam SymbolType the type of symbol of the automaton's input ranked alphabet
+	 * @tparam StateType  the type of states of the automaton
+	 * @param transitions transitions with RTEs to alternate
+	 * @return the @p extendedAutomaton after the elimination of a state @state.
+	 */
+    template < class SymbolType, class StateType >
+    static rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > createAlternation ( const ext::vector< ext::pair< ext::pair< rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >, ext::vector< StateType > >, StateType > >& transitions );
+};
+
+template < class T, class SymbolType, class StateType >
+rte::FormalRTE< ext::variant< SymbolType, StateType > > ToRTEStateElimination::convert ( const T& automaton ) {
+    if ( automaton.getFinalStates ( ).size ( ) == 0 )
+        return rte::FormalRTE< ext::variant< SymbolType, StateType > > ( );
+
+    // create an automaton, extend it with a new final state
+    automaton::ExtendedNFTA< SymbolType, StateType > extendedAutomaton ( automaton );
+    extendExtendedNFTA ( extendedAutomaton );
+
+    // eliminate all non-final states
+    ext::set< StateType > statesToEliminate;
+    std::set_difference ( extendedAutomaton.getStates ( ).begin ( ), extendedAutomaton.getStates ( ).end ( ),
+                          extendedAutomaton.getFinalStates ( ).begin ( ), extendedAutomaton.getFinalStates ( ).end ( ),
+                          std::inserter ( statesToEliminate, statesToEliminate.begin ( ) ) );
+
+    for ( const StateType& state : statesToEliminate ) {
+        extendedAutomaton = eliminateState ( extendedAutomaton, state );
+    }
+
+    // step 4
+    ext::vector< ext::pair< ext::pair< rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >, ext::vector< StateType > >, StateType > > alt;
+    for ( const auto& tr : extendedAutomaton.getTransitions ( ) )
+        for ( const StateType& targetState : tr.second )
+            alt.push_back ( ext::make_pair ( tr.first, targetState ) );
+
+    return rte::FormalRTE< ext::variant< SymbolType, StateType > > ( rte::simplify::RTEOptimize::optimize ( createAlternation ( alt ) ) );
+}
+
+template < class SymbolType, class StateType >
+rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > ToRTEStateElimination::createAlternation ( const ext::vector< ext::pair< ext::pair< rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >, ext::vector< StateType > >, StateType > >& transitions ) {
+    if ( transitions.size ( ) == 0 )
+        return rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > ( rte::FormalRTEEmpty< ext::variant< SymbolType, StateType > > ( ) );
+    if ( transitions.size ( ) == 1 )
+        return transitions.at ( 0 ).first.first;
+
+    static auto alt = [] ( const rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >& sum, const ext::pair< ext::pair< rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >, ext::vector< StateType > >, StateType >& transition ) {
+        return rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > ( rte::FormalRTEAlternation< ext::variant< SymbolType, StateType > > ( sum.getStructure ( ), transition.first.first.getStructure ( ) ) );
+    };
+
+    return std::accumulate ( transitions.begin ( ), transitions.end ( ), rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > ( ), alt );
+}
+
+template < class SymbolType, class StateType >
+automaton::ExtendedNFTA< SymbolType, StateType > ToRTEStateElimination::eliminateState ( const automaton::ExtendedNFTA< SymbolType, StateType >& automaton, const StateType& q ) {
+    // create state symbol in RTE's K alphabet
+    const rte::FormalRTESymbolSubst< ext::variant< SymbolType, StateType > > stateSymbol ( common::ranked_symbol< ext::variant< SymbolType, StateType > > ( q, 0 ) );
+
+    // create new automaton, without state Q
+    automaton::ExtendedNFTA< SymbolType, StateType > newAutomaton ( automaton.getStates ( ), automaton.getInputAlphabet ( ), automaton.getFinalStates ( ) );
+    newAutomaton.removeState ( q ); // preserve all states but q (the one to eliminate)
+
+    // divide transitions into the following groups:
+    // - loop(Q)          - Q is     in sources AND Q is     a target
+    // - incoming(Q)      - Q is NOT in sources AND Q is     a target
+    // - outgoing(Q)      - Q is     in sources AND Q is NOT a target
+    // - not_take_part(Q) - Q is NOT in sources AND Q is NOT a target
+    //
+    // also identify prev(incoming(Q)), loop(incoming(Q))
+    ext::vector< ext::pair< ext::pair< rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >, ext::vector< StateType > >, StateType > > loop, incoming, outgoing;
+    ext::set< StateType > prev_loop, prev_incoming;
+
+    for ( const auto& transition : automaton.getTransitions ( ) ) {
+        for ( const StateType& target : transition.second ) {
+            const ext::vector< StateType >& src_states = transition.first.second;
+
+            const bool is_source = std::find ( src_states.begin ( ), src_states.end ( ), q ) != src_states.end ( );
+            const bool is_target = target == q;
+
+            if ( is_source && is_target ) { // loop
+                loop.push_back ( ext::make_pair ( transition.first, target ) );
+                prev_loop.insert ( transition.first.second.begin ( ), transition.first.second.end ( ) );
+            } else if ( ! is_source && is_target ) { // incoming
+                incoming.push_back ( ext::make_pair ( transition.first, target ) );
+                prev_incoming.insert ( transition.first.second.begin ( ), transition.first.second.end ( ) );
+            } else if ( is_source && ! is_target ) { //outgoing
+                outgoing.push_back ( ext::make_pair ( transition.first, target ) );
+            } else /* ( ! is_source && ! is_target ) */ { // not_take_part
+                newAutomaton.addTransition ( transition.first.first, transition.first.second, target );
+            }
+        }
+    }
+
+    const rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > rte_loop = createAlternation ( loop ),
+                                                                           rte_incoming = createAlternation ( incoming );
+
+    // eliminate all incoming and outgoing transitions as follows:
+    // for every outgoing transition:
+    //  - do the SUBST(outgoing, SUBST(iter(loops), incoming)) operation
+    for ( const auto& transition : outgoing ) {
+        const rte::FormalRTEStructure< ext::variant< SymbolType, StateType > >& tr_rte = transition.first.first;
+        const ext::vector< StateType >& tr_src_states = transition.first.second;
+        const StateType& tr_target = transition.second;
+
+        // by eliminating Q, the new transition T will be in the from ( merge(prev_loop, prev_incoming, prev_outgoing) ) -> outgoing.target
+        // The order of prev_states is not important as the order is present in the RTE structure since the first conversion to ExtendedNFTA
+        ext::set< StateType > prevStates;
+        prevStates.insert ( prev_loop.begin ( ), prev_loop.end ( ) );
+        prevStates.insert ( prev_incoming.begin ( ), prev_incoming.end ( ) );
+        prevStates.insert ( tr_src_states.begin ( ), tr_src_states.end ( ) );
+        prevStates.erase ( q );
+
+        rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > rte (
+            rte::FormalRTESubstitution< ext::variant< SymbolType, StateType > > (
+                tr_rte.getStructure ( ), // outgoing rte
+                rte::FormalRTESubstitution< ext::variant< SymbolType, StateType > > (
+                    rte::FormalRTEIteration< ext::variant< SymbolType, StateType > > ( rte_loop.getStructure ( ), stateSymbol ),
+                    rte_incoming.getStructure ( ), stateSymbol ),
+                stateSymbol ) );
+
+        // TATA pattern
+        /*
+		rte::FormalRTEStructure < ext::variant < SymbolType, StateType > > rte (
+				rte::FormalRTESubstitution < ext::variant < SymbolType, StateType > > (
+					rte::FormalRTESubstitution < ext::variant < SymbolType, StateType > > (
+						tr_rte.getStructure ( ), // outgoing rte
+						rte::FormalRTEIteration < ext::variant < SymbolType, StateType > > ( rte_loop.getStructure ( ), stateSymbol ),
+						stateSymbol ),
+					rte_incoming.getStructure ( ),
+					stateSymbol ) );
+		*/
+
+        newAutomaton.addTransition ( rte::simplify::RTEOptimize::optimize ( rte ), ext::vector< StateType > ( prevStates.begin ( ), prevStates.end ( ) ), tr_target );
+    }
+
+    return newAutomaton;
+}
+
+template < class SymbolType, class StateType >
+void ToRTEStateElimination::extendExtendedNFTA ( automaton::ExtendedNFTA< SymbolType, StateType >& automaton ) {
+    // create new state with final label
+    const StateType f = common::createUnique ( label::FinalStateLabel::instance< StateType > ( ), automaton.getStates ( ) );
+    automaton.addState ( f );
+
+    // create transitions from all final states to the new state, the transition contains only reference (RTE's K symbol) to the previous final state
+    for ( const StateType& state : automaton.getFinalStates ( ) ) {
+        const rte::FormalRTEStructure< ext::variant< SymbolType, StateType > > expr ( rte::FormalRTESymbolSubst< ext::variant< SymbolType, StateType > > ( common::ranked_symbol< ext::variant< SymbolType, StateType > > ( state, 0 ) ) );
+        automaton.addTransition ( expr, { state }, f );
+    }
+
+    // new state is the only final
+    automaton.setFinalStates ( { f } );
+}
+
+} /* namespace convert */
+
+} /* namespace automaton */
+
+#endif /* TO_RTE_STATE_ELIMINATION_H_ */
diff --git a/alib2integrationtest/test-src/tests/conversionsTest2.cpp b/alib2integrationtest/test-src/tests/conversionsTest2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b5aac5b356bf959733d586601851deca0e8e461a
--- /dev/null
+++ b/alib2integrationtest/test-src/tests/conversionsTest2.cpp
@@ -0,0 +1,66 @@
+#include <alib/vector>
+#include <catch2/catch.hpp>
+
+#include "testing/TestFiles.hpp"
+#include "testing/TimeoutAqlTest.hpp"
+
+const unsigned RAND_STATES = 15;
+const unsigned RAND_ALPHABET = 5;
+const unsigned RAND_RANK = 4;
+const double RAND_DENSITY = 5;
+const size_t ITERATIONS = 50;
+
+const std::string qGenNFTA ( ) {
+    std::ostringstream oss;
+    oss << "execute automaton::generate::RandomTreeAutomatonFactory ";
+    oss << "(size_t)" << rand ( ) % RAND_STATES + 1 << " ";
+    oss << "(size_t)" << rand ( ) % RAND_ALPHABET + 1 << " ";
+    oss << "(size_t)" << rand ( ) % RAND_RANK << " ";
+    oss << "(bool)true ";
+    oss << "(double)\"" << RAND_DENSITY << "\"";
+    return oss.str ( );
+}
+
+TEST_CASE ( "FTA-RTE conversions test", "[integration]" ) {
+    static const std::string qMinimize ( "automaton::determinize::Determinize - | automaton::simplify::Trim - | automaton::simplify::Minimize - | automaton::simplify::Normalize -" );
+
+    SECTION ( "RTE Files test" ) {
+        for ( const std::string& inputFile : TestFiles::Get ( "/rte/rte*.xml$" ) ) {
+            ext::vector< std::string > qs = {
+                "execute < " + inputFile + " | rte::convert::ToFTAGlushkov - > $gen",
+                "quit compare::AutomatonCompare <( $gen | " + qMinimize + " )" + " <( $gen | automaton::convert::ToRTEStateElimination - | rte::convert::ToFTAGlushkov - | " + qMinimize + ")" };
+
+            TimeoutAqlTest ( 10s, qs );
+        }
+    }
+
+    SECTION ( "RTE Random tests" ) {
+        for ( size_t i = 0; i < ITERATIONS; i++ ) {
+            ext::vector< std::string > qs = {
+                qGenNFTA ( ) + " > $gen",
+                "quit compare::AutomatonCompare <( $gen | " + qMinimize + " )" + " <( $gen | automaton::convert::ToRTEStateElimination - | rte::convert::ToFTAGlushkov - | " + qMinimize + ")" };
+
+            TimeoutAqlTest ( 10s, qs );
+        }
+    }
+
+    // ------------------------------------------------------------------------------------------------------
+
+    SECTION ( "DFTA Files test" ) {
+        auto files = GENERATE (
+            TestFiles::Get ( "/automaton/DFTA.*.xml$" ),
+            TestFiles::Get ( "/automaton/NFTA.*.xml$" ) );
+
+        for ( const std::string& file : files ) {
+            ext::vector< std::string > qs = {
+                "execute < " + file + " > $fta1",
+                "execute $fta1 | automaton::convert::ToRTEStateElimination - | rte::convert::ToFTAGlushkov - > $fta2",
+                "execute $fta1 | " + qMinimize + " > $m1",
+                "execute $fta2 | " + qMinimize + " > $m2",
+                "quit compare::AutomatonCompare $m1 $m2",
+            };
+
+            TimeoutAqlTest ( 10s, qs );
+        }
+    }
+}