// Path: src/main/java/de/mpii/gsm/utils/IntArrayComparator.java
// public class IntArrayComparator {
// 
//   public static int compare(int[] array1, int[] array2, int len1, int len2) {
// 
//     if (len1 > len2) return 1;
//     if (len1 < len2) return -1;
// 
//     // arrays of the same size check elements one by one
//     for (int a1 = 0; a1 < len1; a1++) {
//       if (array1[a1] == array2[a1]) {
//         continue;
//       } else {
//         return array1[a1] - array2[a1];
//       }
// 
//     }
//     return 0;
// 
//   }
// 
// }


import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.WritableUtils;
import de.mpii.gsm.utils.IntArrayComparator;

		// subsequences_.get(committedSubsequences_ - 1).dropRedundantGaps();
	}

	public void optimizeAll() {
		// Flags for subsequences
		// 0: subsequence not yet checked
		// -1: subsequence can be omitted e.g., same subsequence exists
		// >0: subsequence merged with subsequence at position = flag - 1
		subsequencesFlags = new int[committedSubsequences]; // TODO: avoid new

		// initially no index is built
		subsequencesIndices_ = new boolean[committedSubsequences]; // TODO: avoid new
		for (int subseq1 = 0; subseq1 < committedSubsequences; subseq1++) {
			if (subsequencesFlags[subseq1] == 0) {
				subsequencesFlags[subseq1] = subseq1 + 1;
			}

			if (subsequencesFlags[subseq1] == -1) {
				continue;
			}

			for (int subseq2 = subseq1 + 1; subseq2 < committedSubsequences; subseq2++) {
				if (subsequencesFlags[subseq2] == -1) {
					continue;
				}
				boolean canBeSeparated = true;
				Subsequence s1 = subsequences.get(subseq1), s2 = subsequences.get(subseq2);

				// first check equivalence
// Path: src/main/java/de/mpii/gsm/utils/IntArrayComparator.java
// public class IntArrayComparator {
// 
//   public static int compare(int[] array1, int[] array2, int len1, int len2) {
// 
//     if (len1 > len2) return 1;
//     if (len1 < len2) return -1;
// 
//     // arrays of the same size check elements one by one
//     for (int a1 = 0; a1 < len1; a1++) {
//       if (array1[a1] == array2[a1]) {
//         continue;
//       } else {
//         return array1[a1] - array2[a1];
//       }
// 
//     }
//     return 0;
// 
//   }
// 
// }


// Path: src/main/java/de/mpii/gsm/lash/encoders/SplitGapEncoder.java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.WritableUtils;
import de.mpii.gsm.utils.IntArrayComparator;


		// subsequences_.get(committedSubsequences_ - 1).dropRedundantGaps();
	}

	public void optimizeAll() {
		// Flags for subsequences
		// 0: subsequence not yet checked
		// -1: subsequence can be omitted e.g., same subsequence exists
		// >0: subsequence merged with subsequence at position = flag - 1
		subsequencesFlags = new int[committedSubsequences]; // TODO: avoid new

		// initially no index is built
		subsequencesIndices_ = new boolean[committedSubsequences]; // TODO: avoid new
		for (int subseq1 = 0; subseq1 < committedSubsequences; subseq1++) {
			if (subsequencesFlags[subseq1] == 0) {
				subsequencesFlags[subseq1] = subseq1 + 1;
			}

			if (subsequencesFlags[subseq1] == -1) {
				continue;
			}

			for (int subseq2 = subseq1 + 1; subseq2 < committedSubsequences; subseq2++) {
				if (subsequencesFlags[subseq2] == -1) {
					continue;
				}
				boolean canBeSeparated = true;
				Subsequence s1 = subsequences.get(subseq1), s2 = subsequences.get(subseq2);

				// first check equivalence
				if (IntArrayComparator