class JavaImageIOMigrate implements Migrate {

    public MigrateResult migrate(DigitalObject dob, URI inputFormat,
            URI outputFormat, List<Parameter> parameters) {
        // Start timing...
        ServicePerformanceHelper sph = new ServicePerformanceHelper();
        
        BufferedImage image = null;

        // There must be content:
        if( dob.getContent() == null ) {
            return this.returnWithErrorMessage("The Content of the DigitalObject should not be NULL.", null);
        }
        // Both by-reference and by-value can be read as input streams:
        try {
            image = ImageIO.read( dob.getContent().getInputStream() );
        } catch ( Exception e) {
            return returnWithErrorMessage("Exception reading the image - unsupported or invalid input? ", e);
        }
        // Record time take to load the input into memory:
        sph.loaded();
        
        // If that failed, then report an error.
        if( image == null ) {
            return returnWithErrorMessage("Failed to read the image - unsupported or invalid input? ", null);
        }

        // Pick up the output format:
        //Format format = new Format(outputFormat);
        Set<String> extensionsForURI = format.getExtensions(outputFormat);
        if(extensionsForURI.isEmpty() ) {
            return this.returnWithErrorMessage("Unsupported output format: "+outputFormat,null);
        } else {
            log.info("Outputing image to format: "+format.getExtensions(outputFormat).iterator().next());
        }
        
        String extension = extensionsForURI.iterator().next();
        File outfile = null;
        try {
            outfile = File.createTempFile("imageio", extension);

            // FIXME If writing an RBGA image, this simple write method can accidentally convert to CMYK for JPEG, as that is the only way to represent four channels.
            /*
            ImageWriter iw = ImageIO.getImageWritersByFormatName(extension).next();
            ImageTypeSpecifier its =  iw.getDefaultWriteParam().getDestinationType();
            its.getColorModel().hasAlpha();
            its.getColorModel().getNumComponents();
            // Compare with...
            image.getColorModel().hasAlpha();
            // Write:
            iw.setOutput(new FileImageOutputStream(outfile));
            ImageWriteParam iwp = iw.getDefaultWriteParam();
            iwp.setDestinationType(its);
            iw.write(null, new IIOImage(image, null, null), iwp);
            */
            
            // Write using the simple approach:
            ImageIO.write(image, extension, outfile );
        } catch ( Exception e) {
            return this.returnWithErrorMessage("Could not create image in the new format. ",e);
        }

        //try to build digital object with content by reference
        /*
        try {        	        	
            WebContentHelper webHandler = new WebContentHelper();
        	URL contentUrl = webHandler.copyIntoHTMLDirectory(outfile);
        	log.info("got content URL: "+contentUrl);
        	
            ServiceReport rep = new ServiceReport(Type.INFO, Status.SUCCESS, "OK");
        	DigitalObject ndo = new DigitalObject.Builder(Content.byReference(contentUrl)).build();
            return new MigrateResult(ndo, rep);
        } catch (Exception e) {
            log.log(Level.SEVERE, "Could not return content by reference. ", e);
        }
        */
        ServiceReport rep = new ServiceReport(Type.INFO, Status.SUCCESS, "OK", sph.getPerformanceProperties() );
        DigitalObject ndo = new DigitalObject.Builder(Content.byReference(outfile)).build();
        return new MigrateResult(ndo, rep);
    }

}