indices = Utils.sort(confidences);
indices = Utils.stableSort(confidences);
  public void buildAssociations(Instances instances) throws Exception {    double[] confidences, supports;    int[] indices;    FastVector[] sortedRuleSet;    int necSupport=0;    if (instances.checkForStringAttributes()) {      throw new Exception("Can't handle string attributes!");    }    if (m_removeMissingCols) {      instances = removeMissingColumns(instances);    }    // Decrease minimum support until desired number of rules found.    m_cycles = 0;    m_minSupport = m_upperBoundMinSupport - m_delta;    m_minSupport = (m_minSupport < m_lowerBoundMinSupport)       ? m_lowerBoundMinSupport       : m_minSupport;    do {      // Reserve space for variables      m_Ls = new FastVector();      m_hashtables = new FastVector();      m_allTheRules = new FastVector[6];      m_allTheRules[0] = new FastVector();      m_allTheRules[1] = new FastVector();      m_allTheRules[2] = new FastVector();      if (m_metricType != CONFIDENCE || m_significanceLevel != -1) {	m_allTheRules[3] = new FastVector();	m_allTheRules[4] = new FastVector();	m_allTheRules[5] = new FastVector();      }      sortedRuleSet = new FastVector[6];      sortedRuleSet[0] = new FastVector();      sortedRuleSet[1] = new FastVector();      sortedRuleSet[2] = new FastVector();      if (m_metricType != CONFIDENCE || m_significanceLevel != -1) {	sortedRuleSet[3] = new FastVector();	sortedRuleSet[4] = new FastVector();	sortedRuleSet[5] = new FastVector();      }      // Find large itemsets and rules      findLargeItemSets(instances);      if (m_significanceLevel != -1 || m_metricType != CONFIDENCE) 	findRulesBruteForce();      else	findRulesQuickly();            // Sort rules according to their support      supports = new double[m_allTheRules[2].size()];      for (int i = 0; i < m_allTheRules[2].size(); i++) 	supports[i] = (double)((ItemSet)m_allTheRules[1].elementAt(i)).support();      indices = Utils.sort(supports);      for (int i = 0; i < m_allTheRules[2].size(); i++) {	sortedRuleSet[0].addElement(m_allTheRules[0].elementAt(indices[i]));	sortedRuleSet[1].addElement(m_allTheRules[1].elementAt(indices[i]));	sortedRuleSet[2].addElement(m_allTheRules[2].elementAt(indices[i]));	if (m_metricType != CONFIDENCE || m_significanceLevel != -1) {	  sortedRuleSet[3].addElement(m_allTheRules[3].elementAt(indices[i]));	  sortedRuleSet[4].addElement(m_allTheRules[4].elementAt(indices[i]));	  sortedRuleSet[5].addElement(m_allTheRules[5].elementAt(indices[i]));	}      }      // Sort rules according to their confidence      m_allTheRules[0].removeAllElements();      m_allTheRules[1].removeAllElements();      m_allTheRules[2].removeAllElements();      if (m_metricType != CONFIDENCE || m_significanceLevel != -1) {	m_allTheRules[3].removeAllElements();	m_allTheRules[4].removeAllElements();	m_allTheRules[5].removeAllElements();      }      confidences = new double[sortedRuleSet[2].size()];      int sortType = 2 + m_metricType;      for (int i = 0; i < sortedRuleSet[2].size(); i++) 	confidences[i] = 	  ((Double)sortedRuleSet[sortType].elementAt(i)).doubleValue();      indices = Utils.sort(confidences);      for (int i = sortedRuleSet[0].size() - 1; 	   (i >= (sortedRuleSet[0].size() - m_numRules)) && (i >= 0); i--) {	m_allTheRules[0].addElement(sortedRuleSet[0].elementAt(indices[i]));	m_allTheRules[1].addElement(sortedRuleSet[1].elementAt(indices[i]));	m_allTheRules[2].addElement(sortedRuleSet[2].elementAt(indices[i]));	if (m_metricType != CONFIDENCE || m_significanceLevel != -1) {	  m_allTheRules[3].addElement(sortedRuleSet[3].elementAt(indices[i]));	  m_allTheRules[4].addElement(sortedRuleSet[4].elementAt(indices[i]));	  m_allTheRules[5].addElement(sortedRuleSet[5].elementAt(indices[i]));	}      }      m_minSupport -= m_delta;      m_minSupport = (m_minSupport < m_lowerBoundMinSupport) 	? 0 	: m_minSupport;      necSupport = (int)(m_minSupport * 			 (double)instances.numInstances()+0.5);      m_cycles++;      if (m_verbose) {	if (m_Ls.size() > 1) {	  System.out.println(toString());	}      }    } while ((m_allTheRules[0].size() < m_numRules) && 	     (m_minSupport >= m_lowerBoundMinSupport)	     /*	     (necSupport >= lowerBoundNumInstancesSupport)*/	     /*	     (Utils.grOrEq(m_minSupport, m_lowerBoundMinSupport)) */ &&     	     (necSupport >= 1));    m_minSupport += m_delta;  }