public double[] distributionForInstance(Instance instance) throws Exception {
    String stringInstance = instance.toString();
    double cachedPreds[][] = null;
    
    if (m_cachedPredictions != null) {
      // If we have any cached predictions (i.e., if cachePredictions was
      // called), look for a cached set of predictions for this instance.
      if (m_cachedPredictions.containsKey(stringInstance)) {
	cachedPreds = (double[][]) m_cachedPredictions.get(stringInstance);
      }
    }
    double[] prediction = new double[instance.numClasses()];
    for (int i = 0; i < prediction.length; ++i) {
      prediction[i] = 0.0;
    }
    
    // Now do a weighted average of the predictions of each of our models.
    for (int i = 0; i < m_chosen_models.length; ++i) {
      double[] predictionForThisModel = null;
      if (cachedPreds == null) {
	// If there are no predictions cached, we'll load the model's
	// classifier(s) in to memory and get the predictions.
	m_chosen_models[i].rehydrateModel(m_workingDirectory.getAbsolutePath());
	predictionForThisModel = m_chosen_models[i].getAveragePrediction(instance);
	// We could release the model here to save memory, but we assume
	// that there is enough available since we're not using the
	// prediction caching functionality. If we load and release a
	// model
	// every time we need to get a prediction for an instance, it
	// can be
	// prohibitively slow.
      } else {
	// If it's cached, just get it from the array of cached preds
	// for this instance.
	predictionForThisModel = cachedPreds[i];
      }
      // We have encountered a bug where MultilayerPerceptron returns a
      // null
      // prediction array. If that happens, we just don't count that model
      // in
      // our ensemble prediction.
      if (predictionForThisModel != null) {
	// Okay, the model returned a valid prediction array, so we'll
	// add the appropriate fraction of this model's prediction.
	for (int j = 0; j < prediction.length; ++j) {
	  prediction[j] += m_chosen_model_weights[i] * predictionForThisModel[j] / m_total_weight;
	}
      }
    }
    // normalize to add up to 1.
    if (instance.classAttribute().isNominal()) {
      if (Utils.sum(prediction) > 0)
	Utils.normalize(prediction);
    }
    return prediction;
  }