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");
+// }
+
+}