private WriterWrapper duplicateRecurse(Class<? extends IFormatWriter> imageWriterClass)
      throws FormatException {
    IFormatWriter childCopy = null;
    if (writer instanceof WriterWrapper) {
      // found a nested writer layer; duplicate via recursion
      childCopy = ((WriterWrapper) writer).duplicateRecurse(imageWriterClass);
    } else {
      Class<? extends IFormatWriter> c = null;
      if (writer instanceof ImageWriter) {
        // found an image writer; if given, substitute the writer class
        c = imageWriterClass == null ? ImageWriter.class : imageWriterClass;
      } else {
        // bottom of the writer stack; duplicate the core writer
        c = writer.getClass();
      }
      try {
        childCopy = (IFormatWriter) c.newInstance();
      } catch (IllegalAccessException exc) {
        throw new FormatException(exc);
      } catch (InstantiationException exc) {
        throw new FormatException(exc);
      }
    }

    // use crazy reflection to instantiate a writer of the proper type
    Class<? extends WriterWrapper> wrapperClass = getClass();
    WriterWrapper wrapperCopy = null;
    try {
      wrapperCopy =
          wrapperClass
              .getConstructor(new Class[] {IFormatWriter.class})
              .newInstance(new Object[] {childCopy});
    } catch (InstantiationException exc) {
      throw new FormatException(exc);
    } catch (IllegalAccessException exc) {
      throw new FormatException(exc);
    } catch (NoSuchMethodException exc) {
      throw new FormatException(exc);
    } catch (InvocationTargetException exc) {
      throw new FormatException(exc);
    }

    return wrapperCopy;
  }
 public int getSeries() {
   return writer.getSeries();
 }
 public void close() throws IOException {
   writer.close();
 }
 public Class<?> getNativeDataType() {
   return writer.getNativeDataType();
 }
 public String getFormat() {
   return writer.getFormat();
 }
 /** @deprecated */
 public void savePlane(Object plane, int series, boolean lastInSeries, boolean last)
     throws FormatException, IOException {
   writer.savePlane(plane, series, lastInSeries, last);
 }
 /** @deprecated */
 public void saveBytes(byte[] bytes, int series, boolean lastInSeries, boolean last)
     throws FormatException, IOException {
   writer.saveBytes(bytes, series, lastInSeries, last);
 }
 public String getCompression() {
   return writer.getCompression();
 }
 public void setColorModel(ColorModel cm) {
   writer.setColorModel(cm);
 }
 public MetadataRetrieve getMetadataRetrieve() {
   return writer.getMetadataRetrieve();
 }
 public void setMetadataRetrieve(MetadataRetrieve r) {
   writer.setMetadataRetrieve(r);
 }
 public boolean canDoStacks() {
   return writer.canDoStacks();
 }
 public void setValidBitsPerPixel(int bits) {
   writer.setValidBitsPerPixel(bits);
 }
 public boolean isInterleaved() {
   return writer.isInterleaved();
 }
 public void setInterleaved(boolean interleaved) {
   writer.setInterleaved(interleaved);
 }
 public void setCompression(String compress) throws FormatException {
   writer.setCompression(compress);
 }
 /* @see IFormatWriter#setCodecOptions(CodecOptions) */
 public void setCodecOptions(CodecOptions options) {
   writer.setCodecOptions(options);
 }
 public ColorModel getColorModel() {
   return writer.getColorModel();
 }
 public void setWriteSequentially(boolean sequential) {
   writer.setWriteSequentially(sequential);
 }
 public void setFramesPerSecond(int rate) {
   writer.setFramesPerSecond(rate);
 }
 /** @deprecated */
 public void savePlane(Object plane, boolean last) throws FormatException, IOException {
   writer.savePlane(plane, last);
 }
 public int getFramesPerSecond() {
   return writer.getFramesPerSecond();
 }
 public boolean isThisType(String name) {
   return writer.isThisType(name);
 }
 public String[] getCompressionTypes() {
   return writer.getCompressionTypes();
 }
 public String[] getSuffixes() {
   return writer.getSuffixes();
 }
 public int[] getPixelTypes() {
   return writer.getPixelTypes();
 }
 public void setId(String id) throws FormatException, IOException {
   writer.setId(id);
 }
 public int[] getPixelTypes(String codec) {
   return writer.getPixelTypes(codec);
 }
 public boolean isSupportedType(int type) {
   return writer.isSupportedType(type);
 }
 public void setSeries(int series) throws FormatException {
   writer.setSeries(series);
 }