SAMOA-75 : Integration of the new features in instances
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/AttributesInformation.java b/samoa-instances/src/main/java/org/apache/samoa/instances/AttributesInformation.java
index 58ece8e..214a716 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/AttributesInformation.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/AttributesInformation.java
@@ -148,5 +148,42 @@
     this.numberAttributes=v.size();	
     this.indexValues=indexValues;
   }
+  
+  public void deleteAttributeAt(Integer position) {
+        if ((position < 0) || (position >= attributes.size())) {
+            throw new IllegalArgumentException("Index out of range");
+        }
+
+        ArrayList<Attribute> newList = new ArrayList<Attribute>(attributes.size() - 1);
+        for (int i = 0 ; i < position; i++) {
+            Attribute att = attributes.get(i);
+            newList.add(att);
+        }
+        for (int i = position + 1; i < attributes.size(); i++) {
+            Attribute newAtt = (Attribute) attributes.get(i);
+            newList.add(newAtt);
+        }
+        attributes = newList;
+    }
+
+    public void insertAttributeAt(Attribute att, int position) {
+
+        if ((position < 0) || (position > attributes.size())) {
+            throw new IllegalArgumentException("Index out of range");
+        }
+
+        ArrayList<Attribute> newList = new ArrayList<Attribute>(attributes.size() + 1);
+        for (int i = 0 ; i < position; i++) {
+            Attribute oldAtt = attributes.get(i);
+            newList.add(oldAtt);
+        }
+        newList.add(att);
+        for (int i = position; i < attributes.size(); i++) {
+            Attribute newAtt = (Attribute) attributes.get(i);
+            newList.add(newAtt);
+        }
+        attributes = newList;
+
+    }
 
 }
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/DenseInstanceData.java b/samoa-instances/src/main/java/org/apache/samoa/instances/DenseInstanceData.java
index 6781e91..862001a 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/DenseInstanceData.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/DenseInstanceData.java
@@ -20,12 +20,13 @@
  * #L%
  */
 
