def __init__(self, embs, data, stage, model_dir = None):
        if model_dir is not None:
            self._classify = Classify(model_dir)
            self._labels = [item.strip() for item in open(model_dir + "/relations.txt").read().splitlines()]
        else:
            self._labels = None

        if stage == "ORACLETEST":
            assert(len(data) == 4)
            hooks = False
            tokens, dependencies, relations, alignments = data
            lemmas = None
            relations2 = []
            self.gold = relations
            for r in relations:
                if r[1].startswith(":snt"):
                    r2 = (Node(True),":top",r[2])
                else:
                    r2 = (r[0],r[1],r[2])
                if (r2[0].token is not None or r2[1] == ":top") and r2[2].token is not None:
                    relations2.append(r2)
            oracle = Oracle(relations2)
            self.variables = Variables()
    
        elif stage == "TRAIN" or stage == "COLLECT":
            assert(len(data) == 4)
            hooks = False
            tokens, dependencies, relations, alignments = data
            lemmas = None
            relations2 = []
            for r in relations:
                if r[1].startswith(":snt"):
                    r2 = (Node(True),":top",r[2])
                else:
                    r2 = (r[0],r[1],r[2])
                if (r2[0].token is not None or r2[1] == ":top") and r2[2].token is not None:
                    relations2.append(r2)
            oracle = Oracle(relations2)
            self.variables = None

        else: #PARSING
            assert(len(data) == 2)
            hooks = True
            tokens, dependencies = data
            relations2 = None
            alignments = None
            oracle = None
            self.variables = Variables()
        self.state = State(embs, relations2, tokens, dependencies, alignments, oracle, hooks, self.variables, stage, Rules(self._labels))
        self.history = History()
        while self.state.isTerminal() == False:
            #print self.state
            tok = copy.deepcopy(self.state.buffer.peek())
            if oracle is not None:
                action = oracle.valid_actions(self.state)
            else:
                action = self.classifier()
            #print action
            #raw_input()
            if action is not None:
                f_rel = []
                f_lab = []
                f_reentr = []
                if stage == "TRAIN":
                    f_rel = self.state.rel_features()
                    if action.name== "larc" or action.name == "rarc":
                        f_lab = self.state.lab_features()
                    if action.name == "reduce":
                        f_reentr = self.state.reentr_features()

                self.state.apply(action)
                self.history.add((f_rel, f_lab, f_reentr), action, tok)
            else:
                break
        assert (self.state.stack.isEmpty() == True and self.state.buffer.isEmpty() == True)