for (int i = 0; i < m_Instances.attribute(index).numValues() + 1; i++) {
for (int i = 0; i < m_Instances.attribute(index).numValues(); i++) {
  private double findSplitNominalNominal(int index) throws Exception {    double bestVal = Double.MAX_VALUE, currVal;    double[][] counts = new double[m_Instances.attribute(index).numValues() 				  + 1][m_Instances.numClasses()];    double[] sumCounts = new double[m_Instances.numClasses()];    double[][] bestDist = new double[3][m_Instances.numClasses()];    int numMissing = 0;    // Compute counts for all the values    for (int i = 0; i < m_Instances.numInstances(); i++) {      Instance inst = m_Instances.instance(i);      if (inst.isMissing(index)) {	numMissing++;	counts[m_Instances.attribute(index).numValues()]	  [(int)inst.classValue()] += inst.weight();      } else {	counts[(int)inst.value(index)][(int)inst.classValue()] += inst	  .weight();      }    }    // Compute sum of counts    for (int i = 0; i < m_Instances.attribute(index).numValues() + 1; i++) {      for (int j = 0; j < m_Instances.numClasses(); j++) {	sumCounts[j] += counts[i][j];      }    }        // Make split counts for each possible split and evaluate    System.arraycopy(counts[m_Instances.attribute(index).numValues()], 0,		     m_Distribution[2], 0, m_Instances.numClasses());    for (int i = 0; i < m_Instances.attribute(index).numValues(); i++) {      for (int j = 0; j < m_Instances.numClasses(); j++) {	m_Distribution[0][j] = counts[i][j];	m_Distribution[1][j] = sumCounts[j] - counts[i][j];      }      currVal = ContingencyTables.entropyConditionedOnRows(m_Distribution);      if (Utils.sm(currVal, bestVal)) {	bestVal = currVal;	m_SplitPoint = (double)i;	for (int j = 0; j < 3; j++) {	  System.arraycopy(m_Distribution[j], 0, bestDist[j], 0, 			   m_Instances.numClasses());	}      }    }    // No missing values in training data.    if (numMissing == 0) {      System.arraycopy(sumCounts, 0, bestDist[2], 0, 		       m_Instances.numClasses());    }       m_Distribution = bestDist;    return bestVal;  }