cutPoints =  new double[left.length + right.length + 1];
  private double[] cutPointsForSubset(Instances instances, int attIndex, 				      int first, int lastPlusOne) {     double[][] counts, bestCounts;    double[] priorCounts, left, right, cutPoints;    double currentCutPoint = -Double.MAX_VALUE, bestCutPoint = -1,       currentEntropy, bestEntropy, priorEntropy, gain;    int bestIndex = -1, numInstances = 0, numCutPoints = 0;    // Compute number of instances in set    if ((lastPlusOne - first) < 2) {      return null;    }    // Compute class counts.    counts = new double[2][instances.numClasses()];    for (int i = first; i < lastPlusOne; i++) {      numInstances += instances.instance(i).weight();      counts[1][(int)instances.instance(i).classValue()] +=	instances.instance(i).weight();    }    // Save prior counts    priorCounts = new double[instances.numClasses()];    System.arraycopy(counts[1], 0, priorCounts, 0, 		     instances.numClasses());    // Entropy of the full set    priorEntropy = ContingencyTables.entropy(priorCounts);    bestEntropy = priorEntropy;        // Find best entropy.    bestCounts = new double[2][instances.numClasses()];    for (int i = first; i < (lastPlusOne - 1); i++) {      counts[0][(int)instances.instance(i).classValue()] +=	instances.instance(i).weight();      counts[1][(int)instances.instance(i).classValue()] -=	instances.instance(i).weight();      if (Utils.sm(instances.instance(i).value(attIndex), 		   instances.instance(i + 1).value(attIndex))) {	currentCutPoint = instances.instance(i).value(attIndex); //+ 	//instances.instance(i + 1).value(attIndex)) / 2.0;	currentEntropy = ContingencyTables.entropyConditionedOnRows(counts);	if (Utils.sm(currentEntropy, bestEntropy)) {	  bestCutPoint = currentCutPoint;	  bestEntropy = currentEntropy;	  bestIndex = i;	  System.arraycopy(counts[0], 0, 			   bestCounts[0], 0, instances.numClasses());	  System.arraycopy(counts[1], 0, 			   bestCounts[1], 0, instances.numClasses()); 	}	numCutPoints++;      }    }    // Use worse encoding?    if (!m_UseBetterEncoding) {      numCutPoints = (lastPlusOne - first) - 1;    }    // Checks if gain is zero    gain = priorEntropy - bestEntropy;    if (Utils.eq(gain, 0)) {      return null;    }    // Check if split is to be accepted    if ((m_UseKononenko && KononenkosMDL(priorCounts, bestCounts,					 numInstances, numCutPoints)) ||	(!m_UseKononenko && FayyadAndIranisMDL(priorCounts, bestCounts,					       numInstances, numCutPoints))) {            // Select split points for the left and right subsets      left = cutPointsForSubset(instances, attIndex, first, bestIndex + 1);      right = cutPointsForSubset(instances, attIndex, 				 bestIndex + 1, lastPlusOne);            // Merge cutpoints and return them      if ((left == null) && (right) == null) {	cutPoints = new double[1];	cutPoints[0] = bestCutPoint;      } else if (right == null) {	cutPoints = new double[left.length + 1];	System.arraycopy(left, 0, cutPoints, 0, left.length);	cutPoints[left.length] = bestCutPoint;      } else if (left == null) {	cutPoints = new double[1 + right.length];	cutPoints[0] = bestCutPoint;	System.arraycopy(right, 0, cutPoints, 1, right.length);      } else {	cutPoints =  new double[left.length + right.length + 1];	cutPoints = new double[left.length + right.length + 1];	System.arraycopy(left, 0, cutPoints, 0, left.length);	cutPoints[left.length] = bestCutPoint;	System.arraycopy(right, 0, cutPoints, left.length + 1, right.length);      }            return cutPoints;    } else      return null;  }