Utils.sum(m_ClassProbs))) {
Utils.sum(m_ClassProbs)) || ((getMaxDepth() > 0) && (depth >= getMaxDepth()))) {
  protected void buildTree(int[][] sortedIndices, double[][] weights,			 Instances data, double[] classProbs, 			 Instances header, double minNum, boolean debug,			 int[] attIndicesWindow, Random random)     throws Exception {    // Store structure of dataset, set minimum number of instances    m_Info = header;    m_Debug = debug;    m_MinNum = minNum;    // Make leaf if there are no training instances    if (((data.classIndex() > 0) && (sortedIndices[0].length == 0)) ||	((data.classIndex() == 0) && sortedIndices[1].length == 0)) {      m_Distribution = new double[1][data.numClasses()];      m_ClassProbs = null;      return;    }    // Check if node doesn't contain enough instances or is pure    m_ClassProbs = new double[classProbs.length];    System.arraycopy(classProbs, 0, m_ClassProbs, 0, classProbs.length);    if (Utils.sm(Utils.sum(m_ClassProbs), 2 * m_MinNum) ||	Utils.eq(m_ClassProbs[Utils.maxIndex(m_ClassProbs)],		 Utils.sum(m_ClassProbs))) {      // Make leaf      m_Attribute = -1;      m_Distribution = new double[1][m_ClassProbs.length];      for (int i = 0; i < m_ClassProbs.length; i++) {	m_Distribution[0][i] = m_ClassProbs[i];      }      Utils.normalize(m_ClassProbs);      return;    }    // Compute class distributions and value of splitting    // criterion for each attribute    double[] vals = new double[data.numAttributes()];    double[][][] dists = new double[data.numAttributes()][0][0];    double[][] props = new double[data.numAttributes()][0];    double[] splits = new double[data.numAttributes()];    // Investigate K random attributes    int attIndex = 0;    int windowSize = attIndicesWindow.length;    int k = m_KValue;    boolean gainFound = false;    while ((windowSize > 0) && (k-- > 0 || !gainFound)) {      int chosenIndex = random.nextInt(windowSize);      attIndex = attIndicesWindow[chosenIndex];            // shift chosen attIndex out of window      attIndicesWindow[chosenIndex] = attIndicesWindow[windowSize-1];      attIndicesWindow[windowSize-1] = attIndex;      windowSize--;      splits[attIndex] = distribution(props, dists, attIndex,				      sortedIndices[attIndex], 				      weights[attIndex], data);      vals[attIndex] = gain(dists[attIndex], priorVal(dists[attIndex]));      if (Utils.gr(vals[attIndex], 0)) gainFound = true;    }    // Find best attribute    m_Attribute = Utils.maxIndex(vals);    m_Distribution = dists[m_Attribute];    // Any useful split found?    if (Utils.gr(vals[m_Attribute], 0)) {      // Build subtrees      m_SplitPoint = splits[m_Attribute];      m_Prop = props[m_Attribute];      int[][][] subsetIndices = 	new int[m_Distribution.length][data.numAttributes()][0];      double[][][] subsetWeights = 	new double[m_Distribution.length][data.numAttributes()][0];      splitData(subsetIndices, subsetWeights, m_Attribute, m_SplitPoint, 		sortedIndices, weights, m_Distribution, data);      m_Successors = new RandomTree[m_Distribution.length];      for (int i = 0; i < m_Distribution.length; i++) {	m_Successors[i] = new RandomTree();	m_Successors[i].setKValue(m_KValue);	m_Successors[i].buildTree(subsetIndices[i], subsetWeights[i], data, 				  m_Distribution[i], header, m_MinNum, m_Debug,				  attIndicesWindow, random);      }    } else {            // Make leaf      m_Attribute = -1;      m_Distribution = new double[1][m_ClassProbs.length];      for (int i = 0; i < m_ClassProbs.length; i++) {	m_Distribution[0][i] = m_ClassProbs[i];      }    }    // Normalize class counts    Utils.normalize(m_ClassProbs);  }