Author: schor
Date: Mon Nov  3 22:21:40 2014
New Revision: 1636461

URL: http://svn.apache.org/r1636461
Log:
[UIMA-4059][UIMA-3399] support checking for invalid feature modification, under 
control of external JVM property.

Added:
    
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/FSBagIndexTest.java
Modified:
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
    
uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java?rev=1636461&r1=1636460&r2=1636461&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
 Mon Nov  3 22:21:40 2014
@@ -203,6 +203,9 @@ public class CASRuntimeException extends
    */
   public static final String DEREF_FS_OTHER_CAS = "DEREF_FS_OTHER_CAS";
   
+  /** While FS was in the index, illegal attempt to modify Feature "{0}" which 
is used as a key in one or more indices; FS = "{1}" */
+  public static final String ILLEGAL_FEAT_SET = "ILLEGAL_FEAT_SET";
+
   
        public CASRuntimeException() {
                super();

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=1636461&r1=1636460&r2=1636461&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java 
(original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java 
Mon Nov  3 22:21:40 2014
@@ -82,6 +82,7 @@ import org.apache.uima.cas.text.Annotati
 import org.apache.uima.cas.text.AnnotationIndex;
 import org.apache.uima.cas.text.Language;
 import org.apache.uima.internal.util.IntVector;
+import org.apache.uima.internal.util.PositiveIntSet_impl;
 import org.apache.uima.jcas.JCas;
 import org.apache.uima.jcas.impl.JCasImpl;
 import org.apache.uima.resource.ResourceInitializationException;
@@ -245,6 +246,16 @@ public class CASImpl extends AbstractCas
      */
     private List<MarkerImpl> trackingMarkList;
     
+    private int cache_not_in_index = 0; // a one item cache of a FS not in the 
index
+    
+    private final PositiveIntSet_impl featureCodesInIndexKeys = 
+        FSIndexRepositoryImpl.isTrackingFsIndexed ? 
+          new PositiveIntSet_impl() : null; 
+        
+    private final PositiveIntSet_impl fssIndexed =
+        FSIndexRepositoryImpl.isTrackingFsIndexed ? 
+          new PositiveIntSet_impl() : null;
+          
     private SharedViewData(boolean useFSCache) {
       this.useFSCache = useFSCache;
     }
@@ -256,6 +267,11 @@ public class CASImpl extends AbstractCas
 
   // package protected to let other things share this info
   final SharedViewData svd; // shared view data
+  
+  void featureCodesInIndexKeysAdd(int featCode) {
+    svd.featureCodesInIndexKeys.add(featCode);
+  }
+  
 
   // The index repository. Referenced by XmiCasSerializer
   FSIndexRepositoryImpl indexRepository;
@@ -1916,8 +1932,7 @@ public class CASImpl extends AbstractCas
   }
 
   public String getStringValue(int addr, int feat) {
-    return this.getStringHeap().getStringForCode(
-        this.getHeap().heap[addr + this.svd.casMetadata.featureOffset[feat]]);
+    return ll_getStringValue(addr, feat);
   }
 
   public float getFloatValue(int addr, int feat) {
@@ -3161,8 +3176,35 @@ public class CASImpl extends AbstractCas
     }
     return ll_getIntValue(fsRef, featureCode);
   }
