You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2016/10/03 19:04:54 UTC

svn commit: r1763195 - in /uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src: main/java/org/apache/uima/cas/ main/java/org/apache/uima/cas/impl/ main/java/org/apache/uima/jcas/impl/ main/resources/org/apache/uima/ test/java/org/apache/uima/cas/test/

Author: schor
Date: Mon Oct  3 19:04:54 2016
New Revision: 1763195

URL: http://svn.apache.org/viewvc?rev=1763195&view=rev
Log:
[UIMA-5115] switch to using FeatureStructure instead of TOP and AnnotationFS instead of Annotation, for backwards compatibility.  Initial impls of select and friends.

Added:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_limited.java
Modified:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CAS.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/FSIndex.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_annotation.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_iicp.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_snapshot.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LowLevelIndex.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/impl/JCasImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CAS.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CAS.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CAS.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CAS.java Mon Oct  3 19:04:54 2016
@@ -1103,19 +1103,19 @@ public interface CAS extends AbstractCas
    */
   void protectIndexes(Runnable runnable);
 
-  default <T extends TOP> SelectFSs<T> select() {
+  default <T extends FeatureStructure> SelectFSs<T> select() {
     return new SelectFSs_impl<>(this);
   }
-  default <T extends TOP> SelectFSs<T> select(Type type) {
+  default <T extends FeatureStructure> SelectFSs<T> select(Type type) {
     return new SelectFSs_impl<>(this).type(type);
   }
-  default <T extends TOP> SelectFSs<T> select(Class<T> clazz) {
+  default <T extends FeatureStructure> SelectFSs<T> select(Class<T> clazz) {
     return new SelectFSs_impl<>(this).type(clazz);
   }
-  default <T extends TOP> SelectFSs<T> select(int jcasType) {
+  default <T extends FeatureStructure> SelectFSs<T> select(int jcasType) {
     return new SelectFSs_impl<>(this).type(jcasType);
   }
-  default <T extends TOP> SelectFSs<T> select(String fullyQualifiedTypeName) {
+  default <T extends FeatureStructure> SelectFSs<T> select(String fullyQualifiedTypeName) {
     return new SelectFSs_impl<>(this).type(fullyQualifiedTypeName);
   }
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/CASRuntimeException.java Mon Oct  3 19:04:54 2016
@@ -293,6 +293,14 @@ public class CASRuntimeException extends
   /** Multiply nested classloaders not supported.  Original base loader: {0}, current nested loader: {1}, trying to switch to loader: {2}.*/
   public static final String SWITCH_CLASS_LOADER_NESTED = "SWITCH_CLASS_LOADER_NESTED";
     
+  /** CAS does not contain any ''{0}'' instances{1}. */  // 1 is the position & offset info if available
+  public static final String SELECT_GET_NO_INSTANCES = "SELECT_GET_NO_INSTANCES";
+ 
+  /** CAS has more than 1 instance of ''{0}''{1}.*/
+  public static final String SELECT_GET_TOO_MANY_INSTANCES = "SELECT_GET_TOO_MANY_INSTANCES";
+
+  /** Index "{0}" must be an AnnotationIndex. */ 
+  public static final String ANNOTATION_INDEX_REQUIRED = "ANNOTATION_INDEX_REQUIRED";
   /**
    * The constructors are organized
    * 

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/FSIndex.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/FSIndex.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/FSIndex.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/FSIndex.java Mon Oct  3 19:04:54 2016
@@ -209,13 +209,13 @@ public interface FSIndex<T extends Featu
    */
   FSIndex<T> withSnapshotIterators();
 
-  <N extends TOP> SelectFSs<N> select();
+  <N extends FeatureStructure> SelectFSs<N> select();
   
-  <N extends TOP> SelectFSs<N> select(Type type);
+  <N extends FeatureStructure> SelectFSs<N> select(Type type);
   
-  <N extends TOP> SelectFSs<N> select(Class<N> clazz);
+  <N extends FeatureStructure> SelectFSs<N> select(Class<N> clazz);
   
-  <N extends TOP> SelectFSs<N> select(int jcasType);
+  <N extends FeatureStructure> SelectFSs<N> select(int jcasType);
   
-  <N extends TOP> SelectFSs<N> select(String fullyQualifiedTypeName);
+  <N extends FeatureStructure> SelectFSs<N> select(String fullyQualifiedTypeName);
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java Mon Oct  3 19:04:54 2016
@@ -22,9 +22,10 @@ package org.apache.uima.cas;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Spliterator;
+import java.util.stream.Stream;
 
+import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.jcas.cas.TOP;
-import org.apache.uima.jcas.tcas.Annotation;
 
 /**
  * Collection of builder style methods to specify selection of FSs from indexes
@@ -33,21 +34,21 @@ import org.apache.uima.jcas.tcas.Annotat
  *   Ordered = implies an ordered index not necessarily AnnotationIndex
  *   BI = bounded iterator (boundedBy or bounding)
  */
-public interface SelectFSs<T extends TOP> {
+public interface SelectFSs<T extends FeatureStructure> extends Iterable<T>, Stream<T> {
   
   // If not specified, defaults to all FSs (unordered) unless AnnotationIndex implied
     // Methods take their generic type from the variable to which they are assigned except for
     // index(class) which takes it from its argument.
-  <N extends TOP> SelectFSs<N> index(String indexName);  
-  <N extends TOP> SelectFSs<N> index(FSIndex<N> index);
+  <N extends FeatureStructure> SelectFSs<N> index(String indexName);  
+  <N extends FeatureStructure> SelectFSs<N> index(FSIndex<N> index);
 
   // If not specified defaults to the index's uppermost type.
   // Methods take their generic type from the variable to which they are assigned except for
   // type(class) which takes it from its argument.
-  <N extends TOP> SelectFSs<N> type(Type uimaType);
-  <N extends TOP> SelectFSs<N> type(String fullyQualifiedTypeName);
-  <N extends TOP> SelectFSs<N> type(int jcasClass_dot_type);
-  <N extends TOP> SelectFSs<N> type(Class<N> jcasClass_dot_class);
+  <N extends FeatureStructure> SelectFSs<N> type(Type uimaType);
+  <N extends FeatureStructure> SelectFSs<N> type(String fullyQualifiedTypeName);
+  <N extends FeatureStructure> SelectFSs<N> type(int jcasClass_dot_type);
+  <N extends FeatureStructure> SelectFSs<N> type(Class<N> jcasClass_dot_class);
     
 //  SelectFSs<T> shift(int amount); // incorporated into startAt 
   
@@ -118,6 +119,7 @@ public interface SelectFSs<T extends TOP
   SelectFSs<T> startAt(TOP fs, int shift);        // Ordered
   SelectFSs<T> startAt(int begin, int end, int shift);   // AI
     
+  SelectFSs<T> limit(int n); 
   // ---------------------------------
   // subselection based on bounds
   //   - uses 
@@ -125,27 +127,65 @@ public interface SelectFSs<T extends TOP
   //     -- positionUsesType, 
   //     -- skipEquals
   // ---------------------------------
-  SelectFSs<T> at(Annotation fs);  // AI
+  SelectFSs<T> at(AnnotationFS fs);  // AI
   SelectFSs<T> at(int begin, int end);  // AI
   
-  SelectFSs<T> coveredBy(Annotation fs);       // AI
+  SelectFSs<T> coveredBy(AnnotationFS fs);       // AI
   SelectFSs<T> coveredBy(int begin, int end);       // AI
   
-  SelectFSs<T> covering(Annotation fs);      // AI
+  SelectFSs<T> covering(AnnotationFS fs);      // AI
   SelectFSs<T> covering(int begin, int end);      // AI
   
-  SelectFSs<T> between(Annotation fs1, Annotation fs2);  // AI implies a coveredBy style
-  
+  SelectFSs<T> between(AnnotationFS fs1, AnnotationFS fs2);  // AI implies a coveredBy style
+ 
+  /* ---------------------------------
+  * Semantics: 
+  *   - following uimaFIT
+  *   - must be annotation subtype, annotation index
+  *   - following: move to first fs where begin > pos.end
+  *   - preceding: move to first fs where end < pos.begin
+  *   
+  *   - return the limit() or all
+  *   - for preceding, return in forward order (unless backward is specified)
+  *   - for preceding, skips FSs whose end >= begin (adjusted by offset)
+  * ---------------------------------*/
+  SelectFSs<T> following(TOP fs);
+  SelectFSs<T> following(int begin, int end);
+  SelectFSs<T> following(TOP fs, int offset);
+  SelectFSs<T> following(int begin, int end, int offset);
+
+  SelectFSs<T> preceding(TOP fs);
+  SelectFSs<T> preceding(int begin, int end);
+  SelectFSs<T> preceding(TOP fs, int offset);
+  SelectFSs<T> preceding(int begin, int end, int offset);
   // ---------------------------------
   // terminal operations
   // returning other than SelectFSs
+  // 
   // ---------------------------------
   FSIterator<T> fsIterator();
   Iterator<T> iterator();
   List<T> asList();
+  T[] asArray();
   Spliterator<T> spliterator();
-  T get();
-  T single();
+  
+  // returning one item
+  
+  T get();          // returns first element or null if empty
+  T single();       // throws if not exactly 1 element
+  T singleOrNull(); // throws if more than 1 element, returns single or null
+  T get(TOP fs);          // returns first element or null if empty
+  T single(TOP fs);       // throws if not exactly 1 element
+  T singleOrNull(TOP fs); // throws if more than 1 element, returns single or null
+  T get(TOP fs, int offset);          // returns first element or null if empty
+  T single(TOP fs, int offset);       // throws if not exactly 1 element
+  T singleOrNull(TOP fs, int offset); // throws if more than 1 element, returns single or null
+  T get(int begin, int end);          // returns first element or null if empty
+  T single(int begin, int end);       // throws if not exactly 1 element
+  T singleOrNull(int begin, int end); // throws if more than 1 element, returns single or null
+  T get(int begin, int end, int offset);          // returns first element or null if empty
+  T single(int begin, int end, int offset);       // throws if not exactly 1 element
+  T singleOrNull(int begin, int end, int offset); // throws if more than 1 element, returns single or null
   
   // ---------------------------------
   // The methods below are alternatives 
@@ -154,20 +194,7 @@ public interface SelectFSs<T extends TOP
   // concise forms using positional arguments
   // ---------------------------------
   
-  // ---------------------------------
-  // Semantics: the arg is used to position.
-  // The position is 
-  //   - if the arg is a match, then the next/previous one not matching (skip over matches)
-  //     -- uses typePriority, positionUsesType, and skipEqual for match cas
-  //   - if the arg is not a match, the first position > or < arg 
-  // ---------------------------------
-  SelectFSs<T> following(Annotation fs);
-  SelectFSs<T> following(int begin, int end);
-  SelectFSs<T> following(Annotation fs, int offset);
-  SelectFSs<T> following(int begin, int end, int offset);
-
-  SelectFSs<T> preceding(Annotation fs);
-  SelectFSs<T> preceding(int begin, int end);
-  SelectFSs<T> preceding(Annotation fs, int offset);
-  SelectFSs<T> preceding(int begin, int end, int offset);
+  static <N extends FeatureStructure> SelectFSs<N> sselect(FSIndex<N> index) {
+    return index.select();    
+  } 
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java Mon Oct  3 19:04:54 2016
@@ -170,6 +170,8 @@ public abstract class FSClassRegistry {
       this.generator = generator;
       this.jcasClass = jcasClass;
       this.jcasType = jcasType;    // typeId for jcas class, **NOT Typecode**
+      
+//      System.out.println("debug create jcci, class = " + jcasClass.getName() + ", typeint = " + jcasType);
     }
     
     boolean isCopydown(TypeImpl ti) {
@@ -375,6 +377,8 @@ public abstract class FSClassRegistry {
     // this is done even after the class is first loaded, in case the type system changed.
     // don't set anything if copy down - otherwise was setting the copyed-down typeId ref to the 
     //   new ti
+//    System.out.println("debug set jcas regisered type " + jcci.jcasType + ",  type = " + ti.getName());
+
     if (jcci.jcasType >= 0 && ! isCopyDown) {
       ts.setJCasRegisteredType(jcci.jcasType, ti); 
     }
@@ -604,6 +608,7 @@ public abstract class FSClassRegistry {
                           ti.isArray(); 
     FsGenerator generator = noGenerator ? null : createGenerator(jcasClass);
     JCasClassInfo jcasClassInfo = new JCasClassInfo(jcasClass, generator, jcasType);
+//    System.out.println("debug creating jcci, classname = " + jcasClass.getName() + ", jcasTypeNumber: " + jcasType);
     return jcasClassInfo;
   }
   

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_annotation.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_annotation.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_annotation.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_annotation.java Mon Oct  3 19:04:54 2016
@@ -21,6 +21,9 @@ package org.apache.uima.cas.impl;
 
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.SelectFSs;
+import org.apache.uima.cas.impl.Subiterator.BoundsUse;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas.text.AnnotationIndex;
 import org.apache.uima.cas.text.AnnotationTree;
@@ -56,10 +59,11 @@ public class FsIndex_annotation <T exten
                               null, 
                               ambiguous, 
                               strict, 
-                              isBounded,
+                              null, // no BoundsUse
                               true, // type priority used
                               true, // ignored
                               true, // ignored
+                              
                               this.getFsRepositoryImpl().getAnnotationFsComparator()
                              ); 
   }
@@ -86,7 +90,7 @@ public class FsIndex_annotation <T exten
         (Annotation) annot,
         ambiguous, 
         strict, 
-        true,  // isBounded 
+        BoundsUse.coveredBy,  // isBounded 
         true,  // uses type priority
         true,  // position uses type - ignored
         true,  // skip returning results equal to annot

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_iicp.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_iicp.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_iicp.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_iicp.java Mon Oct  3 19:04:54 2016
@@ -7,10 +7,8 @@ import java.util.Comparator;
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FSIterator;
 import org.apache.uima.cas.FeatureStructure;
-import org.apache.uima.cas.SelectFSs;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.admin.FSIndexComparator;
-import org.apache.uima.jcas.cas.TOP;
 
 /**
  * FsIndex_iicp (iicp)
@@ -485,50 +483,6 @@ class FsIndex_iicp<T extends FeatureStru
     return getCasImpl().indexRepository;
   }
 
-  /**
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_singletype#select() -
-   */
-  public <N extends TOP> SelectFSs<N> select() {
-    return fsIndex_singletype.select();
-  }
-
-  /**
-   * @param type -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_singletype#select(org.apache.uima.cas.Type)
-   */
-  public <N extends TOP> SelectFSs<N> select(Type type) {
-    return fsIndex_singletype.select(type);
-  }
-
-  /**
-   * @param clazz -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_singletype#select(java.lang.Class)
-   */
-  public <N extends TOP> SelectFSs<N> select(Class<N> clazz) {
-    return fsIndex_singletype.select(clazz);
-  }
-
-  /**
-   * @param jcasType -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_singletype#select(int)
-   */
-  public <N extends TOP> SelectFSs<N> select(int jcasType) {
-    return fsIndex_singletype.select(jcasType);
-  }
-
-  /**
-   * @param fullyQualifiedTypeName -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_singletype#select(java.lang.String)
-   */
-  public <N extends TOP> SelectFSs<N> select(String fullyQualifiedTypeName) {
-    return fsIndex_singletype.select(fullyQualifiedTypeName);
-  }
-
 //  /* (non-Javadoc)
 //   * @see org.apache.uima.cas.FSIndex#select()
 //   */

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java Mon Oct  3 19:04:54 2016
@@ -429,40 +429,4 @@ public abstract class FsIndex_singletype
   /* (non-Javadoc)
    * @see org.apache.uima.cas.FSIndex#select()
    */
-  @Override
-  public <N extends TOP> SelectFSs<N> select() {
-    return new SelectFSs_impl<>(getCasImpl()).index((FsIndex_singletype<N>)this);
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.FSIndex#select(org.apache.uima.cas.Type)
-   */
-  @Override
-  public <N extends TOP> SelectFSs<N> select(Type type) {
-    return new SelectFSs_impl<>(getCasImpl()).index((FsIndex_singletype<N>)this).type(type);
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.FSIndex#select(java.lang.Class)
-   */
-  @Override
-  public <N extends TOP> SelectFSs<N> select(Class<N> clazz) {
-    return new SelectFSs_impl<>(getCasImpl()).index((FsIndex_singletype<N>)this).type(clazz);
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.FSIndex#select(int)
-   */
-  @Override
-  public <N extends TOP> SelectFSs<N> select(int jcasType) {
-    return new SelectFSs_impl<>(getCasImpl()).index((FsIndex_singletype<N>)this).type(jcasType);
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.FSIndex#select(java.lang.String)
-   */
-  @Override
-  public <N extends TOP> SelectFSs<N> select(String fullyQualifiedTypeName) {
-    return new SelectFSs_impl<>(getCasImpl()).index((FsIndex_singletype<N>)this).type(fullyQualifiedTypeName);
-  }
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_snapshot.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_snapshot.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_snapshot.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_snapshot.java Mon Oct  3 19:04:54 2016
@@ -19,18 +19,21 @@
 
 package org.apache.uima.cas.impl;
 
+import java.util.Comparator;
+
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FSIterator;
 import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.SelectFSs;
 import org.apache.uima.cas.Type;
+import org.apache.uima.cas.admin.FSIndexComparator;
 import org.apache.uima.jcas.cas.TOP;
 
 /**
  * Implementation of light-weight wrapper of normal indexes, which support special kinds of iterators
  *   base on the setting of IteratorExtraFunction
  */
-public class FsIndex_snapshot <T extends FeatureStructure> implements FSIndex<T> {
+public class FsIndex_snapshot <T extends FeatureStructure> implements LowLevelIndex<T>, Comparator<FeatureStructure> {
     
   /**
    * wrapped index 
@@ -94,48 +97,28 @@ public class FsIndex_snapshot <T extends
   @Override
   public int compare(FeatureStructure o1, FeatureStructure o2) { return wrapped.compare(o1,  o2); }
 
-  /**
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_iicp#select()
-   */
-  public <N extends TOP> SelectFSs<N> select() {
-    return wrapped.select();
-  }
-
-  /**
-   * @param type -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_iicp#select(org.apache.uima.cas.Type)
-   */
-  public <N extends TOP> SelectFSs<N> select(Type type) {
-    return wrapped.select(type);
+  @Override
+  public LowLevelIterator<T> ll_iterator(boolean ambiguous) {
+    if (!ambiguous) {
+      return new LLUnambiguousIteratorImpl<T>((LowLevelIterator<FeatureStructure>) iterator());
+    } else {
+      return (LowLevelIterator<T>) iterator();
+    }
   }
 
-  /**
-   * @param clazz -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_iicp#select(java.lang.Class)
-   */
-  public <N extends TOP> SelectFSs<N> select(Class<N> clazz) {
-    return wrapped.select(clazz);
+  @Override
+  public int ll_compare(int ref1, int ref2) {
+    return wrapped.ll_compare(ref1, ref2);
   }
 
-  /**
-   * @param jcasType -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_iicp#select(int)
-   */
-  public <N extends TOP> SelectFSs<N> select(int jcasType) {
-    return wrapped.select(jcasType);
+  @Override
+  public CASImpl getCasImpl() {
+    return wrapped.getCasImpl();
   }
 
-  /**
-   * @param fullyQualifiedTypeName -
-   * @return -
-   * @see org.apache.uima.cas.impl.FsIndex_iicp#select(java.lang.String)
-   */
-  public <N extends TOP> SelectFSs<N> select(String fullyQualifiedTypeName) {
-    return wrapped.select(fullyQualifiedTypeName);
+  @Override
+  public FSIndexComparator getComparatorForIndexSpecs() {
+    return wrapped.getComparatorForIndexSpecs();
   }
 
 }

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_limited.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_limited.java?rev=1763195&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_limited.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_limited.java Mon Oct  3 19:04:54 2016
@@ -0,0 +1,119 @@
+/*
+ * 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.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+/**
+ * Wraps FSIterator<T>, limits results to n
+ */
+class FsIterator_limited<T extends FeatureStructure>  
+          implements LowLevelIterator<T> {
+  
+  final private LowLevelIterator<T> iterator; // not just for single-type iterators
+  final private int limit;
+  private int count = 0;
+    
+  FsIterator_limited(FSIterator<T> iterator, int limit) {
+    this.iterator = (LowLevelIterator<T>) iterator;
+    this.limit = limit;
+  }
+
+  private void makeInvalid() {
+    iterator.moveToFirst();
+    iterator.moveToPrevious();
+  }
+  
+  public T get() throws NoSuchElementException {
+    if (count == limit) {
+      makeInvalid();
+      throw new NoSuchElementException();
+    }
+    T r = iterator.get();
+    count++;
+    if (count == limit) {
+      makeInvalid();
+    }    
+    return r;
+  }
+
+  public T getNvc() {
+    if (count == limit) {
+      makeInvalid();
+      throw new NoSuchElementException();
+    }
+    T r = iterator.getNvc();
+    count++;
+    if (count == limit) {
+      makeInvalid();
+    }    
+    return r;
+  }
+
+  public void moveToNext() {
+    iterator.moveToNext();
+  }
+
+  public void moveToNextNvc() {
+    iterator.moveToNextNvc();
+  }
+
+  public void moveToPrevious() {
+    iterator.moveToPrevious();
+  }
+
+  public void moveToPreviousNvc() {
+    iterator.moveToPreviousNvc();
+  }
+
+  public void moveToFirst() {
+    iterator.moveToFirst();
+  }
+
+  public void moveToLast() {
+    iterator.moveToLast();
+  }
+
+  public void moveTo(FeatureStructure fs) {
+    iterator.moveTo(fs);
+  }
+
+  public FSIterator<T> copy() {
+    return iterator.copy();
+  }
+
+  public boolean isValid() {
+    return iterator.isValid();
+  }
+
+  @Override
+  public int ll_indexSize() {
+    return iterator.ll_indexSize();
+  }
+
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return iterator.ll_getIndex();
+  }
+
+}

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LowLevelIndex.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LowLevelIndex.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LowLevelIndex.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LowLevelIndex.java Mon Oct  3 19:04:54 2016
@@ -21,6 +21,8 @@ package org.apache.uima.cas.impl;
 
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.SelectFSs;
+import org.apache.uima.cas.Type;
 import org.apache.uima.cas.admin.FSIndexComparator;
 import org.apache.uima.internal.util.IntPointerIterator;
 
@@ -102,5 +104,39 @@ public interface LowLevelIndex<T extends
       }
     };
   }
+  
+  /**
+   * @param ti type which is a subtype of this index's type
+   * @return the index but just over this subtype
+   */
+  default <U extends T> LowLevelIndex<U> getSubIndex(TypeImpl ti) {
+    return getCasImpl().indexRepository.getIndexBySpec(ti.getCode(), getIndexingStrategy(), (FSIndexComparatorImpl) getComparatorForIndexSpecs());
+  }
+
+  @Override
+  default SelectFSs<T> select() {
+    return getCasImpl().select().index(this);
+  }
+
+  @Override
+  default <N extends FeatureStructure> SelectFSs<N> select(Type type) {
+    return select().type(type);
+  }
 
+  @Override
+  default <N extends FeatureStructure> SelectFSs<N> select(Class<N> clazz) {
+    return select().type(clazz);
+  }
+
+  @Override
+  default <N extends FeatureStructure> SelectFSs<N> select(int jcasType) {
+    return select().type(jcasType);
+  }
+
+  @Override
+  default <N extends FeatureStructure> SelectFSs<N> select(String fullyQualifiedTypeName) {
+    return select().type(fullyQualifiedTypeName);
+  }
+  
+  
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java Mon Oct  3 19:04:54 2016
@@ -19,36 +19,59 @@
 
 package org.apache.uima.cas.impl;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.stream.Collector;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 
 import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.CASRuntimeException;
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.SelectFSs;
 import org.apache.uima.cas.Type;
+import org.apache.uima.cas.impl.Subiterator.BoundsUse;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas.text.AnnotationIndex;
 import org.apache.uima.jcas.cas.TOP;
+import org.apache.uima.jcas.impl.JCasImpl;
 import org.apache.uima.jcas.tcas.Annotation;
 
 /**
  * Collection of builder style methods to specify selection of FSs from indexes
+ * shift handled in this routine
  * Comment codes:
  *   AI = implies AnnotationIndex
  */
-public class SelectFSs_impl <T extends TOP> implements SelectFSs<T> {
-  static enum BoundsUse {
-    coveredBy,
-    covering,
-    sameBeginEnd,
-  }
+public class SelectFSs_impl <T extends FeatureStructure> implements SelectFSs<T> {
   
   private CASImpl view;
+  private JCasImpl jcas;
   private FSIndex<T> index; 
   private TypeImpl ti;
   private int shift; 
+  private int limit = -1;
   
   private boolean isTypePriority = false;
   private boolean isPositionUsesType = false;
@@ -59,17 +82,15 @@ public class SelectFSs_impl <T extends T
   private boolean isNullOK = false;
   private boolean isUnordered = false;
   private boolean isBackwards = false;
-  private boolean isShift = false;
+  private boolean isAt = false;
+  private boolean isFollowing = false;
+  private boolean isPreceding = false;
   
   private BoundsUse boundsUse = null; 
   
   private TOP startingFs = null;
-  private Annotation boundingFs = null;
-  private int boundingBegin = -1;
-  private int boundingEnd   = -1;
+  private AnnotationFS boundingFs = null;
   
-  /** derived **/
-  private boolean isUseAnnotationIndex = false;  
   
   /************************************************
    * Constructors
@@ -81,6 +102,7 @@ public class SelectFSs_impl <T extends T
    ************************************************/
   public SelectFSs_impl(CAS cas) {
     this.view = (CASImpl) cas.getLowLevelCAS();
+    this.jcas = (JCasImpl) view.getJCas();
   }
     
   public SelectFSs_impl(CAS cas, Type type) {
@@ -96,13 +118,13 @@ public class SelectFSs_impl <T extends T
    * If not specified, defaults to all FSs (unordered) unless AnnotationIndex implied
    */
   @Override
-  public <N extends TOP> SelectFSs_impl<N> index(String indexName) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> index(String indexName) {
     this.index = view.indexRepository.getIndex(indexName);
     return (SelectFSs_impl<N>) this;
   }
   
   @Override
-  public <N extends TOP> SelectFSs_impl<N> index(FSIndex<N> aIndex) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> index(FSIndex<N> aIndex) {
     this.index = (FSIndex<T>) aIndex;
     return (SelectFSs_impl<N>) this;
   }
@@ -112,22 +134,22 @@ public class SelectFSs_impl <T extends T
    * if not specified defaults to the index's uppermost type.  
    */
   @Override
-  public <N extends TOP> SelectFSs_impl<N> type(Type uimaType) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> type(Type uimaType) {
     this.ti = (TypeImpl) uimaType;
     return (SelectFSs_impl<N>) this;
   }
   @Override
-  public <N extends TOP> SelectFSs_impl<N> type(String fullyQualifiedTypeName) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> type(String fullyQualifiedTypeName) {
     this.ti = view.getTypeSystemImpl().getType(fullyQualifiedTypeName);
     return (SelectFSs_impl<N>) this;
   }
   @Override
-  public <N extends TOP> SelectFSs_impl<N> type(int jcasClass_dot_type) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> type(int jcasClass_dot_type) {
     this.ti = (TypeImpl) view.getJCas().getCasType(jcasClass_dot_type);
     return (SelectFSs_impl<N>) this;
   }
   @Override
-  public <N extends TOP> SelectFSs_impl<N> type(Class<N> jcasClass_dot_class) {
+  public <N extends FeatureStructure> SelectFSs_impl<N> type(Class<N> jcasClass_dot_class) {
     this.ti = (TypeImpl) view.getJCasImpl().getCasType(jcasClass_dot_class);
     return (SelectFSs_impl<N>) this;
   }  
@@ -288,7 +310,7 @@ public class SelectFSs_impl <T extends T
   } 
   @Override
   public SelectFSs_impl<T> startAt(int begin, int end) {  // AI
-    this.startingFs = new Annotation(view.getJCas(), begin, end);
+    this.startingFs = new Annotation(jcas, begin, end);
     return this;
   } 
   
@@ -296,37 +318,42 @@ public class SelectFSs_impl <T extends T
   public SelectFSs_impl<T> startAt(TOP fs, int offset) {  // Ordered
     this.startingFs = fs;
     this.shift = offset;
-    this.isShift = true;
     return this;
   } 
   @Override
   public SelectFSs_impl<T> startAt(int begin, int end, int offset) {  // AI
-    this.startingFs = new Annotation(view.getJCas(), begin, end);
+    this.startingFs = new Annotation(jcas, begin, end);
     this.shift = offset;
-    this.isShift = true;
     return this;
   }  
+  
+  @Override
+  public SelectFSs_impl<T> limit(int limit) {
+    this.limit = limit;
+    return this;
+  }
     
   /*********************************
    * subselection based on boundingFs
    *********************************/
   @Override
-  public SelectFSs_impl<T> coveredBy(Annotation fs) {       // AI
+  public SelectFSs_impl<T> coveredBy(AnnotationFS fs) {       // AI
     boundsUse = BoundsUse.coveredBy;
     this.boundingFs = fs;
+    this.isEndWithinBounds = true; //default
     return this;
   }
   
   @Override
   public SelectFSs_impl<T> coveredBy(int begin, int end) {       // AI
     boundsUse = BoundsUse.coveredBy;
-    this.boundingBegin = begin;
-    this.boundingEnd = end;
+    this.boundingFs = new Annotation(jcas, begin, end);
+    this.isEndWithinBounds = true; //default
     return this;
   }
 
   @Override
-  public SelectFSs_impl<T> covering(Annotation fs) {      // AI
+  public SelectFSs_impl<T> covering(AnnotationFS fs) {      // AI
     boundsUse = BoundsUse.covering;
     this.boundingFs = fs;
     return this;
@@ -335,22 +362,60 @@ public class SelectFSs_impl <T extends T
   @Override
   public SelectFSs_impl<T> covering(int begin, int end) {      // AI
     boundsUse = BoundsUse.covering;
-    this.boundingBegin = begin;
-    this.boundingEnd = end;
+    this.boundingFs = new Annotation(jcas, begin, end);
     return this;
   }
 
   @Override
-  public SelectFSs_impl<T> between(Annotation fs1, Annotation fs2) {   // AI
+  public SelectFSs_impl<T> between(AnnotationFS fs1, AnnotationFS fs2) {   // AI
     final boolean reverse = fs1.getEnd() > fs2.getBegin();
     this.boundingFs = new Annotation(
-        view.getJCas(), 
+        jcas, 
         (reverse ? fs2 : fs1).getEnd(), 
         (reverse ? fs1 : fs2).getBegin());
     this.boundsUse = BoundsUse.coveredBy;
+    this.isBackwards = reverse;
+    this.isEndWithinBounds = true; // default    
+    return this;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#at(org.apache.uima.jcas.tcas.Annotation)
+   */
+  @Override
+  public SelectFSs<T> at(AnnotationFS fs) {
+    boundsUse = BoundsUse.sameBeginEnd;
+    boundingFs = fs;
     return this;
   }
 
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#at(int, int)
+   */
+  @Override
+  public SelectFSs<T> at(int begin, int end) {
+    return at(new Annotation(jcas, begin, end));
+  }
+
+  private String maybeMsgPosition() {
+    StringBuilder sb = new StringBuilder();
+    if (startingFs != null) {
+      if (startingFs instanceof Annotation) {
+        Annotation a = (Annotation)startingFs;
+        sb.append(" at position begin: ").append(a.getBegin()).append(", end: ")
+          .append(a.getEnd());
+      } else {
+        sb.append(" at moveTo position given by Feature Structure:\n");
+        startingFs.prettyPrint(2, 2, sb, false);
+        sb.append("\n ");
+      }
+    }
+    if (shift != 0) {
+      sb.append(" shifted by: ").append(shift);
+    }
+    return sb.toString();
+  }
+  
   /**
    * prepare terminal operations
    */
@@ -360,9 +425,29 @@ public class SelectFSs_impl <T extends T
    * 
    */
   private void prepareTerminalOp() {
-    isUseAnnotationIndex = !isAllViews && (
+    if (boundsUse == null) {
+      boundsUse = BoundsUse.notBounded;
+    }
+    
+    final boolean isUseAnnotationIndex = 
         ((index != null) && (index instanceof AnnotationIndex)) ||
-        isNonOverlapping || isEndWithinBounds || boundsUse != null);
+        isNonOverlapping || 
+        boundsUse != BoundsUse.notBounded;
+    
+    if (isUseAnnotationIndex) {
+      forceAnnotationIndex();  // throws if non-null index not an annotation index
+    }
+    
+    if (ti == null) {
+      if (index != null) {
+        ti = (TypeImpl) index.getType();
+      }
+    } else {
+      if (index != null &&
+          ((TypeImpl)index.getType()).subsumes(ti)) {
+        index = ((LowLevelIndex)index).getSubIndex(ti);
+      }
+    }
     
     if (isUseAnnotationIndex && null == ti) {
       ti = (TypeImpl) view.getAnnotationType();
@@ -372,12 +457,14 @@ public class SelectFSs_impl <T extends T
       ti = view.getTypeSystemImpl().getTopType();
     }
     
-    if (index == null && isUseAnnotationIndex) {
-      this.index = (FSIndex<T>) view.getAnnotationIndex(ti);
+  }
+  
+  private void incr(FSIterator<T> it) {
+    if (isBackwards) {
+      it.moveToPrevious();
+    } else {
+      it.moveToNext();
     }
-    
-    // index may still be null at this point.
-    
   }
   
   /*********************************
@@ -402,10 +489,13 @@ public class SelectFSs_impl <T extends T
   @Override
   public FSIterator<T> fsIterator() {
     prepareTerminalOp();
-    if (isAllViews) {
-      return new FsIterator_aggregation_common<T>(getPlainIteratorsForAllViews(), null);
-    }
-    return plainFsIterator(index, view);
+    FSIterator<T> it = isAllViews 
+                      ? new FsIterator_aggregation_common<T>(getPlainIteratorsForAllViews(), null)
+                      : plainFsIterator(index, view);
+
+    maybePosition(it);
+    maybeShift(it);
+    return  (limit == -1) ? it : new FsIterator_limited<>(it, limit);
   }
   
   
@@ -420,6 +510,12 @@ public class SelectFSs_impl <T extends T
     return ita;
   }
   
+  /** 
+   * gets the index for a view that corresponds to the specified index
+   *   by matching the index specs and type code
+   * @param v -
+   * @return -
+   */
   private FSIndex<T> getIndexForView(CASImpl v) {
     if (index == null) {
       return null;
@@ -446,20 +542,17 @@ public class SelectFSs_impl <T extends T
     final boolean isAnnotationIndex = idx instanceof AnnotationIndex;
     final AnnotationIndex ai = isAnnotationIndex ? (AnnotationIndex)idx: null;
     FSIterator<T> it;
-    if (boundsUse == null) {
+    if (boundsUse == BoundsUse.notBounded) {
       if (!isIndexOrdered) {
         it = idx.iterator();       
       } else {
         // index is ordered but no bounds are being used - return plain fsIterator or maybe nonOverlapping version
         it = (isAnnotationIndex && isNonOverlapping)
-               ? ai.iterator(true)
+               ? ai.iterator(false)
                : (isUnordered && idx instanceof FsIndex_iicp) 
                    ? ((FsIndex_iicp<T>)idx).iteratorUnordered()
                    : idx.iterator();
       }
-      if (null != startingFs) {
-        it.moveTo(startingFs);
-      }
     } else {
     // bounds in use, index must be annotation index, is ordered
     it = (FSIterator<T>) new Subiterator<>(
@@ -467,63 +560,277 @@ public class SelectFSs_impl <T extends T
         boundingFs, 
         !isNonOverlapping,  // ambiguous
         isEndWithinBounds,  // strict 
-        true,               // isBounded
+        boundsUse,
         isTypePriority, 
         isPositionUsesType, 
-        isSkipEquals,
+        isSkipEquals,              
         v.indexRepository.getAnnotationFsComparator());
     }
-    return maybeShift(it);
+    return it;
   }
     
   @Override
   public Iterator<T> iterator() {
-    return null;
+    return fsIterator();
   }
+  
+  
+  /**
+   * Initial simple impl, creates reified list
+   *   Better impl would be to use underlying fsIterator
+   * @return
+   */
   @Override
   public List<T> asList() {
-    return null;
+    T[] a = asArray();
+    return Arrays.asList(a);
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#asArray()
+   */
+  @Override
+  public T[] asArray() {
+    List<T> al = new ArrayList<>();
+    FSIterator<T> it = fsIterator();
+    while (it.isValid()) {
+      al.add(it.getNvc());
+    }
+    return (T[]) al.toArray();
   }
+
+  /**
+   * Iterator respects backwards
+   * 
+   * Sets the characteristics from the context:
+   *   IMMUTABLE / NONNULL / DISTINCT - always
+   *   CONCURRENT - never
+   *   ORDERED - unless unordered index or not SORTED_INDEX or SET_INDEX
+   *   SORTED - only for SORTED_INDEX (and not unordered?)
+   *   SIZED - if exact size is (easily) known, just from index.
+   *           false if bounded, unambiguous
+   *   SUBSIZED - if spliterator result from trysplit also is SIZED, set to true for now
+   * 
+   * trySplit impl: 
+   *   always returns null (no parallelism support for now) 
+   * @return the spliterator 
+   */
   @Override
   public Spliterator<T> spliterator() {
-    return null;
+    return new Spliterator<T>() {
+
+      private final FSIterator<T> it = fsIterator();
+      
+      private final int characteristics;
+      
+      private final Comparator<? super T> comparator;
+
+      { 
+        prepareTerminalOp();
+        // always set
+        int c = Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.DISTINCT;
+        
+        if (boundsUse == BoundsUse.notBounded && !isNonOverlapping) {
+          c |= Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+        
+        // set per indexing strategy
+        int kind = (null == index) ? -1 : index.getIndexingStrategy();
+        if (kind == FSIndex.SORTED_INDEX) {
+          c |= Spliterator.ORDERED | Spliterator.SORTED;
+          comparator = (Comparator<? super T>) index; 
+        } else {
+          comparator = null;
+        }
+        if (kind == FSIndex.SET_INDEX) {
+          c |= Spliterator.ORDERED;
+        }
+        
+        characteristics = c;
+        if (isBackwards) {
+          it.moveToLast();
+        }
+      }
+      
+      @Override
+      public boolean tryAdvance(Consumer<? super T> action) {
+        if (it.isValid()) {
+          action.accept(it.getNvc());
+          incr(it);
+          return true;
+        }
+        return false;
+      }
+
+      @Override
+      public Spliterator<T> trySplit() {
+        // return null for now
+        // could implement something based on type of fsIterator.
+        return null;
+      }
+
+      @Override
+      public long estimateSize() {
+        return ((characteristics & Spliterator.SIZED) == Spliterator.SIZED) ? index.size() : Long.MAX_VALUE;
+      }
+
+      @Override
+      public int characteristics() {
+        return characteristics;
+      }
+
+      @Override
+      public Comparator<? super T> getComparator() {
+        return (comparator == null) ? Spliterator.super.getComparator() : comparator;
+      }
+    };
   }
+  
+  /*
+   * returns the item the select is pointing to, or null 
+   * uses isNullOK 
+   * (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#get()
+   */
   @Override
   public T get() {
+    FSIterator<T> it = fsIterator();
+    if (it.isValid()) {
+      return it.getNvc();
+    }
+    if (!isNullOK) {
+      throw new CASRuntimeException(CASRuntimeException.SELECT_GET_NO_INSTANCES, ti.getName(), maybeMsgPosition());
+    }
     return null;
   }
+
+  /*
+   * like get() but throws if more than one item
+   * (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#single()
+   */
   @Override
   public T single() {
+    T v = singleOrNull();
+    if (v == null && !isNullOK) {
+      throw new CASRuntimeException(CASRuntimeException.SELECT_GET_NO_INSTANCES, ti.getName(), maybeMsgPosition());
+    }
+    return v;
+  }
+  
+  /*
+   * like get() but throws if more than 1 item, always OK to return null if none
+   * (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#singleOrNull()
+   */
+  @Override
+  public T singleOrNull() {
+    FSIterator<T> it = fsIterator();
+    if (it.isValid()) {
+      T v = it.getNvc();
+      it.moveToNext();
+      if (it.isValid()) {
+        throw new CASRuntimeException(CASRuntimeException.SELECT_GET_TOO_MANY_INSTANCES, ti.getName(), maybeMsgPosition());
+      }
+      return v;
+    }
     return null;
   }
   
+  @Override
+  public T get(TOP fs) {
+    startAt(fs);
+    return get();
+  }
+
+  @Override
+  public T single(TOP fs) {
+    startAt(fs);
+    return single();
+  }
+
+  @Override
+  public T singleOrNull(TOP fs) {
+    startAt(fs);
+    return singleOrNull();
+  }
+
+  @Override
+  public T get(TOP fs, int offset) {
+    startAt(fs, offset);
+    return get();
+  }
+
+  @Override
+  public T single(TOP fs, int offset) {
+    startAt(fs, offset);
+    return single();
+  }
+
+  @Override
+  public T singleOrNull(TOP fs, int offset) {
+    startAt(fs, offset);
+    return singleOrNull();
+  }
+
+  @Override
+  public T get(int begin, int end) {
+    startAt(begin, end);
+    return get();
+  }
+
+  @Override
+  public T single(int begin, int end) {
+    startAt(begin, end);
+    return single();
+  }
+
+  @Override
+  public T singleOrNull(int begin, int end) {
+    startAt(begin, end);
+    return singleOrNull();
+  }
+
+  @Override
+  public T get(int begin, int end, int offset) {
+    startAt(begin, end, offset);
+    return get();
+  }
+
+  @Override
+  public T single(int begin, int end, int offset) {
+    startAt(begin, end, offset);
+    return single();
+  }
+
+  @Override
+  public T singleOrNull(int begin, int end, int offset) {
+    startAt(begin, end, offset);
+    return singleOrNull();
+  }
+
   /**
    * works for AnnotationIndex or general index
    * 
    * position taken from startingFs (not necessarily an Annotation subtype)
-   *   - goes to left-most "equal" using comparitor, or if none equal, to the first one > startingFs
+   *   - goes to left-most "equal" using comparator, or if none equal, to the first one > startingFs
    *     -- using moveTo(fs)
    * 
    * special processing for AnnotationIndex (only):
    *   - typePriority - use or ignore
    *     -- ignored: after moveTo(fs), moveToPrevious while begin && end ==
    *       --- and if isPositionUsesType types are == 
-   * @param it
+   * @param it iterator to position
    * @return it positioned if needed
    */
-  public static <T extends TOP> FSIterator<T> maybePosition(
-      FSIterator<T> it,
-      TOP startingFs,
-      boolean isAnnotationIndex,
-      boolean isTypePriority,
-      boolean isPositionUsesType) {
-    if (!it.isValid() || startingFs == null) {
+  public FSIterator<T> maybePosition(FSIterator<T> it) {
+    if (!it.isValid() || startingFs == null || boundsUse != BoundsUse.notBounded) {
       return it;
     }
     
     it.moveTo(startingFs);
     
-    if (isAnnotationIndex) {
+    if (index != null && index instanceof AnnotationIndex) {
       if (!isTypePriority) {
         int begin = ((Annotation)startingFs).getBegin();
         int end = ((Annotation)startingFs).getEnd();
@@ -541,11 +848,19 @@ public class SelectFSs_impl <T extends T
         it.moveToNext();
       }
     }
+    
+    // guaranteed by above not-bounded
+    if (isFollowing) {
+      it.moveToNext();
+    } else if (isPreceding) {
+      it.moveToPrevious();
+    }
+    
     return it;
   }
   
   private FSIterator<T> maybeShift(FSIterator<T> it) {
-    if (isShift) {
+    if (shift != 0) {
       int ps = Math.abs(shift);
       
       for (int i = 0; i < ps; i++) {
@@ -567,30 +882,11 @@ public class SelectFSs_impl <T extends T
    ********************************************/
 
   /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#at(org.apache.uima.jcas.tcas.Annotation)
-   */
-  @Override
-  public SelectFSs<T> at(Annotation fs) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#at(int, int)
-   */
-  @Override
-  public SelectFSs<T> at(int begin, int end) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#following(org.apache.uima.jcas.tcas.Annotation)
+   * @see org.apache.uima.cas.SelectFSs#following(org.apache.uima.jcas.cas.TOP)
    */
   @Override
-  public SelectFSs<T> following(Annotation fs) {
-    // TODO Auto-generated method stub
-    return null;
+  public SelectFSs<T> following(TOP fs) {
+    return commonFollowing(fs, 0);
   }
 
   /* (non-Javadoc)
@@ -598,17 +894,15 @@ public class SelectFSs_impl <T extends T
    */
   @Override
   public SelectFSs<T> following(int begin, int end) {
-    // TODO Auto-generated method stub
-    return null;
+    return commonFollowing(new Annotation(jcas, begin, end), 0);
   }
 
   /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#following(org.apache.uima.jcas.tcas.Annotation, int)
+   * @see org.apache.uima.cas.SelectFSs#following(org.apache.uima.jcas.cas.TOP, int)
    */
   @Override
-  public SelectFSs<T> following(Annotation fs, int offset) {
-    // TODO Auto-generated method stub
-    return null;
+  public SelectFSs<T> following(TOP fs, int offset) {
+    return commonFollowing(fs, offset);
   }
 
   /* (non-Javadoc)
@@ -616,17 +910,15 @@ public class SelectFSs_impl <T extends T
    */
   @Override
   public SelectFSs<T> following(int begin, int end, int offset) {
-    // TODO Auto-generated method stub
-    return null;
+    return commonFollowing(new Annotation(jcas, begin, end), offset);
   }
 
   /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#preceding(org.apache.uima.jcas.tcas.Annotation)
+   * @see org.apache.uima.cas.SelectFSs#preceding(org.apache.uima.jcas.cas.TOP)
    */
   @Override
-  public SelectFSs<T> preceding(Annotation fs) {
-    // TODO Auto-generated method stub
-    return null;
+  public SelectFSs<T> preceding(TOP fs) {
+    return commonPreceding(fs, 0);
   }
 
   /* (non-Javadoc)
@@ -634,17 +926,15 @@ public class SelectFSs_impl <T extends T
    */
   @Override
   public SelectFSs<T> preceding(int begin, int end) {
-    // TODO Auto-generated method stub
-    return null;
+    return commonPreceding(new Annotation(jcas, begin, end), 0);
   }
 
   /* (non-Javadoc)
-   * @see org.apache.uima.cas.SelectFSs#preceding(org.apache.uima.jcas.tcas.Annotation, int)
+   * @see org.apache.uima.cas.SelectFSs#preceding(org.apache.uima.jcas.cas.TOP, int)
    */
   @Override
-  public SelectFSs<T> preceding(Annotation fs, int offset) {
-    // TODO Auto-generated method stub
-    return null;
+  public SelectFSs<T> preceding(TOP fs, int offset) {
+    return commonPreceding(fs, offset);
   }
 
   /* (non-Javadoc)
@@ -652,10 +942,10 @@ public class SelectFSs_impl <T extends T
    */
   @Override
   public SelectFSs<T> preceding(int begin, int end, int offset) {
-    // TODO Auto-generated method stub
-    return null;
+    return commonPreceding(new Annotation(jcas, begin, end), offset);
   }
-  
+
+   
 
   
   /************************
@@ -669,7 +959,244 @@ public class SelectFSs_impl <T extends T
   /**
    * validations
    *   isAnnotationIndex => startingFs is Annotation 
+   *   isAllViews:  doesn't support startAt, coveredBy and friends, backwards
+   *   isAllViews:  supports limit, shift
    */
+    
+//  private void validateSinglePosition(TOP fs, int offset) {
+//    if (startingFs != null) {
+//      /* Select - multiple starting positions not allowed */
+//      throw CASRuntimeException(CASRuntimeException.);
+//    }
+//    startingFs = fs;
+//    
+//    if (offset != 0) { 
+//      if (shift != 0) {
+//        /* Select - multiple offset shifting not allowed */
+//        throw  CASRuntimeException(CASRuntimeException.);
+//      }
+//      shift = offset;
+//    }
+//  }
   
+  private SelectFSs<T> commonFollowing(TOP fs, int offset) {
+//    validateSinglePosition(fs, offset);
+    isFollowing = true;
+    return this;
+  }
+
+  private SelectFSs<T> commonPreceding(TOP fs, int offset) {
+//    validateSinglePosition(fs, offset);
+    isPreceding = true;
+    isBackwards = true; // always iterate backwards
+    return this;
+  }
+  
+  private void forceAnnotationIndex() {
+    if (index == null) {
+      index = (FSIndex<T>) view.getAnnotationIndex();
+    } else {
+      if (!(index instanceof AnnotationIndex)) {
+        /** Index "{0}" must be an AnnotationIndex. */ 
+        throw new CASRuntimeException(CASRuntimeException.ANNOTATION_INDEX_REQUIRED, index);
+      }
+    }
+  }
+  
+  private Stream<T> stream() {
+    return StreamSupport.stream(spliterator(), false);
+  }
+
   
+  /* ***************************************
+   *   S T R E A M   methods
+   * these convert the result to a stream and apply the method
+   */
+  @Override
+  public Stream<T> filter(Predicate<? super T> predicate) {
+    return stream().filter(predicate);
+  }
+
+  @Override
+  public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
+    return stream().map(mapper);
+  }
+
+  @Override
+  public IntStream mapToInt(ToIntFunction<? super T> mapper) {
+    return stream().mapToInt(mapper);
+  }
+
+  @Override
+  public LongStream mapToLong(ToLongFunction<? super T> mapper) {
+    return stream().mapToLong(mapper);
+  }
+
+  @Override
+  public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
+    return stream().mapToDouble(mapper);
+  }
+
+  @Override
+  public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
+    return stream().flatMap(mapper);
+  }
+
+  @Override
+  public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
+    return stream().flatMapToInt(mapper);
+  }
+
+  @Override
+  public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
+    return stream().flatMapToLong(mapper);
+  }
+
+  @Override
+  public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
+    return stream().flatMapToDouble(mapper);
+  }
+
+  @Override
+  public Stream<T> distinct() {
+    return stream().distinct();
+  }
+
+  @Override
+  public Stream<T> sorted() {
+    return stream().sorted();
+  }
+
+  @Override
+  public Stream<T> sorted(Comparator<? super T> comparator) {
+    return stream().sorted(comparator);
+  }
+
+  @Override
+  public Stream<T> peek(Consumer<? super T> action) {
+    return stream().peek(action);
+  }
+
+  @Override
+  public Stream<T> limit(long maxSize) {
+    return stream().limit(maxSize);
+  }
+
+  @Override
+  public Stream<T> skip(long n) {
+    return stream().skip(n);
+  }
+
+  @Override
+  public void forEach(Consumer<? super T> action) {
+    stream().forEach(action);
+  }
+
+  @Override
+  public void forEachOrdered(Consumer<? super T> action) {
+    forEachOrdered(action);
+  }
+
+  @Override
+  public Object[] toArray() {
+    return stream().toArray();
+  }
+
+  @Override
+  public <A> A[] toArray(IntFunction<A[]> generator) {
+    return stream().toArray(generator);
+  }
+
+  @Override
+  public T reduce(T identity, BinaryOperator<T> accumulator) {
+    return stream().reduce(identity, accumulator);
+  }
+
+  @Override
+  public Optional<T> reduce(BinaryOperator<T> accumulator) {
+    return stream().reduce(accumulator);
+  }
+
+  @Override
+  public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,
+      BinaryOperator<U> combiner) {
+    return stream().reduce(identity, accumulator, combiner);
+  }
+
+  @Override
+  public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator,
+      BiConsumer<R, R> combiner) {
+    return stream().collect(supplier, accumulator, combiner);
+  }
+
+  @Override
+  public <R, A> R collect(Collector<? super T, A, R> collector) {
+    return stream().collect(collector);
+  }
+
+  @Override
+  public Optional<T> min(Comparator<? super T> comparator) {
+    return stream().min(comparator);
+  }
+
+  @Override
+  public Optional<T> max(Comparator<? super T> comparator) {
+    return stream().max(comparator);
+  }
+
+  @Override
+  public long count() {
+    return stream().count();
+  }
+
+  @Override
+  public boolean anyMatch(Predicate<? super T> predicate) {
+    return stream().anyMatch(predicate);
+  }
+
+  @Override
+  public boolean allMatch(Predicate<? super T> predicate) {
+    return stream().allMatch(predicate);
+  }
+
+  @Override
+  public boolean noneMatch(Predicate<? super T> predicate) {
+    return stream().noneMatch(predicate);
+  }
+
+  @Override
+  public Optional<T> findFirst() {
+    return stream().findFirst();
+  }
+
+  @Override
+  public Optional<T> findAny() {
+    return stream().findAny();
+  }
+
+  @Override
+  public boolean isParallel() {
+    return stream().isParallel();
+  }
+
+  @Override
+  public Stream<T> sequential() {
+    return stream().sequential();
+  }
+
+  @Override
+  public Stream<T> parallel() {
+    return stream().parallel();
+  }
+
+  @Override
+  public Stream<T> onClose(Runnable closeHandler) {
+    return stream().onClose(closeHandler);
+  }
+
+  @Override
+  public void close() {
+    stream().close();
+  }
+
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java Mon Oct  3 19:04:54 2016
@@ -23,14 +23,15 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.NoSuchElementException;
+import java.util.function.Predicate;
 
-import org.apache.uima.analysis_engine.impl.AnnotatorForCollectionProcessCompleteTest;
 import org.apache.uima.cas.FSIterator;
 import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.internal.util.Misc;
 import org.apache.uima.jcas.cas.TOP;
+import org.apache.uima.jcas.impl.JCasImpl;
 import org.apache.uima.jcas.tcas.Annotation;
 
 /**
@@ -71,6 +72,14 @@ import org.apache.uima.jcas.tcas.Annotat
  */
 public class Subiterator<T extends AnnotationFS> implements LowLevelIterator<T> {
 
+
+  public static enum BoundsUse {
+    coveredBy,
+    covering,
+    sameBeginEnd,
+    notBounded,
+  }
+    
   /*
    * The generic type of this is Annotation, not T, because that allows the use of a comparator which is comparing
    * a key which is not T but some super type of T.
@@ -89,6 +98,8 @@ public class Subiterator<T extends Annot
   private final boolean isTypePriority;
   private final boolean isPositionUsesType;
   private final boolean isSkipEquals;
+  private final BoundsUse boundsUse;
+  
   private final boolean isEmpty;
   
   private int prevEnd = 0;  // for unambiguous iterators
@@ -101,6 +112,8 @@ public class Subiterator<T extends Annot
   private final TypeImpl boundType;
   
   private final Comparator<TOP> annotationComparator;  // implements compare(fs1, fs2) for begin/end/type priority
+  private final JCasImpl jcas;
+  
   /**
    * Caller is the implementation of AnnotationIndex, FSIndex_annotation.
    * 
@@ -121,24 +134,25 @@ public class Subiterator<T extends Annot
    */
   Subiterator(
       FSIterator<T> it, 
-      Annotation boundingAnnot, 
+      AnnotationFS boundingAnnot, 
       boolean ambiguous, 
       boolean strict,    // omit FSs whose end > bounds
-      boolean isBounded, // false if boundingAnnot being used for starting position in unambiguous iterator
+      BoundsUse boundsUse, // null if no bounds; boundingAnnot used for start position if non-null
       boolean isTypePriority,
       boolean isPositionUsesType, 
       boolean isSkipEquals,
       Comparator<TOP> annotationComparator
       ) {
     this.it = (FSIterator<Annotation>) it;
-    this.boundingAnnot = boundingAnnot;
-    this.isBounded = isBounded;
+    this.boundingAnnot = (Annotation) boundingAnnot;
+    this.isBounded = boundsUse != null;
+    this.boundsUse = (boundsUse == null) ? BoundsUse.notBounded : boundsUse;
     this.isAmbiguous = ambiguous;
     this.isStrict = strict;
     this.isTypePriority = isTypePriority;
     this.isPositionUsesType = isPositionUsesType;
     this.isSkipEquals = isSkipEquals;
-
+ 
     if (isBounded && (null == boundingAnnot || !(boundingAnnot instanceof Annotation))) {
       Misc.internalError(new IllegalArgumentException("Bounded Subiterators require a bounding annotation"));
     }
@@ -151,6 +165,7 @@ public class Subiterator<T extends Annot
     moveToStart();
     isEmpty = !isValid();
     startId = isValid() ? get()._id() : 0;
+    this.jcas = (JCasImpl) ((LowLevelIterator<T>)it).ll_getIndex().getCasImpl().getJCas();
   }
    
   /** 
@@ -170,7 +185,7 @@ public class Subiterator<T extends Annot
       Annotation boundingAnnot, 
       boolean ambiguous, 
       boolean strict,    // omit FSs whose end > bounds
-      boolean isBounded, // false if boundingAnnot being used for starting position in unambiguous iterator
+      BoundsUse boundsUse, // null if boundingAnnot being used for starting position in unambiguous iterator
       boolean isTypePriority,
       boolean isPositionUsesType, 
       boolean isSkipEquals,
@@ -180,7 +195,8 @@ public class Subiterator<T extends Annot
       ) {
     this.it = it;
     this.boundingAnnot = boundingAnnot;
-    this.isBounded = isBounded;
+    this.isBounded = boundsUse != null;
+    this.boundsUse = boundsUse;
     this.isAmbiguous = ambiguous;
     this.isStrict = strict;
     this.isTypePriority = isTypePriority;
@@ -194,6 +210,7 @@ public class Subiterator<T extends Annot
     
     this.annotationComparator = annotationComparator;
     this.isEmpty = isEmpty;
+    this.jcas = (JCasImpl) ((LowLevelIterator<T>)it).ll_getIndex().getCasImpl().getJCas();
   }
 
   /**
@@ -210,6 +227,7 @@ public class Subiterator<T extends Annot
       list.add((Annotation) it.getNvc());
       moveToNext();
     }
+    this.pos = 0;
     isListForm = true;  // do at end, so up to this point, iterator is not the list form style
   }
   
@@ -226,14 +244,21 @@ public class Subiterator<T extends Annot
    * Move to the starting position of the sub iterator
    */
   private void moveToStart() {
-    if (!isBounded) {  // unbounded case for unambiguous iterator
+    switch (boundsUse) {
+    case notBounded:
       it.moveToFirst();
-    } else {  // is annotation bounding
+      break;
+    case coveredBy:
+    case sameBeginEnd:
       it.moveTo(boundingAnnot);
       adjustForTypePriorityBoundingBegin();
-      adjustForStrictAndBoundSkip(true);  
-    }   
-    setPrevEnd();  // used for unambiguous
+      adjustForStrictAndBoundSkip(true);
+      break;
+    case covering:
+      Misc.internalError(); // not yet impl
+      break;
+    }
+    maybeSetPrevEnd();  // used for unambiguous
   }
   
   private void adjustForStrictAndBoundSkip(boolean forward) {
@@ -281,7 +306,7 @@ public class Subiterator<T extends Annot
            (isSkipEquals && annotationComparator.compare(fs,  boundingAnnot) == 0);
   }
     
-  private void setPrevEnd() {
+  private void maybeSetPrevEnd() {
     if (!isAmbiguous && it.isValid()) {
       this.prevEnd = it.getNvc().getEnd();
     }    
@@ -292,7 +317,7 @@ public class Subiterator<T extends Annot
    * For strict mode, advance iterator until the end is within the bounding end 
    */
   private void adjustForStrict(boolean forward) {
-    if (isStrict && isBounded) {
+    if (isStrict && boundsUse == BoundsUse.coveredBy) {
       while (it.isValid() && (it.getNvc().getEnd() > this.boundEnd)) {
         if (forward) {
           it.moveToNextNvc();
@@ -304,7 +329,7 @@ public class Subiterator<T extends Annot
   }
   
   /**
-   * Assume: it is valid
+   * Assume: iterator is valid
    */
   private void maybeMoveToPrevBounded() {
     if (it.get()._id == startId) {
@@ -371,13 +396,28 @@ public class Subiterator<T extends Annot
    */
   @Override
   public boolean isValid() {
-    return isListForm ? 
-        (this.pos >= 0) && (this.pos < this.list.size()) :
-          
-        // assume that it position is adjusted for strict and unambiguous already
-        (it.isValid() && 
-            ( isBounded? (it.get().getBegin() <= this.boundEnd) : 
-              true));
+    if (isListForm) {
+      return (this.pos >= 0) && (this.pos < this.list.size());
+    }
+    
+    if (!it.isValid()) {
+      return false;
+    }
+    
+    switch (boundsUse) {
+    case notBounded:
+      return true;
+    case coveredBy:
+      return it.get().getBegin() <= boundEnd;
+    case covering:
+      Misc.internalError();  //not yet impl
+      return false;
+    case sameBeginEnd:
+      Annotation a = it.get();
+      return a.getBegin() == boundBegin &&
+             a.getEnd() == boundEnd;
+    }
+    return false; // ignored, just hear to get rid of invalid compiler error report
   }
 
   /*
@@ -430,7 +470,7 @@ public class Subiterator<T extends Annot
   private void moveToNext(boolean nvc) {
     if (isListForm) {
       ++this.pos;
-      // setPrevEnd not needed because list form already accounted for unambiguous
+      // maybeSetPrevEnd not needed because list form already accounted for unambiguous
       return;
     }
    
@@ -445,12 +485,30 @@ public class Subiterator<T extends Annot
 
     adjustForStrictAndBoundSkip(true); 
     
-    // stop in bounded case if out of bounds going forwards UIMA-5063
-    if (isBounded && it.isValid() && (it.get().getBegin() > boundEnd)) { 
-      it.moveToLast();
-      it.moveToNext();  // mark invalid
-    } else {
-      setPrevEnd();
+    // stop logic going forwards for various bounding cases
+    if (it.isValid()) {
+      // stop in bounded case if out of bounds going forwards UIMA-5063
+      switch(boundsUse) {
+      case notBounded: 
+        break;
+      case coveredBy:
+        maybeMakeItInvalid_bounds(it.getNvc(), a -> a.getBegin() > boundEnd);
+        break;
+      case covering:
+        Misc.internalError(); // not yet implemented
+        break;
+      case sameBeginEnd:
+        maybeMakeItInvalid_bounds(it.getNvc(), a -> a.getBegin() != boundBegin || a.getEnd() != boundEnd);
+        break;
+      }
+    } 
+    maybeSetPrevEnd();
+  }
+  
+  private void maybeMakeItInvalid_bounds(Annotation a, Predicate<Annotation> outOfBounds) {
+    if (outOfBounds.test(a)) {
+      it.moveToFirst();
+      it.moveToPrevious(); // make invalid
     }
   }
   
@@ -479,14 +537,11 @@ public class Subiterator<T extends Annot
       return;
     }
 
- 
-    
     if (it.isValid()) {
       maybeMoveToPrevBounded();
     }
 
     adjustForStrictAndBoundSkip(false);   // false - moving backwards
-    
   }
   
 
@@ -505,7 +560,7 @@ public class Subiterator<T extends Annot
   }
 
   /*
-   * This operation is relatively expensive
+   * This operation is relatively expensive for unambiguous
    * 
    * @see org.apache.uima.cas.FSIterator#moveToLast()
    */
@@ -524,37 +579,51 @@ public class Subiterator<T extends Annot
       if (isEmpty) {
         return; // iterator is invalid, leave it that way
       }
-      // make temp key which is just past end bounds
-      Annotation key = new Annotation(((LowLevelIterator<Annotation>)it).ll_getIndex().getCasImpl().getJCas(), 
-                                      boundEnd + 1,   // last can start at bound end. 
-                                      Integer.MAX_VALUE);
-      it.moveTo(key);
-      // cases:
-      //   iterator never empty (tested above)
-      //   iterator invalid - key is > last element
-      //     use last element as starting point
-      //   iterator valid - go backwards while element's begin is > bound end
-      //     could run off beginning (== startId): if so, use that 
-      // move backwards ignoring type and type priority.
-      if (it.isValid()) {
-        while (it.isValid() && it.get().getBegin() > boundEnd) {
-          Annotation a = it.get();
-          if (a._id == startId) {
-            assert a.getBegin() <= boundEnd; // because it's non-empty
-              // use this as the last
-            break;  // still need to adjust for strict and bound skip
-          } 
-          it.moveToPreviousNvc();
+
+      switch (boundsUse) {
+      case notBounded:
+        Misc.internalError();
+        break;
+
+      case coveredBy:
+        moveToJustPastBoundsAndBackup(boundEnd + 1, Integer.MAX_VALUE, a -> a.getBegin() > boundEnd);
+        break;
+      
+      case covering:
+        Misc.internalError();  // not yet implemented
+        break;
+
+      case sameBeginEnd:
+        moveToJustPastBoundsAndBackup(boundBegin,  boundEnd + 1, 
+            a -> a.getBegin() != boundBegin ||
+                 a.getEnd() != boundEnd);
+        break;
+      }
+    } 
+  }
+
+  private void moveToJustPastBoundsAndBackup(int begin, int end, Predicate<Annotation> goBackwards) {
+    it.moveTo(new Annotation (jcas, begin, end));
+    if (it.isValid()) {
+      Annotation a = it.getNvc();
+      while (goBackwards.test(a)) {
+        if (a._id == startId) {
+          assert a.getBegin() <= boundEnd; // because it's non-empty
+            // use this as the last
+          break;  // still need to adjust for strict and bound skip
+        } 
+        it.moveToPreviousNvc();
+        adjustForStrictAndBoundSkip(false);
+        if (!it.isValid()) {
+          break;
         }
-      } else {
-        it.moveToLast(); 
+        a = it.getNvc();
       }
-      
-      adjustForStrictAndBoundSkip(false);   // false - moving backwards
-      
+    } else {
+      it.moveToLast();
+      adjustForStrictAndBoundSkip(false);
     }
   }
-
   // default visibility - referred to by flat iterator
   static Comparator<AnnotationFS> getAnnotationBeginEndComparator(final int boundingBegin, final int boundingEnd) {
     return new Comparator<AnnotationFS>() {
@@ -683,7 +752,7 @@ public class Subiterator<T extends Annot
         this.boundingAnnot, 
         this.isAmbiguous,
         this.isStrict,
-        this.isBounded,
+        this.boundsUse,
         this.isTypePriority, 
         this.isPositionUsesType, 
         this.isSkipEquals,
@@ -704,7 +773,7 @@ public class Subiterator<T extends Annot
 
   @Override
   public LowLevelIndex<T> ll_getIndex() {
-    throw new UnsupportedOperationException();
+    return ((LowLevelIterator<T>)it).ll_getIndex();
   }
 
 

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/impl/JCasImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/impl/JCasImpl.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/impl/JCasImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/impl/JCasImpl.java Mon Oct  3 19:04:54 2016
@@ -1151,7 +1151,7 @@ public class JCasImpl extends AbstractCa
   /**
    * Static method to get the corresponding Type for a JCas class object 
    */
-  private static int getTypeRegistryIndex(Class<? extends TOP> clazz) {
+  private static int getTypeRegistryIndex(Class<? extends FeatureStructure> clazz) {
     try {
       return clazz.getField("type").getInt(clazz);
     } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
@@ -1165,7 +1165,7 @@ public class JCasImpl extends AbstractCa
    * @param clazz a JCas cover class
    * @return the corresponding UIMA Type object
    */
-  public Type getCasType(Class<? extends TOP> clazz) {
+  public Type getCasType(Class<? extends FeatureStructure> clazz) {
     return getCasType(getTypeRegistryIndex(clazz));
   }
 

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties Mon Oct  3 19:04:54 2016
@@ -602,6 +602,9 @@ TYPESYSTEMS_NOT_COMMITTED = Type Systems
 ADD_ARRAY_TYPE_AFTER_TS_COMMITTED = Can''t add an array type "{0}" to the type system after the type system has been committed.
 FS_NOT_MEMBER_OF_CAS = Feature Structure {0} belongs to CAS {1}, may not be set as the value of an array or list element in a different CAS {2}.
 ILLEGAL_ADD_TO_INDEX_IN_BASE_CAS = Illegal operation - cannot add Feature Structure {0} to base CAS {1}.
+SELECT_GET_NO_INSTANCES = CAS does not contain any ''{0}'' instances {1}.
+SELECT_GET_TOO_MANY_INSTANCES = CAS has more than 1 instance of ''{0}''{1}.
+ANNOTATION_INDEX_REQUIRED = Index "{0}" must be an AnnotationIndex.
 
 #------------------------------------------------------------------------
 # Serialization / deserialization runtime exceptions

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java?rev=1763195&r1=1763194&r2=1763195&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java Mon Oct  3 19:04:54 2016
@@ -27,10 +27,12 @@ import org.apache.uima.cas.CASRuntimeExc
 import org.apache.uima.cas.FSIndexRepository;
 import org.apache.uima.cas.FSIterator;
 import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.SelectFSs;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas.text.AnnotationIndex;
+import org.apache.uima.jcas.tcas.Annotation;
 
 import junit.framework.TestCase;
 
@@ -240,8 +242,10 @@ public class AnnotationIteratorTest exte
     it = tokenIndex.subiterator(a1);
     // make a new iterator that hasn't been converted to a list form internally
     it.moveTo(cas.getDocumentAnnotation());
-    assertFalse(it.isValid());            
+    assertFalse(it.isValid()); 
+        
   }
+  
   /**
    * The tests include:
    *   a) running with / w/o "flattened" indexes
@@ -267,32 +271,59 @@ public class AnnotationIteratorTest exte
     AnnotationIndex<AnnotationFS> annotIndex = this.cas.getAnnotationIndex();
     AnnotationIndex<AnnotationFS> sentIndex = this.cas.getAnnotationIndex(sentenceType);
     FSIterator<AnnotationFS> it = annotIndex.iterator(true);  // a normal "ambiguous" iterator
+    FSIterator<AnnotationFS> select_it = cas.<AnnotationFS>select().fsIterator();
 //    assertTrue((isSave) ? it instanceof FSIteratorWrapper : 
 //      FSIndexFlat.enabled ? it instanceof FSIndexFlat.FSIteratorFlat : it instanceof FSIteratorWrapper);   
     assertCount("Normal ambiguous annot iterator", annotCount, it);
+    assertCount("Normal ambiguous select annot iterator", annotCount, select_it);
     
     it = annotIndex.iterator(false);  // false means create an unambiguous iterator
     assertCount("Unambiguous annot iterator", 1, it);  // because of document Annotation - spans the whole range
+    select_it = cas.<AnnotationFS>select().nonOverlapping().fsIterator();
+    assertCount("Unambiguous select annot iterator", 1, select_it);  // because of document Annotation - spans the whole range
     
     it = sentIndex.iterator(false);  //  false means create an unambiguous iterator
     assertCount("Unambigous sentence iterator", 5, it);
+    select_it = cas.<AnnotationFS>select(sentenceType).nonOverlapping(true).fsIterator();
+    assertCount("Unambigous select sentence iterator", 5, select_it);
+    select_it = sentIndex.<AnnotationFS>select().nonOverlapping().fsIterator();
+    assertCount("Unambigous select sentence iterator", 5, select_it);
+    select_it = SelectFSs.sselect(sentIndex).nonOverlapping().fsIterator();
+    assertCount("Unambigous select sentence iterator", 5, select_it);
+    
     
     AnnotationFS bigBound = this.cas.createAnnotation(this.sentenceType, 10, 41);
     it = annotIndex.subiterator(bigBound, true, true);  // ambiguous, and strict
     assertCount("Subiterator over annot with big bound, strict", 33, it);
+    select_it = cas.<AnnotationFS>select().coveredBy((Annotation) bigBound).endWithinBounds().fsIterator();
+    assertCount("Subiterator select over annot with big bound, strict", 33, select_it);
     
     it = annotIndex.subiterator(bigBound, false, true);  // unambiguous, strict
     assertCount("Subiterator over annot unambiguous strict", 3, it);
+    select_it = cas.<AnnotationFS>select().coveredBy((Annotation) bigBound).endWithinBounds().nonOverlapping().fsIterator();
+    assertCount("Subiterator select over annot unambiguous strict", 3, select_it);
 
     it = annotIndex.subiterator(bigBound, true, false);
     assertCount("Subiterator over annot ambiguous not-strict", 40, it);
     
+    // covered by implies endWithinBounds
+    select_it = SelectFSs.sselect(annotIndex).coveredBy(bigBound).fsIterator();
+    assertCount("Subiterator select over annot ambiguous not-strict", 33, select_it);
+    select_it = annotIndex.<AnnotationFS>select().coveredBy(bigBound).fsIterator();
+    assertCount("Subiterator select over annot ambiguous not-strict", 33, select_it);
+    select_it = SelectFSs.sselect(annotIndex).coveredBy(bigBound).endWithinBounds(false).fsIterator();
+    assertCount("Subiterator select over annot ambiguous not-strict", 40, select_it);
+    
     it = annotIndex.subiterator(bigBound, false, false);  // unambiguous, not strict
     assertCount("Subiterator over annot, unambiguous, not-strict", 4, it);
+    select_it = SelectFSs.sselect(annotIndex).nonOverlapping().coveredBy(bigBound).endWithinBounds(false).fsIterator();
+    assertCount("Subiterator select over annot unambiguous not-strict", 4, select_it);
     
     AnnotationFS sent = this.cas.getAnnotationIndex(this.sentenceType).iterator().get();
     it = annotIndex.subiterator(sent, false, true);
     assertCount("Subiterator over annot unambiguous strict", 2, it);
+    select_it = annotIndex.<AnnotationFS>select().nonOverlapping().coveredBy(sent).fsIterator();
+    assertCount("Subiterator select over annot unambiguous strict", 2, select_it);
     
     // strict skips first item
     bigBound = this.cas.createAnnotation(this.sentenceType,  11, 30);
@@ -308,7 +339,7 @@ public class AnnotationIteratorTest exte
     return s + (isSave ? "" : " with flattened index");
   }
   
-  private void assertCount(String msg, int expected,  FSIterator<AnnotationFS> it) {
+  private void assertCount(String msg, int expected,  FSIterator<? extends AnnotationFS> it) {
     msg = flatStateMsg(msg);
     int count = 0;
     callCount  ++;
@@ -409,17 +440,31 @@ public class AnnotationIteratorTest exte
     cas.addFsToIndexes(cas.createAnnotation(this.sentenceType, 0, 25));
     cas.addFsToIndexes(cas.createAnnotation(this.sentenceType, 26, 52));
     cas.addFsToIndexes(cas.createAnnotation(this.tokenType, 48, 51));
-
+    AnnotationIndex<AnnotationFS> tokenIdx = cas.getAnnotationIndex(this.tokenType);
+    
     AnnotationIndex<AnnotationFS> si = cas.getAnnotationIndex(this.sentenceType);
     for (AnnotationFS sa : si) {
-      AnnotationIndex<AnnotationFS> ti = cas.getAnnotationIndex(this.tokenType);
-      FSIterator<AnnotationFS> ti2 = ti.subiterator(sa, false, false);
+      FSIterator<AnnotationFS> ti2 = tokenIdx.subiterator(sa, false, false);
       
       while (ti2.hasNext()) {
         AnnotationFS t = ti2.next();
         assertTrue("Subiterator returned annotation outside boundaries", t.getBegin() < sa.getEnd());
       }
     }
+
+    SelectFSs<AnnotationFS> ssi = cas.getAnnotationIndex(this.sentenceType).select();
+    
+    for (AnnotationFS sa : ssi) {
+    
+      FSIterator<AnnotationFS> ti2 = tokenIdx.<AnnotationFS>select()
+          .coveredBy(sa).endWithinBounds(false).nonOverlapping().fsIterator();
+      
+      while (ti2.hasNext()) {
+        AnnotationFS t = ti2.next();
+        assertTrue("Subiterator returned annotation outside boundaries", t.getBegin() < sa.getEnd());
+      }
+    }
+
   }
 
   public static void main(String[] args) {