private File localReproject(
      WcsReaderRequest request, File containingDirectory, String baseFilename)
      throws NoSuchAuthorityCodeException, FactoryException, IOException {
    InputStream input = null;
    File tmpFile = null;
    try {
      BoundWcsRequest geotiffRequest = request.bind(_wcsUrl).withFormat("geotiff");
      BoundWcsRequest requestNativeFormat =
          geotiffRequest.withCRS(geotiffRequest.getNativeCRSs().iterator().next());
      requestNativeFormat.assertLegalSize(_maxCoverageExtractionSize);

      input = requestNativeFormat.getCoverage();

      File file = null;
      file = new File(containingDirectory, baseFilename + "." + request.fileExtension());
      LOG.debug("Writing GridCoverage obtained from " + _wcsUrl + " to file " + file);

      tmpFile = File.createTempFile(baseFilename, ".tif");
      writeToFile(tmpFile, input);

      transformCoverage(tmpFile, file, request, requestNativeFormat, true);
      return file;
    } finally {
      if (tmpFile != null) FileUtils.delete(tmpFile);

      if (input != null) IOUtils.closeQuietly(input);
    }
  }
  /* ------------------- Support methods for readToFile ------------------- */
  private File remoteReproject(
      WcsReaderRequest request, File containingDirectory, String baseFilename)
      throws NoSuchAuthorityCodeException, FactoryException, IOException {
    InputStream input = null;
    try {
      BoundWcsRequest requestNegotiatedFormat = negotiateFormat(request.bind(_wcsUrl));
      BoundWcsRequest requestNegotiatedFormatCrs = negotiateRequestCRS(requestNegotiatedFormat);
      BoundWcsRequest requestNegotiatedFormatCrs2 =
          negotiateResponseCRS(requestNegotiatedFormatCrs);
      requestNegotiatedFormatCrs2.assertLegalSize(_maxCoverageExtractionSize);

      input = requestNegotiatedFormatCrs2.getCoverage();

      // file = new File (new File("/tmp/"),
      // baseFilename+"."+request.fileExtension());
      File file = null;
      file = new File(containingDirectory, baseFilename + "." + request.fileExtension());
      LOG.debug("Writing GridCoverage obtained from " + _wcsUrl + " to file " + file);

      convertFormat(baseFilename, input, file, request, requestNegotiatedFormatCrs2);

      transformCoverage(file, file, request, requestNegotiatedFormatCrs2, false);

      return file;
    } finally {
      if (input != null) IOUtils.closeQuietly(input);
    }
  }
  /**
   * Write world image extensions : TFW, PRJ, TAB
   *
   * @param request
   * @param file
   * @param in
   * @throws IOException
   */
  private void writeWorldImageExt(WcsReaderRequest request, File file) throws IOException {

    String baseFilePath = file.getPath().substring(0, file.getPath().lastIndexOf('.'));

    // Compute image size and image transformed BBOX
    ReferencedEnvelope transformedBBox;
    AffineTransform transform;

    int width = -1;
    int height = -1;
    String ext = FileUtils.extension(file);

    try {
      final Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(ext.substring(1));

      while (readers.hasNext() && width < 0 && height < 0) {
        ImageInputStream stream = null;
        try {
          ImageReader reader = readers.next();
          stream = ImageIO.createImageInputStream(file.getAbsoluteFile());
          reader.setInput(stream, true, false);
          width = reader.getWidth(0);
          height = reader.getHeight(0);
          break;
        } catch (Exception e) {
          width = -1;
          height = -1;
          // try next reader;
        } finally {
          if (stream != null) {
            stream.close();
          }
        }
      }

      transformedBBox = request.requestBbox.transform(request.responseCRS, true, 10);
      if (width < 0) {
        width = (int) Math.round(transformedBBox.getWidth() / request.crsResolution());
      }

      if (height < 0) {
        height = (int) Math.round(transformedBBox.getHeight() / request.crsResolution());
      }

      Rectangle imageSize = new Rectangle(width, height);
      transform = RendererUtilities.worldToScreenTransform(transformedBBox, imageSize);
      transform.invert();

    } catch (Exception e) {
      throw new ExtractorException(e);
    }

    // Generate TFW TAB PRJ files
    createWorldFile(transform, ext, baseFilePath);
    createTABFile(transformedBBox, width, height, baseFilePath, ext);
    createPrjFile(request.responseCRS, baseFilePath);
  }
  private void convertFormat(
      String baseFilename,
      InputStream in,
      File file,
      WcsReaderRequest request,
      BoundWcsRequest requestNegotiatedFormat)
      throws IOException, AssertionError, FileNotFoundException {
    if (!request.format.equals(requestNegotiatedFormat.format)) {
      // the server did not support the desired format so we have to
      // reproject
      if (request.format.equalsIgnoreCase("geotiff")) {
        File tmpDir = FileUtils.createTempDirectory();
        try {
          File tmpFile = new File(tmpDir, baseFilename + "." + request.fileExtension());
          writeToFile(tmpFile, in);
          writeWorldImageExt(request, tmpFile);
          convertToGeotiff(tmpFile, file);
        } finally {
          FileUtils.delete(tmpDir);
        }
      } else {
        BufferedImage image = ImageIO.read(in);
        ImageIO.write(image, request.format, file);

        writeWorldImageExt(request, file);
      }
    } else {
      if (Formats.embeddedCrsFormats.contains(request.format)) {
        writeToFile(file, in);
      } else {
        writeToFile(file, in);
        writeWorldImageExt(request, file);
      }
    }
  }