public void open( boolean readOnly )
	throws ReadOnlyException,
	       IOException {

	// Resource cannot be double-opened!
	if( this.isOpen() ) 
	    throw new IOException( "Processable resources cannot be double opened." );

	if( !readOnly ) 
	    throw new IOException( "ProccessableResources can only be opened in read-only mode." );


	this.getLogger().log( Level.INFO,
			      getClass().getName() + ".open(...)",
			      "Starting the internal process builder." );

	// Might throw IOException or a SecurityException. 
	Process process = this.processBuilder.start();
	

	// Write POST data into process's stdin [if POST data is available]
	if( this.postData != null ) {
	    
	    this.getLogger().log( Level.INFO,
				  getClass().getName() + ".open(...)",
				  "HTTP POST data is available. Forwarding POST data to system process ..." );
	    long readLength = CustomUtil.transfer( this.postData.getInputStream(),
						   process.getOutputStream(),
						   this.postData.getContentLength(),  // max read length
						   256                                // buffer size
						   );
	    this.getLogger().log( Level.INFO,
				  getClass().getName() + ".open(...)",
				  "" + readLength + " bytes of POST data written to system process." );
	    
	}


	// Read the generated output DURING the process is running!
	// Otherwise it may block when the process's internal output buffer is full!
	int bufferSize = 256;
	BufferedInputStream bufferedInputStream = new BufferedInputStream( process.getInputStream(), bufferSize );
	ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream( bufferSize );
	byte[] buffer = new byte[ bufferSize ];
	int len;
	while( (len = bufferedInputStream.read(buffer,0,bufferSize)) != -1 ) {

	    if( len > 0 )
		bufferedOutputStream.write(buffer,0,len);

	}

	// Call process.waitFor() at this point ??? !!!
	try {

	    this.getLogger().log( Level.INFO,
				  getClass().getName() + ".open(...)",
				  "Waiting the system process to terminate ..." );
	    process.waitFor();
	    this.exitValue = process.exitValue();

	    this.getLogger().log( Level.INFO,
				  getClass().getName() + ".open(...)",
				  "... process terminated (exitValue=" + this.exitValue + ")." );

	} catch( InterruptedException e ) {
	    
	    // This should not happen! The process might not have completely terminated
	    throw new IOException( "[InterruptedException] Execution process was interrupted. Failed to terminate." );

	}


	// This input stream is piped from the process's standard output stream.
	// If the return code is != 0, there were some errors ...
	InputStream in = null;

	if( this.exitValue == 0 ) {

	    // Successfully executed
	    this.getLogger().log( Level.INFO,
				  getClass().getName(),
				  "The system process was successfully executed (exitValue="+this.exitValue+"). Using stdout to retrieve generated data." 
				  );
	    in = new BufferedInputStream( new ByteArrayInputStream(bufferedOutputStream.toByteArray()) ); // process.getInputStream();

	} else {
	    

	    // Ooops, seems that the PHP script caused some errors.
	    this.getLogger().log( Level.INFO,
				  getClass().getName(),
				  "The system process raised some errors! (exitValue="+this.exitValue+"). Using stderr to retrieve error messages." 
				  );
	    // 'Concatenate' std-out with error-out
	    //in = process.getErrorStream();
	    in = new java.io.SequenceInputStream( new BufferedInputStream(new ByteArrayInputStream(bufferedOutputStream.toByteArray())), // process.getInputStream(), 
						  process.getErrorStream() );


	}


	
	// Store the input stream's data into a BufferedResource.
	this.bufferedResource = new BufferedResource( this.getHTTPHandler(),
						      this.getLogger(),
						      in,
						      false    // it is not necessary to use fair locks as this is a private internal resource
						      );

	// Now open my buffered resource; this will cause the while process output to be read and buffered.
	this.bufferedResource.open( true ); // read-only mode (this is a private field)

	// Don't forget to close the input stream!
	in.close();


	// Store current date as date of last modification
	this.getMetaData().setLastModified( new Date(System.currentTimeMillis()) );
    }