public static <T extends Output<T>> SparseVector createSparseVector(Example<T> example, ImmutableFeatureMap featureInfo, boolean addBias) {
        int size;
        int numFeatures = example.size();
        if (addBias) {
            size = featureInfo.size() + 1;
            numFeatures++;
        } else {
            size = featureInfo.size();
        }
        int[] tmpIndices = new int[numFeatures];
        double[] tmpValues = new double[numFeatures];
        int i = 0;
        int prevIdx = -1;
        for (Feature f : example) {
            int index = featureInfo.getID(f.getName());
            if (index > prevIdx){
                prevIdx = index;
                tmpIndices[i] = index;
                tmpValues[i] = f.getValue();
                if (Double.isNaN(tmpValues[i])) {
                    throw new IllegalArgumentException("Example contained a NaN feature, " + f.toString());
                }
                i++;
            } else if (index > -1) {
                //
                // Collision, deal with it.
                int collisionIdx = Arrays.binarySearch(tmpIndices,0,i,index);
                if (collisionIdx < 0) {
                    //
                    // Collision but not present in tmpIndices
                    // move data and bump i
                    collisionIdx = - (collisionIdx + 1);
                    System.arraycopy(tmpIndices,collisionIdx,tmpIndices,collisionIdx+1,i-collisionIdx);
                    System.arraycopy(tmpValues,collisionIdx,tmpValues,collisionIdx+1,i-collisionIdx);
                    tmpIndices[collisionIdx] = index;
                    tmpValues[collisionIdx] = f.getValue();
                    if (Double.isNaN(tmpValues[collisionIdx])) {
                        throw new IllegalArgumentException("Example contained a NaN feature, " + f.toString());
                    }
                    i++;
                } else {
                    //
                    // Collision present in tmpIndices
                    // add the values.
                    tmpValues[collisionIdx] += f.getValue();
                    if (Double.isNaN(tmpValues[collisionIdx])) {
                        throw new IllegalArgumentException("Example contained a NaN feature, " + f.toString());
                    }
                }
            }
        }
        if (addBias) {
            tmpIndices[i] = size - 1;
            tmpValues[i] = 1.0;
            i++;
        }
        return new SparseVector(size,Arrays.copyOf(tmpIndices,i),Arrays.copyOf(tmpValues,i));
    }
@Test
    public void duplicateFeatureIDs() throws Exception {
        ImmutableFeatureMap fmap = new TestMap();

        Example<MockOutput> collision = generateExample(new String[]{"FOO","BAR","BAZ","QUUX"},new double[]{1.0,2.2,3.3,4.4});
        SparseVector testCollisionVec = SparseVector.createSparseVector(3,new int[]{0,1,2},new double[]{4.3,2.2,4.4});
        SparseVector collisionVec = SparseVector.createSparseVector(collision,fmap,false);
        assertEquals(testCollisionVec,collisionVec);

        Example<MockOutput> fakecollision = generateExample(new String[]{"BAR","BAZ","QUUX"},new double[]{2.2,3.3,4.4});
        SparseVector testFakeCollisionVec = SparseVector.createSparseVector(3,new int[]{0,1,2},new double[]{3.3,2.2,4.4});
        SparseVector fakeCollisionVec = SparseVector.createSparseVector(fakecollision,fmap,false);
        assertEquals(testFakeCollisionVec,fakeCollisionVec);
    }