diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/action/GetListAction.java b/ruta-core/src/main/java/org/apache/uima/ruta/action/GetListAction.java
index cf1a3bd..95c24c0 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/action/GetListAction.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/action/GetListAction.java
@@ -23,6 +23,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.uima.cas.Type;
@@ -71,30 +72,30 @@
     for (AnnotationFS matched : matchedAnnotations) {
 
       if (TYPES_AT_BEGIN.equals(op)) {
-        RutaBasic beginAnchor = stream.getBeginAnchor(matched.getBegin());
-        Collection<?>[] beginMap = beginAnchor.getBeginMap();
-        Set<AnnotationFS> aset = new HashSet<AnnotationFS>();
-        for (Collection<?> set : beginMap) {
-          if (set != null) {
-            aset.addAll((Collection<? extends AnnotationFS>) set);
-          }
-        }
-        for (AnnotationFS annotationFS : aset) {
-          list.add(annotationFS.getType());
-        }
+//        RutaBasic beginAnchor = stream.getBeginAnchor(matched.getBegin());
+//        Map<Integer, Collection<?>> beginMap = beginAnchor.getBeginMap();
+//        Set<AnnotationFS> aset = new HashSet<AnnotationFS>();
+//        for (Collection<?> set : beginMap.values()) {
+//          if (set != null) {
+//            aset.addAll((Collection<? extends AnnotationFS>) set);
+//          }
+//        }
+//        for (AnnotationFS annotationFS : aset) {
+//          list.add(annotationFS.getType());
+//        }
       } else if (TYPES_AT_END.equals(op)) {
-        RutaBasic endAnchor = stream.getEndAnchor(matched.getEnd());
-        // Collection<Set<AnnotationFS>> values = endAnchor.getEndMap().values();
-        Collection<?>[] endMap = endAnchor.getEndMap();
-        Set<AnnotationFS> aset = new HashSet<AnnotationFS>();
-        for (Collection<?> set : endMap) {
-          if (set != null) {
-            aset.addAll((Collection<? extends AnnotationFS>) set);
-          }
-        }
-        for (AnnotationFS annotationFS : aset) {
-          list.add(annotationFS.getType());
-        }
+//        RutaBasic endAnchor = stream.getEndAnchor(matched.getEnd());
+//        // Collection<Set<AnnotationFS>> values = endAnchor.getEndMap().values();
+//        Map<Integer, Collection<?>> endMap = endAnchor.getEndMap();
+//        Set<AnnotationFS> aset = new HashSet<AnnotationFS>();
+//        for (Collection<?> set : endMap.values()) {
+//          if (set != null) {
+//            aset.addAll((Collection<? extends AnnotationFS>) set);
+//          }
+//        }
+//        for (AnnotationFS annotationFS : aset) {
+//          list.add(annotationFS.getType());
+//        }
       } else if (TYPES.equals(op)) {
         Type annotationType = stream.getCas().getAnnotationType();
         List<AnnotationFS> inWindow = stream.getAnnotationsInWindow(matched, annotationType);
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/engine/MemoryFootprintTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/engine/MemoryFootprintTest.java
new file mode 100644
index 0000000..b17c503
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/engine/MemoryFootprintTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ruta.engine;
+
+import java.util.Collection;
+
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.fit.factory.AnalysisEngineFactory;
+import org.apache.uima.fit.factory.JCasFactory;
+import org.apache.uima.fit.util.JCasUtil;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.ruta.type.TruePositive;
+import org.junit.Test;
+
+public class MemoryFootprintTest {
+
+  public static void main(String[] args) throws Exception {
+//     Thread.sleep(20000);
+
+    System.out.println("Start");
+    new MemoryFootprintTest().test();
+    new MemoryFootprintTest().test();
+//    new MemoryFootprintTest().test();
+//    new MemoryFootprintTest().test();
+  }
+
+  @Test
+  public void test() throws Exception {
+
+    int lines = 25000;
+    String line = "This is a simple line with a number like 24 and some special characters like %&$.\n";
+    String rules = "CW SW{-> TruePositive};CW SW{-> TruePositive};CW SW{-> TruePositive};CW SW{-> TruePositive};CW SW{-> TruePositive};";
+
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < lines; i++) {
+      sb.append(line);
+    }
+
+    JCas jcas = JCasFactory.createJCas();
+    jcas.setDocumentText(sb.toString());
+
+    AnalysisEngine ae = AnalysisEngineFactory.createEngine(RutaEngine.class, RutaEngine.PARAM_RULES,
+            rules);
+
+    long start = System.currentTimeMillis();
+    ae.process(jcas);
+    long end = System.currentTimeMillis();
+    System.out.println("took " + (end - start) / 1000);
+    System.out.println("freeMemory " + Runtime.getRuntime().freeMemory() / 1000000);
+    System.out.println("maxMemory " + Runtime.getRuntime().maxMemory() / 1000000);
+    System.out.println("totalMemory " + Runtime.getRuntime().totalMemory() / 1000000);
+
+    Collection<TruePositive> select = JCasUtil.select(jcas, TruePositive.class);
+    System.out.println("TruePositive: " + select.size());
+    jcas.release();
+  }
+
+}
diff --git a/ruta-typesystem/pom.xml b/ruta-typesystem/pom.xml
index 9347fd1..34f05bc 100644
--- a/ruta-typesystem/pom.xml
+++ b/ruta-typesystem/pom.xml
@@ -30,6 +30,11 @@
   <name>Apache UIMA Ruta: ${project.artifactId}</name>
   <dependencies>
     <dependency>
+        <groupId>it.unimi.dsi</groupId>
+        <artifactId>fastutil</artifactId>
+        <version>7.1.0</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.uima</groupId>
       <artifactId>uimaj-core</artifactId>
       <version>${uimaVersion}</version>
diff --git a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic.java b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic.java
index a2b80f6..6cd6f45 100644
--- a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic.java
+++ b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic.java
@@ -23,20 +23,25 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.FeatureStructureImpl;
+import org.apache.uima.cas.impl.LowLevelCAS;
 import org.apache.uima.cas.impl.TypeImpl;
-import org.apache.uima.cas.impl.TypeSystemImpl;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.jcas.JCas;
 import org.apache.uima.jcas.JCasRegistry;
 import org.apache.uima.jcas.cas.TOP_Type;
 import org.apache.uima.jcas.tcas.Annotation;
 
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+
 /**
- * Updated by JCasGen Thu Jul 12 10:42:33 CEST 2012 XML source:
- * D:/work/workspace-uima6/uimaj-ruta/src
- * /main/java/org/apache/uima/ruta/engine/InternalTypeSystem.xml
  * 
  * @generated
  */
@@ -44,19 +49,17 @@
 
   private static final int INITIAL_CAPACITY = 2;
 
-  private static final String ROOT_TYPE1 = "uima.tcas.Annotation";
+  private static final String ROOT_TYPE1 = CAS.TYPE_NAME_ANNOTATION;
 
-  private static final String ROOT_TYPE2 = "uima.cas.AnnotationBase";
+  private static final String ROOT_TYPE2 = CAS.TYPE_NAME_ANNOTATION_BASE;
 
   private boolean lowMemoryProfile = false;
 
-  private int[] partOf = new int[((TypeSystemImpl) getCAS().getTypeSystem()).getLargestTypeCode()];
+  private Int2IntOpenHashMap partOf;
 
-  private Collection<?>[] beginMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
-          .getLargestTypeCode()];
+  private Int2ObjectOpenHashMap<IntArrayList> beginMap;
 
