You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by tw...@apache.org on 2007/09/17 11:25:54 UTC

svn commit: r576326 [2/2] - /incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=576326&r1=576325&r2=576326&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java Mon Sep 17 02:25:53 2007
@@ -81,31 +81,32 @@
 import org.apache.uima.jcas.impl.JCasImpl;
 
 /**
- * Implements the CAS interfaces. This class must be public because we need to be able to create
- * instance of it from outside the package. Use at your own risk. May change without notice.
+ * Implements the CAS interfaces. This class must be public because we need to
+ * be able to create instance of it from outside the package. Use at your own
+ * risk. May change without notice.
  * 
  */
 public class CASImpl extends AbstractCas_ImplBase implements CAS, CASMgr, LowLevelCAS {
 
-	// Notes on the implementation
-	// ---------------------------
+  // Notes on the implementation
+  // ---------------------------
 
-	// Floats are handled by casting them to ints when they are stored
-	// in the heap. Conveniently, 0 casts to 0.0f, which is the default
-	// value.
-    
-	public static final int NULL = 0;
+  // Floats are handled by casting them to ints when they are stored
+  // in the heap. Conveniently, 0 casts to 0.0f, which is the default
+  // value.
 
-	// Boolean scalar values are stored as ints in the fs heap.
-	// TRUE is 1 and false is 0.
-	public static final int TRUE = 1;
+  public static final int NULL = 0;
 
-	public static final int FALSE = 0;
+  // Boolean scalar values are stored as ints in the fs heap.
+  // TRUE is 1 and false is 0.
+  public static final int TRUE = 1;
 
-	public static final int DEFAULT_INITIAL_HEAP_SIZE = 500000;
+  public static final int FALSE = 0;
+
+  public static final int DEFAULT_INITIAL_HEAP_SIZE = 500000;
+
+  public static final int DEFAULT_RESET_HEAP_SIZE = 5000000;
 
-	public static final int DEFAULT_RESET_HEAP_SIZE = 5000000;
-  
   private static final int resetHeapSize = DEFAULT_RESET_HEAP_SIZE;
 
   // The offset for the array length cell. An array consists of length+2
@@ -120,24 +121,24 @@
   // if we have an array starting at addr, the first cell is at
   // addr+arrayContentOffset.
   private static final int arrayContentOffset = 2;
-  
+
   private static final boolean DEFAULT_USE_FS_CACHE = false;
 
-	// this next seemingly non-sensical static block
-	// is to force the classes needed by Eclipse debugging to load
-	// otherwise, you get a com.sun.jdi.ClassNotLoadedException when
-	// the class is used as part of formatting debugging messages
-	static {
-		new DebugNameValuePair(null, null);
-		new DebugFSLogicalStructure();
-	}
+  // this next seemingly non-sensical static block
+  // is to force the classes needed by Eclipse debugging to load
+  // otherwise, you get a com.sun.jdi.ClassNotLoadedException when
+  // the class is used as part of formatting debugging messages
+  static {
+    new DebugNameValuePair(null, null);
+    new DebugFSLogicalStructure();
+  }
 
   // Static classes representing shared instance data
-  //   - shared data is computed once
-  
+  // - shared data is computed once
+
   // fields shared among all CASes belong to views of a common base CAS
   private static class SharedViewData {
-    
+
     private Heap heap;
 
     // private SymbolTable stringTable;
@@ -149,152 +150,151 @@
     private ShortHeap shortHeap; // for storing 16 bit values
 
     private LongHeap longHeap; // for storing 64 bit values
-    
+
     // A map from Sofas to IndexRepositories.
     private HashMap sofa2indexMap;
 
     // A map from Sofa numbers to CAS views.
-    //  number 0 - not used 
-    //  number 1 - used for view named "_InitialView"
-    //  number 2-n  used for other views
+    // number 0 - not used
+    // number 1 - used for view named "_InitialView"
+    // number 2-n used for other views
     private HashMap sofaNbr2ViewMap;
 
-    // set of instantiated sofaNames    
+    // set of instantiated sofaNames
     private HashSet sofaNameSet;
 
     // Flag that initial Sofa has been created
     private boolean initialSofaCreated = false;
 
     // Count of Views created in this cas
-    //   equals count of sofas except if initial view has no sofa.
+    // equals count of sofas except if initial view has no sofa.
     private int viewCount;
-    
+
     // The ClassLoader that should be used by the JCas to load the generated
     // FS cover classes for this CAS. Defaults to the ClassLoader used
     // to load the CASImpl class.
     private ClassLoader jcasClassLoader = this.getClass().getClassLoader();
-    
+
     private ClassLoader previousJCasClassLoader = this.jcasClassLoader;
 
     // If this CAS can be flushed (reset) or not.
-    //   often, the framework disables this before calling users code
+    // often, the framework disables this before calling users code
     private boolean flushEnabled = true;
 
-    // controls whether Java cover objects for CAS objects, 
-    //   including JCas objects, 
-    //   are cached and reused.
-    //   If set true, don't also cache the JCas ones - this will 
-    //   duplicate the space with no benefit
+    // controls whether Java cover objects for CAS objects,
+    // including JCas objects,
+    // are cached and reused.
+    // If set true, don't also cache the JCas ones - this will
+    // duplicate the space with no benefit
     private final boolean useFSCache;
-    
-    // this is the actual cache.  It is simply an array of the same size
-    //   as the heap, with the CAS object's addr slot filled with
-    //   a (strong) ref to the Java object.
-    //      This is a trade off verses using hash tables
-    
-    // The actual cache.  
+
+    // this is the actual cache. It is simply an array of the same size
+    // as the heap, with the CAS object's addr slot filled with
+    // a (strong) ref to the Java object.
+    // This is a trade off verses using hash tables
+
+    // The actual cache.
     // TODO implement the resizing algorithm used for the main heap, here too.
     private FeatureStructure[] fsArray;
-    
+
     // Base CAS for all views
     private CASImpl baseCAS;
-    
+
     private CASMetadata casMetadata;
-    
+
     private ComponentInfo componentInfo;
-    
-    private FSGenerator [] localFsGenerators;
-    
+
+    private FSGenerator[] localFsGenerators;
+
     private SharedViewData(boolean useFSCache) {
       this.useFSCache = useFSCache;
     }
   }
- 
-  //-----------------------------------------------------
-  //  Non-shared instance data for base CAS and each view
-  //-----------------------------------------------------
-  
+
+  // -----------------------------------------------------
+  // Non-shared instance data for base CAS and each view
+  // -----------------------------------------------------
+
   // package protected to let other things share this info
-  final SharedViewData svd;  // shared view data
+  final SharedViewData svd; // shared view data
 
-	// The index repository.  Referenced by XmiCasSerializer
+  // The index repository. Referenced by XmiCasSerializer
   FSIndexRepositoryImpl indexRepository;
 
-	// the sofaFS this view is based on
-	// SofaFS mySofa;
-	private int mySofaRef = 0;
-
-	private JCas jcas = null;
-
-	private final ArrayList getStringList() {
-		ArrayList stringList = new ArrayList();
-		stringList.add(null);
-		int pos = this.getStringHeap().getLeastStringCode();
-		final int end = this.getStringHeap().getLargestStringCode();
-		while (pos <= end) {
-			stringList.add(this.getStringHeap().getStringForCode(pos));
-			++pos;
-		}
-		return stringList;
-	}
+  // the sofaFS this view is based on
+  // SofaFS mySofa;
+  private int mySofaRef = 0;
+
+  private JCas jcas = null;
+
+  private final ArrayList getStringList() {
+    ArrayList stringList = new ArrayList();
+    stringList.add(null);
+    int pos = this.getStringHeap().getLeastStringCode();
+    final int end = this.getStringHeap().getLargestStringCode();
+    while (pos <= end) {
+      stringList.add(this.getStringHeap().getStringForCode(pos));
+      ++pos;
+    }
+    return stringList;
+  }
 
-	/*
+  /*
    * (non-Javadoc)
    * 
    * @see org.apache.uima.cas.admin.CASMgr#setCAS(org.apache.uima.cas.CAS)
-   * Internal use
-   * Never called
-   * Kept because it's in the interface.
-   */
-	public void setCAS(CAS cas) {
-
-//		this.indexRepository = ((CASImpl)cas).indexRepository;  // only for test case, others override later
-//		this.svd.casMetadata.fsClassRegistry = casImpl.fsClassReg;
-
-//		initTypeCodeVars();
-		// this.jcas = in.jcas;
-	}
-
-	// CASImpl(TypeSystemImpl typeSystem) {
-	// this(typeSystem, DEFAULT_INITIAL_HEAP_SIZE);
-	// }
-
-	// // Reference existing CAS
-	// // For use when creating views of the CAS
-	// CASImpl(CAS cas) {
-	// this.setCAS(cas);
-	// this.useFSCache = false;
-	// initTypeVariables();
-	// }
-
-	public CASImpl(TypeSystemImpl typeSystem, int initialHeapSize) {
-		this(typeSystem, initialHeapSize, DEFAULT_USE_FS_CACHE);
-	}
+   *      Internal use Never called Kept because it's in the interface.
+   */
+  public void setCAS(CAS cas) {
+
+    // this.indexRepository = ((CASImpl)cas).indexRepository; // only for test
+    // case, others override later
+    // this.svd.casMetadata.fsClassRegistry = casImpl.fsClassReg;
+
+    // initTypeCodeVars();
+    // this.jcas = in.jcas;
+  }
+
+  // CASImpl(TypeSystemImpl typeSystem) {
+  // this(typeSystem, DEFAULT_INITIAL_HEAP_SIZE);
+  // }
+
+  // // Reference existing CAS
+  // // For use when creating views of the CAS
+  // CASImpl(CAS cas) {
+  // this.setCAS(cas);
+  // this.useFSCache = false;
+  // initTypeVariables();
+  // }
+
+  public CASImpl(TypeSystemImpl typeSystem, int initialHeapSize) {
+    this(typeSystem, initialHeapSize, DEFAULT_USE_FS_CACHE);
+  }
 
   /*
-   * Configure a new (base view) CASImpl, **not a new view** 
-   * typeSystem can be null, in which case a new instance of TypeSystemImpl is set up, but not committed.
-   *    If typeSystem is not null, it is committed (locked).
-   *    
-   * ** Note: it is assumed that the caller of this will always set up the initial view
-   * ** by calling
-   */
-  
-	CASImpl(TypeSystemImpl typeSystem, int initialHeapSize, boolean useFSCache) {
-		super();
+   * Configure a new (base view) CASImpl, **not a new view** typeSystem can be
+   * null, in which case a new instance of TypeSystemImpl is set up, but not
+   * committed. If typeSystem is not null, it is committed (locked). ** Note: it
+   * is assumed that the caller of this will always set up the initial view **
+   * by calling
+   */
+
+  CASImpl(TypeSystemImpl typeSystem, int initialHeapSize, boolean useFSCache) {
+    super();
     TypeSystemImpl ts;
     final boolean externalTypeSystem = (typeSystem != null);
 
     if (externalTypeSystem) {
       ts = typeSystem;
     } else {
-      ts = new TypeSystemImpl();  // creates also new CASMetadata and FSClassRegistry instances
+      ts = new TypeSystemImpl(); // creates also new CASMetadata and
+      // FSClassRegistry instances
     }
-       
+
     this.svd = new SharedViewData(useFSCache);
     this.svd.casMetadata = ts.casMetadata;
     this.svd.baseCAS = this;
-    
+
     // Set up new heaps
     this.svd.heap = new Heap(initialHeapSize);
     this.svd.stringHeap = new StringHeap();
@@ -302,1677 +302,1710 @@
     this.svd.byteHeap = new ByteHeap();
     this.svd.shortHeap = new ShortHeap();
     this.svd.longHeap = new LongHeap();
-    
-		if (externalTypeSystem) {
+
+    if (externalTypeSystem) {
       commitTypeSystem();
-		} 
-    
-		this.svd.sofa2indexMap = new HashMap();
-		this.svd.sofaNbr2ViewMap = new HashMap();
-		this.svd.sofaNameSet = new HashSet();
-		this.svd.initialSofaCreated = false;
-		this.svd.viewCount = 0;
-	}
+    }
+
+    this.svd.sofa2indexMap = new HashMap();
+    this.svd.sofaNbr2ViewMap = new HashMap();
+    this.svd.sofaNameSet = new HashSet();
+    this.svd.initialSofaCreated = false;
+    this.svd.viewCount = 0;
+  }
 
-	/**
+  /**
    * Constructor. Use only if you want to use the low-level APIs.
    */
-	public CASImpl() {
-		this(DEFAULT_INITIAL_HEAP_SIZE);
-	}
-
-	public CASImpl(int initialHeapSize) {
-		this((TypeSystemImpl) null, initialHeapSize);
-	}
-
-  // In May 2007, appears to have 1 caller, createCASMgr in Serialization class, could have
-  //   out-side the framework callers because it is public.
-	public CASImpl(CASMgrSerializer ser) {
-		this(ser.getTypeSystem(), DEFAULT_INITIAL_HEAP_SIZE);  
-		checkInternalCodes(ser);
-		// assert(ts != null);
-		// assert(getTypeSystem() != null);
+  public CASImpl() {
+    this(DEFAULT_INITIAL_HEAP_SIZE);
+  }
+
+  public CASImpl(int initialHeapSize) {
+    this((TypeSystemImpl) null, initialHeapSize);
+  }
+
+  // In May 2007, appears to have 1 caller, createCASMgr in Serialization class,
+  // could have
+  // out-side the framework callers because it is public.
+  public CASImpl(CASMgrSerializer ser) {
+    this(ser.getTypeSystem(), DEFAULT_INITIAL_HEAP_SIZE);
+    checkInternalCodes(ser);
+    // assert(ts != null);
+    // assert(getTypeSystem() != null);
     this.indexRepository = ser.getIndexRepository(this);
-	}
+  }
 
-	// Use this when creating a CAS view
-	CASImpl(CASImpl cas, SofaFS aSofa) {
+  // Use this when creating a CAS view
+  CASImpl(CASImpl cas, SofaFS aSofa) {
     // these next fields are final and must be set in the constructor
     this.svd = cas.svd;
 
-		// this.mySofa = aSofa;
-		if (aSofa != null) {
-			// save address of SofaFS
-			this.mySofaRef = ((FeatureStructureImpl)aSofa).getAddress();
-		} else {
-			// this is the InitialView
-			this.mySofaRef = -1;
-		}
-
-		// get the indexRepository for this Sofa
-		this.indexRepository = (this.mySofaRef == -1) ?
-            (FSIndexRepositoryImpl)cas.getSofaIndexRepository(1) : 
-            (FSIndexRepositoryImpl)cas.getSofaIndexRepository(aSofa);
-		if (null == this.indexRepository) {
-			// create the indexRepository for this CAS
-			// use the baseIR to create a lightweight IR copy
-			this.indexRepository = new FSIndexRepositoryImpl(this,
-					(FSIndexRepositoryImpl)cas.getBaseIndexRepository());
-			this.indexRepository.commit();
-			// save new sofa index
-			if (this.mySofaRef == -1) {
-				cas.setSofaIndexRepository(1, this.indexRepository);
-			} else {
-				cas.setSofaIndexRepository(aSofa, this.indexRepository);
-			}
-		}
-	}
+    // this.mySofa = aSofa;
+    if (aSofa != null) {
+      // save address of SofaFS
+      this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
+    } else {
+      // this is the InitialView
+      this.mySofaRef = -1;
+    }
+
+    // get the indexRepository for this Sofa
+    this.indexRepository = (this.mySofaRef == -1) ? (FSIndexRepositoryImpl) cas
+        .getSofaIndexRepository(1) : (FSIndexRepositoryImpl) cas.getSofaIndexRepository(aSofa);
+    if (null == this.indexRepository) {
+      // create the indexRepository for this CAS
+      // use the baseIR to create a lightweight IR copy
+      this.indexRepository = new FSIndexRepositoryImpl(this, (FSIndexRepositoryImpl) cas
+          .getBaseIndexRepository());
+      this.indexRepository.commit();
+      // save new sofa index
+      if (this.mySofaRef == -1) {
+        cas.setSofaIndexRepository(1, this.indexRepository);
+      } else {
+        cas.setSofaIndexRepository(aSofa, this.indexRepository);
+      }
+    }
+  }
 
-	// Use this when creating a CAS view
+  // Use this when creating a CAS view
   void refreshView(CAS cas, SofaFS aSofa) {
 
-		if (aSofa != null) {
-			// save address of SofaFS
-			this.mySofaRef = ((FeatureStructureImpl)aSofa).getAddress();
-		} else {
-			// this is the InitialView
-			this.mySofaRef = -1;
-		}
-
-		// toss the JCas, if it exists
-		this.jcas = null;
-
-		// create the indexRepository for this Sofa
-		this.indexRepository = new FSIndexRepositoryImpl(this, (FSIndexRepositoryImpl) ((CASImpl) cas)
-				.getBaseIndexRepository());
-		this.indexRepository.commit();
-		// save new sofa index
-		if (this.mySofaRef == -1) {
-			((CASImpl) cas).setSofaIndexRepository(1, this.indexRepository);
-		} else {
-			((CASImpl) cas).setSofaIndexRepository(aSofa, this.indexRepository);
-		}
-	}
-
-
-	private void checkInternalCodes(CASMgrSerializer ser) throws CASAdminException {
-		if ((ser.topTypeCode > 0) && (ser.topTypeCode != ((TypeImpl) this.svd.casMetadata.ts.getTopType()).getCode())) {
-			throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
-		}
-		if (ser.featureOffsets == null) {
-			return;
-		}
-		if (ser.featureOffsets.length != this.svd.casMetadata.featureOffset.length) {
-			throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
-		}
-		for (int i = 1; i < ser.featureOffsets.length; i++) {
-			if (ser.featureOffsets[i] != this.svd.casMetadata.featureOffset[i]) {
-				throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
-			}
-		}
-	}
-
-	public void enableReset(boolean flag) {
-		this.svd.flushEnabled = flag;
-	}
-
-	public TypeSystem getTypeSystem() {
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		if (ts.isCommitted()) {
-			return ts;
-		}
-		throw new CASRuntimeException(CASRuntimeException.TYPESYSTEM_NOT_LOCKED);
-	}
-
-	public ConstraintFactory getConstraintFactory() {
-		return ConstraintFactory.instance();
-	}
-
-	public FeatureStructure createFS(Type type) {
-		final int typeCode = ((TypeImpl) type).getCode();
-		if (!isCreatableType(typeCode)) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.NON_CREATABLE_TYPE,
-					new String[] { type.getName(), "CAS.createFS()" });
-			throw e;
-		}
-		final int addr = ll_createFS(typeCode);
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		final boolean isAnnot = ts.subsumes(ts.annotBaseTypeCode, typeCode);
-		if (isAnnot && (this == this.getBaseCAS())) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS,
-					new String[] { type.getName() });
-			throw e;
-		}
+    if (aSofa != null) {
+      // save address of SofaFS
+      this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
+    } else {
+      // this is the InitialView
+      this.mySofaRef = -1;
+    }
+
+    // toss the JCas, if it exists
+    this.jcas = null;
+
+    // create the indexRepository for this Sofa
+    this.indexRepository = new FSIndexRepositoryImpl(this, (FSIndexRepositoryImpl) ((CASImpl) cas)
+        .getBaseIndexRepository());
+    this.indexRepository.commit();
+    // save new sofa index
+    if (this.mySofaRef == -1) {
+      ((CASImpl) cas).setSofaIndexRepository(1, this.indexRepository);
+    } else {
+      ((CASImpl) cas).setSofaIndexRepository(aSofa, this.indexRepository);
+    }
+  }
+
+  private void checkInternalCodes(CASMgrSerializer ser) throws CASAdminException {
+    if ((ser.topTypeCode > 0)
+        && (ser.topTypeCode != ((TypeImpl) this.svd.casMetadata.ts.getTopType()).getCode())) {
+      throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
+    }
+    if (ser.featureOffsets == null) {
+      return;
+    }
+    if (ser.featureOffsets.length != this.svd.casMetadata.featureOffset.length) {
+      throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
+    }
+    for (int i = 1; i < ser.featureOffsets.length; i++) {
+      if (ser.featureOffsets[i] != this.svd.casMetadata.featureOffset[i]) {
+        throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
+      }
+    }
+  }
+
+  public void enableReset(boolean flag) {
+    this.svd.flushEnabled = flag;
+  }
+
+  public TypeSystem getTypeSystem() {
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    if (ts.isCommitted()) {
+      return ts;
+    }
+    throw new CASRuntimeException(CASRuntimeException.TYPESYSTEM_NOT_LOCKED);
+  }
+
+  public ConstraintFactory getConstraintFactory() {
+    return ConstraintFactory.instance();
+  }
+
+  public FeatureStructure createFS(Type type) {
+    final int typeCode = ((TypeImpl) type).getCode();
+    if (!isCreatableType(typeCode)) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.NON_CREATABLE_TYPE,
+          new String[] { type.getName(), "CAS.createFS()" });
+      throw e;
+    }
+    final int addr = ll_createFS(typeCode);
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    final boolean isAnnot = ts.subsumes(ts.annotBaseTypeCode, typeCode);
+    if (isAnnot && (this == this.getBaseCAS())) {
+      CASRuntimeException e = new CASRuntimeException(
+          CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS,
+          new String[] { type.getName() });
+      throw e;
+    }
     if (isAnnot) {
       getLowLevelCAS().ll_setIntValue(addr, ts.annotSofaFeatCode, this.getSofaRef());
     }
