private GridCoverage2D readCoverage()
      throws NoSuchAuthorityCodeException, FactoryException, IOException {
    final AbstractGridFormat format = TestUtils.getFormat(testMosaicUrl);
    final ImageMosaicReader reader = TestUtils.getReader(testMosaicUrl, format);
    // activate footprint management
    GeneralParameterValue[] params = new GeneralParameterValue[2];
    ParameterValue<String> footprintManagement = ImageMosaicFormat.FOOTPRINT_BEHAVIOR.createValue();
    footprintManagement.setValue(FootprintBehavior.Cut.name());
    params[0] = footprintManagement;

    // this prevents us from having problems with link to files still open.
    ParameterValue<Boolean> jaiImageRead = ImageMosaicFormat.USE_JAI_IMAGEREAD.createValue();
    jaiImageRead.setValue(false);
    params[1] = jaiImageRead;
    GridCoverage2D coverage = reader.read(params);
    reader.dispose();
    assertNotNull(coverage);
    return coverage;
  }
  @Test
  public void testAreaOutside() throws Exception {
    // copy the footprints mosaic over
    FileUtils.copyDirectory(footprintsSource, testMosaic);
    Properties p = new Properties();
    p.put(MultiLevelROIProviderFactory.INSET_PROPERTY, "0.1");
    saveFootprintProperties(p);
    final AbstractGridFormat format = TestUtils.getFormat(testMosaicUrl);
    final ImageMosaicReader reader = TestUtils.getReader(testMosaicUrl, format);

    // activate footprint management
    GeneralParameterValue[] params = new GeneralParameterValue[3];
    ParameterValue<String> footprintManagement = ImageMosaicFormat.FOOTPRINT_BEHAVIOR.createValue();
    footprintManagement.setValue(FootprintBehavior.None.name());
    params[0] = footprintManagement;

    // this prevents us from having problems with link to files still open.
    ParameterValue<Boolean> jaiImageRead = ImageMosaicFormat.USE_JAI_IMAGEREAD.createValue();
    jaiImageRead.setValue(false);
    params[1] = jaiImageRead;

    // limit yourself to reading just a bit of it
    final ParameterValue<GridGeometry2D> gg = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
    final Dimension dim = new Dimension();
    dim.setSize(4, 4);
    final Rectangle rasterArea = ((GridEnvelope2D) reader.getOriginalGridRange());
    rasterArea.setSize(dim);
    final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
    gg.setValue(
        new GridGeometry2D(
            range,
            PixelInCell.CELL_CENTER,
            reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER),
            reader.getCoordinateReferenceSystem(),
            null));
    params[2] = gg;

    GridCoverage2D coverage = reader.read(params);
    reader.dispose();
    assertNotNull(coverage);
  }
  @Test
  public void testInsetsMargin() throws Exception {
    // copy the footprints mosaic over
    FileUtils.copyDirectory(footprintsSource, testMosaic);
    Properties p = new Properties();
    p.put(MultiLevelROIProviderFactory.INSET_PROPERTY, "0.1");
    p.put(MultiLevelROIProviderFactory.INSET_TYPE_PROPERTY, "border");
    saveFootprintProperties(p);

    GridCoverage2D coverage = readCoverage();
    //         RenderedImageBrowser.showChain(coverage.getRenderedImage());
    //         System.in.read();

    //        // check the footprints have been applied by pocking the output image
    byte[] pixel = new byte[3];
    // Close to San Marino, black if we have the insets
    coverage.evaluate(new DirectPosition2D(12.54, 44.03), pixel);
    assertEquals(0, pixel[0]);
    assertEquals(0, pixel[1]);
    assertEquals(0, pixel[2]);
    // Inner BORDER should not get black with border insets
    coverage.evaluate(new DirectPosition2D(11.52, 44.57), pixel);
    assertTrue(pixel[0] + pixel[1] + pixel[2] > 0);
    // Golfo di La Spezia, should be black
    coverage.evaluate(new DirectPosition2D(9.12, 44.25), pixel);
    assertEquals(0, pixel[0]);
    assertEquals(0, pixel[1]);
    assertEquals(0, pixel[2]);
    // Sardinia, not black
    coverage.evaluate(new DirectPosition2D(9, 40), pixel);
    assertTrue(pixel[0] + pixel[1] + pixel[2] > 0);
    // Piedmont, not black
    coverage.evaluate(new DirectPosition2D(8, 45), pixel);
    assertTrue(pixel[0] + pixel[1] + pixel[2] > 0);
    disposeCoverage(coverage);

    final ImageMosaicReader reader = TestUtils.getReader(testMosaicUrl, new ImageMosaicFormat());
    // activate footprint management
    GeneralParameterValue[] params = new GeneralParameterValue[3];
    ParameterValue<String> footprintManagement = ImageMosaicFormat.FOOTPRINT_BEHAVIOR.createValue();
    footprintManagement.setValue(FootprintBehavior.Transparent.name());
    params[0] = footprintManagement;

    // this prevents us from having problems with link to files still open.
    ParameterValue<Boolean> jaiImageRead = ImageMosaicFormat.USE_JAI_IMAGEREAD.createValue();
    jaiImageRead.setValue(false);
    params[1] = jaiImageRead;

    // GridGeometry, small aread at the upper right corner
    final GridEnvelope2D ge2D =
        new GridEnvelope2D(
            reader.getOriginalGridRange().getHigh(0) - 3,
            reader.getOriginalGridRange().getLow(1),
            3,
            3);
    final GridGeometry2D gg2D =
        new GridGeometry2D(
            ge2D,
            reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER),
            reader.getCoordinateReferenceSystem());
    ParameterValue<GridGeometry2D> gg2DParam = ImageMosaicFormat.READ_GRIDGEOMETRY2D.createValue();
    gg2DParam.setValue(gg2D);
    params[2] = gg2DParam;

    coverage = reader.read(params);
    MathTransform tr = reader.getOriginalGridToWorld(PixelInCell.CELL_CORNER);
    reader.dispose();
    assertNotNull(coverage);

    // check the footprints have been applied by pocking the output image
    pixel = new byte[4];
    // Close to San Marino, black if we have the insets
    coverage.evaluate(
        tr.transform(
            new DirectPosition2D(
                coverage.getRenderedImage().getMinX(), coverage.getRenderedImage().getMinY()),
            null),
        pixel);
    //        RenderedImageBrowser.showChain(coverage.getRenderedImage());
    assertEquals(0, pixel[0]);
    assertEquals(0, pixel[1]);
    assertEquals(0, pixel[2]);
    assertEquals(0, pixel[3]);

    disposeCoverage(coverage);
  }
  /**
   * Complex test for Postgis indexing on db.
   *
   * @throws Exception
   */
  @Test
  public void testPostgisIndexing() throws Exception {
    final File workDir = new File(TestData.file(this, "."), "watertemp4");
    assertTrue(workDir.mkdir());
    FileUtils.copyFile(TestData.file(this, "watertemp.zip"), new File(workDir, "watertemp.zip"));
    TestData.unzipFile(this, "watertemp4/watertemp.zip");
    final URL timeElevURL = TestData.url(this, "watertemp4");

    // place datastore.properties file in the dir for the indexing
    FileWriter out = null;
    try {
      out = new FileWriter(new File(TestData.file(this, "."), "/watertemp4/datastore.properties"));

      final Set<Object> keyset = fixture.keySet();
      for (Object key : keyset) {
        final String key_ = (String) key;
        final String value = fixture.getProperty(key_);

        out.write(key_.replace(" ", "\\ ") + "=" + value.replace(" ", "\\ ") + "\n");
      }
      out.flush();
    } finally {
      if (out != null) {
        IOUtils.closeQuietly(out);
      }
    }

    // now start the test
    final AbstractGridFormat format = TestUtils.getFormat(timeElevURL);
    assertNotNull(format);
    ImageMosaicReader reader = TestUtils.getReader(timeElevURL, format);
    assertNotNull(reader);

    final String[] metadataNames = reader.getMetadataNames();
    assertNotNull(metadataNames);
    assertEquals(metadataNames.length, 10);

    assertEquals("true", reader.getMetadataValue("HAS_TIME_DOMAIN"));
    final String timeMetadata = reader.getMetadataValue("TIME_DOMAIN");
    assertNotNull(timeMetadata);
    assertEquals(2, timeMetadata.split(",").length);
    assertEquals(timeMetadata.split(",")[0], reader.getMetadataValue("TIME_DOMAIN_MINIMUM"));
    assertEquals(timeMetadata.split(",")[1], reader.getMetadataValue("TIME_DOMAIN_MAXIMUM"));

    assertEquals("true", reader.getMetadataValue("HAS_ELEVATION_DOMAIN"));
    final String elevationMetadata = reader.getMetadataValue("ELEVATION_DOMAIN");
    assertNotNull(elevationMetadata);
    assertEquals(2, elevationMetadata.split(",").length);
    assertEquals(
        Double.parseDouble(elevationMetadata.split(",")[0]),
        Double.parseDouble(reader.getMetadataValue("ELEVATION_DOMAIN_MINIMUM")),
        1E-6);
    assertEquals(
        Double.parseDouble(elevationMetadata.split(",")[1]),
        Double.parseDouble(reader.getMetadataValue("ELEVATION_DOMAIN_MAXIMUM")),
        1E-6);

    // limit yourself to reading just a bit of it
    final ParameterValue<GridGeometry2D> gg = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
    final GeneralEnvelope envelope = reader.getOriginalEnvelope();
    final Dimension dim = new Dimension();
    dim.setSize(
        reader.getOriginalGridRange().getSpan(0) / 2.0,
        reader.getOriginalGridRange().getSpan(1) / 2.0);
    final Rectangle rasterArea = ((GridEnvelope2D) reader.getOriginalGridRange());
    rasterArea.setSize(dim);
    final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
    gg.setValue(new GridGeometry2D(range, envelope));

    // use imageio with defined tiles
    final ParameterValue<List> time = ImageMosaicFormat.TIME.createValue();
    final List<Date> timeValues = new ArrayList<Date>();
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
    Date date = sdf.parse("2008-10-31T00:00:00.000Z");
    timeValues.add(date);
    time.setValue(timeValues);

    final ParameterValue<double[]> bkg = ImageMosaicFormat.BACKGROUND_VALUES.createValue();
    bkg.setValue(new double[] {-9999.0});

    final ParameterValue<Boolean> direct = ImageMosaicFormat.USE_JAI_IMAGEREAD.createValue();
    direct.setValue(false);

    final ParameterValue<List> elevation = ImageMosaicFormat.ELEVATION.createValue();
    elevation.setValue(Arrays.asList(100.0));

    // Test the output coverage
    TestUtils.checkCoverage(
        reader,
        new GeneralParameterValue[] {gg, time, bkg, elevation, direct},
        "Time-Elevation Test");

    reader = TestUtils.getReader(timeElevURL, format);
    elevation.setValue(Arrays.asList(NumberRange.create(0.0, 10.0)));

    // Test the output coverage
    TestUtils.checkCoverage(
        reader,
        new GeneralParameterValue[] {gg, time, bkg, elevation, direct},
        "Time-Elevation Test");
  }