public FileFlatField(FileAccessor accessor, CacheStrategy strategy) throws VisADException {
    super(accessor.getFunctionType(), getNullDomainSet(accessor.getFunctionType().getDomain()));

    fileAccessor = accessor;
    cacheStrategy = strategy;

    // '0' is in legal range of adaptedFlatFieldIndex,
    // but not owned by this
    adaptedFlatFieldIndex = 0;
  }
  private FlatField getAdaptedFlatField() {
    // if owner array is null,
    //  assume this object got serialized & unserialized
    if (adaptedFlatFieldOwner == null) {
      return null;
    }

    synchronized (adaptedFlatFields) {
      for (int ii = 0; ii < MAX_FILE_FLAT_FIELDS; ii++) {
        if (this == adaptedFlatFieldOwner[ii]) {

          // mark time of most recent access

          adaptedFlatFieldTimes[ii] = System.currentTimeMillis();

          return adaptedFlatFields[ii];
        }
      }

      // this FileFlatField does not own a cache entry, so invoke
      // CahceStrategy.allocate to allocate one, possibly by taking
      // one, possibly by taking one from another FileFlatField;
      // this will be an area for lots of thought and experimentation;

      adaptedFlatFieldIndex =
          cacheStrategy.allocate(
              adaptedFlatFields, adaptedFlatFieldDirty,
              adaptedFlatFieldSizes, adaptedFlatFieldTimes);

      // flush cache entry, if dirty

      if (adaptedFlatFieldDirty[adaptedFlatFieldIndex]) {
        try {
          adaptedFlatFieldOwner[adaptedFlatFieldIndex].flushCache();
        } catch (VisADException e) {
          System.out.println(e.getMessage());
        }
      }

      // create a new entry in adaptedFlatFields at adaptedFlatFieldIndex
      // and read data values from fileAccessor at fileLocation
      try {
        adaptedFlatFields[adaptedFlatFieldIndex] = fileAccessor.getFlatField();
      } catch (VisADException e1) {
        System.out.println(e1.getMessage());
      } catch (RemoteException e2) {
        System.out.println(e2.getMessage());
      }

      // mark cache entry as belonging to this FileFlatField

      adaptedFlatFieldOwner[adaptedFlatFieldIndex] = this;

      // get size of adapted FlatField
      // (by calling a method that currently does not exist)

      /*adaptedFlatFields[adaptedFlatFieldIndex].getSize(); */

      adaptedFlatFieldTimes[adaptedFlatFieldIndex] = System.currentTimeMillis();

      return adaptedFlatFields[adaptedFlatFieldIndex];
    }
  }