diff --git a/adeterminize.rhdpda2/makefile b/adeterminize.rhdpda2/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..043ec4d1e675caf5c49150e529e130c7f7f3191e
--- /dev/null
+++ b/adeterminize.rhdpda2/makefile
@@ -0,0 +1,20 @@
+CC=g++
+EXECUTIBLE=adeterminize.rhdpda2
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -I../adeterminize/src
+LDFLAGS= -L../alib/lib -L../adeterminize/lib -lxml2 -lalib -ladeterminize -Wl,-rpath,.
+
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
+
+all: $(SOURCES) bin/$(EXECUTIBLE)
+
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(OBJECTS) -o $@ $(LDFLAGS)
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
+
+clean:
+	$(RM) -r *.o *.d bin obj
diff --git a/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..076da5ccc459c23b4b4f3cfa5a1d9e129c228b7d
--- /dev/null
+++ b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp
@@ -0,0 +1,226 @@
+#include "RHDPDADeterminizer2.h"
+
+namespace determinization {
+
+
+void RHDPDADeterminizer2::divideTransitions(const set<TransitionPDA>& transitions, set<TransitionPDA>& internalTransitions,
+        set<TransitionPDA>& pushTransitions, set<TransitionPDA>& popTransitions) {
+    for (set<TransitionPDA>::iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+        if (transition->getPush().size() == 1) {
+            pushTransitions.insert(*transition);
+        } else if (transition->getPop().size() == 1) {
+            popTransitions.insert(*transition);
+        } else {
+            internalTransitions.insert(*transition);
+        }
+    }
+}
+
+
+PDA RHDPDADeterminizer2::determinize(PDA& rhdpda) {
+    PDA rdpda;
+    map<string, StateData> states;
+    const set<TransitionPDA>& transitions = rhdpda.getTransitions();
+    set<TransitionPDA> internalTransitions;
+    set<TransitionPDA> pushTransitions;
+    set<TransitionPDA> popTransitions;
+    set<StateSymbolPair> allStateSymbolPairs = RHDPDADeterminizationUtils::buildAllStateSymbolPairs(rhdpda);
+    vector<SComponent> allScomponents = RHDPDADeterminizationUtils::generateAllPossibleSComponents(allStateSymbolPairs);
+    vector<RComponent> allRcomponents = RHDPDADeterminizationUtils::generateAllPossibleRComponents(allStateSymbolPairs);
+    const set<Symbol>& inputAlphabet = rhdpda.getInputAlphabet();
+    
+    DeterminizationUtils::copyInputAlphabet(rhdpda, rdpda);
+    divideTransitions(transitions, internalTransitions, pushTransitions, popTransitions);
+    
+    set<StateSymbolPair> initialSPairs = RHDPDADeterminizationUtils::combineStatesWithSymbol(rhdpda.getStates(),
+            RHDPDADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL);
+    set<StateSymbolPair> initialRPairs = RHDPDADeterminizationUtils::combineStatesWithSymbol(rhdpda.getInitialStates(),
+            RHDPDADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL);
+    const SComponent& initialS = RHDPDADeterminizationUtils::getSComponentWithPairsIdentity(initialSPairs);
+    const RComponent& initialR(initialRPairs);
+    const State& initialState = RHDPDADeterminizationUtils::getOrCreateState(initialS, initialR, states, rdpda);
+    rdpda.addInitialState(initialState);
+
+    while (true) {
+        StateData* unmarkedStateData = RHDPDADeterminizationUtils::getUnmarkedState(states);
+        if (unmarkedStateData == NULL) {
+            break;
+        }
+        
+        // Internal
+        for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) {
+            SComponent sPrimed;
+            SComponent& s = unmarkedStateData->s;
+            for (set<PairOfPairs>::iterator pairOfPairs = s.pairsOfPairs.begin();
+                    pairOfPairs != s.pairsOfPairs.end();
+                    pairOfPairs++) {
+                const StateSymbolPair& x = pairOfPairs->pair1;
+                const State& r = pairOfPairs->pair2.state;
+                const Symbol& Y = pairOfPairs->pair2.symbol;
+                for (set<TransitionPDA>::iterator transition = internalTransitions.begin();
+                        transition != internalTransitions.end();
+                        transition++) {
+                    if (transition->getFrom() == r && transition->getInput() == *a) {
+                        const State& q = transition->getTo();
+                        sPrimed.pairsOfPairs.insert(PairOfPairs(x, StateSymbolPair(q, Y)));
+                    }
+                }
+            }
+            RComponent rPrimed;
+            RComponent& r = unmarkedStateData->r;
+            for (set<StateSymbolPair>::iterator pair = r.pairs.begin(); pair != r.pairs.end(); pair++) {
+                const State& p = pair->state;
+                const Symbol& Y = pair->symbol;
+                for (set<TransitionPDA>::iterator transition = internalTransitions.begin();
+                        transition != internalTransitions.end();
+                        transition++) {
+                    if (transition->getFrom() == p && transition->getInput() == *a) {
+                        const State& q = transition->getTo();
+                        rPrimed.pairs.insert(StateSymbolPair(q, Y));
+                    }
+                }
+            }
+            if (sPrimed.pairsOfPairs.size() > 0 && rPrimed.pairs.size() > 0) {
+                const State& fromState = unmarkedStateData->state;
+                const State& toState = RHDPDADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, rdpda);
+                const TransitionPDA transition(fromState, *a, toState);
+                rdpda.addTransition(transition);
+            }
+        }
+        
+        // Push
+        for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) {
+            SComponent sDoublePrimed = RHDPDADeterminizationUtils::getSComponentWithPairsIdentity(allStateSymbolPairs);
+            SComponent& s = unmarkedStateData->s;
+            RComponent rDoublePrimed;
+            RComponent& r = unmarkedStateData->r;
+            for (set<StateSymbolPair>::iterator pair = r.pairs.begin(); pair != r.pairs.end(); pair++) {
+                const State& p = pair->state;
+                for (set<TransitionPDA>::iterator transition = pushTransitions.begin();
+                        transition != pushTransitions.end();
+                        transition++) {
+                    if (transition->getFrom() == p && transition->getInput() == *a) {
+                        const State& q = transition->getTo();
+                        const Symbol& Z = transition->getPush().front();
+                        rDoublePrimed.pairs.insert(StateSymbolPair(q, Z));
+                    }
+                }
+            }
+            if (rDoublePrimed.pairs.size() > 0) {
+                const State& fromState = unmarkedStateData->state;
+                const State& toState =
+                        RHDPDADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, states, rdpda);
+                string stackSymbolName = RHDPDADeterminizationUtils::buildStackSymbolName(s, r, *a, rdpda);
+                list<Symbol> pop;
+                list<Symbol> push(1, Symbol(stackSymbolName));
+                const TransitionPDA transition(fromState, *a, toState, pop, push);
+                rdpda.addTransition(transition);
+            }
+        }
+
+        // Pop
+        for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) {
+            for (set<Symbol>::iterator b = inputAlphabet.begin(); b != inputAlphabet.end(); b++) {
+                SComponent& s = unmarkedStateData->s;
+
+                set<PairOfPairs> update;
+                for (set<PairOfPairs>::iterator pairOfPairs = s.pairsOfPairs.begin();
+                        pairOfPairs != s.pairsOfPairs.end();
+                        pairOfPairs++) {
+                    const State& r = pairOfPairs->pair1.state;
+                    const Symbol& Z = pairOfPairs->pair1.symbol;
+                    const State& rPrimed = pairOfPairs->pair2.state;
+                    if (pairOfPairs->pair2.symbol == Z) {
+                        for (set<TransitionPDA>::iterator pushTransition = pushTransitions.begin();
+                                pushTransition != pushTransitions.end();
+                                pushTransition++) {
+                            for (set<TransitionPDA>::iterator popTransition = popTransitions.begin();
+                                    popTransition != popTransitions.end();
+                                    popTransition++) {
+                                const State& p = pushTransition->getFrom();
+                                const State& q = popTransition->getTo();
+                                if (pushTransition->getInput() == *a && pushTransition->getTo() == r &&
+                                        popTransition->getInput() == *b && popTransition->getFrom() == rPrimed &&
+                                        pushTransition->getPush().front() == Z && popTransition->getPop().front() == Z) {
+                                    StateSymbolPair pair1(p, Z);
+                                    StateSymbolPair pair2(q, Z);
+                                    update.insert(PairOfPairs(pair1, pair2));
+                                }
+                            }
+                        }
+                    }
+                }
+                if (update.size() == 0) {
+                    continue;
+                }
+
+                for (vector<SComponent>::iterator sPrimed = allScomponents.begin();
+                        sPrimed != allScomponents.end();
+                        sPrimed++) {
+                    for (vector<RComponent>::iterator rPrimed = allRcomponents.begin();
+                            rPrimed != allRcomponents.end();
+                            rPrimed++) {
+                        RComponent rDoublePrimed;
+                        for (set<PairOfPairs>::iterator updateItem = update.begin();
+                                updateItem != update.end();
+                                updateItem++) {
+                            const StateSymbolPair& y = updateItem->pair1;
+                            const StateSymbolPair& x = updateItem->pair2;
+                            if (rPrimed->pairs.find(y) != rPrimed->pairs.end()) {
+                                rDoublePrimed.pairs.insert(x);
+                            }
+                        }
+                        SComponent sDoublePrimed;
+                        for (set<PairOfPairs>::iterator updateItem = update.begin();
+                                updateItem != update.end();
+                                updateItem++) {
+                            const StateSymbolPair& z = updateItem->pair1;
+                            const StateSymbolPair& y = updateItem->pair2;
+                            for (set<PairOfPairs>::iterator sPrimedPair = sPrimed->pairsOfPairs.begin();
+                                    sPrimedPair != sPrimed->pairsOfPairs.end();
+                                    sPrimedPair++) {
+                                if (sPrimedPair->pair2 == z) {
+                                    const StateSymbolPair& x = sPrimedPair->pair1;
+                                    sDoublePrimed.pairsOfPairs.insert(PairOfPairs(x, y));
+                                }
+                            }
+                        }
+                        if (sDoublePrimed.pairsOfPairs.size() > 0 && rDoublePrimed.pairs.size() > 0) {
+                            const State& fromState = unmarkedStateData->state;
+                            const State& toState =
+                                    RHDPDADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, states, rdpda);
+                            string stackSymbolName =
+                                    RHDPDADeterminizationUtils::buildStackSymbolName(*sPrimed, *rPrimed, *a, rdpda);
+                            list<Symbol> pop(1, Symbol(stackSymbolName));
+                            list<Symbol> push;
+                            const TransitionPDA transition(fromState, *b, toState, pop, push);
+                            rdpda.addTransition(transition);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    const set<State>& rhdpdaFinalState = rhdpda.getFinalStates();
+    for (map<string, StateData>::iterator state = states.begin();
+            state != states.end();
+            state++) {
+        bool isFinalState = false;
+        RComponent& r = state->second.r;
+        for (set<StateSymbolPair>::iterator pair = r.pairs.begin();
+                pair != r.pairs.end();
+                pair++) {
+            if (rhdpdaFinalState.find(pair->state) != rhdpdaFinalState.end()) {
+                isFinalState = true;
+            }
+        }
+        if (isFinalState) {
+            rdpda.addFinalState(state->second.state);
+        }
+    }
+
+    return rdpda;
+}
+
+} /* namespace determinization */
diff --git a/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h
new file mode 100644
index 0000000000000000000000000000000000000000..05afe45dbe19a0327ac3ac3351984ecbc74a3dec
--- /dev/null
+++ b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h
@@ -0,0 +1,33 @@
+#ifndef RHDPDADETERMINZER2_H_
+#define RHDPDADETERMINZER2_H_
+
+#include <string>
+#include <set>
+#include <map>
+#include <vector>
+
+#include "automaton/PDA/PDA.h"
+#include "automaton/Transition.h"
+#include "automaton/exception/AutomatonException.h"
+#include "alphabet/Symbol.h"
+#include "DeterminizationUtils.h"
+#include "RHDPDADeterminizationUtils.h"
+#include "RHDPDADeterminizationStructs.h"
+
+using namespace std;
+using namespace automaton;
+using namespace alphabet;
+
+namespace determinization {
+
+class RHDPDADeterminizer2 {
+protected:
+    static void divideTransitions(const set<TransitionPDA>& transitions, set<TransitionPDA>& internalTransitions,
+        set<TransitionPDA>& pushTransitions, set<TransitionPDA>& popTransitions);
+
+public:
+    static PDA determinize(PDA& automaton);
+};
+
+} /* namespace determinization */
+#endif /* RHDPDADETERMINZER2_H_ */
\ No newline at end of file
diff --git a/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp b/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..700b2bad75c94d8f4bbd89f6d2d4a3853583821d
--- /dev/null
+++ b/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <set>
+
+#include "automaton/UnknownAutomaton.h"
+#include "AutomatonFactory.h"
+#include "AlibException.h"
+#include "RHDPDADeterminizer2.h"
+
+
+using namespace std;
+using namespace automaton;
+using namespace determinization;
+using namespace alib;
+
+
+int main(int argc, char** argv) {
+    UnknownAutomaton automaton;
+    
+    try {
+        string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>()));
+        automaton = AutomatonFactory::fromString(input);
+        
+        Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton);
+        // TODO check that automaton is RHDPDA
+        PDA deterministicPDA = RHDPDADeterminizer2::determinize(*((PDA*) knownAutomaton));
+        deterministicPDA.toXML(cout);
+        
+        delete knownAutomaton;
+        
+    } catch (AlibException& e) {
+        cout << e.what() << endl;
+        return 0;
+    }
+}
diff --git a/examples/RHDPDA3.xml b/examples/RHDPDA3.xml
new file mode 100644
index 0000000000000000000000000000000000000000..772fa5879085e209e8251b2968d3e9a173e815f5
--- /dev/null
+++ b/examples/RHDPDA3.xml
@@ -0,0 +1,114 @@
+<automaton>
+  <states>
+    <state>0</state>
+    <state>1</state>
+    <state>2</state>
+    <state>3</state>
+    <state>ERR</state>
+  </states>
+  <inputAlphabet>
+    <symbol>a</symbol>
+    <symbol>b</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>a</symbol>
+    <symbol>x</symbol>
+    <symbol>_</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>0</from>
+      <input>a</input>
+      <to>1</to>
+      <pop></pop>
+      <push>
+        <symbol>x</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>0</from>
+      <input>b</input>
+      <to>3</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>1</from>
+      <input>a</input>
+      <to>1</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>1</from>
+      <input>b</input>
+      <to>2</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>2</from>
+      <input>a</input>
+      <to>2</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>2</from>
+      <input>a</input>
+      <to>3</to>
+      <pop>
+        <symbol>x</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>2</from>
+      <input>b</input>
+      <to>ERR</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>3</from>
+      <input>a</input>
+      <to>ERR</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>3</from>
+      <input>b</input>
+      <to>ERR</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>ERR</from>
+      <input>a</input>
+      <to>ERR</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>ERR</from>
+      <input>b</input>
+      <to>ERR</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>0</state>
+  </initialStates>
+  <startSymbols>
+    <symbol>_</symbol>
+  </startSymbols>
+  <finalStates>
+    <state>3</state>
+  </finalStates>
+</automaton>
diff --git a/examples/RHDPDA5.xml b/examples/RHDPDA5.xml
new file mode 100644
index 0000000000000000000000000000000000000000..91a822d4ee09a5a21ca9ae1d6eb799a0b99d2b04
--- /dev/null
+++ b/examples/RHDPDA5.xml
@@ -0,0 +1,42 @@
+<automaton>
+  <states>
+    <state>0</state>
+    <state>1</state>
+  </states>
+  <inputAlphabet>
+    <symbol>a</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>a</symbol>
+    <symbol>_</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>0</from>
+      <input>a</input>
+      <to>1</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>1</from>
+      <input>a</input>
+      <to>0</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>0</state>
+  </initialStates>
+  <startSymbols>
+    <symbol>_</symbol>
+  </startSymbols>
+  <finalStates>
+    <state>0</state>
+  </finalStates>
+</automaton>
diff --git a/makefile b/makefile
index 3958ffa67c0195d0ced76f40241dc8a4ec161665..44ef8fbcef539a11dfc0d6664274efb6bd7b763d 100644
--- a/makefile
+++ b/makefile
@@ -6,7 +6,7 @@ SUBDIRS_LIBS = alib adeterminize
 SUBDIRS_BINS = acat \
                aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar \
                aminimize \
-               adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adeterminize.rhdpda \
+               adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adeterminize.rhdpda adeterminize.rhdpda2 \
                adiff adiff.automaton adiff.grammar \
                aepsilon \
                atrim \