diff --git a/alib2algo/src/automaton/transform/AutomataUnion.cpp b/alib2algo/src/automaton/transform/AutomataUnion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f743b2d8219ec45fd7fc9c3efdf0c1fefc06acc3
--- /dev/null
+++ b/alib2algo/src/automaton/transform/AutomataUnion.cpp
@@ -0,0 +1,41 @@
+/*
+ * AutomataUnion.cpp
+ *
+ *  Created on: 20. 11. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "AutomataUnion.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto AutomataUnionEpsilonNFA = registration::AbstractRegister < automaton::transform::AutomataUnion, automaton::MultiInitialStateEpsilonNFA < DefaultSymbolType, ext::pair < DefaultStateType, unsigned > >, const automaton::EpsilonNFA < > &, const automaton::EpsilonNFA < > & > ( automaton::transform::AutomataUnion::unification, "first", "second" ).setDocumentation (
+"Union of two automata using epsilon transitions.\n\
+\n\
+@param first First automaton (A1)\n\
+@param second Second automaton (A2)\n\
+@return multi initial state nondeterministic epsilon FA representing the union of two automata" );
+
+auto AutomataUnionNFA = registration::AbstractRegister < automaton::transform::AutomataUnion, automaton::MultiInitialStateNFA < DefaultSymbolType, ext::pair < DefaultStateType, unsigned > >, const automaton::NFA < > &, const automaton::NFA < > & > ( automaton::transform::AutomataUnion::unification, "first", "second" ).setDocumentation (
+"Union of two automata using epsilon transitions.\n\
+\n\
+@param first First automaton (A1)\n\
+@param second Second automaton (A2)\n\
+@return multi initial state nondeterministic FA representing the union of two automata" );
+
+auto AutomataUnionDFA = registration::AbstractRegister < automaton::transform::AutomataUnion, automaton::MultiInitialStateNFA < DefaultSymbolType, ext::pair < DefaultStateType, unsigned > >, const automaton::DFA < > &, const automaton::DFA < > & > ( automaton::transform::AutomataUnion::unification, "first", "second" ).setDocumentation (
+"Union of two automata using epsilon transitions.\n\
+\n\
+@param first First automaton (A1)\n\
+@param second Second automaton (A2)\n\
+@return multi initial state nondeterministic FA representing the union of two automata" );
+
+auto AutomataUnionNFTA = registration::AbstractRegister < automaton::transform::AutomataUnion, automaton::NFTA < DefaultSymbolType, ext::pair < DefaultStateType, unsigned > >, const automaton::NFTA < > &, const automaton::NFTA < > & > ( automaton::transform::AutomataUnion::unification, "first", "second" ).setDocumentation (
+"Union of two finite tree automata.\n\
+\n\
+@param first First automaton (A1)\n\
+@param second Second automaton (A2)\n\
+@return nondeterministic FTA representing the union of two automata" );
+
+} /* namespace */
diff --git a/alib2algo/src/automaton/transform/AutomataUnion.h b/alib2algo/src/automaton/transform/AutomataUnion.h
new file mode 100644
index 0000000000000000000000000000000000000000..52140cee819f9f6326ec167cc4453d89fa9e99a3
--- /dev/null
+++ b/alib2algo/src/automaton/transform/AutomataUnion.h
@@ -0,0 +1,226 @@
+/*
+ * AutomataUnion.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: 20. 11. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef AUTOMATA_UNION_H_
+#define AUTOMATA_UNION_H_
+
+#include <automaton/FSM/MultiInitialStateEpsilonNFA.h>
+#include <automaton/TA/NFTA.h>
+
+namespace automaton {
+
+namespace transform {
+
+/**
+ * Union of two finite automata.
+ * For finite automata A1, A2, we create a finite automaton A such that L(A) = L(A1) \cup L(A2).
+ * This method utilizes epsilon transitions in finite automata (Melichar: Jazyky a překlady, 2.73).
+ */
+class AutomataUnion {
+public:
+	/**
+	 * Union of two automata using epsilon transitions.
+	 * @tparam SymbolType Type for input symbols.
+	 * @tparam StateType Type for states.
+	 * @param first First automaton (A1)
+	 * @param second Second automaton (A2)
+	 * @return multi initial state epsilon nondeterministic FA representing the union of two automata
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateEpsilonNFA < SymbolType, ext::pair < StateType, unsigned > > unification(const automaton::EpsilonNFA < SymbolType, StateType > & first, const automaton::EpsilonNFA < SymbolType, StateType > & second);
+
+	/**
+	 * @overload
+	 * @return multi initial state nondeterministic FA representing the union of two automata
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > unification(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second);
+
+	/**
+	 * @overload
+	 * @return multi initial state nondeterministic FA representing the union of two automata
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > unification(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second);
+
+	/**
+	 * Union of two finite tree automata.
+	 * @tparam SymbolType Type for input symbols.
+	 * @tparam StateType Type for states.
+	 * @param first First automaton (A1)
+	 * @param second Second automaton (A2)
+	 * @return NFTA representing the union of two automata
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::NFTA < SymbolType, ext::pair < StateType, unsigned > > unification ( const automaton::NFTA < SymbolType, StateType > & first, const automaton::NFTA < SymbolType, StateType > & second );
+
+};
+
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateEpsilonNFA < SymbolType, ext::pair < StateType, unsigned > > AutomataUnion::unification(const automaton::EpsilonNFA < SymbolType, StateType > & first, const automaton::EpsilonNFA < SymbolType, StateType > & second) {
+	unsigned firstDefault = 1;
+	unsigned secondDefault = 2;
+
+	automaton::MultiInitialStateEpsilonNFA < SymbolType, ext::pair < StateType, unsigned > > res;
+
+	for(const auto& a : first.getInputAlphabet())
+		res.addInputSymbol(a);
+	for(const auto& a : second.getInputAlphabet())
+		res.addInputSymbol(a);
+
+	for ( const auto & q : first.getStates ( ) )
+		res.addState ( ext::make_pair ( q, firstDefault ) );
+	for ( const auto & q : second.getStates ( ) )
+		res.addState ( ext::make_pair ( q, secondDefault ) );
+
+	for(const auto& q : first.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, firstDefault ) );
+	for(const auto& q : second.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, secondDefault ) );
+
+	res.addInitialState ( ext::make_pair ( first.getInitialState ( ), firstDefault ) );
+	res.addInitialState ( ext::make_pair ( second.getInitialState ( ), secondDefault ) );
+
+	for(const auto& t : first.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, firstDefault ), t.first.second, ext::make_pair ( t.second, firstDefault ) );
+
+	for(const auto& t : second.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, secondDefault ), t.first.second, ext::make_pair ( t.second, secondDefault ) );
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > AutomataUnion::unification(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second) {
+	unsigned firstDefault = 1;
+	unsigned secondDefault = 2;
+
+	automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > res;
+
+	for(const auto& a : first.getInputAlphabet())
+		res.addInputSymbol(a);
+	for(const auto& a : second.getInputAlphabet())
+		res.addInputSymbol(a);
+
+	for ( const auto & q : first.getStates ( ) )
+		res.addState ( ext::make_pair ( q, firstDefault ) );
+	for ( const auto & q : second.getStates ( ) )
+		res.addState ( ext::make_pair ( q, secondDefault ) );
+
+	for(const auto& q : first.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, firstDefault ) );
+	for(const auto& q : second.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, secondDefault ) );
+
+	res.addInitialState ( ext::make_pair ( first.getInitialState ( ), firstDefault ) );
+	res.addInitialState ( ext::make_pair ( second.getInitialState ( ), secondDefault ) );
+
+	for(const auto& t : first.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, firstDefault ), t.first.second, ext::make_pair ( t.second, firstDefault ) );
+
+	for(const auto& t : second.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, secondDefault ), t.first.second, ext::make_pair ( t.second, secondDefault ) );
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > AutomataUnion::unification(const automaton::DFA< SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second) {
+	unsigned firstDefault = 1;
+	unsigned secondDefault = 2;
+
+	automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType, unsigned > > res;
+
+	for(const auto& a : first.getInputAlphabet())
+		res.addInputSymbol(a);
+	for(const auto& a : second.getInputAlphabet())
+		res.addInputSymbol(a);
+
+	for ( const auto & q : first.getStates ( ) )
+		res.addState ( ext::make_pair ( q, firstDefault ) );
+	for ( const auto & q : second.getStates ( ) )
+		res.addState ( ext::make_pair ( q, secondDefault ) );
+
+	for(const auto& q : first.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, firstDefault ) );
+	for(const auto& q : second.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, secondDefault ) );
+
+	res.addInitialState ( ext::make_pair ( first.getInitialState ( ), firstDefault ) );
+	res.addInitialState ( ext::make_pair ( second.getInitialState ( ), secondDefault ) );
+
+	for(const auto& t : first.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, firstDefault ), t.first.second, ext::make_pair ( t.second, firstDefault ) );
+
+	for(const auto& t : second.getTransitions())
+		res.addTransition ( ext::make_pair ( t.first.first, secondDefault ), t.first.second, ext::make_pair ( t.second, secondDefault ) );
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+automaton::NFTA < SymbolType, ext::pair < StateType, unsigned > > AutomataUnion::unification ( const automaton::NFTA < SymbolType, StateType > & first, const automaton::NFTA < SymbolType, StateType > & second ) {
+	unsigned firstDefault = 1;
+	unsigned secondDefault = 2;
+
+	automaton::NFTA < SymbolType, ext::pair < StateType, unsigned > > res;
+
+	for(const auto& a : first.getInputAlphabet())
+		res.addInputSymbol(a);
+	for(const auto& a : second.getInputAlphabet())
+		res.addInputSymbol(a);
+
+	for ( const auto & q : first.getStates ( ) )
+		res.addState ( ext::make_pair ( q, firstDefault ) );
+	for ( const auto & q : second.getStates ( ) )
+		res.addState ( ext::make_pair ( q, secondDefault ) );
+
+	for(const auto& q : first.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, firstDefault ) );
+	for(const auto& q : second.getFinalStates())
+		res.addFinalState ( ext::make_pair ( q, secondDefault ) );
+
+	for(const auto& t : first.getTransitions()) {
+		ext::vector < ext::pair < StateType, unsigned > > source;
+		for ( const auto & state : t.first.second ) {
+			source.push_back ( ext::make_pair ( state, firstDefault ) );
+		}
+		res.addTransition ( t.first.first, std::move ( source ), ext::make_pair ( t.second, firstDefault ) );
+	}
+
+	for(const auto& t : second.getTransitions()) {
+		ext::vector < ext::pair < StateType, unsigned > > source;
+		for ( const auto & state : t.first.second ) {
+			source.push_back ( ext::make_pair ( state, firstDefault ) );
+		}
+		res.addTransition ( t.first.first, std::move ( source ), ext::make_pair ( t.second, secondDefault ) );
+	}
+
+	return res;
+}
+
+} /* namespace transform */
+
+} /* namespace automaton */
+
+#endif /* AUTOMATA_UNION_H_ */