-		final FeatureStructure newFS = ll_getFSForRef(addr);
-		return newFS;
-	}
-
-	// public FeatureStructure createPermFS(Type type) {
-	// final int addr = createPermFS(((TypeImpl) type).getCode());
-	// return getFSClassRegistry().createFS(addr, this);
-	// }
-
-	public ArrayFS createArrayFS(int length) {
-		checkArrayPreconditions(length);
-		final int addr = createTempArray(this.svd.casMetadata.ts.fsArrayTypeCode, length);
-		return (ArrayFS) createFS(addr);
-	}
-
-	public IntArrayFS createIntArrayFS(int length) {
-		checkArrayPreconditions(length);
-		final int addr = createTempArray(this.svd.casMetadata.ts.intArrayTypeCode, length);
-		return (IntArrayFS) createFS(addr);
-	}
-
-	public FloatArrayFS createFloatArrayFS(int length) {
-		checkArrayPreconditions(length);
-		final int addr = createTempArray(this.svd.casMetadata.ts.floatArrayTypeCode, length);
-		return (FloatArrayFS) createFS(addr);
-	}
-
-	public StringArrayFS createStringArrayFS(int length) {
-		checkArrayPreconditions(length);
-		final int addr = createTempArray(this.svd.casMetadata.ts.stringArrayTypeCode, length);
-		return (StringArrayFS) createFS(addr);
-	}
-
-	public final void checkArrayPreconditions(int len) throws CASRuntimeException {
-		// Check array size.
-		if (len < 0) {
-			throw new CASRuntimeException(CASRuntimeException.ILLEGAL_ARRAY_SIZE);
-		}
-	}
-
-	// return true if only one sofa and it is the default text sofa
-	public boolean isBackwardCompatibleCas() {
-		// check that there is exactly one sofa
-		if (this.svd.viewCount != 1) {
-			return false;
-		}
-
-		if (!this.svd.initialSofaCreated) {
-			return false;
-		}
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		final int llsofa = getLowLevelCAS().ll_getFSRef(this.getInitialView().getSofa());
-
-		// check for mime type exactly equal to "text"
-		String sofaMime = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaMimeFeatCode);
-		if (!"text".equals(sofaMime)) {
+    final FeatureStructure newFS = ll_getFSForRef(addr);
+    return newFS;
+  }
+
+  // public FeatureStructure createPermFS(Type type) {
+  // final int addr = createPermFS(((TypeImpl) type).getCode());
+  // return getFSClassRegistry().createFS(addr, this);
+  // }
+
+  public ArrayFS createArrayFS(int length) {
+    checkArrayPreconditions(length);
+    final int addr = createTempArray(this.svd.casMetadata.ts.fsArrayTypeCode, length);
+    return (ArrayFS) createFS(addr);
+  }
+
+  public IntArrayFS createIntArrayFS(int length) {
+    checkArrayPreconditions(length);
+    final int addr = createTempArray(this.svd.casMetadata.ts.intArrayTypeCode, length);
+    return (IntArrayFS) createFS(addr);
+  }
+
+  public FloatArrayFS createFloatArrayFS(int length) {
+    checkArrayPreconditions(length);
+    final int addr = createTempArray(this.svd.casMetadata.ts.floatArrayTypeCode, length);
+    return (FloatArrayFS) createFS(addr);
+  }
+
+  public StringArrayFS createStringArrayFS(int length) {
+    checkArrayPreconditions(length);
+    final int addr = createTempArray(this.svd.casMetadata.ts.stringArrayTypeCode, length);
+    return (StringArrayFS) createFS(addr);
+  }
+
+  public final void checkArrayPreconditions(int len) throws CASRuntimeException {
+    // Check array size.
+    if (len < 0) {
+      throw new CASRuntimeException(CASRuntimeException.ILLEGAL_ARRAY_SIZE);
+    }
+  }
+
+  // return true if only one sofa and it is the default text sofa
+  public boolean isBackwardCompatibleCas() {
+    // check that there is exactly one sofa
+    if (this.svd.viewCount != 1) {
+      return false;
+    }
+
+    if (!this.svd.initialSofaCreated) {
+      return false;
+    }
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    final int llsofa = getLowLevelCAS().ll_getFSRef(this.getInitialView().getSofa());
+
+    // check for mime type exactly equal to "text"
+    String sofaMime = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaMimeFeatCode);
+    if (!"text".equals(sofaMime)) {
       return false;
     }
