public PRMSAnimationShapefileAttributeJoiningReader(
     ShapefileAttributeReader delegate,
     PRMSAnimationFileMetaData animationFileMetaData,
     int shapefileJoinAttributeIndex,
     int animationJoinValueOffset,
     int timeStepIndex)
     throws IOException {
   super(hack(delegate), null, null); // lame duck
   this.delegate = delegate;
   this.shapefileJoinAttributeIndex = shapefileJoinAttributeIndex;
   this.animationJoinValueOffset = animationJoinValueOffset;
   this.animationTimeStepRecordOffset =
       timeStepIndex * animationFileMetaData.getTimeStepRecordCount();
   animationRecordBuffer =
       new PRMSAnimationRecordBuffer(
           animationFileMetaData,
           animationTimeStepRecordOffset,
           animationTimeStepRecordOffset + animationFileMetaData.getTimeStepRecordCount());
   this.recordEntryDescriptors =
       animationFileMetaData.getRecordEntryDescriptors().toArray(new RecordEntryDescriptor[0]);
 }
 PRMSAnimationAttributeReader(
     PRMSAnimationFileMetaData animationFileMetaData, SimpleFeatureType featureType)
     throws IOException {
   this.featureType = featureType;
   this.animationFileMetaData = animationFileMetaData;
   this.readerAttributeCount = featureType.getAttributeCount();
   this.readerRecordIndex = 0;
   readerAttributeToRecordEntryIndices = new int[readerAttributeCount];
   for (int readerAttributeIndex = 0;
       readerAttributeIndex < readerAttributeCount;
       ++readerAttributeIndex) {
     readerAttributeToRecordEntryIndices[readerAttributeIndex] =
         animationFileMetaData.getRecordEntryIndex(
             featureType.getDescriptor(readerAttributeIndex).getLocalName());
   }
   readerRecordBuffer = new PRMSAnimationRecordBuffer(animationFileMetaData);
 }
 @Override
 public boolean hasNext() throws IOException {
   return (readerRecordIndex + 1) < animationFileMetaData.getRecordCount();
 }