diff --git a/alib2algo/src/automaton/simplify/Rename.h b/alib2algo/src/automaton/simplify/Rename.h
index 195ee09c82ccf4a87da078b6625e0fac50ed69d5..17b0edc5a07bf2044315dc5cf1b1710a1b6e7d7b 100644
--- a/alib2algo/src/automaton/simplify/Rename.h
+++ b/alib2algo/src/automaton/simplify/Rename.h
@@ -32,6 +32,7 @@
 
 #include <automaton/FSM/DFA.h>
 #include <automaton/FSM/NFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
 #include <automaton/PDA/DPDA.h>
 #include <automaton/PDA/NPDA.h>
 #include <automaton/PDA/InputDrivenDPDA.h>
@@ -52,32 +53,40 @@ namespace simplify {
  * @sa automaton::simplify::Normalize
  */
 class Rename {
-public:
-	/**
-	 * Rename automaton's states.
-	 *
-	 * @tparam SymbolType Type for input symbols
-	 * @tparam StateType Type for states
-	 *
-	 * @param dfa finite automaton to rename
-	 *
-	 * @return @p dfa with renamed states
-	 */
-	template < class SymbolType, class StateType >
-	static automaton::DFA < SymbolType, unsigned > rename ( const automaton::DFA < SymbolType, StateType > & dfa );
+	template < class T >
+	struct DFATra {
+		using type = automaton::DFA < typename T::SymbolType, unsigned >;
+	};
+
+	template < class T >
+	struct NFATra {
+		using type = automaton::NFA < typename T::SymbolType, unsigned >;
+	};
+
+	template < class T >
+	struct EpsilonNFATra {
+		using type = automaton::EpsilonNFA < typename T::SymbolType, typename T::EpsilonType, unsigned >;
+	};
+
+	template < class T >
+	using RenamedAutomaton = typename ext::casional <
+			ext::boolean < isDFA < T > >, DFATra < T >,
+			ext::boolean < isNFA < T > >, NFATra < T >,
+			ext::boolean < isEpsilonNFA < T > >, EpsilonNFATra < T >
+		>::type::type;
 
+public:
 	/**
 	 * Rename automaton's states.
 	 *
-	 * @tparam SymbolType Type for input symbols
-	 * @tparam StateType Type for states
+	 * @tparam T Type of automaton to rename
 	 *
 	 * @param nfa finite automaton to rename
 	 *
 	 * @return @p dfa with renamed states
 	 */
-	template < class SymbolType, class StateType >
-	static automaton::NFA < SymbolType, unsigned > rename ( const automaton::NFA < SymbolType, StateType > & nfa );
+	template < class T >
+	static ext::require < isDFA < T > || isNFA < T >, Rename::RenamedAutomaton < T > > rename ( const T & fsm );
 
 	/**
 	 * @overload
@@ -174,39 +183,17 @@ public:
 	static automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, unsigned, unsigned > rename ( const automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & pda );
 };
 
-template < class SymbolType, class StateType >
-automaton::DFA < SymbolType, unsigned > Rename::rename ( const automaton::DFA < SymbolType, StateType > & fsm ) {
-	unsigned counter = 0;
-	ext::map < StateType, unsigned > renamingData;
-
-	for ( const StateType & state : fsm.getStates ( ) )
-		renamingData.insert ( std::make_pair ( state, counter++ ) );
-
-	automaton::DFA < SymbolType, unsigned > result ( renamingData.at ( fsm.getInitialState ( ) ) );
-
-	result.setInputAlphabet ( fsm.getInputAlphabet ( ) );
-
-	for ( const StateType & state : fsm.getStates ( ) )
-		result.addState ( renamingData.at ( state ) );
-
-	for ( const StateType & state : fsm.getFinalStates ( ) )
-		result.addFinalState ( renamingData.at ( state ) );
-
-	for ( const auto & transition : fsm.getTransitions ( ) )
-		result.addTransition ( renamingData.at ( transition.first.first ), transition.first.second, renamingData.at ( transition.second ) );
-
-	return result;
-}
+template < class T >
+ext::require < isDFA < T > || isNFA < T >, Rename::RenamedAutomaton < T > > Rename::rename ( const T & fsm ) {
+	using StateType = automaton::StateTypeOfAutomaton < T >;
 
-template < class SymbolType, class StateType >
-automaton::NFA < SymbolType, unsigned > Rename::rename ( const automaton::NFA < SymbolType, StateType > & fsm ) {
 	unsigned counter = 0;
 	ext::map < StateType, unsigned > renamingData;
 
 	for ( const StateType & state : fsm.getStates ( ) )
 		renamingData.insert ( std::make_pair ( state, counter++ ) );
 
-	automaton::NFA < SymbolType, unsigned > result ( renamingData.at ( fsm.getInitialState ( ) ) );
+	Rename::RenamedAutomaton < T > result ( renamingData.at ( fsm.getInitialState ( ) ) );
 
 	result.setInputAlphabet ( fsm.getInputAlphabet ( ) );
 
diff --git a/alib2std/src/extensions/type_traits.hpp b/alib2std/src/extensions/type_traits.hpp
index a36d973597f50a6e3e97dcbbf3655f73d397f9aa..63dc1e3dfc1c9e78a5b5519ac3812a9278b7b64f 100644
--- a/alib2std/src/extensions/type_traits.hpp
+++ b/alib2std/src/extensions/type_traits.hpp
@@ -138,6 +138,32 @@ namespace ext {
 	template < bool value, typename type = int >
 	using require = typename std::enable_if < value, type >::type;
 
+// ----------------------------------------------------------------------------------------------------
+
+	template < bool value>
+	using boolean = typename std::conditional < value, std::true_type, std::false_type >::type;
+
+	template < class ... Ts >
+	struct casional;
+
+	template < >
+	struct casional < > {
+		typedef void type;
+	};
+
+	template < class T >
+	struct casional < T > {
+		typedef T type;
+	};
+
+	template < class R, class ... Ts >
+	struct casional < std::true_type, R, Ts ... > : public casional < R > {
+	};
+
+	template < class R, class ... Ts >
+	struct casional < std::false_type, R, Ts ... > : public casional < Ts ... > {
+	};
+
 } /* namespace ext */
 
 #endif /* __TYPE_TRAITS_HPP_ */