private static List<AttributeDescriptor> hack(ShapefileAttributeReader delegate) {
   int attributeCount = delegate.getAttributeCount();
   List<AttributeDescriptor> descriptors =
       new ArrayList<AttributeDescriptor>(delegate.getAttributeCount());
   for (int attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) {
     descriptors.add(delegate.getAttributeType(attributeIndex));
   }
   return descriptors;
 }
 @Override
 public void next() throws IOException {
   delegate.next();
   animationRecord =
       animationRecordBuffer.getRecord(
           animationTimeStepRecordOffset
               + ((Number) delegate.read(shapefileJoinAttributeIndex)).intValue()
               - animationJoinValueOffset);
   _isRecordDebuged = false;
 }
  @Override
  public Object read(int attributeIndex) throws IOException, ArrayIndexOutOfBoundsException {

    if (LOGGER.isLoggable(Level.FINE) && !_isRecordDebuged) {
      _isRecordDebuged = true;
      logCurrentRecord();
    }

    Object ret = null;

    if (isNhruData(attributeIndex)) {

      int animationRecordIndex = mapToNhruColumn(attributeIndex);

      switch (animationRecordIndex) {
        case 0:
          ret = animationRecord.getTimeStamp().toDate();
          break;
        case 1:
          ret = animationRecord.getNHRU();
          break;
        default:
          ret = animationRecord.getValue(animationRecordIndex);
      }

    } else {
      ret = delegate.read(attributeIndex);
    }

    return ret;
  }
  /**
   * Hack method to display all the attributes within the various files
   *
   * @throws IOException
   */
  public void logCurrentRecord() throws IOException {
    LOGGER.log(Level.FINE, "###################################################");
    LOGGER.log(Level.FINE, "Debug record info for record #" + getRecordNumber());
    LOGGER.log(Level.FINE, "###################################################");

    // Log new shapefile record info
    LOGGER.log(Level.FINE, "# Shapefile Record for #" + getRecordNumber() + " : ");
    for (int i = 0; i < delegate.getAttributeCount(); i++) {

      LOGGER.log(
          Level.FINE,
          ""
              + i
              + ": "
              + delegate.getAttributeType(i).getLocalName()
              + " : "
              + delegate.read(i).toString());
    }

    // Log new animation record info
    LOGGER.log(
        Level.FINE,
        "# Animation Record for #" + getRecordNumber() + ", NHRU: " + animationRecord.getNHRU());
    LOGGER.log(
        Level.FINE,
        "0: " + recordEntryDescriptors[0].getName() + " : " + animationRecord.getTimeStamp());
    LOGGER.log(
        Level.FINE,
        "1: " + recordEntryDescriptors[1].getName() + " : " + animationRecord.getNHRU());
    for (int i = 2; i < animationRecord.getColumnCount(); i++) {

      LOGGER.log(
          Level.FINE,
          ""
              + i
              + ": "
              + recordEntryDescriptors[i].getName()
              + " : "
              + animationRecord.getValue(i));
    }
    LOGGER.log(Level.FINE, "###################################################");
  }
 @Override
 public void close() throws IOException {
   try {
     delegate.close();
   } catch (IOException e) {
     /* don't care */
   }
   try {
     animationRecordBuffer.close();
   } catch (IOException e) {
     /* don't care */
   }
 }
 @Override
 public boolean hasNext() throws IOException {
   return delegate.hasNext();
 }
 @Override
 public int getRecordNumber() {
   return delegate.getRecordNumber();
 }
 @Override
 public void setTargetBBox(Envelope envelope) {
   delegate.setTargetBBox(envelope);
 }
 @Override
 public void setSimplificationDistance(double distance) {
   delegate.setSimplificationDistance(distance);
 }
 @Override
 public void setScreenMap(ScreenMap screenMap) {
   delegate.setScreenMap(screenMap);
 }