-		// check that sofaURI and sofaArray are not set
-		String sofaUri = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaUriFeatCode);
-		if (sofaUri != null) {
+    // check that sofaURI and sofaArray are not set
+    String sofaUri = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaUriFeatCode);
+    if (sofaUri != null) {
       return false;
     }
-		int sofaArray = getLowLevelCAS().ll_getRefValue(llsofa, ts.sofaArrayFeatCode);
-		if (sofaArray != CASImpl.NULL) {
+    int sofaArray = getLowLevelCAS().ll_getRefValue(llsofa, ts.sofaArrayFeatCode);
+    if (sofaArray != CASImpl.NULL) {
       return false;
     }
-		// check that name is NAME_DEFAULT_SOFA
-		String sofaname = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaIdFeatCode);
-		return NAME_DEFAULT_SOFA.equals(sofaname);
-	}
-
-	int getBaseSofaCount() {
-		return this.svd.viewCount;
-	}
-
-	FSIndexRepository getSofaIndexRepository(SofaFS aSofa) {
-		return getSofaIndexRepository(aSofa.getSofaRef());
-	}
-
-	FSIndexRepository getSofaIndexRepository(int aSofaRef) {
-		return (FSIndexRepositoryImpl) this.svd.sofa2indexMap.get(new Integer(aSofaRef));
-	}
-
-	void setSofaIndexRepository(SofaFS aSofa, FSIndexRepository indxRepos) {
-		setSofaIndexRepository(aSofa.getSofaRef(), indxRepos);
-	}
-
-	void setSofaIndexRepository(int aSofaRef, FSIndexRepository indxRepos) {
-		this.svd.sofa2indexMap.put(new Integer(aSofaRef), indxRepos);
-	}
+    // check that name is NAME_DEFAULT_SOFA
+    String sofaname = getLowLevelCAS().ll_getStringValue(llsofa, ts.sofaIdFeatCode);
+    return NAME_DEFAULT_SOFA.equals(sofaname);
+  }
 
-	/**
+  int getBaseSofaCount() {
+    return this.svd.viewCount;
+  }
+
+  FSIndexRepository getSofaIndexRepository(SofaFS aSofa) {
+    return getSofaIndexRepository(aSofa.getSofaRef());
+  }
+
+  FSIndexRepository getSofaIndexRepository(int aSofaRef) {
+    return (FSIndexRepositoryImpl) this.svd.sofa2indexMap.get(new Integer(aSofaRef));
+  }
+
+  void setSofaIndexRepository(SofaFS aSofa, FSIndexRepository indxRepos) {
+    setSofaIndexRepository(aSofa.getSofaRef(), indxRepos);
+  }
+
+  void setSofaIndexRepository(int aSofaRef, FSIndexRepository indxRepos) {
+    this.svd.sofa2indexMap.put(new Integer(aSofaRef), indxRepos);
+  }
+
+  /**
    * @deprecated
    */
-	public SofaFS createSofa(SofaID sofaID, String mimeType) {
-		// extract absolute SofaName string from the ID
-		SofaFS aSofa =  createSofa(sofaID.getSofaID(), mimeType); 
-    getView(aSofa);  // will create the view, needed to make the
-                     // resetNoQuestions and other things that
-                     // iterate over views work.
+  public SofaFS createSofa(SofaID sofaID, String mimeType) {
+    // extract absolute SofaName string from the ID
+    SofaFS aSofa = createSofa(sofaID.getSofaID(), mimeType);
+    getView(aSofa); // will create the view, needed to make the
+    // resetNoQuestions and other things that
+    // iterate over views work.
     return aSofa;
-	}
+  }
+
+  SofaFS createSofa(String sofaName, String mimeType) {
+    final int addr = ll_createFS(this.svd.casMetadata.ts.sofaTypeCode);
+    final FeatureStructure sofa = ll_getFSForRef(addr);
+    addSofa(sofa, sofaName, mimeType);
+    return (SofaFS) sofa;
+  }
+
+  SofaFS createInitialSofa(String mimeType) {
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    final int addr = ll_createFS(ts.sofaTypeCode);
+    final FeatureStructure sofa = ll_getFSForRef(addr);
+    // final int llsofa = getLowLevelCAS().ll_getFSRef(sofa);
+    getLowLevelCAS().ll_setIntValue(/* llsofa */addr, ts.sofaNumFeatCode, 1);
+    addSofa(sofa, CAS.NAME_DEFAULT_SOFA, mimeType);
+    registerInitialSofa();
+    this.mySofaRef = /* ((FeatureStructureImpl)sofa).getAddress() */addr;
+    return (SofaFS) sofa;
+  }
+
+  void registerInitialSofa() {
+    this.svd.initialSofaCreated = true;
+  }
+
+  boolean isInitialSofaCreated() {
+    return this.svd.initialSofaCreated;
+  }
 
-	SofaFS createSofa(String sofaName, String mimeType) {
-		final int addr = ll_createFS(this.svd.casMetadata.ts.sofaTypeCode);
-		final FeatureStructure sofa = ll_getFSForRef(addr);
-		addSofa(sofa, sofaName, mimeType);
-		return (SofaFS) sofa;
-	}
-
-	SofaFS createInitialSofa(String mimeType) {
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		final int addr = ll_createFS(ts.sofaTypeCode);
-		final FeatureStructure sofa = ll_getFSForRef(addr);
-//		final int llsofa = getLowLevelCAS().ll_getFSRef(sofa);
-		getLowLevelCAS().ll_setIntValue(/*llsofa*/addr, ts.sofaNumFeatCode, 1);
-		addSofa(sofa, CAS.NAME_DEFAULT_SOFA, mimeType);
-		registerInitialSofa();
-		this.mySofaRef = /*((FeatureStructureImpl)sofa).getAddress()*/ addr;
-		return (SofaFS) sofa;
-	}
-
-	void registerInitialSofa() {
-		this.svd.initialSofaCreated = true;
-	}
-
-	boolean isInitialSofaCreated() {
-		return this.svd.initialSofaCreated;
-	}
-
-	// Internal use only
-	public void addSofa(FeatureStructure sofa, String sofaName, String mimeType) {
-		if (this.svd.sofaNameSet.contains(sofaName)) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_ALREADY_EXISTS,
-					new String[] { sofaName });
-			throw e;
-		}
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		final int llsofa = getLowLevelCAS().ll_getFSRef(sofa);
-		if (0 == getLowLevelCAS().ll_getIntValue(llsofa, ts.sofaNumFeatCode)) {
-			getLowLevelCAS().ll_setIntValue(llsofa, ts.sofaNumFeatCode, ++this.svd.viewCount);
-		}
-		getLowLevelCAS().ll_setStringValue(llsofa, ts.sofaIdFeatCode, sofaName);
-		getLowLevelCAS().ll_setStringValue(llsofa, ts.sofaMimeFeatCode, mimeType);
-		this.getBaseIndexRepository().addFS(sofa);
-		this.svd.sofaNameSet.add(sofaName);
-	}
+  // Internal use only
+  public void addSofa(FeatureStructure sofa, String sofaName, String mimeType) {
+    if (this.svd.sofaNameSet.contains(sofaName)) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_ALREADY_EXISTS,
+          new String[] { sofaName });
+      throw e;
+    }
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    final int llsofa = getLowLevelCAS().ll_getFSRef(sofa);
+    if (0 == getLowLevelCAS().ll_getIntValue(llsofa, ts.sofaNumFeatCode)) {
+      getLowLevelCAS().ll_setIntValue(llsofa, ts.sofaNumFeatCode, ++this.svd.viewCount);
+    }
+    getLowLevelCAS().ll_setStringValue(llsofa, ts.sofaIdFeatCode, sofaName);
+    getLowLevelCAS().ll_setStringValue(llsofa, ts.sofaMimeFeatCode, mimeType);
+    this.getBaseIndexRepository().addFS(sofa);
+    this.svd.sofaNameSet.add(sofaName);
+  }
 
-	/**
+  /**
    * @deprecated
    */
