public void finalizeCellProcessing(){
        // Unary Role Traverse.
        for (String state : parser.grammar.getStates()) {
            if (!cell.CKYTable.hasState(state, cell.i, cell.j)) continue;

            // state is the state that current span could be
            ScoreState previouScoreState = cell.CKYTable
                    .safeGetScoreStateForWriting(state, cell.i, cell.j);
            // try to transform to next state
            for (UnaryRule rule : parser.unaryClosure
                    .getClosedUnaryRulesByChild(state)) {
                String parentTag = rule.getParent();
                double updateScore = rule.getScore()// transition prob
                        * previouScoreState.getScore();// previous prob

                // update CKYTable state when needed to
                ScoreState currentState = cell.CKYTable.safeGetScoreStateForWriting(parentTag, cell.i, cell.j);
                synchronized (currentState) {

                    if (currentState.getScore() < updateScore) {
                        currentState.state = parentTag;
                        currentState.score = updateScore;
                        currentState.children = Arrays
                                .asList(previouScoreState);
                    }
                }
            }
        }

//        System.out.println("[ThreadPoolIntraCellParser.mergeInCellResult] Cell "
//        + cell.i + "," + cell.j + " is processed");
        Cell aboveCell = cell.getAbove();
        if (aboveCell != null) decreaseCellDependencyOrSpawn(aboveCell);

        // Update right
        Cell rightCell = cell.getRight();
        if (rightCell != null) decreaseCellDependencyOrSpawn(rightCell);

        // For barrier notification in ThreadPool
        if (cell.i == 0 && cell.j == cell.CKYTable.sentenceLength) {
            try {
                System.out.println("end!!");
                parser.barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }