// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/Spectrum.java
// public interface Spectrum {
// 
//     /**
//      * ion of a spectra
//      * @return
//      */
//     public List<Ion> getIons();
// 
//     /**
//      * convmerts the spectrum to a relative spectra
//      * @return
//      * @param scale
//      */
//     Spectrum toRelative(int scale);
// 
//     /**
//      *
//      * @return
//      */
//     String getOrigin();
// 
//     /**
//      * what kind of a spectra do we have
//      * @return
//      */
//     public SpectraType getType();
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/Splash.java
// public interface Splash {
// 
//     /**
//      * generates a new spectra hash based on the given spectrum
//      * @return
//      */
//     String splashIt(Spectrum spectrum);
// 
//     /**
//      * adds an optional listener to the
//      * @param listener
//      */
//     void addListener(SplashListener listener);
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/io/SpectraHandler.java
// public interface SpectraHandler {
// 
//     /**
//      * beginning to read
//      */
//     void begin() throws IOException;
//     /**
//      * a spectrum was found, lets do something with it
//      * @param spectrum
//      */
//     void handle(Spectrum spectrum);
// 
//     /**
//      * no more data
//      */
//     void done() throws IOException;
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/io/SpectrumReader.java
// public class SpectrumReader {
// 
//     private Logger logger = Logger.getLogger(getClass().getName());
// 
//     /**
//      * read a spectrum and notify our handler
//      *
//      * @param reader
//      * @param handler
//      */
//     public void readSpectrum(Reader reader, SpectraHandler handler, SpectraType spectraType) throws IOException {
//         Scanner scanner = new Scanner(reader);
// 
//         handler.begin();
//         while (scanner.hasNextLine()) {
//             String line = scanner.nextLine().trim();
// 
//             String origin = "unknown";
// 
//             //in case some people use several spaces instead of a tab...
//             line = line.replaceAll(" {2,}", "\t");
// 
//             //in case people use csv instead of a tab
//             line = line.replaceAll(",", "\t");
// 
//             if (line.contains("\t")) {
//                 String t[] = line.split("\t");
// 
//                 origin = t[0];
//                 line = t[1];
// 
//                 if (t.length == 3) {
//                     origin = origin + "_" + t[2];
//                 }
//             }
// 
//             if (line.contains(":") && line.contains(" ")) {
// 
//                 Spectrum spectrum = SpectraUtil.convertStringToSpectrum(line,spectraType,origin);
// 
//                 handler.handle(spectrum);
//             }
//         }
// 
//         handler.done();
//     }
// 
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/types/SpectraType.java
// public enum SpectraType {
//     MS('1'),
//     NMR('2'),
//     UV('3'),
//     IR('4'),
//     RAMAN('5');
// 
//     /**
//      * identifier has to be a single character
//      */
//     private final char identifier;
// 
//     /**
//      * creates a new spectra type with the assoicated reference number
//      *
//      * @param referenceNumber
//      */
//     SpectraType(char referenceNumber) {
//         this.identifier = referenceNumber;
//     }
// 
//     /**
//      * access to it's identifier
//      *
//      * @return
//      */
//     public char getIdentifier() {
//         return this.identifier;
//     }
// }


import edu.ucdavis.fiehnlab.spectra.hash.core.Spectrum;
import edu.ucdavis.fiehnlab.spectra.hash.core.Splash;
import edu.ucdavis.fiehnlab.spectra.hash.core.io.SpectraHandler;
import edu.ucdavis.fiehnlab.spectra.hash.core.io.SpectrumReader;
import edu.ucdavis.fiehnlab.spectra.hash.core.types.SpectraType;
import org.geirove.exmeso.CloseableIterator;
import org.geirove.exmeso.ExternalMergeSort;
import org.geirove.exmeso.kryo.KryoSerializer;
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import static org.junit.Assert.fail;
package edu.ucdavis.fiehnlab.spectra.hash.core.impl;




/**
 * general testing strategy for splash implementations
 */
public abstract class AbstractSpectraHashImplTester{

    /**
     * get our impl to test
     *
     * @return
     */
    abstract Splash getHashImpl();