-	public SofaFS getSofa(SofaID sofaID) {
-		// extract absolute SofaName string from the ID
-		return getSofa(sofaID.getSofaID());
-	}
-
-	private SofaFS getSofa(String sofaName) {
-		FSIterator iterator = this.svd.baseCAS.getSofaIterator();
-		while (iterator.isValid()) {
-			SofaFS sofa = (SofaFS) iterator.get();
-			if (sofaName.equals(getStringValue(((FeatureStructureImpl)sofa).getAddress(), this.svd.casMetadata.ts.sofaIdFeatCode))) {
-				return sofa;
-			}
-			iterator.moveToNext();
-		}
-		CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_NOT_FOUND,
-				new String[] { sofaName });
-		throw e;
-	}
-
-	SofaFS getSofa(int sofaRef) {
-		SofaFS aSofa = (SofaFS) this.ll_getFSForRef(sofaRef);
-		if (aSofa == null) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFAREF_NOT_FOUND);
-			throw e;
-		}
-		return aSofa;
-	}
-
-	public CASImpl getBaseCAS() {
-		return this.svd.baseCAS;
-	}
-
-	public FSIterator getSofaIterator() {
-		FSIndex sofaIndex = this.svd.baseCAS.indexRepository.getIndex(CAS.SOFA_INDEX_NAME);
-		return sofaIndex.iterator();
-	}
-
-	// For internal use only
-	public void setSofaFeat(int addr, int sofa) {
-		setFeatureValue(addr, this.svd.casMetadata.ts.annotSofaFeatCode, sofa);
-	}
-
-	// For internal use only
-	public int getSofaFeat(int addr) {
-		return getFeatureValue(addr, this.svd.casMetadata.ts.annotSofaFeatCode);
-	}
-
-	// For internal use only
-	public int getSofaRef() {
-		if (this.mySofaRef == -1) {
-			// create the SofaFS for _InitialView ...
-			// ... and reset mySofaRef to point to it
-			this.mySofaRef = this.createInitialSofa(null).hashCode();
-		}
-		return this.mySofaRef;
-	}
-
-	// For internal use only
-	public InputStream getSofaDataStream(SofaFS aSofa) {
-		try {
-
-			if (null != aSofa.getLocalStringData()) {
-				ByteArrayInputStream bis = new ByteArrayInputStream(aSofa.getLocalStringData().getBytes(
-						"UTF-8"));
-				return bis;
-			} else if (null != aSofa.getLocalFSData()) {
-				FeatureStructureImpl fs = (FeatureStructureImpl) aSofa.getLocalFSData();
-
-				int arrayStart = 0;
-				int arraySize = this.ll_getArraySize(fs.getAddress());
-				ByteBuffer buf = null;
-				Type type = fs.getType();
-				if (type.getName().equals(CAS.TYPE_NAME_INTEGER_ARRAY)) {
-					arrayStart = getArrayStartAddress(fs.getAddress());
-					buf = ByteBuffer.allocate(arraySize * 4);
-					IntBuffer intbuf = buf.asIntBuffer();
-					intbuf.put(this.getHeap().heap, arrayStart, arraySize);
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				} else if (type.getName().equals(CAS.TYPE_NAME_FLOAT_ARRAY)) {
-					arrayStart = getArrayStartAddress(fs.getAddress());
-					buf = ByteBuffer.allocate(arraySize * 4);
-					FloatBuffer floatbuf = buf.asFloatBuffer();
-					float[] floatArray = new float[arraySize];
-					for (int i = arrayStart; i < arrayStart + arraySize; i++) {
-						floatArray[i - arrayStart] = Float.intBitsToFloat(this.getHeap().heap[i]);
-					}
-					floatbuf.put(floatArray);
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				} else if (type.getName().equals(CAS.TYPE_NAME_BOOLEAN_ARRAY)
-						|| type.getName().equals(CAS.TYPE_NAME_BYTE_ARRAY)) {
-					arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
-					buf = ByteBuffer.allocate(arraySize);
-					buf.put(this.getByteHeap().heap, arrayStart, arraySize);
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				} else if (type.getName().equals(CAS.TYPE_NAME_SHORT_ARRAY)) {
-					arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
-					buf = ByteBuffer.allocate(arraySize * 2);
-					ShortBuffer shortbuf = buf.asShortBuffer();
-					shortbuf.put(this.getShortHeap().heap, arrayStart, arraySize);
-
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				} else if (type.getName().equals(CAS.TYPE_NAME_LONG_ARRAY)) {
-					arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
-					buf = ByteBuffer.allocate(arraySize * 8);
-					LongBuffer longbuf = buf.asLongBuffer();
-					longbuf.put(this.getLongHeap().heap, arrayStart, arraySize);
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				} else if (type.getName().equals(CAS.TYPE_NAME_DOUBLE_ARRAY)) {
-					arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
-					buf = ByteBuffer.allocate(arraySize * 8);
-					DoubleBuffer doublebuf = buf.asDoubleBuffer();
-					double[] doubleArray = new double[arraySize];
-					for (int i = arrayStart; i < arrayStart + arraySize; i++) {
-						doubleArray[i - arrayStart] = Double.longBitsToDouble(this.getLongHeap().heap[i]);
-					}
-					doublebuf.put(doubleArray);
-					ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
-					return bis;
-				}
-
-			} else if (null != aSofa.getSofaURI()) {
-				URL url = new URL(aSofa.getSofaURI());
-				return url.openStream();
-			} else {
-				return null;
-			}
-		} catch (MalformedURLException exc) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
-					new String[] { exc.getMessage() });
-			throw e;
-		} catch (CASRuntimeException exc) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
-					new String[] { exc.getMessage() });
-			throw e;
-		} catch (IOException exc) {
-			CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
-					new String[] { exc.getMessage() });
-			throw e;
-		}
-		return null;
-	}
-
-	public FSIterator createFilteredIterator(FSIterator it, FSMatchConstraint cons) {
-		return new FilteredIterator(it, cons);
-	}
+  public SofaFS getSofa(SofaID sofaID) {
+    // extract absolute SofaName string from the ID
+    return getSofa(sofaID.getSofaID());
+  }
+
+  private SofaFS getSofa(String sofaName) {
+    FSIterator iterator = this.svd.baseCAS.getSofaIterator();
+    while (iterator.isValid()) {
+      SofaFS sofa = (SofaFS) iterator.get();
+      if (sofaName.equals(getStringValue(((FeatureStructureImpl) sofa).getAddress(),
+          this.svd.casMetadata.ts.sofaIdFeatCode))) {
+        return sofa;
+      }
+      iterator.moveToNext();
+    }
+    CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_NOT_FOUND,
+        new String[] { sofaName });
+    throw e;
+  }
+
+  SofaFS getSofa(int sofaRef) {
+    SofaFS aSofa = (SofaFS) this.ll_getFSForRef(sofaRef);
+    if (aSofa == null) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFAREF_NOT_FOUND);
+      throw e;
+    }
+    return aSofa;
+  }
 
-	public void commitTypeSystem() {
+  public CASImpl getBaseCAS() {
+    return this.svd.baseCAS;
+  }
+
+  public FSIterator getSofaIterator() {
+    FSIndex sofaIndex = this.svd.baseCAS.indexRepository.getIndex(CAS.SOFA_INDEX_NAME);
+    return sofaIndex.iterator();
+  }
+
+  // For internal use only
+  public void setSofaFeat(int addr, int sofa) {
+    setFeatureValue(addr, this.svd.casMetadata.ts.annotSofaFeatCode, sofa);
+  }
+
+  // For internal use only
+  public int getSofaFeat(int addr) {
+    return getFeatureValue(addr, this.svd.casMetadata.ts.annotSofaFeatCode);
+  }
+
+  // For internal use only
+  public int getSofaRef() {
+    if (this.mySofaRef == -1) {
+      // create the SofaFS for _InitialView ...
+      // ... and reset mySofaRef to point to it
+      this.mySofaRef = this.createInitialSofa(null).hashCode();
+    }
+    return this.mySofaRef;
+  }
+
+  // For internal use only
+  public InputStream getSofaDataStream(SofaFS aSofa) {
+    try {
+
+      if (null != aSofa.getLocalStringData()) {
+        ByteArrayInputStream bis = new ByteArrayInputStream(aSofa.getLocalStringData().getBytes(
+            "UTF-8"));
+        return bis;
+      } else if (null != aSofa.getLocalFSData()) {
+        FeatureStructureImpl fs = (FeatureStructureImpl) aSofa.getLocalFSData();
+
+        int arrayStart = 0;
+        int arraySize = this.ll_getArraySize(fs.getAddress());
+        ByteBuffer buf = null;
+        Type type = fs.getType();
+        if (type.getName().equals(CAS.TYPE_NAME_INTEGER_ARRAY)) {
+          arrayStart = getArrayStartAddress(fs.getAddress());
+          buf = ByteBuffer.allocate(arraySize * 4);
+          IntBuffer intbuf = buf.asIntBuffer();
+          intbuf.put(this.getHeap().heap, arrayStart, arraySize);
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        } else if (type.getName().equals(CAS.TYPE_NAME_FLOAT_ARRAY)) {
+          arrayStart = getArrayStartAddress(fs.getAddress());
+          buf = ByteBuffer.allocate(arraySize * 4);
+          FloatBuffer floatbuf = buf.asFloatBuffer();
+          float[] floatArray = new float[arraySize];
+          for (int i = arrayStart; i < arrayStart + arraySize; i++) {
+            floatArray[i - arrayStart] = Float.intBitsToFloat(this.getHeap().heap[i]);
+          }
+          floatbuf.put(floatArray);
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        } else if (type.getName().equals(CAS.TYPE_NAME_BOOLEAN_ARRAY)
+            || type.getName().equals(CAS.TYPE_NAME_BYTE_ARRAY)) {
+          arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
+          buf = ByteBuffer.allocate(arraySize);
+          buf.put(this.getByteHeap().heap, arrayStart, arraySize);
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        } else if (type.getName().equals(CAS.TYPE_NAME_SHORT_ARRAY)) {
+          arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
+          buf = ByteBuffer.allocate(arraySize * 2);
+          ShortBuffer shortbuf = buf.asShortBuffer();
+          shortbuf.put(this.getShortHeap().heap, arrayStart, arraySize);
+
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        } else if (type.getName().equals(CAS.TYPE_NAME_LONG_ARRAY)) {
+          arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
+          buf = ByteBuffer.allocate(arraySize * 8);
+          LongBuffer longbuf = buf.asLongBuffer();
+          longbuf.put(this.getLongHeap().heap, arrayStart, arraySize);
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        } else if (type.getName().equals(CAS.TYPE_NAME_DOUBLE_ARRAY)) {
+          arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
+          buf = ByteBuffer.allocate(arraySize * 8);
+          DoubleBuffer doublebuf = buf.asDoubleBuffer();
+          double[] doubleArray = new double[arraySize];
+          for (int i = arrayStart; i < arrayStart + arraySize; i++) {
+            doubleArray[i - arrayStart] = Double.longBitsToDouble(this.getLongHeap().heap[i]);
+          }
+          doublebuf.put(doubleArray);
+          ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+          return bis;
+        }
+
+      } else if (null != aSofa.getSofaURI()) {
+        URL url = new URL(aSofa.getSofaURI());
+        return url.openStream();
+      } else {
+        return null;
+      }
+    } catch (MalformedURLException exc) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
+          new String[] { exc.getMessage() });
+      throw e;
+    } catch (CASRuntimeException exc) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
+          new String[] { exc.getMessage() });
+      throw e;
+    } catch (IOException exc) {
+      CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
+          new String[] { exc.getMessage() });
+      throw e;
+    }
+    return null;
+  }
+
+  public FSIterator createFilteredIterator(FSIterator it, FSMatchConstraint cons) {
+    return new FilteredIterator(it, cons);
+  }
+
+  public void commitTypeSystem() {
     final TypeSystemImpl ts = this.svd.casMetadata.ts;
     // For CAS pools, the type system could have already been committed
     // Skip the initFSClassReg if so, because it may have been updated to a JCas
-    //   version by another CAS processing in the pool
-    //   @see org.apache.uima.cas.impl.FSClassRegistry
-    
-    // avoid race: two instances of a CAS from a pool attempting to commit the ts 
+    // version by another CAS processing in the pool
+    // @see org.apache.uima.cas.impl.FSClassRegistry
+
+    // avoid race: two instances of a CAS from a pool attempting to commit the
+    // ts
     // at the same time
     synchronized (ts) {
-  		if ( ! ts.isCommitted()) {
+      if (!ts.isCommitted()) {
         this.svd.casMetadata.ts.commit();
         initFSClassRegistry();
         FSClassRegistry fscr = getFSClassRegistry();
-        // save for the case of non=jcas pipeline with a jcas pear in the middle - this
-        //  allows subsequent downstream annotators to run without jcas
-        fscr.saveGeneratorsForClassLoader(this.svd.previousJCasClassLoader, fscr.getBaseGenerators());      
+        // save for the case of non=jcas pipeline with a jcas pear in the middle
+        // - this
+        // allows subsequent downstream annotators to run without jcas
+        fscr.saveGeneratorsForClassLoader(this.svd.previousJCasClassLoader, fscr
+            .getBaseGenerators());
       }
     }
     setLocalFsGenerators(this.svd.casMetadata.fsClassRegistry.getBaseGenerators());
-		// After the type system has been committed, we can create the
-		// index repository.
-		createIndexRepository();
-	}
-  
+    // After the type system has been committed, we can create the
+    // index repository.
+    createIndexRepository();
+  }
+
   // internal use, public for cross class ref
