// Path: src/main/java/com/feedzai/fos/impl/weka/utils/Cloner.java
// public class Cloner<T extends Serializable> {
//     private byte[] serializedObject;
// 
//     /**
//      * Creates a new clonner from the given serialized object.
//      *
//      * @param serializedObject the serialized object that will cloned
//      */
//     public Cloner(byte[] serializedObject) {
//         checkNotNull(serializedObject, "The serialized object cannot be null");
// 
//         this.serializedObject = serializedObject;
//     }
// 
// 
//     /**
//      * Creates a clonner from the given object.
//      *
//      * @param serializable the object to clone
//      * @throws IOException when there were problems serializing the object
//      */
//     public Cloner(T serializable) throws IOException {
//         checkNotNull(serializable, "The serialized object cannot be null");
// 
//         ObjectOutputStream oos = null;
//         ByteArrayOutputStream baos = null;
// 
//         try {
//             baos = new ByteArrayOutputStream();
//             oos = new ObjectOutputStream(baos);
//             oos.writeObject(serializable);
//             oos.flush();
// 
//             this.serializedObject = baos.toByteArray();
//         } finally {
//             IOUtils.closeQuietly(baos);
//             IOUtils.closeQuietly(oos);
//         }
//     }
// 
//     /**
//      * Creates a clonner by reading a serialized object from file.
//      *
//      * @param descriptor A {@link com.feedzai.fos.api.ModelDescriptor} with the information about the classifier.
//      * @throws IOException when there were problems reading the file
//      */
//     public Cloner(ModelDescriptor descriptor) throws IOException {
//         checkNotNull(descriptor.getModelFilePath(), "Source file cannot be null");
// 
//         File file = new File(descriptor.getModelFilePath());
// 
//         checkArgument(file.exists(), "Source file '"+ file.getAbsolutePath() + "' must exist");
// 
//         switch (descriptor.getFormat()) {
//             case BINARY:
//                 this.serializedObject = FileUtils.readFileToByteArray(file);
//                 break;
//             case PMML:
//                 try {
//                     this.serializedObject = SerializationUtils.serialize(PMMLConsumers.consume(file));
//                 } catch (FOSException e) {
//                     throw new RuntimeException("Failed to consume PMML file.", e);
//                 }
//                 break;
//         }
//     }
// 
//     /**
//      * Gets a fresh clone of the object.
//      *
//      * @return a fresh clone
//      * @throws IOException            when there were problems serializing the object
//      * @throws ClassNotFoundException when the serialized objects's class was not found
//      */
//     @NotNull
//     public T get() throws IOException, ClassNotFoundException {
//         /* cannot be pre-instantiated to enable thread concurrency*/
//         ByteArrayInputStream byteArrayInputStream = null;
//         ObjectInputStream objectInputStream = null;
//         try {
//             byteArrayInputStream = new ByteArrayInputStream(this.serializedObject);
//             objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 
//             return (T) objectInputStream.readObject();
//         } finally {
//             IOUtils.closeQuietly(byteArrayInputStream);
//             IOUtils.closeQuietly(objectInputStream);
//         }
//     }
// 
//     /**
//      * Returns a copy of the serialized object.
//      *
//      * @return a copy (this object is immutable)
//      */
//     @NotNull
//     public byte[] getSerialized() {
//         byte[] result = new byte[serializedObject.length];
//         System.arraycopy(serializedObject, 0, result, 0, serializedObject.length);
// 
//         return result;
//     }
// 
//     /**
//      * Writes the serialized object to file.
//      *
//      * @param file the file to write to (will be overwritten)
//      * @throws IOException when the file could not be written
//      */
//     public void write(File file) throws IOException {
//         checkNotNull(file, "Output file cannot be null");
// 
//         FileUtils.writeByteArrayToFile(file, serializedObject);
//     }
// }


import java.io.File;
import com.feedzai.fos.api.CategoricalAttribute;
import com.feedzai.fos.impl.weka.utils.Cloner;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
        isTrainingSet.setClassIndex(3);

        // Create the instance
        Instance iExample1 = new Instance(4);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(0), 1.0);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(3), "positive");

        Instance iExample2 = new Instance(4);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(0), 2.0);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(3), "negative");

        Instance iExample3 = new Instance(4);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(0), 0.9);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(3), "positive");

        // add the instance
        isTrainingSet.add(iExample1);
        isTrainingSet.add(iExample2);
        isTrainingSet.add(iExample3);

        // Create a naïve bayes classifier
        Classifier cModel = new NaiveBayes();
        cModel.buildClassifier(isTrainingSet);