-  private Collection<?>[] endMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
-          .getLargestTypeCode()];
+  private Int2ObjectOpenHashMap<IntArrayList> endMap;
 
   private boolean empty = true;
 
@@ -78,7 +81,10 @@
   }
 
   private void addPartOf(int code) {
-    partOf[code] = partOf[code] + 1;
+    if (partOf == null) {
+      partOf = new Int2IntOpenHashMap();
+    }
+    partOf.addTo(code, 1);
     if (!lowMemoryProfile) {
       int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
       if (parentCode > 0) {
@@ -93,8 +99,8 @@
   }
 
   private void removePartOf(int code) {
-    if (partOf[code] != 0) {
-      partOf[code] = partOf[code] - 1;
+    if (partOf != null && partOf.get(code) != 0) {
+      partOf.addTo(code, -1);
       if (!lowMemoryProfile) {
         int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
         if (parentCode > 0) {
@@ -105,8 +111,11 @@
   }
 
   public boolean isPartOf(Type type) {
+    if (partOf == null) {
+      return false;
+    }
     int code = ((TypeImpl) type).getCode();
-    int count = partOf[code];
+    int count = partOf.get(code);
     if (count > 0) {
       return true;
     }
@@ -114,7 +123,7 @@
       List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
       for (Type each : subsumedTypes) {
         int code2 = ((TypeImpl) each).getCode();
-        int count2 = partOf[code2];
+        int count2 = partOf.get(code2);
         if (count2 > 0) {
           return true;
         }
@@ -125,71 +134,78 @@
 
   }
 
-  public void setPartOf(int[] partOf) {
+  public void setPartOf(Int2IntOpenHashMap partOf) {
     this.partOf = partOf;
   }
-  
-  public int[] getPartOf() {
+
+  public Int2IntOpenHashMap getPartOf() {
     return partOf;
   }
-  
-  @SuppressWarnings("unchecked")
+
   public Collection<AnnotationFS> getBeginAnchors(Type type) {
+    if (beginMap == null) {
+      return Collections.emptyList();
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<AnnotationFS> set = (Collection<AnnotationFS>) beginMap[code];
+    IntArrayList list = beginMap.get(code);
     if (lowMemoryProfile) {
-      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
-      if (set != null) {
-        result.addAll(set);
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>(list.size());
+      if (list != null) {
+        result.addAll(adressToAnnotationList(list));
       }
       List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
       for (Type each : subsumedTypes) {
         int parentCode = ((TypeImpl) each).getCode();
-        Collection<?> c = beginMap[parentCode];
+        IntArrayList c = beginMap.get(parentCode);
         if (c != null) {
-          result.addAll((Collection<? extends AnnotationFS>) c);
+          result.addAll(adressToAnnotationList(c));
         }
       }
       return result;
     } else {
-      if (set == null) {
+      if (list == null) {
         return Collections.emptySet();
       } else {
-        return set;
+        return adressToAnnotationList(list);
       }
     }
   }
 
-  @SuppressWarnings("unchecked")
   public Collection<AnnotationFS> getEndAnchors(Type type) {
+    if (endMap == null) {
+      return Collections.emptyList();
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<AnnotationFS> set = (Collection<AnnotationFS>) endMap[code];
+    IntArrayList list = endMap.get(code);
     if (lowMemoryProfile) {
-      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
-      if (set != null) {
-        result.addAll(set);
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>(list.size());
+      if (list != null) {
+        result.addAll(adressToAnnotationList(list));
       }
       List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
       for (Type each : subsumedTypes) {
         int parentCode = ((TypeImpl) each).getCode();
-        Collection<?> c = endMap[parentCode];
+        IntArrayList c = endMap.get(parentCode);
         if (c != null) {
-          result.addAll((Collection<? extends AnnotationFS>) c);
+          result.addAll(adressToAnnotationList(c));
         }
       }
       return result;
     } else {
-      if (set == null) {
+      if (list == null) {
         return Collections.emptySet();
       } else {
-        return set;
+        return adressToAnnotationList(list);
       }
     }
   }
 
   public boolean beginsWith(Type type) {
+    if (beginMap == null) {
+      return false;
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<?> set = beginMap[code];
+    Collection<?> set = beginMap.get(code);
     boolean beginsWith = set != null && !set.isEmpty();
     if (beginsWith) {
       return true;
@@ -206,8 +222,11 @@
   }
 
   public boolean endsWith(Type type) {
+    if (endMap == null) {
+      return false;
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<?> set = endMap[code];
+    Collection<?> set = endMap.get(code);
     boolean endswith = set != null && !set.isEmpty();
     if (endswith) {
       return true;
@@ -223,16 +242,18 @@
     return false;
   }
 
-  @SuppressWarnings("unchecked")
   public void addBegin(AnnotationFS annotation, Type type) {
+    if (beginMap == null) {
+      beginMap = new Int2ObjectOpenHashMap<>();
+    }
     empty = false;
     int code = ((TypeImpl) type).getCode();
-    Collection<Object> set = (Collection<Object>) beginMap[code];
-    if (set == null) {
-      set = new ArrayList<Object>(INITIAL_CAPACITY);
-      beginMap[code] = set;
+    IntArrayList list = beginMap.get(code);
+    if (list == null) {
+      list = new IntArrayList(INITIAL_CAPACITY);
+      beginMap.put(code, list);
     }
-    set.add(annotation);
+    list.add(annotationToAddress(annotation));
     if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
             && !type.getName().equals(ROOT_TYPE2)) {
       TypeSystem typeSystem = getCAS().getTypeSystem();
@@ -243,16 +264,18 @@
     }
   }
 
-  @SuppressWarnings("unchecked")
   public void addEnd(AnnotationFS annotation, Type type) {
+    if (endMap == null) {
+      endMap = new Int2ObjectOpenHashMap<>();
+    }
     empty = false;
     int code = ((TypeImpl) type).getCode();
-    Collection<Object> set = (Collection<Object>) endMap[code];
-    if (set == null) {
-      set = new ArrayList<Object>(INITIAL_CAPACITY);
-      endMap[code] = set;
+    IntArrayList list = endMap.get(code);
+    if (list == null) {
+      list = new IntArrayList(INITIAL_CAPACITY);
+      endMap.put(code, list);
     }
-    set.add(annotation);
+    list.add(annotationToAddress(annotation));
     if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
             && !type.getName().equals(ROOT_TYPE2)) {
       TypeSystem typeSystem = getCAS().getTypeSystem();
@@ -263,14 +286,16 @@
     }
   }
 
-  @SuppressWarnings("unchecked")
   public void removeBegin(AnnotationFS annotation, Type type) {
+    if (beginMap == null) {
+      return;
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<Object> set = (Collection<Object>) beginMap[code];
-    if (set != null) {
-      set.remove(annotation);
-      if (set.isEmpty()) {
-        beginMap[code] = null;
+    IntArrayList list = beginMap.get(code);
+    if (list != null) {
+      list.removeInt(annotationToAddress(annotation));
+      if (list.isEmpty()) {
+        beginMap.remove(code);
       }
     }
     if (!lowMemoryProfile) {
@@ -282,14 +307,16 @@
     }
   }
 
-  @SuppressWarnings("unchecked")
   public void removeEnd(AnnotationFS annotation, Type type) {
+    if (endMap == null) {
+      return;
+    }
     int code = ((TypeImpl) type).getCode();
-    Collection<Object> set = (Collection<Object>) endMap[code];
-    if (set != null) {
-      set.remove(annotation);
-      if (set.isEmpty()) {
-        endMap[code] = null;
+    IntArrayList list = endMap.get(code);
+    if (list != null) {
+      list.removeInt(annotationToAddress(annotation));
+      if (list.isEmpty()) {
+        endMap.remove(code);
       }
     }
     if (!lowMemoryProfile) {
@@ -301,28 +328,30 @@
     }
   }
 
-  public Collection<?>[] getBeginMap() {
+  public Int2ObjectOpenHashMap<IntArrayList> getBeginMap() {
     return beginMap;
   }
 
-  public Collection<?>[] getEndMap() {
+  public Int2ObjectOpenHashMap<IntArrayList> getEndMap() {
     return endMap;
   }
 
-  public void setBeginMap(Collection<?>[] beginMap) {
+  public void setBeginMap(Int2ObjectOpenHashMap<IntArrayList> beginMap) {
     this.beginMap = beginMap;
-    for (Collection<?> each : beginMap) {
-      if (each != null && !each.isEmpty()) {
+    for (Entry<IntArrayList> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
         this.empty = false;
         break;
       }
     }
   }
 
-  public void setEndMap(Collection<?>[] endMap) {
+  public void setEndMap(Int2ObjectOpenHashMap<IntArrayList> endMap) {
     this.endMap = endMap;
-    for (Collection<?> each : endMap) {
-      if (each != null && !each.isEmpty()) {
+    for (Entry<IntArrayList> entry : endMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
         this.empty = false;
         break;
       }
@@ -330,20 +359,40 @@
   }
 
   public void clearBeginMap() {
-    this.beginMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
-            .getLargestTypeCode()];
+    this.beginMap.clear();
   }
 
   public void clearEndMap() {
-    this.endMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem()).getLargestTypeCode()];
-    for (Collection<?> each : beginMap) {
-      if (each != null && !each.isEmpty()) {
-        return;
+    this.endMap.clear();
+    if (beginMap != null) {
+      for (Entry<IntArrayList> entry : beginMap.int2ObjectEntrySet()) {
+        Collection<?> value = entry.getValue();
+        if (value != null && !value.isEmpty()) {
+          return;
+        }
       }
     }
     this.empty = true;
   }
 
+  private Collection<AnnotationFS> adressToAnnotationList(IntArrayList addressList) {
+    List<AnnotationFS> result = new ArrayList<>(addressList.size());
+    for (int value : addressList) {
+      result.add(addressToAnnotation(value));
+    }
+    return result;
+  }
+
+  private int annotationToAddress(AnnotationFS annotation) {
+    return ((FeatureStructureImpl) annotation).getAddress();
+  }
+
+  private AnnotationFS addressToAnnotation(int address) {
+    LowLevelCAS lowLevelCAS = getCASImpl().getLowLevelCAS();
+    FeatureStructure fs = lowLevelCAS.ll_getFSForRef(address);
+    return (AnnotationFS) fs;
+  }
+
   /**
    * @generated
    * @ordered
diff --git a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic1.java b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic1.java
new file mode 100644
index 0000000..6df0050
--- /dev/null
+++ b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic1.java
@@ -0,0 +1,428 @@
+/*
+ * 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.ruta.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.TypeImpl;
+import org.apache.uima.cas.impl.TypeSystemImpl;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.JCasRegistry;
+import org.apache.uima.jcas.cas.TOP_Type;
+import org.apache.uima.jcas.tcas.Annotation;
+
+/**
+ * 
+ * @generated
+ */
+public class RutaBasic1 extends Annotation {
+
+  private static final int INITIAL_CAPACITY = 2;
+
+  private static final String ROOT_TYPE1 = "uima.tcas.Annotation";
+
+  private static final String ROOT_TYPE2 = "uima.cas.AnnotationBase";
+
+  private boolean lowMemoryProfile = false;
+
+  private int[] partOf = new int[((TypeSystemImpl) getCAS().getTypeSystem()).getLargestTypeCode()];
+
+  private Collection<?>[] beginMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
+          .getLargestTypeCode()];
+
+  private Collection<?>[] endMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
+          .getLargestTypeCode()];
+
+  private boolean empty = true;
+
+  public boolean isEmpty() {
+    return empty;
+  }
+
+  public boolean isLowMemoryProfile() {
+    return lowMemoryProfile;
+  }
+
+  public void setLowMemoryProfile(boolean lowMemoryProfile) {
+    this.lowMemoryProfile = lowMemoryProfile;
+  }
+
+  public void addPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    addPartOf(code);
+  }
+
+  private void addPartOf(int code) {
+    partOf[code] = partOf[code] + 1;
+    if (!lowMemoryProfile) {
+      int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+      if (parentCode > 0) {
+        addPartOf(parentCode);
+      }
+    }
+  }
+
+  public void removePartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    removePartOf(code);
+  }
+
+  private void removePartOf(int code) {
+    if (partOf[code] != 0) {
+      partOf[code] = partOf[code] - 1;
+      if (!lowMemoryProfile) {
+        int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+        if (parentCode > 0) {
+          removePartOf(parentCode);
+        }
+      }
+    }
+  }
+
+  public boolean isPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    int count = partOf[code];
+    if (count > 0) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int code2 = ((TypeImpl) each).getCode();
+        int count2 = partOf[code2];
+        if (count2 > 0) {
+          return true;
+        }
+      }
+
+    }
+    return false;
+
+  }
+
+  public void setPartOf(int[] partOf) {
+    this.partOf = partOf;
+  }
+  
+  public int[] getPartOf() {
+    return partOf;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getBeginAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) beginMap[code];
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c = beginMap[parentCode];
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getEndAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) endMap[code];
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c = endMap[parentCode];
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  public boolean beginsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = beginMap[code];
+    boolean beginsWith = set != null && !set.isEmpty();
+    if (beginsWith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (beginsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public boolean endsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = endMap[code];
+    boolean endswith = set != null && !set.isEmpty();
+    if (endswith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (endsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addBegin(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap[code];
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      beginMap[code] = set;
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addEnd(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap[code];
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      endMap[code] = set;
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addEnd(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeBegin(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap[code];
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        beginMap[code] = null;
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeEnd(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap[code];
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        endMap[code] = null;
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeEnd(annotation, parent);
+      }
+    }
+  }
+
+  public Collection<?>[] getBeginMap() {
+    return beginMap;
+  }
+
+  public Collection<?>[] getEndMap() {
+    return endMap;
+  }
+
+  public void setBeginMap(Collection<?>[] beginMap) {
+    this.beginMap = beginMap;
+    for (Collection<?> each : beginMap) {
+      if (each != null && !each.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void setEndMap(Collection<?>[] endMap) {
+    this.endMap = endMap;
+    for (Collection<?> each : endMap) {
+      if (each != null && !each.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void clearBeginMap() {
+    this.beginMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem())
+            .getLargestTypeCode()];
+  }
+
+  public void clearEndMap() {
+    this.endMap = new ArrayList<?>[((TypeSystemImpl) getCAS().getTypeSystem()).getLargestTypeCode()];
+    for (Collection<?> each : beginMap) {
+      if (each != null && !each.isEmpty()) {
+        return;
+      }
+    }
+    this.empty = true;
+  }
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int typeIndexID = JCasRegistry.register(RutaBasic1.class);
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int type = typeIndexID;
+
+  /** @generated */
+  @Override
+  public int getTypeIndexID() {
+    return typeIndexID;
+  }
+
+  /**
+   * Never called. Disable default constructor
+   * 
+   * @generated
+   */
+  protected RutaBasic1() {/* intentionally empty block */
+  }
+
+  /**
+   * Internal - constructor used by generator
+   * 
+   * @generated
+   */
+  public RutaBasic1(int addr, TOP_Type type) {
+    super(addr, type);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic1(JCas jcas) {
+    super(jcas);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic1(JCas jcas, int begin, int end) {
+    super(jcas);
+    setBegin(begin);
+    setEnd(end);
+    readObject();
+  }
+
+  /**
+   * <!-- begin-user-doc --> Write your own initialization here <!-- end-user-doc -->
+   * 
+   * @generated modifiable
+   */
+  private void readObject() {
+  }
+
+  // *--------------*
+  // * Feature: Replacement
+
+  /**
+   * getter for Replacement - gets
+   * 
+   * @generated
+   */
+  public String getReplacement() {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    return jcasType.ll_cas.ll_getStringValue(addr,
+            ((RutaBasic_Type) jcasType).casFeatCode_replacement);
+  }
+
+  /**
+   * setter for Replacement - sets
+   * 
+   * @generated
+   */
+  public void setReplacement(String v) {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    jcasType.ll_cas.ll_setStringValue(addr, ((RutaBasic_Type) jcasType).casFeatCode_replacement, v);
+  }
+
+}
diff --git a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic2.java b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic2.java
new file mode 100644
index 0000000..5f153db
--- /dev/null
+++ b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic2.java
@@ -0,0 +1,431 @@
+/*
+ * 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.ruta.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.TypeImpl;
+import org.apache.uima.cas.impl.TypeSystemImpl;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.JCasRegistry;
+import org.apache.uima.jcas.cas.TOP_Type;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+
+/**
+ * 
+ * @generated
+ */
+public class RutaBasic2 extends Annotation {
+
+  private static final int INITIAL_CAPACITY = 2;
+
+  private static final String ROOT_TYPE1 = CAS.TYPE_NAME_ANNOTATION;
+
+  private static final String ROOT_TYPE2 = CAS.TYPE_NAME_ANNOTATION_BASE;
+
+  private boolean lowMemoryProfile = false;
+
+  private int[] partOf = new int[((TypeSystemImpl) getCAS().getTypeSystem()).getLargestTypeCode()];
+
+  private Int2ObjectOpenHashMap<Collection<?>> beginMap = new Int2ObjectOpenHashMap<>();
+  private Int2ObjectOpenHashMap<Collection<?>> endMap = new Int2ObjectOpenHashMap<>();
+  
+  private boolean empty = true;
+
+  public boolean isEmpty() {
+    return empty;
+  }
+
+  public boolean isLowMemoryProfile() {
+    return lowMemoryProfile;
+  }
+
+  public void setLowMemoryProfile(boolean lowMemoryProfile) {
+    this.lowMemoryProfile = lowMemoryProfile;
+  }
+
+  public void addPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    addPartOf(code);
+  }
+
+  private void addPartOf(int code) {
+    partOf[code] = partOf[code] + 1;
+    if (!lowMemoryProfile) {
+      int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+      if (parentCode > 0) {
+        addPartOf(parentCode);
+      }
+    }
+  }
+
+  public void removePartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    removePartOf(code);
+  }
+
+  private void removePartOf(int code) {
+    if (partOf[code] != 0) {
+      partOf[code] = partOf[code] - 1;
+      if (!lowMemoryProfile) {
+        int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+        if (parentCode > 0) {
+          removePartOf(parentCode);
+        }
+      }
+    }
+  }
+
+  public boolean isPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    int count = partOf[code];
+    if (count > 0) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int code2 = ((TypeImpl) each).getCode();
+        int count2 = partOf[code2];
+        if (count2 > 0) {
+          return true;
+        }
+      }
+
+    }
+    return false;
+
+  }
+
+  public void setPartOf(int[] partOf) {
+    this.partOf = partOf;
+  }
+  
+  public int[] getPartOf() {
+    return partOf;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getBeginAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) beginMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c =  beginMap.get(parentCode);
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getEndAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) endMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c = endMap.get(parentCode);
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  public boolean beginsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = beginMap.get(code);
+    boolean beginsWith = set != null && !set.isEmpty();
+    if (beginsWith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (beginsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public boolean endsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = endMap.get(code);
+    boolean endswith = set != null && !set.isEmpty();
+    if (endswith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (endsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addBegin(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap.get(code);
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      beginMap.put(code, set);
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addEnd(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap.get(code);
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      endMap.put(code, set);
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addEnd(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeBegin(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap.get(code);
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        beginMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeEnd(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap.get(code);
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        endMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeEnd(annotation, parent);
+      }
+    }
+  }
+
+  public Int2ObjectOpenHashMap<Collection<?>> getBeginMap() {
+    return beginMap;
+  }
+
+  public Int2ObjectOpenHashMap<Collection<?>> getEndMap() {
+    return endMap;
+  }
+
+  public void setBeginMap(Int2ObjectOpenHashMap<Collection<?>> beginMap) {
+    this.beginMap = beginMap;
+    for (Entry<Collection<?>> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void setEndMap(Int2ObjectOpenHashMap<Collection<?>> endMap) {
+    this.endMap = endMap;
+    for (Entry<Collection<?>> entry : endMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void clearBeginMap() {
+    this.beginMap.clear();;
+  }
+
+  public void clearEndMap() {
+    this.endMap.clear();
+    for (Entry<Collection<?>> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        return;
+      }
+    }
+    this.empty = true;
+  }
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int typeIndexID = JCasRegistry.register(RutaBasic2.class);
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int type = typeIndexID;
+
+  /** @generated */
+  @Override
+  public int getTypeIndexID() {
+    return typeIndexID;
+  }
+
+  /**
+   * Never called. Disable default constructor
+   * 
+   * @generated
+   */
+  protected RutaBasic2() {/* intentionally empty block */
+  }
+
+  /**
+   * Internal - constructor used by generator
+   * 
+   * @generated
+   */
+  public RutaBasic2(int addr, TOP_Type type) {
+    super(addr, type);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic2(JCas jcas) {
+    super(jcas);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic2(JCas jcas, int begin, int end) {
+    super(jcas);
+    setBegin(begin);
+    setEnd(end);
+    readObject();
+  }
+
+  /**
+   * <!-- begin-user-doc --> Write your own initialization here <!-- end-user-doc -->
+   * 
+   * @generated modifiable
+   */
+  private void readObject() {
+  }
+
+  // *--------------*
+  // * Feature: Replacement
+
+  /**
+   * getter for Replacement - gets
+   * 
+   * @generated
+   */
+  public String getReplacement() {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    return jcasType.ll_cas.ll_getStringValue(addr,
+            ((RutaBasic_Type) jcasType).casFeatCode_replacement);
+  }
+
+  /**
+   * setter for Replacement - sets
+   * 
+   * @generated
+   */
+  public void setReplacement(String v) {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    jcasType.ll_cas.ll_setStringValue(addr, ((RutaBasic_Type) jcasType).casFeatCode_replacement, v);
+  }
+
+}
diff --git a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic3.java b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic3.java
new file mode 100644
index 0000000..d07be47
--- /dev/null
+++ b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic3.java
@@ -0,0 +1,431 @@
+/*
+ * 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.ruta.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.TypeImpl;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.JCasRegistry;
+import org.apache.uima.jcas.cas.TOP_Type;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+
+/**
+ * 
+ * @generated
+ */
+public class RutaBasic3 extends Annotation {
+
+  private static final int INITIAL_CAPACITY = 2;
+
+  private static final String ROOT_TYPE1 = CAS.TYPE_NAME_ANNOTATION;
+
+  private static final String ROOT_TYPE2 = CAS.TYPE_NAME_ANNOTATION_BASE;
+
+  private boolean lowMemoryProfile = false;
+
+  private Int2IntOpenHashMap partOf = new Int2IntOpenHashMap();
+
+  private Int2ObjectOpenHashMap<Collection<?>> beginMap = new Int2ObjectOpenHashMap<>();
+  private Int2ObjectOpenHashMap<Collection<?>> endMap = new Int2ObjectOpenHashMap<>();
+  
+  private boolean empty = true;
+
+  public boolean isEmpty() {
+    return empty;
+  }
+
+  public boolean isLowMemoryProfile() {
+    return lowMemoryProfile;
+  }
+
+  public void setLowMemoryProfile(boolean lowMemoryProfile) {
+    this.lowMemoryProfile = lowMemoryProfile;
+  }
+
+  public void addPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    addPartOf(code);
+  }
+
+  private void addPartOf(int code) {
+    partOf.addTo(code, 1);
+    if (!lowMemoryProfile) {
+      int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+      if (parentCode > 0) {
+        addPartOf(parentCode);
+      }
+    }
+  }
+
+  public void removePartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    removePartOf(code);
+  }
+
+  private void removePartOf(int code) {
+    if (partOf.get(code) != 0) {
+      partOf.addTo(code, -1);
+      if (!lowMemoryProfile) {
+        int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+        if (parentCode > 0) {
+          removePartOf(parentCode);
+        }
+      }
+    }
+  }
+
+  public boolean isPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    int count = partOf.get(code);
+    if (count > 0) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int code2 = ((TypeImpl) each).getCode();
+        int count2 = partOf.get(code2);
+        if (count2 > 0) {
+          return true;
+        }
+      }
+
+    }
+    return false;
+
+  }
+
+  public void setPartOf(Int2IntOpenHashMap partOf) {
+    this.partOf = partOf;
+  }
+
+  public Int2IntOpenHashMap getPartOf() {
+    return partOf;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getBeginAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) beginMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c =  beginMap.get(parentCode);
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public Collection<AnnotationFS> getEndAnchors(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<AnnotationFS> set = (Collection<AnnotationFS>) endMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>();
+      if (set != null) {
+        result.addAll(set);
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        Collection<?> c = endMap.get(parentCode);
+        if (c != null) {
+          result.addAll((Collection<? extends AnnotationFS>) c);
+        }
+      }
+      return result;
+    } else {
+      if (set == null) {
+        return Collections.emptySet();
+      } else {
+        return set;
+      }
+    }
+  }
+
+  public boolean beginsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = beginMap.get(code);
+    boolean beginsWith = set != null && !set.isEmpty();
+    if (beginsWith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (beginsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public boolean endsWith(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = endMap.get(code);
+    boolean endswith = set != null && !set.isEmpty();
+    if (endswith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (endsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addBegin(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap.get(code);
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      beginMap.put(code, set);
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void addEnd(AnnotationFS annotation, Type type) {
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap.get(code);
+    if (set == null) {
+      set = new ArrayList<Object>(INITIAL_CAPACITY);
+      endMap.put(code, set);
+    }
+    set.add(annotation);
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addEnd(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeBegin(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) beginMap.get(code);
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        beginMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeBegin(annotation, parent);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void removeEnd(AnnotationFS annotation, Type type) {
+    int code = ((TypeImpl) type).getCode();
+    Collection<Object> set = (Collection<Object>) endMap.get(code);
+    if (set != null) {
+      set.remove(annotation);
+      if (set.isEmpty()) {
+        endMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeEnd(annotation, parent);
+      }
+    }
+  }
+
+  public Int2ObjectOpenHashMap<Collection<?>> getBeginMap() {
+    return beginMap;
+  }
+
+  public Int2ObjectOpenHashMap<Collection<?>> getEndMap() {
+    return endMap;
+  }
+
+  public void setBeginMap(Int2ObjectOpenHashMap<Collection<?>> beginMap) {
+    this.beginMap = beginMap;
+    for (Entry<Collection<?>> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void setEndMap(Int2ObjectOpenHashMap<Collection<?>> endMap) {
+    this.endMap = endMap;
+    for (Entry<Collection<?>> entry : endMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void clearBeginMap() {
+    this.beginMap.clear();;
+  }
+
+  public void clearEndMap() {
+    this.endMap.clear();
+    for (Entry<Collection<?>> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        return;
+      }
+    }
+    this.empty = true;
+  }
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int typeIndexID = JCasRegistry.register(RutaBasic3.class);
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int type = typeIndexID;
+
+  /** @generated */
+  @Override
+  public int getTypeIndexID() {
+    return typeIndexID;
+  }
+
+  /**
+   * Never called. Disable default constructor
+   * 
+   * @generated
+   */
+  protected RutaBasic3() {/* intentionally empty block */
+  }
+
+  /**
+   * Internal - constructor used by generator
+   * 
+   * @generated
+   */
+  public RutaBasic3(int addr, TOP_Type type) {
+    super(addr, type);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic3(JCas jcas) {
+    super(jcas);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic3(JCas jcas, int begin, int end) {
+    super(jcas);
+    setBegin(begin);
+    setEnd(end);
+    readObject();
+  }
+
+  /**
+   * <!-- begin-user-doc --> Write your own initialization here <!-- end-user-doc -->
+   * 
+   * @generated modifiable
+   */
+  private void readObject() {
+  }
+
+  // *--------------*
+  // * Feature: Replacement
+
+  /**
+   * getter for Replacement - gets
+   * 
+   * @generated
+   */
+  public String getReplacement() {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    return jcasType.ll_cas.ll_getStringValue(addr,
+            ((RutaBasic_Type) jcasType).casFeatCode_replacement);
+  }
+
+  /**
+   * setter for Replacement - sets
+   * 
+   * @generated
+   */
+  public void setReplacement(String v) {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    jcasType.ll_cas.ll_setStringValue(addr, ((RutaBasic_Type) jcasType).casFeatCode_replacement, v);
+  }
+
+}
diff --git a/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic4.java b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic4.java
new file mode 100644
index 0000000..aefd282
--- /dev/null
+++ b/ruta-typesystem/src/main/java/org/apache/uima/ruta/type/RutaBasic4.java
@@ -0,0 +1,480 @@
+/*
+ * 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.ruta.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.FeatureStructureImpl;
+import org.apache.uima.cas.impl.LowLevelCAS;
+import org.apache.uima.cas.impl.TypeImpl;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.JCasRegistry;
+import org.apache.uima.jcas.cas.TOP_Type;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+
+/**
+ * 
+ * @generated
+ */
+public class RutaBasic4 extends Annotation {
+
+  private static final int INITIAL_CAPACITY = 2;
+
+  private static final String ROOT_TYPE1 = CAS.TYPE_NAME_ANNOTATION;
+
+  private static final String ROOT_TYPE2 = CAS.TYPE_NAME_ANNOTATION_BASE;
+
+  private boolean lowMemoryProfile = false;
+
+  private Int2IntOpenHashMap partOf;
+
+  private Int2ObjectOpenHashMap<IntArrayList> beginMap;
+
+  private Int2ObjectOpenHashMap<IntArrayList> endMap;
+
+  private boolean empty = true;
+
+  public boolean isEmpty() {
+    return empty;
+  }
+
+  public boolean isLowMemoryProfile() {
+    return lowMemoryProfile;
+  }
+
+  public void setLowMemoryProfile(boolean lowMemoryProfile) {
+    this.lowMemoryProfile = lowMemoryProfile;
+  }
+
+  public void addPartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    addPartOf(code);
+  }
+
+  private void addPartOf(int code) {
+    if (partOf == null) {
+      partOf = new Int2IntOpenHashMap();
+    }
+    partOf.addTo(code, 1);
+    if (!lowMemoryProfile) {
+      int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+      if (parentCode > 0) {
+        addPartOf(parentCode);
+      }
+    }
+  }
+
+  public void removePartOf(Type type) {
+    int code = ((TypeImpl) type).getCode();
+    removePartOf(code);
+  }
+
+  private void removePartOf(int code) {
+    if (partOf != null && partOf.get(code) != 0) {
+      partOf.addTo(code, -1);
+      if (!lowMemoryProfile) {
+        int parentCode = getCAS().getTypeSystem().getLowLevelTypeSystem().ll_getParentType(code);
+        if (parentCode > 0) {
+          removePartOf(parentCode);
+        }
+      }
+    }
+  }
+
+  public boolean isPartOf(Type type) {
+    if (partOf == null) {
+      return false;
+    }
+    int code = ((TypeImpl) type).getCode();
+    int count = partOf.get(code);
+    if (count > 0) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int code2 = ((TypeImpl) each).getCode();
+        int count2 = partOf.get(code2);
+        if (count2 > 0) {
+          return true;
+        }
+      }
+
+    }
+    return false;
+
+  }
+
+  public void setPartOf(Int2IntOpenHashMap partOf) {
+    this.partOf = partOf;
+  }
+
+  public Int2IntOpenHashMap getPartOf() {
+    return partOf;
+  }
+
+  public Collection<AnnotationFS> getBeginAnchors(Type type) {
+    if (beginMap == null) {
+      return Collections.emptyList();
+    }
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = beginMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>(list.size());
+      if (list != null) {
+        result.addAll(adressToAnnotationList(list));
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        IntArrayList c = beginMap.get(parentCode);
+        if (c != null) {
+          result.addAll(adressToAnnotationList(c));
+        }
+      }
+      return result;
+    } else {
+      if (list == null) {
+        return Collections.emptySet();
+      } else {
+        return adressToAnnotationList(list);
+      }
+    }
+  }
+
+  public Collection<AnnotationFS> getEndAnchors(Type type) {
+    if (endMap == null) {
+      return Collections.emptyList();
+    }
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = endMap.get(code);
+    if (lowMemoryProfile) {
+      Collection<AnnotationFS> result = new ArrayList<AnnotationFS>(list.size());
+      if (list != null) {
+        result.addAll(adressToAnnotationList(list));
+      }
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        int parentCode = ((TypeImpl) each).getCode();
+        IntArrayList c = endMap.get(parentCode);
+        if (c != null) {
+          result.addAll(adressToAnnotationList(c));
+        }
+      }
+      return result;
+    } else {
+      if (list == null) {
+        return Collections.emptySet();
+      } else {
+        return adressToAnnotationList(list);
+      }
+    }
+  }
+
+  public boolean beginsWith(Type type) {
+    if (beginMap == null) {
+      return false;
+    }
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = beginMap.get(code);
+    boolean beginsWith = set != null && !set.isEmpty();
+    if (beginsWith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (beginsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public boolean endsWith(Type type) {
+    if (endMap == null) {
+      return false;
+    }
+    int code = ((TypeImpl) type).getCode();
+    Collection<?> set = endMap.get(code);
+    boolean endswith = set != null && !set.isEmpty();
+    if (endswith) {
+      return true;
+    }
+    if (lowMemoryProfile) {
+      List<Type> subsumedTypes = getCAS().getTypeSystem().getProperlySubsumedTypes(type);
+      for (Type each : subsumedTypes) {
+        if (endsWith(each)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public void addBegin(AnnotationFS annotation, Type type) {
+    if (beginMap == null) {
+      beginMap = new Int2ObjectOpenHashMap<>();
+    }
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = beginMap.get(code);
+    if (list == null) {
+      list = new IntArrayList(INITIAL_CAPACITY);
+      beginMap.put(code, list);
+    }
+    list.add(annotationToAddress(annotation));
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addBegin(annotation, parent);
+      }
+    }
+  }
+
+  public void addEnd(AnnotationFS annotation, Type type) {
+    if (endMap == null) {
+      endMap = new Int2ObjectOpenHashMap<>();
+    }
+    empty = false;
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = endMap.get(code);
+    if (list == null) {
+      list = new IntArrayList(INITIAL_CAPACITY);
+      endMap.put(code, list);
+    }
+    list.add(annotationToAddress(annotation));
+    if (!lowMemoryProfile && !type.getName().equals(ROOT_TYPE1)
+            && !type.getName().equals(ROOT_TYPE2)) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        addEnd(annotation, parent);
+      }
+    }
+  }
+
+  public void removeBegin(AnnotationFS annotation, Type type) {
+    if (beginMap == null) {
+      return;
+    }
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = beginMap.get(code);
+    if (list != null) {
+      list.removeInt(annotationToAddress(annotation));
+      if (list.isEmpty()) {
+        beginMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeBegin(annotation, parent);
+      }
+    }
+  }
+
+  public void removeEnd(AnnotationFS annotation, Type type) {
+    if (endMap == null) {
+      return;
+    }
+    int code = ((TypeImpl) type).getCode();
+    IntArrayList list = endMap.get(code);
+    if (list != null) {
+      list.removeInt(annotationToAddress(annotation));
+      if (list.isEmpty()) {
+        endMap.remove(code);
+      }
+    }
+    if (!lowMemoryProfile) {
+      TypeSystem typeSystem = getCAS().getTypeSystem();
+      Type parent = typeSystem.getParent(type);
+      if (parent != null) {
+        removeEnd(annotation, parent);
+      }
+    }
+  }
+
+  public Int2ObjectOpenHashMap<IntArrayList> getBeginMap() {
+    return beginMap;
+  }
+
+  public Int2ObjectOpenHashMap<IntArrayList> getEndMap() {
+    return endMap;
+  }
+
+  public void setBeginMap(Int2ObjectOpenHashMap<IntArrayList> beginMap) {
+    this.beginMap = beginMap;
+    for (Entry<IntArrayList> entry : beginMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void setEndMap(Int2ObjectOpenHashMap<IntArrayList> endMap) {
+    this.endMap = endMap;
+    for (Entry<IntArrayList> entry : endMap.int2ObjectEntrySet()) {
+      Collection<?> value = entry.getValue();
+      if (value != null && !value.isEmpty()) {
+        this.empty = false;
+        break;
+      }
+    }
+  }
+
+  public void clearBeginMap() {
+    this.beginMap.clear();
+  }
+
+  public void clearEndMap() {
+    this.endMap.clear();
+    if (beginMap != null) {
+      for (Entry<IntArrayList> entry : beginMap.int2ObjectEntrySet()) {
+        Collection<?> value = entry.getValue();
+        if (value != null && !value.isEmpty()) {
+          return;
+        }
+      }
+    }
+    this.empty = true;
+  }
+
+  private Collection<AnnotationFS> adressToAnnotationList(IntArrayList addressList) {
+    List<AnnotationFS> result = new ArrayList<>(addressList.size());
+    for (int value : addressList) {
+      result.add(addressToAnnotation(value));
+    }
+    return result;
+  }
+
+  private int annotationToAddress(AnnotationFS annotation) {
+    return ((FeatureStructureImpl) annotation).getAddress();
+  }
+
+  private AnnotationFS addressToAnnotation(int address) {
+    LowLevelCAS lowLevelCAS = getCASImpl().getLowLevelCAS();
+    FeatureStructure fs = lowLevelCAS.ll_getFSForRef(address);
+    return (AnnotationFS) fs;
+  }
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int typeIndexID = JCasRegistry.register(RutaBasic4.class);
+
+  /**
+   * @generated
+   * @ordered
+   */
+  public final static int type = typeIndexID;
+
+  /** @generated */
+  @Override
+  public int getTypeIndexID() {
+    return typeIndexID;
+  }
+
+  /**
+   * Never called. Disable default constructor
+   * 
+   * @generated
+   */
+  protected RutaBasic4() {/* intentionally empty block */
+  }
+
+  /**
+   * Internal - constructor used by generator
+   * 
+   * @generated
+   */
+  public RutaBasic4(int addr, TOP_Type type) {
+    super(addr, type);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic4(JCas jcas) {
+    super(jcas);
+    readObject();
+  }
+
+  /** @generated */
+  public RutaBasic4(JCas jcas, int begin, int end) {
+    super(jcas);
+    setBegin(begin);
+    setEnd(end);
+    readObject();
+  }
+
+  /**
+   * <!-- begin-user-doc --> Write your own initialization here <!-- end-user-doc -->
+   * 
+   * @generated modifiable
+   */
+  private void readObject() {
+  }
+
+  // *--------------*
+  // * Feature: Replacement
+
+  /**
+   * getter for Replacement - gets
+   * 
+   * @generated
+   */
+  public String getReplacement() {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    return jcasType.ll_cas.ll_getStringValue(addr,
+            ((RutaBasic_Type) jcasType).casFeatCode_replacement);
+  }
+
+  /**
+   * setter for Replacement - sets
+   * 
+   * @generated
+   */
+  public void setReplacement(String v) {
+    if (RutaBasic_Type.featOkTst && ((RutaBasic_Type) jcasType).casFeat_replacement == null)
+      jcasType.jcas.throwFeatMissing("replacement", "org.apache.uima.ruta.type.RutaBasic");
+    jcasType.ll_cas.ll_setStringValue(addr, ((RutaBasic_Type) jcasType).casFeatCode_replacement, v);
+  }
+
+}