-  public void setLocalFsGenerators(FSGenerator [] fsGenerators) {
+  public void setLocalFsGenerators(FSGenerator[] fsGenerators) {
     this.svd.localFsGenerators = fsGenerators;
   }
-  
-	private void createIndexRepository() {
-		if (!this.getTypeSystemMgr().isCommitted()) {
-			throw new CASAdminException(CASAdminException.MUST_COMMIT_TYPE_SYSTEM);
-		}
-		if (this.indexRepository == null) {
-			this.indexRepository = new FSIndexRepositoryImpl(this);
-		}
-	}
-
-	public FSIndexRepositoryMgr getIndexRepositoryMgr() {
-		// assert(this.cas.getIndexRepository() != null);
-		return this.indexRepository;
-	}
 
-	/**
+  private void createIndexRepository() {
+    if (!this.getTypeSystemMgr().isCommitted()) {
+      throw new CASAdminException(CASAdminException.MUST_COMMIT_TYPE_SYSTEM);
+    }
+    if (this.indexRepository == null) {
+      this.indexRepository = new FSIndexRepositoryImpl(this);
+    }
+  }
+
+  public FSIndexRepositoryMgr getIndexRepositoryMgr() {
+    // assert(this.cas.getIndexRepository() != null);
+    return this.indexRepository;
+  }
+
+  /**
    * @deprecated
    */
-	public void commitFS(FeatureStructure fs) {
-		getIndexRepository().addFS(fs);
-	}
+  public void commitFS(FeatureStructure fs) {
+    getIndexRepository().addFS(fs);
+  }
 
-	public FeaturePath createFeaturePath() {
-		return new FeaturePathImpl();
-	}
+  public FeaturePath createFeaturePath() {
+    return new FeaturePathImpl();
+  }
 
-	// Implement the ConstraintFactory interface.
+  // Implement the ConstraintFactory interface.
 
-	/**
+  /**
    * @see org.apache.uima.cas.admin.CASMgr#getTypeSystemMgr()
    */
-	public TypeSystemMgr getTypeSystemMgr() {
-		return this.svd.casMetadata.ts;
-	}
-
-	public void reset() {
-		if (!this.svd.flushEnabled) {
-			throw new CASAdminException(CASAdminException.FLUSH_DISABLED);
-		}
-		if (this == this.svd.baseCAS) {
-			resetNoQuestions();
-			return;
-		}
-		// called from a CAS view.
-		// clear CAS ...
-		this.svd.baseCAS.resetNoQuestions();
-	}
+  public TypeSystemMgr getTypeSystemMgr() {
+    return this.svd.casMetadata.ts;
+  }
+
+  public void reset() {
+    if (!this.svd.flushEnabled) {
+      throw new CASAdminException(CASAdminException.FLUSH_DISABLED);
+    }
+    if (this == this.svd.baseCAS) {
+      resetNoQuestions();
+      return;
+    }
+    // called from a CAS view.
+    // clear CAS ...
+    this.svd.baseCAS.resetNoQuestions();
+  }
 
   /*
    * iterated reset - once per view of a CAS except for the base CAS
    */
-	private void resetView() {
-		this.indexRepository.flush();
-//		if (this.mySofaRef > 0 && this.getSofa().getSofaRef() == 1) {
-//			// indicate no Sofa exists for the initial view
-//			this.mySofaRef = -1;
-//		} else {
-//			this.mySofaRef = 0;
-//		}
-//		if (this.jcas != null) {
-//			try {
-//				JCasImpl.clearData(this);
-//			} catch (CASException e) {
-//				CASAdminException cae = new CASAdminException(CASAdminException.JCAS_ERROR);
-//				cae.addArgument(e.getMessage());
-//				throw cae;
-//			}
-//		}
-	}
-
-	public void resetNoQuestions() {
-		int numViews = this.getBaseSofaCount();
-		// Flush indexRepository for all Sofa
-		for (int view = 1; view <= numViews; view++) {
-			CAS tcas = (view == 1) ? getInitialView() : getView(view);
-			if (tcas != null) {
-				((CASImpl) tcas).resetView();
-
-      // mySofaRef = -1 is a flag in initial view that sofa has not been set.
-      //    For the initial view, it is possible to not have a sofa - it is set
-      //    "lazily" upon the first need.
-      //  all other views always have a sofa set.  The sofaRef is set to 0, 
-      //  but will be set to the actual sofa addr in the cas when the view is
-      //  initialized.
+  private void resetView() {
+    this.indexRepository.flush();
+    // if (this.mySofaRef > 0 && this.getSofa().getSofaRef() == 1) {
+    // // indicate no Sofa exists for the initial view
+    // this.mySofaRef = -1;
+    // } else {
+    // this.mySofaRef = 0;
+    // }
+    // if (this.jcas != null) {
+    // try {
+    // JCasImpl.clearData(this);
+    // } catch (CASException e) {
+    // CASAdminException cae = new
+    // CASAdminException(CASAdminException.JCAS_ERROR);
+    // cae.addArgument(e.getMessage());
+    // throw cae;
+    // }
+    // }
+  }
+
+  public void resetNoQuestions() {
+    int numViews = this.getBaseSofaCount();
+    // Flush indexRepository for all Sofa
+    for (int view = 1; view <= numViews; view++) {
+      CAS tcas = (view == 1) ? getInitialView() : getView(view);
+      if (tcas != null) {
+        ((CASImpl) tcas).resetView();
+
+        // mySofaRef = -1 is a flag in initial view that sofa has not been set.
+        // For the initial view, it is possible to not have a sofa - it is set
+        // "lazily" upon the first need.
+        // all other views always have a sofa set. The sofaRef is set to 0,
+        // but will be set to the actual sofa addr in the cas when the view is
+        // initialized.
         ((CASImpl) tcas).mySofaRef = (1 == view) ? -1 : 0;
       }
- 		}
-		if (this.getHeap().getCurrentTempSize() > CASImpl.resetHeapSize) {
-			this.getHeap().resetTempHeap(true);
-			resetStringTable(true);
-		} else {
-			this.getHeap().resetTempHeap(false);
-			resetStringTable(false);
-		}
-
-		this.getByteHeap().reset();
-		this.getShortHeap().reset();
-		this.getLongHeap().reset();
-
-		this.indexRepository.flush();
-		this.svd.sofaNameSet.clear();
-		this.svd.initialSofaCreated = false;
-		// always an Initial View now!!!
-		this.svd.viewCount = 1;
-
-		if (null != this.svd.casMetadata.fsClassRegistry ) {
-			// needed only if caching non-JCas Java cover objects
-      //  NOTE:  This code may not work - has not been maintained
-			this.svd.casMetadata.fsClassRegistry.flush();
-		}
-		if (this.jcas != null) {
-				JCasImpl.clearData(this);
-		}
-	}
+    }
+    if (this.getHeap().getCurrentTempSize() > CASImpl.resetHeapSize) {
+      this.getHeap().resetTempHeap(true);
+      resetStringTable(true);
+    } else {
+      this.getHeap().resetTempHeap(false);
+      resetStringTable(false);
+    }
+
+    this.getByteHeap().reset();
+    this.getShortHeap().reset();
+    this.getLongHeap().reset();
+
+    this.indexRepository.flush();
+    this.svd.sofaNameSet.clear();
+    this.svd.initialSofaCreated = false;
+    // always an Initial View now!!!
+    this.svd.viewCount = 1;
 
-	/**
+    if (null != this.svd.casMetadata.fsClassRegistry) {
+      // needed only if caching non-JCas Java cover objects
+      // NOTE: This code may not work - has not been maintained
+      this.svd.casMetadata.fsClassRegistry.flush();
+    }
+    if (this.jcas != null) {
+      JCasImpl.clearData(this);
+    }
+  }
+
+  /**
    * @deprecated Use {@link #reset reset()}instead.
    */
-	public void flush() {
-		reset();
-	}
-
-	/**
-   * 
-   */
-	public FSIndexRepository getIndexRepository() {
-		if (this == this.svd.baseCAS) {
-			// BaseCas has no indexes for users
-			return null;
-		}
-		if (this.indexRepository.isCommitted()) {
-			return this.indexRepository;
-		}
-		return null;
-	}
-
-	FSIndexRepository getBaseIndexRepository() {
-		if (this.svd.baseCAS.indexRepository.isCommitted()) {
-			return this.svd.baseCAS.indexRepository;
-		}
-		return null;
-	}
-
-	void addSofaFsToIndex(SofaFS sofa) {
-		this.svd.baseCAS.getBaseIndexRepository().addFS(sofa);
-	}
-
-	void registerView(SofaFS aSofa) {
-		this.mySofaRef = ((FeatureStructureImpl)aSofa).getAddress();
-	}
-
-	public void reinit(CASSerializer ser) {
-		if (this != this.svd.baseCAS) {
-			this.svd.baseCAS.reinit(ser);
-			return;
-		}
-		this.resetNoQuestions();
-		reinit(ser.getHeapMetadata(), ser.getHeapArray(), ser.getStringTable(), ser.getFSIndex(), ser
-				.getByteArray(), ser.getShortArray(), ser.getLongArray());
-	}
+  public void flush() {
+    reset();
+  }
+
+  /**
+   * 
+   */
+  public FSIndexRepository getIndexRepository() {
+    if (this == this.svd.baseCAS) {
+      // BaseCas has no indexes for users
+      return null;
+    }
+    if (this.indexRepository.isCommitted()) {
+      return this.indexRepository;
+    }
+    return null;
+  }
+
+  FSIndexRepository getBaseIndexRepository() {
+    if (this.svd.baseCAS.indexRepository.isCommitted()) {
+      return this.svd.baseCAS.indexRepository;
+    }
+    return null;
+  }
+
+  void addSofaFsToIndex(SofaFS sofa) {
+    this.svd.baseCAS.getBaseIndexRepository().addFS(sofa);
+  }
+
+  void registerView(SofaFS aSofa) {
+    this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
+  }
+
+  public void reinit(CASSerializer ser) {
+    if (this != this.svd.baseCAS) {
+      this.svd.baseCAS.reinit(ser);
+      return;
+    }
+    this.resetNoQuestions();
+    reinit(ser.getHeapMetadata(), ser.getHeapArray(), ser.getStringTable(), ser.getFSIndex(), ser
+        .getByteArray(), ser.getShortArray(), ser.getLongArray());
+  }
 
-	/**
+  /**
    * @see org.apache.uima.cas.CAS#fs2listIterator(FSIterator)
    */
-	public ListIterator fs2listIterator(FSIterator it) {
-		return new FSListIteratorImpl(it);
-	}
+  public ListIterator fs2listIterator(FSIterator it) {
+    return new FSListIteratorImpl(it);
+  }
 
-	/**
+  /**
    * @see org.apache.uima.cas.admin.CASMgr#getCAS()
    */
-	public CAS getCAS() {
-		if (this.indexRepository.isCommitted()) {
-			return this;
-		}
-		throw new CASAdminException(CASAdminException.MUST_COMMIT_INDEX_REPOSITORY);
-	}
-
-	void resetStringTable() {
-		this.resetStringTable(false);
-	}
-
-	void resetStringTable(boolean doFullReset) {
-		this.getStringHeap().reset(doFullReset);
-	}
-
-//	public void setFSClassRegistry(FSClassRegistry fsClassReg) {
-//		this.svd.casMetadata.fsClassRegistry = fsClassReg;
-//	}
-
-	private void initFSClassRegistry() {
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		// System.out.println("Initializing FSClassRegistry");
-		this.svd.casMetadata.fsClassRegistry.initGeneratorArray();
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.fsArrayType, new ArrayFSGenerator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.intArrayType, IntArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.floatArrayType, FloatArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.stringArrayType, StringArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.sofaType, SofaFSImpl.getSofaFSGenerator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotBaseType, AnnotationBaseImpl.getAnnotationGenerator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotType, AnnotationImpl.getAnnotationGenerator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.byteArrayType, ByteArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.booleanArrayType, BooleanArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.shortArrayType, ShortArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.longArrayType, LongArrayFSImpl.generator());
-		this.svd.casMetadata.fsClassRegistry.addClassForType(ts.doubleArrayType, DoubleArrayFSImpl.generator());
-
-		// assert(fsClassReg != null);
-	}
-  // JCasGen'd cover classes use this to add their generators to the class registry
-  //   Note that this now (June 2007) a no-op for JCasGen'd generators
-  // Also used in JCas initialization to copy-down super generators to subtypes as needed
-	public FSClassRegistry getFSClassRegistry() // for JCas integration
-	{
-		return this.svd.casMetadata.fsClassRegistry;
-	}
-
-	public void reinit(CASCompleteSerializer casCompSer) {
-		if (this != this.svd.baseCAS) {
-			this.svd.baseCAS.reinit(casCompSer);
-			return;
-		}
-		TypeSystemImpl ts = casCompSer.getCASMgrSerializer().getTypeSystem();
+  public CAS getCAS() {
+    if (this.indexRepository.isCommitted()) {
+      return this;
+    }
+    throw new CASAdminException(CASAdminException.MUST_COMMIT_INDEX_REPOSITORY);
+  }
+
+  void resetStringTable() {
+    this.resetStringTable(false);
+  }
+
+  void resetStringTable(boolean doFullReset) {
+    this.getStringHeap().reset(doFullReset);
+  }
+
+  // public void setFSClassRegistry(FSClassRegistry fsClassReg) {
+  // this.svd.casMetadata.fsClassRegistry = fsClassReg;
+  // }
+
+  private void initFSClassRegistry() {
+    final TypeSystemImpl ts = this.svd.casMetadata.ts;
+    // System.out.println("Initializing FSClassRegistry");
+    this.svd.casMetadata.fsClassRegistry.initGeneratorArray();
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.fsArrayType, new ArrayFSGenerator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.intArrayType, IntArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.floatArrayType, FloatArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.stringArrayType, StringArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.sofaType, SofaFSImpl
+        .getSofaFSGenerator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotBaseType, AnnotationBaseImpl
+        .getAnnotationGenerator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotType, AnnotationImpl
+        .getAnnotationGenerator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.byteArrayType, ByteArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.booleanArrayType, BooleanArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.shortArrayType, ShortArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.longArrayType, LongArrayFSImpl
+        .generator());
+    this.svd.casMetadata.fsClassRegistry.addClassForType(ts.doubleArrayType, DoubleArrayFSImpl
+        .generator());
+
+    // assert(fsClassReg != null);
+  }
+
+  // JCasGen'd cover classes use this to add their generators to the class
+  // registry
+  // Note that this now (June 2007) a no-op for JCasGen'd generators
+  // Also used in JCas initialization to copy-down super generators to subtypes
+  // as needed
+  public FSClassRegistry getFSClassRegistry() // for JCas integration
+  {
+    return this.svd.casMetadata.fsClassRegistry;
+  }
+
+  public void reinit(CASCompleteSerializer casCompSer) {
+    if (this != this.svd.baseCAS) {
+      this.svd.baseCAS.reinit(casCompSer);
+      return;
+    }
+    TypeSystemImpl ts = casCompSer.getCASMgrSerializer().getTypeSystem();
     this.svd.casMetadata = ts.casMetadata;
-		commitTypeSystem();
+    commitTypeSystem();
 
-		// reset index repositories -- wipes out Sofa index
-		this.indexRepository = casCompSer.getCASMgrSerializer().getIndexRepository(this);
-		this.indexRepository.commit();
-
-		// get handle to existing initial View
-		CAS initialView = this.getInitialView();
-
-		// throw away all other View information as the CAS definition may have changed
-		this.svd.sofa2indexMap.clear();
-		this.svd.sofaNbr2ViewMap.clear();
-		this.svd.viewCount = 0;
-
-		// freshen the initial view
-		((CASImpl) initialView).refreshView(this.svd.baseCAS, null);
-		this.svd.sofaNbr2ViewMap.put(new Integer(1), initialView);
+    // reset index repositories -- wipes out Sofa index
+    this.indexRepository = casCompSer.getCASMgrSerializer().getIndexRepository(this);
+    this.indexRepository.commit();
+
+    // get handle to existing initial View
+    CAS initialView = this.getInitialView();
+
+    // throw away all other View information as the CAS definition may have
+    // changed
+    this.svd.sofa2indexMap.clear();
+    this.svd.sofaNbr2ViewMap.clear();
+    this.svd.viewCount = 0;
+
+    // freshen the initial view
+    ((CASImpl) initialView).refreshView(this.svd.baseCAS, null);
+    this.svd.sofaNbr2ViewMap.put(new Integer(1), initialView);
     this.svd.viewCount = 1;
 
-		// deserialize heap
-		CASSerializer casSer = casCompSer.getCASSerializer();
-		reinit(casSer.getHeapMetadata(), casSer.getHeapArray(), casSer.getStringTable(), casSer
-				.getFSIndex(), casSer.getByteArray(), casSer.getShortArray(), casSer.getLongArray());
-
-		// we also need to throw away the JCAS. A new JCAS will be created on
-		// the next
-		// call to getJCas(). As with the CAS, we are counting on the fact that
-		// this happens only in a service, where JCAS handles are not held on
-		// to.
-		this.jcas = null;
-//		this.sofa2jcasMap.clear();
-	}
-
-	void reinit(int[] heapMetadata, int[] heapArray, String[] stringTable, int[] fsIndex,
-			byte[] byteHeapArray, short[] shortHeapArray, long[] longHeapArray) {
-		createStringTableFromArray(stringTable);
-		this.getHeap().reinit(heapMetadata, heapArray);
-		if (byteHeapArray != null) {
+    // deserialize heap
+    CASSerializer casSer = casCompSer.getCASSerializer();
+    reinit(casSer.getHeapMetadata(), casSer.getHeapArray(), casSer.getStringTable(), casSer
+        .getFSIndex(), casSer.getByteArray(), casSer.getShortArray(), casSer.getLongArray());
+
+    // we also need to throw away the JCAS. A new JCAS will be created on
+    // the next
+    // call to getJCas(). As with the CAS, we are counting on the fact that
+    // this happens only in a service, where JCAS handles are not held on
+    // to.
+    this.jcas = null;
+    // this.sofa2jcasMap.clear();
+  }
+
+  void reinit(int[] heapMetadata, int[] heapArray, String[] stringTable, int[] fsIndex,
+      byte[] byteHeapArray, short[] shortHeapArray, long[] longHeapArray) {
+    createStringTableFromArray(stringTable);
+    this.getHeap().reinit(heapMetadata, heapArray);
+    if (byteHeapArray != null) {
       this.getByteHeap().reinit(byteHeapArray);
     }
-		if (shortHeapArray != null) {
+    if (shortHeapArray != null) {
       this.getShortHeap().reinit(shortHeapArray);
     }
-		if (longHeapArray != null) {
+    if (longHeapArray != null) {
       this.getLongHeap().reinit(longHeapArray);
     }
 
-		reinitIndexedFSs(fsIndex);
-	}
+    reinitIndexedFSs(fsIndex);
+  }
 
-	/**
-   * --------------------------------------------------------------------- 
-   * see Blob Format in CASSerializer
+  /**
+   * --------------------------------------------------------------------- see
+   * Blob Format in CASSerializer
    * 
-   * This reads in and deserializes CAS data from a stream. Byte swapping may be needed if the blob
-   * is from C++ -- C++ blob serialization writes data in native byte order.
+   * This reads in and deserializes CAS data from a stream. Byte swapping may be
+   * needed if the blob is from C++ -- C++ blob serialization writes data in
+   * native byte order.
    * 
    * @param istream
    * @throws CASRuntimeException
    */
-	public void reinit(InputStream istream) throws CASRuntimeException {
-		if (this != this.svd.baseCAS) {
-			this.svd.baseCAS.reinit(istream);
-			return;
-		}
-		this.resetNoQuestions();
-		DataInputStream dis = new DataInputStream(istream);
-
-		try {
-			// key
-			// deteremine if byte swap if needed based on key
-			byte[] bytebuf = new byte[4];
-			bytebuf[0] = dis.readByte();  // U
-			bytebuf[1] = dis.readByte();  // I
-			bytebuf[2] = dis.readByte();  // M
-			bytebuf[3] = dis.readByte();  // A
-
-			boolean swap = false;
-			// check if first byte is ascii char U
-			if (bytebuf[0] != 85) {
-				swap = true;
-			}
-
-			// version
-			// NOTE: even though nothing ever uses the version (yet),
-			// we MUST read it from the stream or else subsequent 
-			// reads will not work. So that's why
-			// we are reading here and not assigning to any variable.
-			if (swap) {
-				swap4(dis, bytebuf);
-			} else {
-				dis.readInt();
-			}
-
-			// main fsheap
-			int fsheapsz = 0;
-			if (swap) {
-				fsheapsz = swap4(dis, bytebuf);
-			} else {
-				fsheapsz = dis.readInt();
-			}
-
-			this.getHeap().reinitSizeOnly(fsheapsz);
-			for (int i = 0; i < fsheapsz; i++) {
-				if (swap) {
-					this.getHeap().heap[i] = swap4(dis, bytebuf);
-				} else {
-					this.getHeap().heap[i] = dis.readInt();
-				}
-			}
-
-			// string heap
-			int stringheapsz = 0;
-			if (swap) {
-				stringheapsz = swap4(dis, bytebuf);
-			} else {
-				stringheapsz = dis.readInt();
-			}
-
-			this.getStringHeap().stringHeap = new char[stringheapsz];
-			for (int i = 0; i < stringheapsz; i++) {
-				if (swap) {
-					this.getStringHeap().stringHeap[i] = swap2(dis, bytebuf);
-				} else {
-					this.getStringHeap().stringHeap[i] = dis.readChar();
-				}
-			}
-			this.getStringHeap().charHeapPos = stringheapsz;
-
-			// word alignment
-			if (stringheapsz % 2 != 0) {
-				dis.readChar();
-			}
-
-			// string ref heap
-			int refheapsz = 0;
-			if (swap) {
-				refheapsz = swap4(dis, bytebuf);
-			} else {
-				refheapsz = dis.readInt();
-			}
-
-			refheapsz--;
-			refheapsz = refheapsz / 2;
-			refheapsz = refheapsz * 3;
-
-			// read back into references consisting to three ints
-			// --stringheap offset,length, stringlist offset
-			this.getStringHeap().refHeap = new int[StringHeap.FIRST_CELL_REF + refheapsz];
-
-			dis.readInt(); // 0
-			for (int i = this.getStringHeap().refHeapPos; i < this.getStringHeap().refHeap.length; i += StringHeap.REF_HEAP_CELL_SIZE) {
-				if (swap) {
-					this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_POINTER_OFFSET] = swap4(dis, bytebuf);
-					this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_STRLEN_OFFSET] = swap4(dis, bytebuf);
-				} else {
-					this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_POINTER_OFFSET] = dis.readInt();
-					this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_STRLEN_OFFSET] = dis.readInt();
-				}
-				this.getStringHeap().refHeap[i + StringHeap.STRING_LIST_ADDR_OFFSET] = 0;
-			}
-			this.getStringHeap().refHeapPos = refheapsz+ StringHeap.FIRST_CELL_REF;
-
-			// indexed FSs
-			int fsindexsz = 0;
-			if (swap) {
-				fsindexsz = swap4(dis, bytebuf);
-			} else {
-				fsindexsz = dis.readInt();
-			}
-			int[] fsindexes = new int[fsindexsz];
-			for (int i = 0; i < fsindexsz; i++) {
-				if (swap) {
-					fsindexes[i] = swap4(dis, bytebuf);
-				} else {
-					fsindexes[i] = dis.readInt();
-				}
-			}
-
-			// build the index
-			reinitIndexedFSs(fsindexes);
-
-			// byte heap
-			int byteheapsz = 0;
-			if (swap) {
-				byteheapsz = swap4(dis, bytebuf);
-			} else {
-				byteheapsz = dis.readInt();
-			}
-
-			this.getByteHeap().heap = new byte[Math.max(16, byteheapsz)]; // must
-			// be >
-			// 0
-			for (int i = 0; i < byteheapsz; i++) {
-				this.getByteHeap().heap[i] = dis.readByte();
-			}
-			this.getByteHeap().heapPos = byteheapsz;
+  public void reinit(InputStream istream) throws CASRuntimeException {
+    if (this != this.svd.baseCAS) {
+      this.svd.baseCAS.reinit(istream);
+      return;
+    }
+    this.resetNoQuestions();
+    DataInputStream dis = new DataInputStream(istream);
 
-			// word alignment
-      int align = (4 - (byteheapsz % 4)) % 4;
-			for (int i = 0; i < align; i++) {
-				dis.readByte();
-			}
-
-			// short heap
-			int shortheapsz = 0;
-			if (swap) {
-				shortheapsz = swap4(dis, bytebuf);
-			} else {
-				shortheapsz = dis.readInt();
-			}
-			this.getShortHeap().heap = new short[Math.max(16, shortheapsz)]; // must
-			// be >
-			// 0
-			for (int i = 0; i < shortheapsz; i++) {
-				if (swap) {
-					this.getShortHeap().heap[i] = (short) swap2(dis, bytebuf);
-				} else {
-					this.getShortHeap().heap[i] = dis.readShort();
-				}
-			}
-			this.getShortHeap().heapPos = shortheapsz;
-
-			// word alignment
-			if (shortheapsz % 2 != 0) {
-				dis.readShort();
-			}
-
-			// long heap
-			int longheapsz = 0;
-			if (swap) {
-				longheapsz = swap4(dis, bytebuf);
-				bytebuf = new byte[8];
-			} else {
-				longheapsz = dis.readInt();
-			}
-			this.getLongHeap().heap = new long[Math.max(16, longheapsz)]; // must
-			// be >
-			// 0
-			for (int i = 0; i < longheapsz; i++) {
-				if (swap) {
-					this.getLongHeap().heap[i] = swap8(dis, bytebuf);
-				} else {
-					this.getLongHeap().heap[i] = dis.readLong();
-				}
-			}
-			this.getLongHeap().heapPos = longheapsz;
-
-		} catch (IOException e) {
-			CASRuntimeException exception = new CASRuntimeException(
-					CASRuntimeException.BLOB_DESERIALIZATION, new String[] { e.getMessage() });
-			throw exception;
-		}
-	}
-
-	private long swap8(DataInputStream dis, byte[] buf) throws IOException {
-
-		buf[7] = dis.readByte();
-		buf[6] = dis.readByte();
-		buf[5] = dis.readByte();
-		buf[4] = dis.readByte();
-		buf[3] = dis.readByte();
-		buf[2] = dis.readByte();
-		buf[1] = dis.readByte();
-		buf[0] = dis.readByte();
-		ByteBuffer bb = ByteBuffer.wrap(buf);
-		return bb.getLong();
-	}
-
-	private int swap4(DataInputStream dis, byte[] buf) throws IOException {
-		buf[3] = dis.readByte();
-		buf[2] = dis.readByte();
-		buf[1] = dis.readByte();
-		buf[0] = dis.readByte();
-		ByteBuffer bb = ByteBuffer.wrap(buf);
-		return bb.getInt();
-	}
-
-	private char swap2(DataInputStream dis, byte[] buf) throws IOException {
-		buf[1] = dis.readByte();
-		buf[0] = dis.readByte();
-		ByteBuffer bb = ByteBuffer.wrap(buf, 0, 2);
-		return bb.getChar();
-	}
+    try {
+      // key
+      // deteremine if byte swap if needed based on key
+      byte[] bytebuf = new byte[4];
+      bytebuf[0] = dis.readByte(); // U
+      bytebuf[1] = dis.readByte(); // I
+      bytebuf[2] = dis.readByte(); // M
+      bytebuf[3] = dis.readByte(); // A
+
+      boolean swap = false;
+      // check if first byte is ascii char U
+      if (bytebuf[0] != 85) {
+        swap = true;
+      }
 
-  // assumes:
-  //   indexes are empty on entry
-  //   
-	private void reinitIndexedFSs(int[] fsIndex) {
-		// Add FSs to index repository for base CAS
-		int numViews = fsIndex[0]; 
-		int loopLen = fsIndex[1];  // number of sofas, not necessarily the same as number of views
-                               // because the initial view may not have a sofa
-		for (int i = 2; i < loopLen + 2; i++) {  //iterate over all the sofas,
-			this.indexRepository.addFS(fsIndex[i]);  // add to base index
-		}
-		int loopStart = loopLen + 2;
-
-		FSIterator iterator = this.svd.baseCAS.getSofaIterator();
-		final Feature idFeat = getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID);
-		// Add FSs to index repository for each View
-		while (iterator.isValid()) {
-			SofaFS sofa = (SofaFS) iterator.get();
-			String id = getLowLevelCAS().ll_getStringValue(((FeatureStructureImpl)sofa).getAddress(),
-					((FeatureImpl) idFeat).getCode());
-			if (CAS.NAME_DEFAULT_SOFA.equals(id)) {
-				this.registerInitialSofa();
-        this.svd.sofaNameSet.add(id);
-			}
-      // next line the getView as a side effect
-      //   checks for dupl sofa name, and if not,
-      //   adds the name to the sofaNameSet
-      ((CASImpl) this.getView(sofa)).registerView(sofa);
-  
-			iterator.moveToNext();
-		}
-    this.svd.viewCount = numViews;  // total number of views
-		for (int viewNbr = 1; viewNbr <= numViews; viewNbr++) {
-			CAS view = (viewNbr == 1) ? getInitialView() : getView(viewNbr);
-			if (view != null) {
-				FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) getSofaIndexRepository(viewNbr);
-				loopLen = fsIndex[loopStart];
-				for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
-					loopIndexRep.addFS(fsIndex[i]);
-				}
-				loopStart += loopLen + 1;
-				((CASImpl) view).updateDocumentAnnotation();
-			} else {
-				loopStart += 1;
-			}
-		}
-	}
-
-	// IndexedFSs format:
-	// number of views
-	// number of sofas
-	// [sofa-1 ... sofa-n]
-	// number of FS indexed in View1
-	// [FS-1 ... FS-n]
-	// etc.
-	int[] getIndexedFSs() {
-		IntVector v = new IntVector();
-		int[] fsLoopIndex;
-
-		int numViews = getBaseSofaCount();
-		v.add(numViews);
-
-		// Get indexes for base CAS
-		fsLoopIndex = this.svd.baseCAS.indexRepository.getIndexedFSs();
-		v.add(fsLoopIndex.length);
-		for (int k = 0; k < fsLoopIndex.length; k++) {
-			v.add(fsLoopIndex[k]);
-		}
-
-		// Get indexes for each SofaFS in the CAS
-		for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) {
-			FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) this.svd.baseCAS
-					.getSofaIndexRepository(sofaNum);
-			if (loopIndexRep != null) {
-        fsLoopIndex = loopIndexRep.getIndexedFSs();
+      // version
+      // NOTE: even though nothing ever uses the version (yet),
+      // we MUST read it from the stream or else subsequent
+      // reads will not work. So that's why
+      // we are reading here and not assigning to any variable.
+      if (swap) {
+        swap4(dis, bytebuf);
       } else {
-        fsLoopIndex = (new IntVector()).toArray();
+        dis.readInt();
       }
-			v.add(fsLoopIndex.length);
-			for (int k = 0; k < fsLoopIndex.length; k++) {
-				v.add(fsLoopIndex[k]);
-			}
-		}
-		return v.toArray();
-	}
-
-	void createStringTableFromArray(String[] stringTable) {
-		// why a new heap instead of reseting the old one???
-		// this.stringHeap = new StringHeap();
-		this.getStringHeap().reset();
-		for (int i = 1; i < stringTable.length; i++) {
-			this.getStringHeap().addString(stringTable[i]);
-		}
-	}
-
-	static String mapName(String name, HashMap map) {
-		String out = (String) map.get(name);
-		if (out != null) {
-			return out;
-		}
-		return name;
-	}
-
-	/**
-   * This is your link from the low-level API to the high-level API. Use this method to create a
-   * FeatureStructure object from an address. Not that the reverse is not supported by public APIs
-   * (i.e., there is currently no way to get at the address of a FeatureStructure. Maybe we will
-   * need to change that.
-   * 
-   * @param addr
-   *          The address of the feature structure to be created.
-   * @return A FeatureStructure object. Note that no checking whatsoever is done on the input
-   *         address. There is really no way of finding out which addresses in the valid address
-   *         space actually represent feature structures, and which don't.
-   */
-	public FeatureStructure createFS(int addr) {
-		return ll_getFSForRef(addr);
-	}
-
-	public int ll_getArraySize(int arrayFsRef) {
-		return this.getHeap().heap[arrayFsRef + arrayLengthFeatOffset];
-	}
 
