Index: trunk/CrossPare/src/de/ugoe/cs/cpdp/util/SortUtils.java
===================================================================
--- trunk/CrossPare/src/de/ugoe/cs/cpdp/util/SortUtils.java	(revision 61)
+++ trunk/CrossPare/src/de/ugoe/cs/cpdp/util/SortUtils.java	(revision 61)
@@ -0,0 +1,58 @@
+package de.ugoe.cs.cpdp.util;
+
+public class SortUtils {
+
+    public static <T extends Comparable<T>> void quicksort(T[] main, int[] index) {
+        quicksort(main, index, 0, index.length - 1, false);
+    }
+    
+    public static <T extends Comparable<T>> void quicksort(T[] main, int[] index, boolean descending) {
+        quicksort(main, index, 0, index.length - 1, descending);
+    }
+
+    // quicksort a[left] to a[right]
+    private static <T extends Comparable<T>> void quicksort(T[] a, int[] index, int left, int right, boolean descending) {
+        if (right <= left)
+            return;
+        int i = partition(a, index, left, right, descending);
+        quicksort(a, index, left, i - 1, descending);
+        quicksort(a, index, i + 1, right, descending);
+    }
+
+    // partition a[left] to a[right], assumes left < right
+    private static <T extends Comparable<T>> int partition(T[] a, int[] index, int left, int right, boolean descending) {
+        int i = left - 1;
+        int j = right;
+        while (true) {
+            while (compare(a[++i], a[right], descending)) // find item on left to swap
+            ; // a[right] acts as sentinel
+            while (compare(a[right], a[--j], descending)) // find item on right to swap
+                if (j == left)
+                    break; // don't go out-of-bounds
+            if (i >= j)
+                break; // check if pointers cross
+            exch(a, index, i, j); // swap two elements into place
+        }
+        exch(a, index, i, right); // swap with partition element
+        return i;
+    }
+
+    // is x < y ?
+    private static <T extends Comparable<T>> boolean compare(T x, T y, boolean descending) {
+        if( descending ) {
+            return x.compareTo(y)>0;
+        } else {
+            return x.compareTo(y)<0;
+        }
+    }
+
+    // exchange a[i] and a[j]
+    private static <T extends Comparable<T>> void exch(T[] a, int[] index, int i, int j) {
+        T swap = a[i];
+        a[i] = a[j];
+        a[j] = swap;
+        int b = index[i];
+        index[i] = index[j];
+        index[j] = b;
+    }
+}
Index: trunk/CrossPare/src/de/ugoe/cs/cpdp/util/WekaUtils.java
===================================================================
--- trunk/CrossPare/src/de/ugoe/cs/cpdp/util/WekaUtils.java	(revision 61)
+++ trunk/CrossPare/src/de/ugoe/cs/cpdp/util/WekaUtils.java	(revision 61)
@@ -0,0 +1,153 @@
+// Copyright 2015 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.cpdp.util;
+
+// TODO comment
+import org.apache.commons.math3.ml.distance.EuclideanDistance;
+
+import weka.core.Instance;
+import weka.core.Instances;
+
+public class WekaUtils {
+
+    public static class DistChar {
+        public final double mean;
+        public final double std;
+        public final double min;
+        public final double max;
+        public final int num;
+        private DistChar(double mean, double std, double min, double max, int num) {
+            this.mean = mean;
+            this.std = std;
+            this.min = min;
+            this.max = max;
+            this.num = num;
+        }
+    }
+    
+    /**
+     * <p>
+     * Adoption of the Hamming difference to numerical values, i.e., basically a count of different
+     * metric values.
+     * </p>
+     *
+     * @param inst1
+     *            first instance to be compared
+     * @param inst2
+     *            second instance to be compared
+     * @return the distance
+     */
+    public static double hammingDistance(Instance inst1, Instance inst2) {
+        double distance = 0.0;
+        for (int j = 0; j < inst1.numAttributes(); j++) {
+            if (j != inst1.classIndex()) {
+                if (inst1.value(j) != inst2.value(j)) {
+                    distance += 1.0;
+                }
+            }
+        }
+        return distance;
+    }
+    
+    public static double[] instanceValues(Instance instance) {
+        double[] values = new double[instance.numAttributes()-1];
+        int k=0; 
+        for( int j=0; j<instance.numAttributes() ; j++ ) {
+            if( j!= instance.classIndex() ) {
+                values[k] = instance.value(j);
+                k++;
+            }
+        }
+        return values;
+    }
+    
+    public static DistChar datasetDistance(Instances data) {
+        double distance;
+        double sumAll = 0.0;
+        double sumAllQ = 0.0;
+        double min = Double.MAX_VALUE;
+        double max = Double.MIN_VALUE;
+        int numCmp = 0;
+        int l = 0;
+        double[] inst1 = new double[data.numAttributes()-1];
+        double[] inst2 = new double[data.numAttributes()-1];
+        EuclideanDistance euclideanDistance = new EuclideanDistance();
+        for( int i=0; i<data.numInstances(); i++ ) {
+            l=0;
+            for( int k=0; k<data.numAttributes(); k++ ) {
+                if( k!=data.classIndex() ) {
+                    inst1[l] = data.instance(i).value(k);
+                }
+            }
+            for( int j=0; j<data.numInstances(); j++ ) {
+                if( j!=i ) {
+                    l=0;
+                    for( int k=0; k<data.numAttributes(); k++ ) {
+                        if( k!=data.classIndex() ) {
+                            inst2[l] = data.instance(j).value(k);
+                        }
+                    }
+                    distance = euclideanDistance.compute(inst1, inst2);
+                    sumAll += distance;
+                    sumAllQ += distance*distance;
+                    numCmp++;
+                    if( distance < min ) {
+                        min = distance;
+                    }
+                    if( distance > max ) {
+                        max = distance;
+                    }
+                }
+            }
+        }
+        double mean = sumAll / numCmp;
+        double std = Math.sqrt((sumAllQ-(sumAll*sumAll)/numCmp) *
+                                  (1.0d / (numCmp - 1)));
+        return new DistChar(mean, std, min, max, data.numInstances());
+    }
+    
+    // like above, but for single attribute
+    public static DistChar attributeDistance(Instances data, int index) {
+        double distance;
+        double sumAll = 0.0;
+        double sumAllQ = 0.0;
+        double min = Double.MAX_VALUE;
+        double max = Double.MIN_VALUE;
+        int numCmp = 0;
+        double value1, value2;
+        for( int i=0; i<data.numInstances(); i++ ) {
+            value1 = data.instance(i).value(index);
+            for( int j=0; j<data.numInstances(); j++ ) {
+                if( j!=i ) {
+                    value2 = data.instance(j).value(index);
+                    distance = Math.abs(value1-value2);
+                    sumAll += distance;
+                    sumAllQ += distance*distance;
+                    numCmp++;
+                    if( distance < min ) {
+                        min = distance;
+                    }
+                    if( distance > max ) {
+                        max = distance;
+                    }
+                }
+            }
+        }
+        double mean = sumAll / numCmp;
+        double std = Math.sqrt((sumAllQ-(sumAll*sumAll)/numCmp) *
+                                  (1.0d / (numCmp - 1)));
+        return new DistChar(mean, std, min, max, data.numInstances());
+    }
+}
