private void splitTreeNode(RandForestNode currentNode, Set<Node> curCandidates, boolean isTrueChild) {
        Set<Integer> sampleList = null;
        if (isTrueChild) {
            sampleList = currentNode.sampleSetTrue;
        } else {
            sampleList = currentNode.sampleSetFalse;
        }
//        System.out.println("new sample list size for "+ isTrueChild + "class for node " + currentNode.feature.label + " is "+ sampleList.size());
//        System.out.println(" the smaple list is:");
//        for(int i: sampleList)
//            System.out.println(i);
//        System.out.println("current candidate list size " + curCandidates.size());
//        for(Node n: curCandidates)
//            System.out.println(n.label);
        Node chosenFeature = chooseFeature(sampleList, curCandidates, currentNode.GiniIndex);
        double currentGini = -1;
        //System.out.println("receied a chosen feature " + chosenFeature.label);
        if(chosenFeature!=null){
             currentGini = GiniFeature(chosenFeature, sampleList);
            //System.out.println("feature " + chosenFeature.label + "Gini value: " + currentNode.GiniIndex);
        }

        // get the majority class in the sampleList
        int _noTrue = getNoTrueClass(sampleList);
       /// System.out.println("num of trues " + _noTrue);
        // if all samples are in the same class or no more feature to use, no need to split
        if (_noTrue == 0 || _noTrue == sampleList.size() || chosenFeature == null) {
           // System.out.println("haha");
            RandForestNode newNode = new RandForestNode(null, currentNode, currentGini);
            newNode.trueProb = (double)_noTrue / sampleList.size();
            currentNode.insertChild(newNode, isTrueChild);
            return;
        }
        
        // other wise keep splitting
        Set<Integer> trueSamples = new HashSet<Integer>();
        Set<Integer> falseSamples = new HashSet<Integer>();

        // split the sample list
        splitSampleOnFeature(chosenFeature.id, sampleList, trueSamples, falseSamples);

        RandForestNode newNode = new RandForestNode(chosenFeature, currentNode, currentGini);
        usedFeatures.add(chosenFeature);

        // insert child into current node
        currentNode.insertChild(newNode, isTrueChild);

        // find the new candidate node list
        Set<Node> candidates = newNode.updateCandidateFeatures(curCandidates, usedFeatures, chosenFeature);

        if (!trueSamples.isEmpty()) {
            newNode.sampleSetTrue = trueSamples;
            // continue to split node
            splitTreeNode(newNode, candidates, true);
        }

        if (!falseSamples.isEmpty()) {
            newNode.sampleSetFalse = falseSamples;
            // continue to split node
            splitTreeNode(newNode, candidates, false);
        }
    }