// Path: src/main/java/com/feedzai/fos/impl/weka/utils/Cloner.java
// public class Cloner<T extends Serializable> {
//     private byte[] serializedObject;
// 
//     /**
//      * Creates a new clonner from the given serialized object.
//      *
//      * @param serializedObject the serialized object that will cloned
//      */
//     public Cloner(byte[] serializedObject) {
//         checkNotNull(serializedObject, "The serialized object cannot be null");
// 
//         this.serializedObject = serializedObject;
//     }
// 
// 
//     /**
//      * Creates a clonner from the given object.
//      *
//      * @param serializable the object to clone
//      * @throws IOException when there were problems serializing the object
//      */
//     public Cloner(T serializable) throws IOException {
//         checkNotNull(serializable, "The serialized object cannot be null");
// 
//         ObjectOutputStream oos = null;
//         ByteArrayOutputStream baos = null;
// 
//         try {
//             baos = new ByteArrayOutputStream();
//             oos = new ObjectOutputStream(baos);
//             oos.writeObject(serializable);
//             oos.flush();
// 
//             this.serializedObject = baos.toByteArray();
//         } finally {
//             IOUtils.closeQuietly(baos);
//             IOUtils.closeQuietly(oos);
//         }
//     }
// 
//     /**
//      * Creates a clonner by reading a serialized object from file.
//      *
//      * @param descriptor A {@link com.feedzai.fos.api.ModelDescriptor} with the information about the classifier.
//      * @throws IOException when there were problems reading the file
//      */
//     public Cloner(ModelDescriptor descriptor) throws IOException {
//         checkNotNull(descriptor.getModelFilePath(), "Source file cannot be null");
// 
//         File file = new File(descriptor.getModelFilePath());
// 
//         checkArgument(file.exists(), "Source file '"+ file.getAbsolutePath() + "' must exist");
// 
//         switch (descriptor.getFormat()) {
//             case BINARY:
//                 this.serializedObject = FileUtils.readFileToByteArray(file);
//                 break;
//             case PMML:
//                 try {
//                     this.serializedObject = SerializationUtils.serialize(PMMLConsumers.consume(file));
//                 } catch (FOSException e) {
//                     throw new RuntimeException("Failed to consume PMML file.", e);
//                 }
//                 break;
//         }
//     }
// 
//     /**
//      * Gets a fresh clone of the object.
//      *
//      * @return a fresh clone
//      * @throws IOException            when there were problems serializing the object
//      * @throws ClassNotFoundException when the serialized objects's class was not found
//      */
//     @NotNull
//     public T get() throws IOException, ClassNotFoundException {
//         /* cannot be pre-instantiated to enable thread concurrency*/
//         ByteArrayInputStream byteArrayInputStream = null;
//         ObjectInputStream objectInputStream = null;
//         try {
//             byteArrayInputStream = new ByteArrayInputStream(this.serializedObject);
//             objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 
//             return (T) objectInputStream.readObject();
//         } finally {
//             IOUtils.closeQuietly(byteArrayInputStream);
//             IOUtils.closeQuietly(objectInputStream);
//         }
//     }
// 
//     /**
//      * Returns a copy of the serialized object.
//      *
//      * @return a copy (this object is immutable)
//      */
//     @NotNull
//     public byte[] getSerialized() {
//         byte[] result = new byte[serializedObject.length];
//         System.arraycopy(serializedObject, 0, result, 0, serializedObject.length);
// 
//         return result;
//     }
// 
//     /**
//      * Writes the serialized object to file.
//      *
//      * @param file the file to write to (will be overwritten)
//      * @throws IOException when the file could not be written
//      */
//     public void write(File file) throws IOException {
//         checkNotNull(file, "Output file cannot be null");
// 
//         FileUtils.writeByteArrayToFile(file, serializedObject);
//     }
// }


// Path: src/test/java/com/feedzai/fos/impl/weka/CreateTestModel.java
import java.io.File;
import com.feedzai.fos.api.CategoricalAttribute;
import com.feedzai.fos.impl.weka.utils.Cloner;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

        isTrainingSet.setClassIndex(3);

        // Create the instance
        Instance iExample1 = new Instance(4);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(0), 1.0);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample1.setValue((Attribute)fvWekaAttributes.elementAt(3), "positive");

        Instance iExample2 = new Instance(4);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(0), 2.0);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample2.setValue((Attribute)fvWekaAttributes.elementAt(3), "negative");

        Instance iExample3 = new Instance(4);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(0), 0.9);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(1), 0.5);
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(2), "gray");
        iExample3.setValue((Attribute)fvWekaAttributes.elementAt(3), "positive");

        // add the instance
        isTrainingSet.add(iExample1);
        isTrainingSet.add(iExample2);
        isTrainingSet.add(iExample3);

        // Create a naïve bayes classifier
        Classifier cModel = new NaiveBayes();
        cModel.buildClassifier(isTrainingSet);

        Cloner<Classifier> cloner = new Cloner<>(cModel);