+  
+  /**
+   * Throw an exception if a modification is made to a feature of some FS 
where:
+   *   - the feature is being used as a key in one or more indexes, and 
+   *   - the FS is known to already have been added to the indexes
+   * @param fsRef - the FS to test if it is in the indexes
+   * @param featureCode - the feature being tested
+   */
+  private void checkForInvalidFeatureSetting(int fsRef, int featureCode) {
+    if ((null == svd.featureCodesInIndexKeys) || 
+        (svd.cache_not_in_index == fsRef)) {
+      return;
+    }
+    if (svd.featureCodesInIndexKeys.contains(featureCode)) {
+      if (this.svd.fssIndexed.contains(fsRef)) {
+        // signal error - modifying a feature which is used in some index as a 
key
+        CASRuntimeException e = new 
CASRuntimeException(CASRuntimeException.ILLEGAL_FEAT_SET,
+            new String[] { 
+              
this.getTypeSystemImpl().ll_getFeatureForCode(featureCode).getName(),
+              new FeatureStructureImplC(this, fsRef).toString()});
+           throw e; 
+      } else {
+        svd.cache_not_in_index = fsRef;
+      }
+    }
+  }
 
   public final void ll_setIntValue(int fsRef, int featureCode, int value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = value;
     if (this.svd.trackingMark != null) {
        this.logFSUpdate(fsRef, fsRef +  
this.svd.casMetadata.featureOffset[featureCode],
@@ -3171,6 +3213,7 @@ public class CASImpl extends AbstractCas
   }
 
   public final void ll_setFloatValue(int fsRef, int featureCode, float value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = float2int(value);
     if (this.svd.trackingMark != null) {
        this.logFSUpdate(fsRef, fsRef +  
this.svd.casMetadata.featureOffset[featureCode],
@@ -3179,6 +3222,7 @@ public class CASImpl extends AbstractCas
   }
 
   public final void ll_setStringValue(int fsRef, int featureCode, String 
value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     if (null != value) {
       final TypeSystemImpl ts = this.svd.casMetadata.ts;
       String[] stringSet = ts.ll_getStringSet(ts.ll_getRangeType(featureCode));
@@ -3202,6 +3246,7 @@ public class CASImpl extends AbstractCas
   }
 
   public final void ll_setRefValue(int fsRef, int featureCode, int value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = value;
     if (this.svd.trackingMark != null) {
        this.logFSUpdate(fsRef, fsRef +  
this.svd.casMetadata.featureOffset[featureCode],
@@ -3240,6 +3285,7 @@ public class CASImpl extends AbstractCas
 
   public final void ll_setCharBufferValue(int fsRef, int featureCode, char[] 
buffer, int start,
       int length) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     final int stringCode = this.getStringHeap().addCharBuffer(buffer, start, 
length);
     ll_setIntValue(fsRef, featureCode, stringCode);
   }
@@ -3676,6 +3722,7 @@ public class CASImpl extends AbstractCas
   }
 
   public void ll_setBooleanValue(int fsRef, int featureCode, boolean value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = value ? CASImpl.TRUE
         : CASImpl.FALSE;
     if (this.svd.trackingMark != null) {
@@ -3691,6 +3738,7 @@ public class CASImpl extends AbstractCas
   }
 
   public final void ll_setByteValue(int fsRef, int featureCode, byte value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = value;
     if (this.svd.trackingMark != null) {
       this.logFSUpdate(fsRef, fsRef + 
this.svd.casMetadata.featureOffset[featureCode], ModifiedHeap.FSHEAP, 1);
@@ -3705,6 +3753,7 @@ public class CASImpl extends AbstractCas
   }
 
   public final void ll_setShortValue(int fsRef, int featureCode, short value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     this.getHeap().heap[fsRef + 
this.svd.casMetadata.featureOffset[featureCode]] = value;
     if (this.svd.trackingMark != null) {
       this.logFSUpdate(fsRef, fsRef + 
this.svd.casMetadata.featureOffset[featureCode], ModifiedHeap.FSHEAP, 1);
@@ -3719,6 +3768,7 @@ public class CASImpl extends AbstractCas
   }
 
   public void ll_setLongValue(int fsRef, int featureCode, long value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     final int offset = this.getLongHeap().addLong(value);
     setFeatureValue(fsRef, featureCode, offset);
   }
@@ -3731,6 +3781,7 @@ public class CASImpl extends AbstractCas
   }
 
   public void ll_setDoubleValue(int fsRef, int featureCode, double value) {
+    checkForInvalidFeatureSetting(fsRef, featureCode);
     long val = Double.doubleToLongBits(value);
     final int offset = this.getLongHeap().addLong(val);
     setFeatureValue(fsRef, featureCode, offset);

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java?rev=1636461&r1=1636460&r2=1636461&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
 Mon Nov  3 22:21:40 2014
@@ -47,7 +47,7 @@ import org.apache.uima.internal.util.Int
 import org.apache.uima.internal.util.IntPointerIterator;
 import org.apache.uima.internal.util.IntSet;
 import org.apache.uima.internal.util.IntVector;
-import org.apache.uima.internal.util.PositiveIntSet;
+import org.apache.uima.internal.util.PositiveIntSet_impl;
 
 public class FSIndexRepositoryImpl implements FSIndexRepositoryMgr, 
LowLevelIndexRepository {
 
@@ -57,9 +57,18 @@ public class FSIndexRepositoryImpl imple
   public static final int DEFAULT_INDEX_SIZE = 100;
 
   /**
-   * 
+   * Define this JVM property to some value other than "false" to enable 
tracking which FSs are in an index,
+   * <ul>
+   *   <li>to prevent the identical FS from being added multiple times to 
indexes in the same View, and</li>
+   *   <li>to allow checking on feature value setting to signal a runtime 
exception if a feature is changed which is
+   *     being used as a key, and that FS is added to indices in some 
View.</li>
+   *   <li>The following are the same:  -Duima.track_fs_indexed    and 
-Duima.track_fs_indexed=true</li>
+   * </ul> 
    */
   public static final String TRACK_FS_INDEXED = "uima.track_fs_indexed";
+  
+  public static final boolean isTrackingFsIndexed =  
!System.getProperty(TRACK_FS_INDEXED, "false").equals("false");
+  
   // Implementation note: the use of equals() here is pretty hairy and
   // should probably be fixed. We rely on the fact that when two
   // FSIndexComparators are compared, the type of the comparators is
@@ -998,7 +1007,7 @@ public class FSIndexRepositoryImpl imple
     // A reference to the type system.
     private final TypeSystemImpl typeSystem;
     
-    private int cache_not_in_index; // a one item cache of a FS not in the 
index
+    private boolean isSetUpFromBaseCAS = false;
     
     SharedIndexInfo(TypeSystemImpl typeSystem) {
       this.typeSystem = typeSystem;
@@ -1006,6 +1015,7 @@ public class FSIndexRepositoryImpl imple
   }
   
   /*****  I N S T A N C E   V A R I A B L E S  *****/
+  /*****           Replicated per view         *****/                 
 
   // A reference to the CAS.
   private final CASImpl cas;
@@ -1048,16 +1058,6 @@ public class FSIndexRepositoryImpl imple
   
   private final SharedIndexInfo sii;
   
-  // the overhead of this (if used) is anywhere from 1 bit up to 3 32-bit 
words per indexed item
-  // if the avg size of a fs on the heap is 8 (32 bit) words, and 
-  //    about 50 - 100 % of FSs are indexed, then the "typical" space used 
should be in the order of
-  //    2 bytes / indexed item, per view
-  // This mechanism is under the control of a Java system defined variable 
uima.track_fs_indexed
-  private final PositiveIntSet fsIndexed =
-      System.getProperty(TRACK_FS_INDEXED, "false").equals("false") ? 
-          null : 
-          new PositiveIntSet(); // set of FSs (addrs) that are in the index 
UIMA-4059
-
   @SuppressWarnings("unused")
   private FSIndexRepositoryImpl() {
     super();
@@ -1067,7 +1067,7 @@ public class FSIndexRepositoryImpl imple
 
   /**
    * Constructor.
-   * Assumption: called with the base CAS view
+   * Assumption: called first before next constructor call, with the base CAS 
view
    * 
    * @param cas
    */
@@ -1095,6 +1095,7 @@ public class FSIndexRepositoryImpl imple
     super();
     this.cas = cas;
     this.sii = baseIndexRepo.sii;
+    sii.isSetUpFromBaseCAS = true;  // bypasses initialization already done
     this.name2indexMap = new HashMap<String, IndexIteratorCachePair>();
     this.indexUpdates = new IntVector();
     this.indexUpdateOperation = new BitSet();
@@ -1179,7 +1180,7 @@ public class FSIndexRepositoryImpl imple
   /**
    * This is where the actual index gets created.
    */
-  private IndexIteratorCachePair addNewIndex(FSIndexComparator comparator, int 
initialSize,
+  private IndexIteratorCachePair addNewIndex(final FSIndexComparator 
comparator, int initialSize,
       int indexType) {
     final Type type = comparator.getType();
     final int typeCode = ((TypeImpl) type).getCode();
@@ -1214,6 +1215,7 @@ public class FSIndexRepositoryImpl imple
     // ind = new FSRBTIndex(this.cas, type);
     // ind = new FSVectorIndex(this.cas, initialSize);
     ind.init(comparator);
+    
     final IndexIteratorCachePair iicp = new IndexIteratorCachePair();
     iicp.index = ind;
     indexVector.add(iicp);
@@ -1362,12 +1364,24 @@ public class FSIndexRepositoryImpl imple
    * @param indexType
    * @return boolean
    */
-  public boolean createIndexNoQuestionsAsked(FSIndexComparator comp, String 
label, int indexType) {
+  public boolean createIndexNoQuestionsAsked(final FSIndexComparator comp, 
String label, int indexType) {
     IndexIteratorCachePair cp = this.name2indexMap.get(label);
     // Now check if the index already exists.
     if (cp == null) {
       // The name is new.
       cp = this.addNewIndexRecursive(comp, indexType);
+      
+      // create a set of feature codes that are in one or more index 
definitions
+      if (isTrackingFsIndexed && !sii.isSetUpFromBaseCAS) {
+        final int nKeys = comp.getNumberOfKeys();
+        for (int i = 0; i < nKeys; i++) {
+          if (comp.getKeyType(i) == FSIndexComparator.FEATURE_KEY) {
+            final int featCode = 
((FeatureImpl)comp.getKeyFeature(i)).getCode();
+            cas.featureCodesInIndexKeysAdd(featCode);
+          }
+        }
+      }
+      
       this.name2indexMap.put(label, cp);
       return true;
     }
@@ -1855,7 +1869,7 @@ public class FSIndexRepositoryImpl imple
       getAllIndexedFS((Type) subtypes.get(i), iteratorList);
     }
   }
-
+  
   private void logIndexOperation(int fsRef, boolean added) {
     this.indexUpdates.add(fsRef);
     if (added) {
@@ -1892,7 +1906,7 @@ public class FSIndexRepositoryImpl imple
       if (added) {
         final int indexOfDeletedItem = this.fsDeletedFromIndex.indexOf(fsRef);
         if (indexOfDeletedItem >= 0) {
-          this.fsDeletedFromIndex.remove(indexOfDeletedItem);
+          this.fsDeletedFromIndex.removeElementAt(indexOfDeletedItem);
           this.fsReindexed.add(fsRef);
         } else if (this.fsReindexed.contains(fsRef)) {
           continue;  // skip adding this to anything
@@ -1902,11 +1916,11 @@ public class FSIndexRepositoryImpl imple
       } else {
         final int indexOfaddedItem = this.fsAddedToIndex.indexOf(fsRef);
         if (indexOfaddedItem >= 0) {
-          this.fsAddedToIndex.remove(indexOfaddedItem);
+          this.fsAddedToIndex.removeElementAt(indexOfaddedItem);
         } else {
           final int indexOfReindexedItem = this.fsReindexed.indexOf(fsRef);
           if (indexOfReindexedItem >= 0) {
-            this.fsReindexed.remove(indexOfReindexedItem);
+            this.fsReindexed.removeElementAt(indexOfReindexedItem);
             this.fsDeletedFromIndex.add(fsRef);
           }
           else {

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties?rev=1636461&r1=1636460&r2=1636461&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
 Mon Nov  3 22:21:40 2014
@@ -563,4 +563,5 @@ INVALID_MARKER = Marker is invalid.
 MULTIPLE_CREATE_MARKER = CreateMarker called multiple times for one CAS.  This 
implementation only supports one call.
 DESERIALIZING_BINARY_INVALID_HEADER = While deserializing binary CAS, found 
invalid header.
 DESERIALIZING_COMPRESSED_BINARY_UNSUPPORTED = Using the reinit method to 
deserialize a binary CAS serialized with compressed serialization not supported 
for this case.
-DEREF_FS_OTHER_CAS = Dereferencing a FeatureStructure of a CAS in a different 
CAS's context. This can happen if you try to set a feature structure reference 
to a value of a feature structure belonging to an entirely different CAS. FS = 
"{0}", CAS = "{1}".
\ No newline at end of file
+DEREF_FS_OTHER_CAS = Dereferencing a FeatureStructure of a CAS in a different 
CAS's context. This can happen if you try to set a feature structure reference 
to a value of a feature structure belonging to an entirely different CAS. FS = 
"{0}", CAS = "{1}".
+ILLEGAL_FEAT_SET = While a FeatureStructure was in the index, an illegal 
attempt was made to modify Feature "{0}" which is used as a key in one or more 
indices; the Feature Structure being modified was "{1}".
\ No newline at end of file

Added: 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/FSBagIndexTest.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/FSBagIndexTest.java?rev=1636461&view=auto
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/FSBagIndexTest.java
 (added)
+++ 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/FSBagIndexTest.java
 Mon Nov  3 22:21:40 2014
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.io.File;
+import java.util.Arrays;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.FSIndex;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.impl.UIMAFramework_impl;
+import org.apache.uima.internal.util.IntPointerIterator;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.resource.metadata.impl.TypePriorities_impl;
+import org.apache.uima.test.junit_extension.JUnitExtension;
+import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.XMLInputSource;
+
+import junit.framework.TestCase;
+
+public class FSBagIndexTest extends TestCase {
+
+  private TypeSystemDescription typeSystemDescription;
+  
+  private TypeSystem ts;
+
+  private FsIndexDescription[] indexes;
+  
+  private CASImpl cas;
+
+  File typeSystemFile1 = 
JUnitExtension.getFile("ExampleCas/testTypeSystem.xml");
+  File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml");
+
+  
+  FSBagIndex bi;
+  
+  
+  protected void setUp() throws Exception {
+    typeSystemDescription  = 
UIMAFramework.getXMLParser().parseTypeSystemDescription(
+        new XMLInputSource(typeSystemFile1));
+    indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new 
XMLInputSource(indexesFile))
+        .getFsIndexes();
+    cas = (CASImpl) CasCreationUtils.createCas(typeSystemDescription, new 
TypePriorities_impl(), indexes);
+    ts = cas.getTypeSystem();
+    
+    bi = cbi();
+  }
+  
+  private FSBagIndex cbi() {
+    return new FSBagIndex(cas, ts.getType("uima.cas.TOP"), 16, 
FSIndex.BAG_INDEX);
+  }
+
+  protected void tearDown() throws Exception {
+    super.tearDown();
+  }
+
+  public void testInsert() {
+    // starts out as bit set;
+    int[] ns = new int[] {1,15, 33};
+    tc(ns);
+        
+    bi = cbi();
+    ns = new int[] {1, 100000, 15, 4};
+    tc(ns, 1);
+   
+    bi = cbi();
+    ns = new int[] {1, 100000, 15, 4};
+    tc(ns, 1);
+    
+  }
+  
+  private void tc(int[] ns) {
+    tc(ns, 0);
+  }
+  
+  private void tc(int[] ns, int sortEnd) {
+    bi.flush();
+    for (int n : ns) {
+      bi.insert(n);
+    }
+    
+    if (sortEnd > 0) {
+      Arrays.sort(ns, 0, sortEnd);
+    }
+    
+    IntPointerIterator it = bi.getIntIterator();
+    for (int n : ns) {
+      assertTrue(it.isValid());
+      assertEquals(n, it.get());
+      it.inc();
+    }
+    assertFalse(it.isValid());
+  }
+
+//  public void testRemove() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testPointerIterator() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testGetVector() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testFlush() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testLl_iterator() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testContains() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testFind() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testSize() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testGetIntIterator() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testIterator() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testIteratorFeatureStructure() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testLl_iteratorBoolean() {
+//    fail("Not yet implemented");
+//  }
+//
+//  public void testLl_rootIterator() {
+//    fail("Not yet implemented");
+//  }
+
+}


Reply via email to