public static Stella_Object buildDecisionTree(List examples, List features, Cons featureStack) {
    { int p = 0;
      int n = 0;
      double currentEntropy = 0.0;
      double newEntropy = 0.0;
      DecisionTree tree = DecisionTree.newDecisionTree();
      double minNewEntropy = 1.0;
      int featureIndex = 0;
      Symbol splitFeature = null;

      { TrainingExample example = null;
        Cons iter000 = examples.theConsList;

        for (;!(iter000 == Stella.NIL); iter000 = iter000.rest) {
          example = ((TrainingExample)(iter000.value));
          if (BooleanWrapper.coerceWrappedBooleanToBoolean(((BooleanWrapper)(example.output)))) {
            p = p + 1;
          }
          else {
            n = n + 1;
          }
        }
      }
      if (p > n) {
        tree.truthValue = true;
      }
      else {
        tree.truthValue = false;
      }
      if ((p == 0) ||
          (n == 0)) {
        return (tree);
      }
      currentEntropy = Logic.entropy(p, n);
      { Symbol feature = null;
        Cons iter001 = features.theConsList;
        int i = Stella.NULL_INTEGER;
        int iter002 = 0;

        for (;!(iter001 == Stella.NIL); iter001 = iter001.rest, iter002 = iter002 + 1) {
          feature = ((Symbol)(iter001.value));
          i = iter002;
          if (!featureStack.memberP(feature)) {
            newEntropy = Logic.expectedEntropy(i, examples);
            if (newEntropy < minNewEntropy) {
              if (Logic.$TRACE_ID3$) {
                System.out.println("Info gain for feature " + feature + ": " + (currentEntropy - newEntropy));
              }
              minNewEntropy = newEntropy;
              featureIndex = i;
              splitFeature = feature;
            }
          }
        }
      }
      if (Logic.$TRACE_ID3$) {
        System.out.println("Splitting on feature " + splitFeature);
      }
      if (splitFeature == null) {
        return (tree);
      }
      { List leftExamples = List.newList();
        List rightExamples = List.newList();

        { TrainingExample example = null;
          Cons iter003 = examples.theConsList;

          for (;!(iter003 == Stella.NIL); iter003 = iter003.rest) {
            example = ((TrainingExample)(iter003.value));
            if (Stella_Object.eqlP((example.input.theArray)[featureIndex], Stella.ONE_WRAPPER)) {
              leftExamples.push(example);
            }
            else {
              rightExamples.push(example);
            }
          }
        }
        tree.feature = splitFeature;
        tree.featureIndex = featureIndex;
        tree.trueBranch = ((DecisionTree)(Logic.buildDecisionTree(leftExamples, features, Cons.cons(splitFeature, featureStack))));
        tree.falseBranch = ((DecisionTree)(Logic.buildDecisionTree(rightExamples, features, Cons.cons(splitFeature, featureStack))));
      }
      return (tree);
    }
  }