-public class DenseInstanceData implements InstanceData{
+public class DenseInstanceData implements InstanceData {
 
   /**
    * Instantiates a new dense instance data.
    *
-   * @param array the array
+   * @param array
+   *          the array
    */
   public DenseInstanceData(double[] array) {
     this.attributeValues = array;
@@ -34,7 +35,8 @@
   /**
    * Instantiates a new dense instance data.
    *
-   * @param length the length
+   * @param length
+   *          the length
    */
   public DenseInstanceData(int length) {
     this.attributeValues = new double[length];
@@ -63,21 +65,23 @@
   /**
    * Value.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the double
    */
   @Override
   public double value(int indexAttribute) {
-	if (this.attributeValues.length <= indexAttribute)
-      return this.attributeValues[this.attributeValues.length-1];
-    
-	return this.attributeValues[indexAttribute];
+    if (this.attributeValues.length <= indexAttribute)
+      return this.attributeValues[this.attributeValues.length - 1];
+
+    return this.attributeValues[indexAttribute];
   }
 
   /**
    * Checks if is missing.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return true, if is missing
    */
   @Override
@@ -98,7 +102,8 @@
   /**
    * Index.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the int
    */
   @Override
@@ -109,7 +114,8 @@
   /**
    * Value sparse.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the double
    */
   @Override
@@ -120,7 +126,8 @@
   /**
    * Checks if is missing sparse.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return true, if is missing sparse
    */
   @Override
@@ -141,8 +148,10 @@
   /**
    * Sets the value.
    *
-   * @param attributeIndex the attribute index
-   * @param d the d
+   * @param attributeIndex
+   *          the attribute index
+   * @param d
+   *          the d
    */
   @Override
   public void setValue(int attributeIndex, double d) {
@@ -163,6 +172,22 @@
   }
 
   @Override
+  public void insertAttributeAt(int index) {
+    if ((index < 0) || (index > numAttributes())) {
+      throw new IllegalArgumentException("Can't insert attribute: index out "
+          + "of range");
+    }
+    double[] newValues = new double[attributeValues.length + 1];
+
+    System.arraycopy(attributeValues, 0, newValues, 0, index);
+    newValues[index] = Double.NaN; //Missing Value
+    System.arraycopy(attributeValues, index, newValues, index + 1,
+        attributeValues.length - index);
+    attributeValues = newValues;
+
+  }
+
+  @Override
   public InstanceData copy() {
     return new DenseInstanceData(this.attributeValues);
   }
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceData.java b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceData.java
index b735ea5..a5a5658 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceData.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceData.java
@@ -34,7 +34,8 @@
   /**
    * Value.
    *
-   * @param instAttIndex the inst att index
+   * @param instAttIndex
+   *          the inst att index
    * @return the double
    */
   public double value(int instAttIndex);
@@ -42,7 +43,8 @@
   /**
    * Checks if is missing.
    *
-   * @param instAttIndex the inst att index
+   * @param instAttIndex
+   *          the inst att index
    * @return true, if is missing
    */
   public boolean isMissing(int instAttIndex);
@@ -57,7 +59,8 @@
   /**
    * Index.
    *
-   * @param i the i
+   * @param i
+   *          the i
    * @return the int
    */
   public int index(int i);
@@ -65,7 +68,8 @@
   /**
    * Value sparse.
    *
-   * @param i the i
+   * @param i
+   *          the i
    * @return the double
    */
   public double valueSparse(int i);
@@ -73,7 +77,8 @@
   /**
    * Checks if is missing sparse.
    *
-   * @param p1 the p1
+   * @param p1
+   *          the p1
    * @return true, if is missing sparse
    */
   public boolean isMissingSparse(int p1);
@@ -88,21 +93,31 @@
   /**
    * Sets the value.
    *
-   * @param m_numAttributes the m_num attributes
-   * @param d the d
+   * @param m_numAttributes
+   *          the m_num attributes
+   * @param d
+   *          the d
    */
   public void setValue(int m_numAttributes, double d);
 
-
   /**
    * Deletes an attribute.
    *
-   * @param index the indes
+   * @param index
+   *          the indes
    */
   public void deleteAttributeAt(int index);
 
   /**
-   * Produces a shallow copy of this instance data. 
+   * Inserts an attribute.
+   *
+   * @param index
+   *          the indes
+   */
+  public void insertAttributeAt(int index);
+
+  /**
+   * Produces a shallow copy of this instance data.
    * 
    * @return the shallow copy
    */
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceImpl.java b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceImpl.java
index ff77dc2..e81c8a5 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceImpl.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceImpl.java
@@ -42,7 +42,8 @@
   /**
    * Instantiates a new instance.
    *
-   * @param inst the inst
+   * @param inst
+   *          the inst
    */
   public InstanceImpl(InstanceImpl inst) {
     this.weight = inst.weight;
@@ -54,8 +55,10 @@
   /**
    * Instantiates a new instance.
    *
-   * @param weight the weight
-   * @param res the res
+   * @param weight
+   *          the weight
+   * @param res
+   *          the res
    */
   public InstanceImpl(double weight, double[] res) {
     this.weight = weight;
@@ -66,10 +69,14 @@
   /**
    * Instantiates a new instance.
    *
-   * @param weight the weight
-   * @param attributeValues the attribute values
-   * @param indexValues the index values
-   * @param numberAttributes the number attributes
+   * @param weight
+   *          the weight
+   * @param attributeValues
+   *          the attribute values
+   * @param indexValues
+   *          the index values
+   * @param numberAttributes
+   *          the number attributes
    */
   public InstanceImpl(double weight, double[] attributeValues, int[] indexValues, int numberAttributes) {
     this.weight = weight;
@@ -79,8 +86,10 @@
   /**
    * Instantiates a new instance.
    *
-   * @param weight the weight
-   * @param instanceData the instance data
+   * @param weight
+   *          the weight
+   * @param instanceData
+   *          the instance data
    */
   public InstanceImpl(double weight, InstanceData instanceData) {
     this.weight = weight;
@@ -90,7 +99,8 @@
   /**
    * Instantiates a new instance.
    *
-   * @param numAttributes the num attributes
+   * @param numAttributes
+   *          the num attributes
    */
   public InstanceImpl(int numAttributes) {
     this.instanceData = new DenseInstanceData(new double[numAttributes]); //JD
@@ -110,7 +120,8 @@
   /**
    * Sets the weight.
    *
-   * @param weight the new weight
+   * @param weight
+   *          the new weight
    */
   @Override
   public void setWeight(double weight) {
@@ -120,7 +131,8 @@
   /**
    * Attribute.
    *
-   * @param instAttIndex the inst att index
+   * @param instAttIndex
+   *          the inst att index
    * @return the attribute
    */
   @Override
@@ -128,14 +140,15 @@
     return this.instanceHeader.attribute(instAttIndex);
   }
 
-  public int indexOfAttribute(Attribute attribute){
+  public int indexOfAttribute(Attribute attribute) {
     return this.instanceHeader.indexOf(attribute);
   }
 
   /**
    * Delete attribute at.
    *
-   * @param i the i
+   * @param i
+   *          the i
    */
   @Override
   public void deleteAttributeAt(int i) {
@@ -145,11 +158,12 @@
   /**
    * Insert attribute at.
    *
-   * @param i the i
+   * @param i
+   *          the i
    */
   @Override
   public void insertAttributeAt(int i) {
-    throw new UnsupportedOperationException("Not yet implemented");
+    this.instanceData.insertAttributeAt(i);
   }
 
   /**
@@ -165,7 +179,8 @@
   /**
    * Value.
    *
-   * @param instAttIndex the inst att index
+   * @param instAttIndex
+   *          the inst att index
    * @return the double
    */
   @Override
@@ -176,7 +191,8 @@
   /**
    * Checks if is missing.
    *
-   * @param instAttIndex the inst att index
+   * @param instAttIndex
+   *          the inst att index
    * @return true, if is missing
    */
   @Override
@@ -197,7 +213,8 @@
   /**
    * Index.
    *
-   * @param i the i
+   * @param i
+   *          the i
    * @return the int
    */
   @Override
@@ -208,7 +225,8 @@
   /**
    * Value sparse.
    *
-   * @param i the i
+   * @param i
+   *          the i
    * @return the double
    */
   @Override
@@ -219,7 +237,8 @@
   /**
    * Checks if is missing sparse.
    *
-   * @param p the p
+   * @param p
+   *          the p
    * @return true, if is missing sparse
    */
   @Override
@@ -230,7 +249,8 @@
   /**
    * String value.
    *
-   * @param i the i
+   * @param i
+   *          the i
    * @return the string
    */
   @Override
@@ -251,8 +271,10 @@
   /**
    * Sets the value.
    *
-   * @param numAttribute the num attribute
-   * @param d the d
+   * @param numAttribute
+   *          the num attribute
+   * @param d
+   *          the d
    */
   @Override
   public void setValue(int numAttribute, double d) {
@@ -279,11 +301,11 @@
     int classIndex = instanceHeader.classIndex();
     //return classIndex != Integer.MAX_VALUE ? classIndex : 0;
     // return  ? classIndex : 0;
-    if(classIndex == Integer.MAX_VALUE)
-      if(this.instanceHeader.instanceInformation.range!=null)
-        classIndex=instanceHeader.instanceInformation.range.getStart();
+    if (classIndex == Integer.MAX_VALUE)
+      if (this.instanceHeader.instanceInformation.range != null)
+        classIndex = instanceHeader.instanceInformation.range.getStart();
       else
-        classIndex=0;
+        classIndex = 0;
     return classIndex;
   }
 
@@ -320,7 +342,8 @@
   /**
    * Sets the class value.
    *
-   * @param d the new class value
+   * @param d
+   *          the new class value
    */
   @Override
   public void setClassValue(double d) {
@@ -351,7 +374,8 @@
   /**
    * Sets the dataset.
    *
-   * @param dataset the new dataset
+   * @param dataset
+   *          the new dataset
    */
   @Override
   public void setDataset(Instances dataset) {
@@ -361,9 +385,12 @@
   /**
    * Adds the sparse values.
    *
-   * @param indexValues the index values
-   * @param attributeValues the attribute values
-   * @param numberAttributes the number attributes
+   * @param indexValues
+   *          the index values
+   * @param attributeValues
+   *          the attribute values
+   * @param numberAttributes
+   *          the number attributes
    */
   @Override
   public void addSparseValues(int[] indexValues, double[] attributeValues, int numberAttributes) {
@@ -454,7 +481,8 @@
   /**
    * Value.
    *
-   * @param attribute the attribute
+   * @param attribute
+   *          the attribute
    * @return the double
    */
   @Override
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceInformation.java b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceInformation.java
index cfd7f51..9d39791 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceInformation.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/InstanceInformation.java
@@ -53,7 +53,8 @@
   /**
    * Instantiates a new instance information.
    *
-   * @param chunk the chunk
+   * @param chunk
+   *          the chunk
    */
   public InstanceInformation(InstanceInformation chunk) {
     this.relationName = chunk.relationName;
@@ -64,8 +65,10 @@
   /**
    * Instantiates a new instance information.
    *
-   * @param st the st
-   * @param v the v
+   * @param st
+   *          the st
+   * @param input
+   *          the input
    */
   public InstanceInformation(String st, List<Attribute> input) {
     this.relationName = st;
@@ -141,29 +144,29 @@
    * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#deleteAttributeAt(java.lang.Integer)
    */
   public void deleteAttributeAt(Integer integer) {
-    throw new UnsupportedOperationException("Not yet implemented");
+    this.attributesInformation.deleteAttributeAt(integer);
   }
 
   /* (non-Javadoc)
    * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#insertAttributeAt(com.yahoo.labs.samoa.instances.Attribute, int)
    */
   public void insertAttributeAt(Attribute attribute, int i) {
-    throw new UnsupportedOperationException("Not yet implemented");
+    this.attributesInformation.insertAttributeAt(attribute, i);
   }
 
   public void setAttributes(List<Attribute> v) {
-    if(this.attributesInformation==null)
-      this.attributesInformation= new AttributesInformation();
+    if (this.attributesInformation == null)
+      this.attributesInformation = new AttributesInformation();
     this.attributesInformation.setAttributes(v);
   }
 
   public int inputAttributeIndex(int index) {
     int ret = 0;
     if (classIndex == Integer.MAX_VALUE) {//Multi Label
-      if(index<range.getStart())//JD
-        ret= index;
-      else 
-        ret= index+range.getSelectionLength();
+      if (index < range.getStart())//JD
+        ret = index;
+      else
+        ret = index + range.getSelectionLength();
 
     } else { //Single Label
       ret = classIndex() > index ? index : index + 1;
@@ -174,7 +177,7 @@
   public int outputAttributeIndex(int attributeIndex) {
     int ret = 0;
     if (classIndex == Integer.MAX_VALUE) {//Multi Label
-      ret=attributeIndex+range.getStart(); //JD - Range should be a "block"
+      ret = attributeIndex + range.getStart(); //JD - Range should be a "block"
     } else { //Single Label
       ret = classIndex;
     }
@@ -184,7 +187,7 @@
   public int numInputAttributes() {
     int ret = 0;
     if (classIndex == Integer.MAX_VALUE) {//Multi Label
-      ret=this.numAttributes()-range.getSelectionLength(); //JD
+      ret = this.numAttributes() - range.getSelectionLength(); //JD
     } else { //Single Label
       ret = this.numAttributes() - 1;
     }
@@ -194,7 +197,7 @@
   public int numOutputAttributes() {
     int ret = 0;
     if (classIndex == Integer.MAX_VALUE) {//Multi Label
-      ret=range.getSelectionLength(); //JD
+      ret = range.getSelectionLength(); //JD
     } else { //Single Label
       ret = 1;
     }
@@ -207,9 +210,9 @@
   }
 
   public void setAttributes(List<Attribute> v, List<Integer> indexValues) {
-    if(this.attributesInformation==null)
-      this.attributesInformation= new AttributesInformation();
-    this.attributesInformation.setAttributes(v,indexValues);
+    if (this.attributesInformation == null)
+      this.attributesInformation = new AttributesInformation();
+    this.attributesInformation.setAttributes(v, indexValues);
 
   }
 
diff --git a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
index 77b634b..940271a 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
@@ -25,9 +25,12 @@
   /**
    * Instantiates a new sparse instance data.
    *
-   * @param attributeValues the attribute values
-   * @param indexValues the index values
-   * @param numberAttributes the number attributes
+   * @param attributeValues
+   *          the attribute values
+   * @param indexValues
+   *          the index values
+   * @param numberAttributes
+   *          the number attributes
    */
   public SparseInstanceData(double[] attributeValues, int[] indexValues, int numberAttributes) {
     this.attributeValues = attributeValues;
@@ -38,7 +41,8 @@
   /**
    * Instantiates a new sparse instance data.
    *
-   * @param length the length
+   * @param length
+   *          the length
    */
   public SparseInstanceData(int length) {
     this.attributeValues = new double[length];
@@ -62,7 +66,8 @@
   /**
    * Sets the attribute values.
    *
-   * @param attributeValues the new attribute values
+   * @param attributeValues
+   *          the new attribute values
    */
   public void setAttributeValues(double[] attributeValues) {
     this.attributeValues = attributeValues;
@@ -80,7 +85,8 @@
   /**
    * Sets the index values.
    *
-   * @param indexValues the new index values
+   * @param indexValues
+   *          the new index values
    */
   public void setIndexValues(int[] indexValues) {
     this.indexValues = indexValues;
@@ -98,7 +104,8 @@
   /**
    * Sets the number of attributes.
    *
-   * @param numberAttributes the new number attributes
+   * @param numberAttributes
+   *          the new number attributes
    */
   public void setNumberAttributes(int numberAttributes) {
     this.numberAttributes = numberAttributes;
@@ -127,7 +134,8 @@
   /**
    * Value.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the double
    */
   @Override
@@ -145,7 +153,8 @@
   /**
    * Checks if is missing.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return true, if is missing
    */
   @Override
@@ -166,7 +175,8 @@
   /**
    * Index.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the int
    */
   @Override
@@ -177,7 +187,8 @@
   /**
    * Value sparse.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return the double
    */
   @Override
@@ -188,7 +199,8 @@
   /**
    * Checks if is missing sparse.
    *
-   * @param indexAttribute the index attribute
+   * @param indexAttribute
+   *          the index attribute
    * @return true, if is missing sparse
    */
   @Override
@@ -213,8 +225,10 @@
   /**
    * Sets the value.
    *
-   * @param attributeIndex the attribute index
-   * @param d the d
+   * @param attributeIndex
+   *          the attribute index
+   * @param d
+   *          the d
    */
   @Override
   public void setValue(int attributeIndex, double d) {
@@ -229,8 +243,7 @@
   /**
    * Locates the greatest index that is not greater than the given index.
    *
-   * @return the internal index of the attribute index. Returns -1 if no index
-   * with this property could be found
+   * @return the internal index of the attribute index. Returns -1 if no index with this property could be found
    */
   public int locateIndex(int index) {
 
@@ -262,7 +275,8 @@
   /**
    * Deletes an attribute at the given position (0 to numAttributes() - 1).
    * 
-   * @param pos the attribute's position
+   * @param position
+   *          the attribute's position
    */
   @Override
   public void deleteAttributeAt(int position) {
@@ -296,9 +310,46 @@
   }
 
   @Override
-  public InstanceData copy() {
-    return new SparseInstanceData(this.attributeValues,this.indexValues,this.numberAttributes);
+  public void insertAttributeAt(int position) {
+    if ((position < 0) || (position > numAttributes())) {
+      throw new IllegalArgumentException("Can't insert attribute: index out "
+          + "of range");
+    }
+    int index = locateIndex(position);
+
+    this.numberAttributes++;
+    if ((index >= 0) && (indexValues[index] == position)) {
+      int[] tempIndices = new int[indexValues.length + 1];
+      double[] tempValues = new double[attributeValues.length + 1];
+      System.arraycopy(indexValues, 0, tempIndices, 0, index);
+      System.arraycopy(attributeValues, 0, tempValues, 0, index);
+      tempIndices[index] = position;
+      tempValues[index] = Double.NaN; //Missing Value
+      for (int i = index; i < indexValues.length; i++) {
+        tempIndices[i + 1] = indexValues[i] + 1;
+        tempValues[i + 1] = attributeValues[i];
+      }
+      indexValues = tempIndices;
+      attributeValues = tempValues;
+    } else {
+      int[] tempIndices = new int[indexValues.length + 1];
+      double[] tempValues = new double[attributeValues.length + 1];
+      System.arraycopy(indexValues, 0, tempIndices, 0, index + 1);
+      System.arraycopy(attributeValues, 0, tempValues, 0, index + 1);
+      tempIndices[index + 1] = position;
+      tempValues[index + 1] = Double.NaN; //Missing Value
+      for (int i = index + 1; i < indexValues.length; i++) {
+        tempIndices[i + 1] = indexValues[i] + 1;
+        tempValues[i + 1] = attributeValues[i];
+      }
+      indexValues = tempIndices;
+      attributeValues = tempValues;
+    }
   }
 
+  @Override
+  public InstanceData copy() {
+    return new SparseInstanceData(this.attributeValues, this.indexValues, this.numberAttributes);
+  }
 
 }