-	/**
-   * Get the heap address of the first cell of this array.
-   * 
-   * @param addr
-   *          The address of the array.
-   * @return The address where the first cell of the array is located.
-   */
-	public final int getArrayStartAddress(int addr) {
-		return addr + arrayContentOffset;
-	}
+      // main fsheap
+      int fsheapsz = 0;
+      if (swap) {
+        fsheapsz = swap4(dis, bytebuf);
+      } else {
+        fsheapsz = dis.readInt();
+      }
 
-	/**
-   * Get a specific value out of an array.
-   * 
-   * @param addr
-   *          The address of the array.
-   * @param index
-   *          The index of the value we're interested in.
-   * @return The value at <code>index</code>.
-   * @exception ArrayIndexOutOfBoundsException
-   */
-	public int getArrayValue(int addr, int index) {
-		checkArrayBounds(addr, index);
-		return this.getHeap().heap[addr + arrayContentOffset + index];
-	}
+      this.getHeap().reinitSizeOnly(fsheapsz);
+      for (int i = 0; i < fsheapsz; i++) {
+        if (swap) {
+          this.getHeap().heap[i] = swap4(dis, bytebuf);
+        } else {
+          this.getHeap().heap[i] = dis.readInt();
+        }
+      }
 
-	/**
-   * Set an array value.
-   * 
-   * @param addr
-   *          The address of the array.
-   * @param index
-   *          The index we want to set.
-   * @param value
-   *          The value we want to set.
+      // string heap
+      int stringheapsz = 0;
+      if (swap) {
+        stringheapsz = swap4(dis, bytebuf);
+      } else {
+        stringheapsz = dis.readInt();
+      }
+
+      this.getStringHeap().stringHeap = new char[stringheapsz];
+      for (int i = 0; i < stringheapsz; i++) {
+        if (swap) {
+          this.getStringHeap().stringHeap[i] = swap2(dis, bytebuf);
+        } else {
+          this.getStringHeap().stringHeap[i] = dis.readChar();
+        }
+      }
+      this.getStringHeap().charHeapPos = stringheapsz;
+
+      // word alignment
+      if (stringheapsz % 2 != 0) {
+        dis.readChar();
+      }
+
+      // string ref heap
+      int refheapsz = 0;
+      if (swap) {
+        refheapsz = swap4(dis, bytebuf);
+      } else {
+        refheapsz = dis.readInt();
+      }
+
+      refheapsz--;
+      refheapsz = refheapsz / 2;
+      refheapsz = refheapsz * 3;
+
+      // read back into references consisting to three ints
+      // --stringheap offset,length, stringlist offset
+      this.getStringHeap().refHeap = new int[StringHeap.FIRST_CELL_REF + refheapsz];
+
+      dis.readInt(); // 0
+      for (int i = this.getStringHeap().refHeapPos; i < this.getStringHeap().refHeap.length; i += StringHeap.REF_HEAP_CELL_SIZE) {
+        if (swap) {
+          this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_POINTER_OFFSET] = swap4(dis,
+              bytebuf);
+          this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_STRLEN_OFFSET] = swap4(dis, bytebuf);
+        } else {
+          this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_POINTER_OFFSET] = dis.readInt();
+          this.getStringHeap().refHeap[i + StringHeap.CHAR_HEAP_STRLEN_OFFSET] = dis.readInt();
+        }
+        this.getStringHeap().refHeap[i + StringHeap.STRING_LIST_ADDR_OFFSET] = 0;
+      }
+      this.getStringHeap().refHeapPos = refheapsz + StringHeap.FIRST_CELL_REF;
+
+      // indexed FSs
+      int fsindexsz = 0;
+      if (swap) {
+        fsindexsz = swap4(dis, bytebuf);
+      } else {
+        fsindexsz = dis.readInt();
+      }
+      int[] fsindexes = new int[fsindexsz];
+      for (int i = 0; i < fsindexsz; i++) {
+        if (swap) {
+          fsindexes[i] = swap4(dis, bytebuf);
+        } else {
+          fsindexes[i] = dis.readInt();
+        }
+      }
+
+      // build the index
+      reinitIndexedFSs(fsindexes);
+
+      // byte heap
+      int byteheapsz = 0;
+      if (swap) {
+        byteheapsz = swap4(dis, bytebuf);
+      } else {
+        byteheapsz = dis.readInt();
+      }
+
+      this.getByteHeap().heap = new byte[Math.max(16, byteheapsz)]; // must
+      // be >
+      // 0
+      for (int i = 0; i < byteheapsz; i++) {
+        this.getByteHeap().heap[i] = dis.readByte();
+      }
+      this.getByteHeap().heapPos = byteheapsz;
+
+      // word alignment
+      int align = (4 - (byteheapsz % 4)) % 4;
+      for (int i = 0; i < align; i++) {
+        dis.readByte();
+      }
+
+      // short heap
+      int shortheapsz = 0;
+      if (swap) {
+        shortheapsz = swap4(dis, bytebuf);
+      } else {
+        shortheapsz = dis.readInt();
+      }
+      this.getShortHeap().heap = new short[Math.max(16, shortheapsz)]; // must
+      // be >
+      // 0
+      for (int i = 0; i < shortheapsz; i++) {
+        if (swap) {
+          this.getShortHeap().heap[i] = (short) swap2(dis, bytebuf);
+        } else {
+          this.getShortHeap().heap[i] = dis.readShort();
+        }
+      }
+      this.getShortHeap().heapPos = shortheapsz;
+
+      // word alignment
+      if (shortheapsz % 2 != 0) {
+        dis.readShort();
+      }
+
+      // long heap
+      int longheapsz = 0;
+      if (swap) {
+        longheapsz = swap4(dis, bytebuf);
+        bytebuf = new byte[8];
+      } else {
+        longheapsz = dis.readInt();
+      }
+      this.getLongHeap().heap = new long[Math.max(16, longheapsz)]; // must
+      // be >
+      // 0
+      for (int i = 0; i < longheapsz; i++) {
+        if (swap) {
+          this.getLongHeap().heap[i] = swap8(dis, bytebuf);
+        } else {
+          this.getLongHeap().heap[i] = dis.readLong();
+        }
+      }
+      this.getLongHeap().heapPos = longheapsz;
+
+    } catch (IOException e) {
+      CASRuntimeException exception = new CASRuntimeException(
+          CASRuntimeException.BLOB_DESERIALIZATION, new String[] { e.getMessage() });
+      throw exception;
+    }
+  }
+
+  private long swap8(DataInputStream dis, byte[] buf) throws IOException {
+
+    buf[7] = dis.readByte();
+    buf[6] = dis.readByte();
+    buf[5] = dis.readByte();
+    buf[4] = dis.readByte();
+    buf[3] = dis.readByte();
+    buf[2] = dis.readByte();
+    buf[1] = dis.readByte();
+    buf[0] = dis.readByte();
+    ByteBuffer bb = ByteBuffer.wrap(buf);
+    return bb.getLong();
+  }
+
+  private int swap4(DataInputStream dis, byte[] buf) throws IOException {
+    buf[3] = dis.readByte();
+    buf[2] = dis.readByte();
+    buf[1] = dis.readByte();
+    buf[0] = dis.readByte();
+    ByteBuffer bb = ByteBuffer.wrap(buf);
+    return bb.getInt();
+  }
+
+  private char swap2(DataInputStream dis, byte[] buf) throws IOException {
+    buf[1] = dis.readByte();
+    buf[0] = dis.readByte();
+    ByteBuffer bb = ByteBuffer.wrap(buf, 0, 2);
+    return bb.getChar();
+  }
+
+  // assumes:
+  // indexes are empty on entry
+  //   
+  private void reinitIndexedFSs(int[] fsIndex) {
+    // Add FSs to index repository for base CAS
+    int numViews = fsIndex[0];
+    int loopLen = fsIndex[1]; // number of sofas, not necessarily the same as
+    // number of views
+    // because the initial view may not have a sofa
+    for (int i = 2; i < loopLen + 2; i++) { // iterate over all the sofas,
+      this.indexRepository.addFS(fsIndex[i]); // add to base index
+    }
+    int loopStart = loopLen + 2;
+
+    FSIterator iterator = this.svd.baseCAS.getSofaIterator();
+    final Feature idFeat = getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID);
+    // Add FSs to index repository for each View
+    while (iterator.isValid()) {
+      SofaFS sofa = (SofaFS) iterator.get();
+      String id = getLowLevelCAS().ll_getStringValue(((FeatureStructureImpl) sofa).getAddress(),
+          ((FeatureImpl) idFeat).getCode());
+      if (CAS.NAME_DEFAULT_SOFA.equals(id)) {
+        this.registerInitialSofa();
+        this.svd.sofaNameSet.add(id);
+      }
+      // next line the getView as a side effect
+      // checks for dupl sofa name, and if not,
+      // adds the name to the sofaNameSet
+      ((CASImpl) this.getView(sofa)).registerView(sofa);
+
+      iterator.moveToNext();
+    }
+    this.svd.viewCount = numViews; // total number of views
+    for (int viewNbr = 1; viewNbr <= numViews; viewNbr++) {
+      CAS view = (viewNbr == 1) ? getInitialView() : getView(viewNbr);
+      if (view != null) {
+        FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) getSofaIndexRepository(viewNbr);
+        loopLen = fsIndex[loopStart];
+        for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
+          loopIndexRep.addFS(fsIndex[i]);
+        }
+        loopStart += loopLen + 1;
+        ((CASImpl) view).updateDocumentAnnotation();
+      } else {
+        loopStart += 1;
+      }
+    }
+  }
+
+  // IndexedFSs format:
+  // number of views
+  // number of sofas
+  // [sofa-1 ... sofa-n]
+  // number of FS indexed in View1
+  // [FS-1 ... FS-n]
+  // etc.
+  int[] getIndexedFSs() {
+    IntVector v = new IntVector();
+    int[] fsLoopIndex;
+
+    int numViews = getBaseSofaCount();
+    v.add(numViews);
+
+    // Get indexes for base CAS
+    fsLoopIndex = this.svd.baseCAS.indexRepository.getIndexedFSs();
+    v.add(fsLoopIndex.length);
+    for (int k = 0; k < fsLoopIndex.length; k++) {
+      v.add(fsLoopIndex[k]);
+    }
+
+    // Get indexes for each SofaFS in the CAS
+    for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) {
+      FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) this.svd.baseCAS
+          .getSofaIndexRepository(sofaNum);
+      if (loopIndexRep != null) {
+        fsLoopIndex = loopIndexRep.getIndexedFSs();
+      } else {
+        fsLoopIndex = (new IntVector()).toArray();
+      }
+      v.add(fsLoopIndex.length);
+      for (int k = 0; k < fsLoopIndex.length; k++) {
+        v.add(fsLoopIndex[k]);
+      }
+    }
+    return v.toArray();
+  }
+
+  void createStringTableFromArray(String[] stringTable) {
+    // why a new heap instead of reseting the old one???
+    // this.stringHeap = new StringHeap();
+    this.getStringHeap().reset();
+    for (int i = 1; i < stringTable.length; i++) {
+      this.getStringHeap().addString(stringTable[i]);
+    }
+  }
+
+  static String mapName(String name, HashMap map) {
+    String out = (String) map.get(name);
+    if (out != null) {
+      return out;
+    }
+    return name;
+  }
+
+  /**
+   * This is your link from the low-level API to the high-level API. Use this
+   * method to create a FeatureStructure object from an address. Not that the
+   * reverse is not supported by public APIs (i.e., there is currently no way to
+   * get at the address of a FeatureStructure. Maybe we will need to change
+   * that.
+   * 
+   * @param addr
+   *                The address of the feature structure to be created.
+   * @return A FeatureStructure object. Note that no checking whatsoever is done
+   *         on the input address. There is really no way of finding out which
+   *         addresses in the valid address space actually represent feature
+   *         structures, and which don't.
+   */
+  public FeatureStructure createFS(int addr) {
+    return ll_getFSForRef(addr);
+  }
+
+  public int ll_getArraySize(int arrayFsRef) {
+    return this.getHeap().heap[arrayFsRef + arrayLengthFeatOffset];
+  }
+
+  /**
+   * Get the heap address of the first cell of this array.
+   * 
+   * @param addr
+   *                The address of the array.
+   * @return The address where the first cell of the array is located.
+   */
+  public final int getArrayStartAddress(int addr) {
+    return addr + arrayContentOffset;
+  }
+
+  /**
+   * Get a specific value out of an array.
+   * 
+   * @param addr
+   *                The address of the array.
+   * @param index
+   *                The index of the value we're interested in.
+   * @return The value at <code>index</code>.
+   * @exception ArrayIndexOutOfBoundsException
+   */
+  public int getArrayValue(int addr, int index) {
+    checkArrayBounds(addr, index);
+    return this.getHeap().heap[addr + arrayContentOffset + index];
+  }
+
+  /**
+   * Set an array value.
+   * 
+   * @param addr
+   *                The address of the array.
+   * @param index
+   *                The index we want to set.
+   * @param value
+   *                The value we want to set.
    * @exception ArrayIndexOutOfBoundsException
    */
