public void buildClassifier(Instances data) throws Exception {
    
    // can classifier handle the data?
    getCapabilities().testWithFail(data);

    // remove instances with missing class
    data = new Instances(data);
    data.deleteWithMissingClass();
    
    if (!(m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.ND) && 
	!(m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.ClassBalancedND) &&  
	!(m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.DataNearBalancedND)) {
      throw new IllegalArgumentException("END only works with ND, ClassBalancedND " +
					 "or DataNearBalancedND classifier");
    }
    
    m_hashtable = new Hashtable();
    
    m_Classifiers = Classifier.makeCopies(m_Classifier, m_NumIterations);
    
    Random random = data.getRandomNumberGenerator(m_Seed);
    for (int j = 0; j < m_Classifiers.length; j++) {
      
      // Set the random number seed for the current classifier.
      ((Randomizable) m_Classifiers[j]).setSeed(random.nextInt());
      
      // Set the hashtable
      if (m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.ND) 
	((weka.classifiers.meta.nestedDichotomies.ND)m_Classifiers[j]).setHashtable(m_hashtable);
      else if (m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.ClassBalancedND) 
	((weka.classifiers.meta.nestedDichotomies.ClassBalancedND)m_Classifiers[j]).setHashtable(m_hashtable);
      else if (m_Classifier instanceof weka.classifiers.meta.nestedDichotomies.DataNearBalancedND) 
	((weka.classifiers.meta.nestedDichotomies.DataNearBalancedND)m_Classifiers[j]).
	  setHashtable(m_hashtable);
      
      // Build the classifier.
      m_Classifiers[j].buildClassifier(data);
    }
  }