    /**
     * runs our actual tests on the input and output files
     *
     * @param resultFile
     * @param inputFile
     * @throws IOException
     */
    protected TestResult runTest(String resultFile, String inputFile, SpectraType spectraType, boolean onlyDuplicates) throws IOException {
        final File tempFile = File.createTempFile("splash", "tmp");
        tempFile.deleteOnExit();
        final OutputStream temp = new BufferedOutputStream(new FileOutputStream(tempFile));
        final ExternalMergeSort.Serializer<TestSpectraImpl> serializer = new KryoSerializer<TestSpectraImpl>(TestSpectraImpl.class);

// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/Spectrum.java
// public interface Spectrum {
// 
//     /**
//      * ion of a spectra
//      * @return
//      */
//     public List<Ion> getIons();
// 
//     /**
//      * convmerts the spectrum to a relative spectra
//      * @return
//      * @param scale
//      */
//     Spectrum toRelative(int scale);
// 
//     /**
//      *
//      * @return
//      */
//     String getOrigin();
// 
//     /**
//      * what kind of a spectra do we have
//      * @return
//      */
//     public SpectraType getType();
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/Splash.java
// public interface Splash {
// 
//     /**
//      * generates a new spectra hash based on the given spectrum
//      * @return
//      */
//     String splashIt(Spectrum spectrum);
// 
//     /**
//      * adds an optional listener to the
//      * @param listener
//      */
//     void addListener(SplashListener listener);
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/io/SpectraHandler.java
// public interface SpectraHandler {
// 
//     /**
//      * beginning to read
//      */
//     void begin() throws IOException;
//     /**
//      * a spectrum was found, lets do something with it
//      * @param spectrum
//      */
//     void handle(Spectrum spectrum);
// 
//     /**
//      * no more data
//      */
//     void done() throws IOException;
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/io/SpectrumReader.java
// public class SpectrumReader {
// 
//     private Logger logger = Logger.getLogger(getClass().getName());
// 
//     /**
//      * read a spectrum and notify our handler
//      *
//      * @param reader
//      * @param handler
//      */
//     public void readSpectrum(Reader reader, SpectraHandler handler, SpectraType spectraType) throws IOException {
//         Scanner scanner = new Scanner(reader);
// 
//         handler.begin();
//         while (scanner.hasNextLine()) {
//             String line = scanner.nextLine().trim();
// 
//             String origin = "unknown";
// 
//             //in case some people use several spaces instead of a tab...
//             line = line.replaceAll(" {2,}", "\t");
// 
//             //in case people use csv instead of a tab
//             line = line.replaceAll(",", "\t");
// 
//             if (line.contains("\t")) {
//                 String t[] = line.split("\t");
// 
//                 origin = t[0];
//                 line = t[1];
// 
//                 if (t.length == 3) {
//                     origin = origin + "_" + t[2];
//                 }
//             }
// 
//             if (line.contains(":") && line.contains(" ")) {
// 
//                 Spectrum spectrum = SpectraUtil.convertStringToSpectrum(line,spectraType,origin);
// 
//                 handler.handle(spectrum);
//             }
//         }
// 
//         handler.done();
//     }
// 
// }
// 
// Path: core/src/main/java/edu/ucdavis/fiehnlab/spectra/hash/core/types/SpectraType.java
// public enum SpectraType {
//     MS('1'),
//     NMR('2'),
//     UV('3'),
//     IR('4'),
//     RAMAN('5');
// 
//     /**
//      * identifier has to be a single character
//      */
//     private final char identifier;
// 
//     /**
//      * creates a new spectra type with the assoicated reference number
//      *
//      * @param referenceNumber
//      */
//     SpectraType(char referenceNumber) {
//         this.identifier = referenceNumber;
//     }
// 
//     /**
//      * access to it's identifier
//      *
//      * @return
//      */
//     public char getIdentifier() {
//         return this.identifier;
//     }
// }


// Path: core/src/test/java/edu/ucdavis/fiehnlab/spectra/hash/core/impl/AbstractSpectraHashImplTester.java
import edu.ucdavis.fiehnlab.spectra.hash.core.Spectrum;
import edu.ucdavis.fiehnlab.spectra.hash.core.Splash;
import edu.ucdavis.fiehnlab.spectra.hash.core.io.SpectraHandler;
import edu.ucdavis.fiehnlab.spectra.hash.core.io.SpectrumReader;
import edu.ucdavis.fiehnlab.spectra.hash.core.types.SpectraType;
import org.geirove.exmeso.CloseableIterator;
import org.geirove.exmeso.ExternalMergeSort;
import org.geirove.exmeso.kryo.KryoSerializer;
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import static org.junit.Assert.fail;

package edu.ucdavis.fiehnlab.spectra.hash.core.impl;




/**
 * general testing strategy for splash implementations
 */
public abstract class AbstractSpectraHashImplTester{

    /**
     * get our impl to test
     *
     * @return
     */
    abstract Splash getHashImpl();

    /**
     * runs our actual tests on the input and output files
     *
     * @param resultFile
     * @param inputFile
     * @throws IOException
     */
    protected TestResult runTest(String resultFile, String inputFile, SpectraType spectraType, boolean onlyDuplicates) throws IOException {
        final File tempFile = File.createTempFile("splash", "tmp");
        tempFile.deleteOnExit();
        final OutputStream temp = new BufferedOutputStream(new FileOutputStream(tempFile));
        final ExternalMergeSort.Serializer<TestSpectraImpl> serializer = new KryoSerializer<TestSpectraImpl>(TestSpectraImpl.class);

        final SpectrumReader reader = new SpectrumReader();