-	void setArrayValue(final int addr, final int index, final int value)
-			throws ArrayIndexOutOfBoundsException {
-		// Get the length of this array.
-		final int arraySize = this.getHeap().heap[addr + arrayLengthFeatOffset];
-		// Check for boundary violation.
-		if ((index < 0) || (index >= arraySize)) {
-			throw new ArrayIndexOutOfBoundsException();
-		}
-		this.getHeap().heap[addr + arrayContentOffset + index] = value;
-	}
-
-	void setArrayValueFromString(final int addr, final int index, final String value) {
-    final TypeSystemImpl ts = this.svd.casMetadata.ts;
-		int arrayType = this.getHeap().heap[addr];
-
-		if (arrayType == ts.intArrayTypeCode) {
-			setArrayValue(addr, index, Integer.parseInt(value));
-		} else if (arrayType == ts.floatArrayTypeCode) {
-			setArrayValue(addr, index, CASImpl.float2int(Float.parseFloat(value)));
-		} else if (arrayType == ts.stringArrayTypeCode) {
-			setArrayValue(addr, index, addString(value));
-		} else if (arrayType == ts.booleanArrayTypeCode) {
-			getLowLevelCAS().ll_setBooleanArrayValue(addr, index, Boolean.valueOf(value).booleanValue());
-		} else if (arrayType == ts.byteArrayTypeCode) {
-			getLowLevelCAS().ll_setByteArrayValue(addr, index, Byte.parseByte(value));
-		} else if (arrayType == ts.shortArrayTypeCode) {
-			getLowLevelCAS().ll_setShortArrayValue(addr, index, Short.parseShort(value));
-		} else if (arrayType == ts.longArrayTypeCode) {
-			getLowLevelCAS().ll_setLongArrayValue(addr, index, Long.parseLong(value));
-		} else if (arrayType == ts.doubleArrayTypeCode) {

[... 4385 lines stripped ...]