public static void mapClasses(int numClusters, int lev, int[][] counts, int[] clusterTotals,
                                  double[] current, double[] best, int error) {
        // leaf
        if (lev == numClusters) {
            if (error < best[numClusters]) {
                best[numClusters] = error;
                for (int i = 0; i < numClusters; i++) {
                    best[i] = current[i];
                }
            }
        } else {
            // empty cluster -- ignore
            if (clusterTotals[lev] == 0) {
                current[lev] = -1; // cluster ignored
                mapClasses(numClusters, lev + 1, counts, clusterTotals, current, best,
                        error);
            } else {
                // first try no class assignment to this cluster
                current[lev] = -1; // cluster assigned no class (ie all errors)
                mapClasses(numClusters, lev + 1, counts, clusterTotals, current, best,
                        error + clusterTotals[lev]);
                // now loop through the classes in this cluster
                for (int i = 0; i < counts[0].length; i++) {
                    if (counts[lev][i] > 0) {
                        boolean ok = true;
                        // check to see if this class has already been assigned
                        for (int j = 0; j < lev; j++) {
                            if ((int) current[j] == i) {
                                ok = false;
                                break;
                            }
                        }
                        if (ok) {
                            current[lev] = i;
                            mapClasses(numClusters, lev + 1, counts, clusterTotals, current, best,
                                    (error + (clusterTotals[lev] - counts[lev][i])));
                        }
                    }
                }
            }
        }
    }