Commits

P_W999 committed 4bbf96a

- organize imports
- cleanup
- copyright

Comments (0)

Files changed (37)

src/be/pw/jexif/DemoApp.java

 
 import be.pw.jexif.enums.Errors;
 import be.pw.jexif.enums.tag.ExifIFD;
-import be.pw.jexif.enums.tag.ExifGPS;
 import be.pw.jexif.exception.ExifError;
 import be.pw.jexif.exception.JExifException;
 import be.pw.jexif.internal.constants.ExecutionConstant;
 		File tmp = File.createTempFile("jexiftool", ".jpg");
 		File gps = File.createTempFile("gpstest", ".jpg");
 		tmp.deleteOnExit();
-		//gps.deleteOnExit();
+		// gps.deleteOnExit();
 		Files.copy(new File("test-resources/read04.JPG"), tmp);
 		Files.copy(new File("test-resources/read04.JPG"), gps);
 
 		System.out.println(Cal10nUtil.get(Errors.GENERAL, "test"));
 
 		JExifInfo gpsInfo = tool.getInfo(gps);
-		//50.84791165546716N 4.350469368264016E == Bourse @ Brussels
-		//gpsInfo.setGPSInfo("50.84791165546716", "N", "4.350469368264016", "E", "50", "0");
-		
-		//60.586967S 131.835938W == South Pacific Ocean
+		// 50.84791165546716N 4.350469368264016E == Bourse @ Brussels
+		// gpsInfo.setGPSInfo("50.84791165546716", "N", "4.350469368264016", "E", "50", "0");
+
+		// 60.586967S 131.835938W == South Pacific Ocean
 		gpsInfo.setGPSInfo("60 35 13.08", "S", "131 50 9.38", "W", "100", "1");
 		tool.stop();
-		
+
 		LOG.info("Executing took {} ms", watch.elapsedTime(TimeUnit.MILLISECONDS));
 		LOG.info("Finished main method");
 	}

src/be/pw/jexif/JExifInfo.java

 /**
  * The JExifInfo class can be used to read or write a Tag from and to a given file.<br />
  * Reading tags involves lazy-loading, this means that tag information will only be read when asked for.
- *
  * @author phillip
  */
 @Beta
 public class JExifInfo {
-    /**
-     * The reference to exifTool (and thus: the ExifTool process and EventBus).
-     */
-    private final JExifTool exifTool;
-    /**
-     * This image file.
-     */
-    private final File file;
+	/**
+	 * The reference to exifTool (and thus: the ExifTool process and EventBus).
+	 */
+	private final JExifTool exifTool;
+	/**
+	 * This image file.
+	 */
+	private final File file;
 
-    /**
-     * Packaged constructor as this object must always be instantiated from an JExifTool instance.
-     *
-     * @param tool the reference to the JExifTool which instantiated this object.
-     * @param file the image file specified by the user.
-     */
-    JExifInfo(final JExifTool tool, final File file) {
-        this.exifTool = tool;
-        this.file = file;
-    }
+	/**
+	 * Packaged constructor as this object must always be instantiated from an JExifTool instance.
+	 * @param tool the reference to the JExifTool which instantiated this object.
+	 * @param file the image file specified by the user.
+	 */
+	JExifInfo(final JExifTool tool, final File file) {
+		this.exifTool = tool;
+		this.file = file;
+	}
 
-    /**
-     * Reads out a tag.<br />
-     * Reading involves lazy-loading so there might be a little delay when calling this method.
-     *
-     * @param tag the tag to read.
-     * @return the tag value as a String or null if no value found.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    @Beta
-    public String getTagValue(final Tag tag) throws JExifException, ExifError {
-        return exifTool.readTagInfo(file, tag);
-    }
+	/**
+	 * Reads out a tag.<br />
+	 * Reading involves lazy-loading so there might be a little delay when calling this method.
+	 * @param tag the tag to read.
+	 * @return the tag value as a String or null if no value found.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	@Beta
+	public String getTagValue(final Tag tag) throws JExifException, ExifError {
+		return exifTool.readTagInfo(file, tag);
+	}
 
-    /**
-     * Reads out a tag returning it's exact value (so instead of 1/400s it'll return 0.025).<br />
-     * Reading involves lazy-loading so there might be a little delay when calling this method.
-     *
-     * @param tag the tag to read.
-     * @return the tag value as a String or null if no value found.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     */
-    @Beta
-    public String getExactTagValue(final Tag tag) throws JExifException, ExifError {
-        return exifTool.readTagInfo(file, tag, true);
-    }
+	/**
+	 * Reads out a tag returning it's exact value (so instead of 1/400s it'll return 0.025).<br />
+	 * Reading involves lazy-loading so there might be a little delay when calling this method.
+	 * @param tag the tag to read.
+	 * @return the tag value as a String or null if no value found.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 */
+	@Beta
+	public String getExactTagValue(final Tag tag) throws JExifException, ExifError {
+		return exifTool.readTagInfo(file, tag, true);
+	}
 
-    /**
-     * Writes a single value to an Exif tag. <br />
-     * Be aware that not all tags are writable. The following methods should all return false if you can safely write something to an Exif tag.
-     * <ul>
-     * 	<li>{@link Tag#isAvoided()}</li>
-     *  <li>{@link Tag#isProtectedField()}</li>
-     *  <li>{@link Tag#isUnsafe()}</li>
-     * </ul>
-     *
-     * @param tag   the tag to write to.
-     * @param value the value to write.
-     * @return the exact value that was read from the image after writing it.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     */
-    @Beta
-    public String setTagValue(final Tag tag, final String value) throws ExifError, JExifException {
-        exifTool.writeTagInfo(file, tag, value);
-        return getExactTagValue(tag);
-    }
-    
-    /**
-     * Writes GPS info.
-     * @param GPSLatitude gps latitude
-     * @param GPSLatitudeRef N or S (Northern or Southern hemisphere)
-     * @param GPSLongitude gps longitude
-     * @param GPSLongitudeRef E or W (Eastern or Western)
-     * @param GPSAltitude gps altitude (always a positive value).
-     * @param GPSAltitudeRef 0 or 1 (above sea level or below sea level)
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     */
-    @Beta
-    public void setGPSInfo(String GPSLatitude, String GPSLatitudeRef, String GPSLongitude, String GPSLongitudeRef, String GPSAltitude, String GPSAltitudeRef) throws ExifError, JExifException {
-    	Map<Tag, String> valuesToWrite = new HashMap<Tag, String>(6);
-    	valuesToWrite.put(ExifGPS.GPSALTITUDE, GPSAltitude);
-    	valuesToWrite.put(ExifGPS.GPSALTITUDEREF, GPSAltitudeRef);
-    	valuesToWrite.put(ExifGPS.GPSLATITUDE, GPSLatitude);
-    	valuesToWrite.put(ExifGPS.GPSLATITUDEREF, GPSLatitudeRef);
-    	valuesToWrite.put(ExifGPS.GPSLONGITUDE, GPSLongitude);
-    	valuesToWrite.put(ExifGPS.GPSLONGITUDEREF, GPSLongitudeRef);
-    	exifTool.writeGPSTagInfo(file, valuesToWrite);
-    }
-    
-    /**
-     * Reads out all the tag values in human read-able format, even the ones not known in J-ExifTool. 
-     * 
-     * @return a map with all the tag values.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     */
-    @Beta
-    public Map<String, String> getAllTagsValues() throws ExifError, JExifException {
-    	return exifTool.getAllTagInfo(file, false);
-    }
-    
-    /**
-     * Reads out all the tag values in exact format, even the ones not known in J-ExifTool. 
-     * 
-     * @return a map with all the tag values.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     */
-    @Beta
-    public Map<String, String> getAllExactTagsValues() throws ExifError, JExifException {
-    	return exifTool.getAllTagInfo(file, true);
-    } 
-    
-    /**
-     * Reads out all the tag values in human read-able format, limited to only the tags known to J-ExifTool.<br />
-     * The set of known tags can be extended by using {@link TagUtil#register(Class)}.
-     * 
-     * @return a map with all the tag values.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     * @see be.pw.jexif.enums.tag
-     */
-    @Beta
-    public Map<Tag, String> getAllSupportedTagsValues() throws ExifError, JExifException {
-    	return exifTool.getAllSupportedTagInfo(file, false);
-    }
-    
-    /**
-     * Reads out all the tag values in exact format, limited to only the tags known to J-ExifTool. <br />
-     * The set of known tags can be extended by using {@link TagUtil#register(Class)}.
-     * 
-     * @return a map with all the tag values.
-     * @throws JExifException in case something goes wrong internally.
-     * @throws ExifError      if something went wrong in ExifTool
-     * @see be.pw.jexif.enums.tag
-     */
-    @Beta
-    public Map<Tag, String> getAllSupportedExactTagsValues() throws ExifError, JExifException {
-    	return exifTool.getAllSupportedTagInfo(file, true);
-    }
+	/**
+	 * Writes a single value to an Exif tag. <br />
+	 * Be aware that not all tags are writable. The following methods should all return false if you can safely write something to an Exif tag.
+	 * <ul>
+	 * <li>{@link Tag#isAvoided()}</li>
+	 * <li>{@link Tag#isProtectedField()}</li>
+	 * <li>{@link Tag#isUnsafe()}</li>
+	 * </ul>
+	 * @param tag the tag to write to.
+	 * @param value the value to write.
+	 * @return the exact value that was read from the image after writing it.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 */
+	@Beta
+	public String setTagValue(final Tag tag, final String value) throws ExifError, JExifException {
+		exifTool.writeTagInfo(file, tag, value);
+		return getExactTagValue(tag);
+	}
+
+	/**
+	 * Writes GPS info.
+	 * @param GPSLatitude gps latitude
+	 * @param GPSLatitudeRef N or S (Northern or Southern hemisphere)
+	 * @param GPSLongitude gps longitude
+	 * @param GPSLongitudeRef E or W (Eastern or Western)
+	 * @param GPSAltitude gps altitude (always a positive value).
+	 * @param GPSAltitudeRef 0 or 1 (above sea level or below sea level)
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 */
+	@Beta
+	public void setGPSInfo(final String GPSLatitude, final String GPSLatitudeRef, final String GPSLongitude, final String GPSLongitudeRef, final String GPSAltitude, final String GPSAltitudeRef) throws ExifError, JExifException {
+		Map<Tag, String> valuesToWrite = new HashMap<Tag, String>(6);
+		valuesToWrite.put(ExifGPS.GPSALTITUDE, GPSAltitude);
+		valuesToWrite.put(ExifGPS.GPSALTITUDEREF, GPSAltitudeRef);
+		valuesToWrite.put(ExifGPS.GPSLATITUDE, GPSLatitude);
+		valuesToWrite.put(ExifGPS.GPSLATITUDEREF, GPSLatitudeRef);
+		valuesToWrite.put(ExifGPS.GPSLONGITUDE, GPSLongitude);
+		valuesToWrite.put(ExifGPS.GPSLONGITUDEREF, GPSLongitudeRef);
+		exifTool.writeGPSTagInfo(file, valuesToWrite);
+	}
+
+	/**
+	 * Reads out all the tag values in human read-able format, even the ones not known in J-ExifTool.
+	 * @return a map with all the tag values.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 */
+	@Beta
+	public Map<String, String> getAllTagsValues() throws ExifError, JExifException {
+		return exifTool.getAllTagInfo(file, false);
+	}
+
+	/**
+	 * Reads out all the tag values in exact format, even the ones not known in J-ExifTool.
+	 * @return a map with all the tag values.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 */
+	@Beta
+	public Map<String, String> getAllExactTagsValues() throws ExifError, JExifException {
+		return exifTool.getAllTagInfo(file, true);
+	}
+
+	/**
+	 * Reads out all the tag values in human read-able format, limited to only the tags known to J-ExifTool.<br />
+	 * The set of known tags can be extended by using {@link TagUtil#register(Class)}.
+	 * @return a map with all the tag values.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 * @see be.pw.jexif.enums.tag
+	 */
+	@Beta
+	public Map<Tag, String> getAllSupportedTagsValues() throws ExifError, JExifException {
+		return exifTool.getAllSupportedTagInfo(file, false);
+	}
+
+	/**
+	 * Reads out all the tag values in exact format, limited to only the tags known to J-ExifTool. <br />
+	 * The set of known tags can be extended by using {@link TagUtil#register(Class)}.
+	 * @return a map with all the tag values.
+	 * @throws JExifException in case something goes wrong internally.
+	 * @throws ExifError if something went wrong in ExifTool
+	 * @see be.pw.jexif.enums.tag
+	 */
+	@Beta
+	public Map<Tag, String> getAllSupportedExactTagsValues() throws ExifError, JExifException {
+		return exifTool.getAllSupportedTagInfo(file, true);
+	}
 
 }

src/be/pw/jexif/JExifTool.java

 import com.google.common.eventbus.EventBus;
 
 /**
- * The JExifTool class acts as the bridge between ExifTool and your java code.<br /> 
- * 
+ * The JExifTool class acts as the bridge between ExifTool and your java code.<br />
  * This class is responsible for starting and stopping the ExifTool process. <br />
  * <br />
  * In order to use J-ExifTool you must download ExifTool from <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">http://www.sno.phy.queensu.ca/~phil/exiftool/</a> <br />
  * The System Property {@link ExecutionConstant#EXIFTOOLPATH} should point to the executable.<br />
  * <br />
- * If you want to read or write Exif tags, you first need to make an instance of this class and the use the {@link #getInfo(File)) method to create a {@link JExifInfo} object.
- * <br />
+ * If you want to read or write Exif tags, you first need to make an instance of this class and the use the {@link #getInfo(File)) method to create a {@link JExifInfo} object. <br />
  * <b>JExifTool is not thread-safe</b>
- * 
  * @author phillip
  */
 @Beta
 public class JExifTool {
-    /**
-     * The argsFile is a file on the disk where the command line arguments are stored for ExifTool in -stay_open mode. The path to this file will be passed as the -@ argument.
-     */
-    private final File argsFile = new File("args");
-    /**
-     * The writer for {@link be.pw.jexif.JExifTool#argsFile}
-     */
-    private FileWriter argsWriter = null;
-    /**
-     * The path to the ExifTool executable. If the system property was not defined, the application will back to the current directory and expects the executable to be called "exiftool.exe". <br />
-     *
-     * @see be.pw.jexif.internal.constants.ExecutionConstant#EXIFTOOLPATH
-     */
-    private final File exifToolPath = new File(System.getProperty(ExecutionConstant.EXIFTOOLPATH, ".\\exiftool.exe"));
-    /**
-     * Timeout in milliseconds before the application decides that the for-looping which is waiting for the ExifTool output has deadlocked.<br />
-     * This might happen if all of a sudden ExifTool crashes or is not up and running.
-     *
-     * @see be.pw.jexif.internal.constants.ExecutionConstant#EXIFTOOLDEADLOCK
-     */
-    private final int deadLock = Integer.getInteger(ExecutionConstant.EXIFTOOLDEADLOCK, 4000);
-    /**
-     * This will hold a reference to the ExifTool.exe process.
-     */
-    private Process p;
-    /**
-     * The guava EventBuss will be used to handle the output- and error-streams from the ExifTool process.
-     */
-    private final EventBus bus = new EventBus();
+	/**
+	 * The argsFile is a file on the disk where the command line arguments are stored for ExifTool in -stay_open mode. The path to this file will be passed as the -@ argument.
+	 */
+	private final File argsFile = new File("args");
+	/**
+	 * The writer for {@link be.pw.jexif.JExifTool#argsFile}
+	 */
+	private FileWriter argsWriter = null;
+	/**
+	 * The path to the ExifTool executable. If the system property was not defined, the application will back to the current directory and expects the executable to be called "exiftool.exe". <br />
+	 * @see be.pw.jexif.internal.constants.ExecutionConstant#EXIFTOOLPATH
+	 */
+	private final File exifToolPath = new File(System.getProperty(ExecutionConstant.EXIFTOOLPATH, ".\\exiftool.exe"));
+	/**
+	 * Timeout in milliseconds before the application decides that the for-looping which is waiting for the ExifTool output has deadlocked.<br />
+	 * This might happen if all of a sudden ExifTool crashes or is not up and running.
+	 * @see be.pw.jexif.internal.constants.ExecutionConstant#EXIFTOOLDEADLOCK
+	 */
+	private final int deadLock = Integer.getInteger(ExecutionConstant.EXIFTOOLDEADLOCK, 4000);
+	/**
+	 * This will hold a reference to the ExifTool.exe process.
+	 */
+	private Process p;
+	/**
+	 * The guava EventBuss will be used to handle the output- and error-streams from the ExifTool process.
+	 */
+	private final EventBus bus = new EventBus();
+
+	/**
+	 * The logger for this class.
+	 */
+	private static final Logger LOG = LoggerFactory.getLogger(JExifTool.class);
+	/**
+	 * The thread which will handle the output from the ExifTool process.
+	 */
+	private Thread inputReaderThread;
+	/**
+	 * The thread which will handle the error output from the ExifTool process.
+	 */
+	private Thread errorReaderThread;
+
+	/**
+	 * Default constructor. <br />
+	 * This automatically starts the ExifTool process and registers the standard Tag-set that comes with this library.
+	 */
+	@Beta
+	public JExifTool() {
+		TagUtil.register(IFD0.class);
+		TagUtil.register(ExifIFD.class);
+		TagUtil.register(ExifGPS.class);
+		this.start();
+	}
+
+	/**
+	 * Creates a new instance of a JExifInfo object. This object can be used to read and write Exif tags to the specified file.
+	 * @param file the image file from which tags shall be read from or written to.
+	 * @return a JExifInfo object.
+	 * @throws IOException if the file does not exist or if it's folder
+	 */
+	@Beta
+	public JExifInfo getInfo(final File file) throws IOException {
+		Preconditions.checkNotNull(file);
+		if (!file.exists() || file.isDirectory()) {
+			throw new IOException(Cal10nUtil.get(Errors.IO_FILE_NOT_VALID, file.getName()));
+		}
+		return new JExifInfo(this, file);
+	}
 
-    /**
-     * The logger for this class.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(JExifTool.class);
-    /**
-     * The thread which will handle the output from the ExifTool process.
-     */
-    private Thread inputReaderThread;
-    /**
-     * The thread which will handle the error output from the ExifTool process.
-     */
-    private Thread errorReaderThread;
+	/**
+	 * Starts the ExifTool process and several sub-threads to handle the in- and output streams.<br />
+	 * This method is automatically called when a new instance of JExifTool is created.
+	 */
+	private synchronized void start() {
+		LOG.trace("Using exifToolPath in: " + exifToolPath.getAbsolutePath());
+		LOG.trace("Argsfile is stored in: " + argsFile.getAbsolutePath());
+		try {
+			argsWriter = new FileWriter(argsFile);
+			argsWriter.write("");
+			argsWriter.flush();
+			/*
+			 * The "master" thread which is responsible for the ExifTool process and the two sub-threads for handling the output.
+			 */
+			final Thread exifThread = new Thread(new Runnable() {
+				@Override
+				public synchronized void run() {
+					try {
+						String claFormat;
+						String cla;
+						if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+							LOG.trace("Running windows: always putting CLA between \" \"");
+							claFormat = ExecutionConstant.WINDOWS_CLA;
+						} else {
+							if (argsFile.getCanonicalPath().contains(" ")) {
+								claFormat = ExecutionConstant.MAC_CLA;
+							} else {
+								claFormat = ExecutionConstant.LINUX_CLA;
+							}
+						}
+						cla = MessageFormat.format(claFormat, exifToolPath.getCanonicalPath(), argsFile.getCanonicalPath());
+						LOG.trace("Starting ExifTool with command line arguments {}", cla);
+						p = Runtime.getRuntime().exec(cla);
+						BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
+						BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+						DebugHandler debug = new DebugHandler();
+						bus.register(debug);
+						inputReaderThread = new Thread(new RunnableReader(bri, bus, false));
+						inputReaderThread.setName("inputReaderThread");
+						inputReaderThread.start();
+						errorReaderThread = new Thread(new RunnableReader(bre, bus, true));
+						errorReaderThread.setName("errorReaderThread");
+						errorReaderThread.start();
+						notify();
+						LOG.trace("Left the monitor");
+					} catch (Exception e) {
+						LOG.error(Cal10nUtil.get(Errors.EXIFTHREAD), e);
+					}
+				}
+			});
 
-    /**
-     * Default constructor. <br />
-     * This automatically starts the ExifTool process and registers the standard Tag-set that comes with this library.
-     */
-    @Beta
-    public JExifTool() {
-    	TagUtil.register(IFD0.class);
-    	TagUtil.register(ExifIFD.class);
-    	TagUtil.register(ExifGPS.class);
-        this.start();
-    }
+			synchronized (exifThread) {
+				exifThread.setName("ExifTool-thread");
+				exifThread.start();
+				exifThread.wait(); // wait unconditionally for the notify, we must be sure all the threads are running.
+				// also: starting the ExifTool process normally takes long enough so that the wait can be reached before the notify is called.
+			}
+			LOG.debug("ExifTool-thread and subthreads started");
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+		} catch (InterruptedException e) {
+			LOG.error("Failed to join exifThread", e);
+		}
+	}
 
-    /**
-     * Creates a new instance of a JExifInfo object. This object can be used to read and write Exif tags to the specified file.
-     *
-     * @param file the image file from which tags shall be read from or written to.
-     * @return a JExifInfo object.
-     * @throws IOException if the file does not exist or if it's folder
-     */
-    @Beta
-    public JExifInfo getInfo(final File file) throws IOException {
-        Preconditions.checkNotNull(file);
-        if (!file.exists() || file.isDirectory()) {
-        	throw new IOException(Cal10nUtil.get(Errors.IO_FILE_NOT_VALID, file.getName()));
-        }
-        return new JExifInfo(this, file);
-    }
+	/**
+	 * Starts the ExifTool process if needed (if eg. it auto-closed itself after 10 minutes).
+	 */
+	private synchronized void startIfNecessary() {
+		if (p != null) {
+			try {
+				p.exitValue();
+			} catch (IllegalThreadStateException e) {
+				LOG.debug("ExifTool process was still running");
+				return;
+			}
+		}
+		LOG.info("ExifTool process was not running, re-starting it");
+		inputReaderThread.interrupt();
+		errorReaderThread.interrupt();
+		start();
+	}
 
-    /**
-     * Starts the ExifTool process and several sub-threads to handle the in- and output streams.<br />
-     * This method is automatically called when a new instance of JExifTool is created.
-     */
-    private synchronized void start() {
-        LOG.trace("Using exifToolPath in: " + exifToolPath.getAbsolutePath());
-        LOG.trace("Argsfile is stored in: " + argsFile.getAbsolutePath());
-        try {
-            argsWriter = new FileWriter(argsFile);
-            argsWriter.write("");
-            argsWriter.flush();
-            /*
-         The "master" thread which is responsible for the ExifTool process and the two sub-threads for handling the output.
-        */
-            final Thread exifThread = new Thread(new Runnable() {
-                @Override
-                public synchronized void run() {
-                    try {
-                        String claFormat;
-                        String cla;
-                        if (System.getProperty("os.name").toLowerCase().contains("windows")) {
-                            LOG.trace("Running windows: always putting CLA between \" \"");
-                            claFormat = ExecutionConstant.WINDOWS_CLA;
-                        } else {
-                            if (argsFile.getCanonicalPath().contains(" ")) {
-                                claFormat = ExecutionConstant.MAC_CLA;
-                            } else {
-                                claFormat = ExecutionConstant.LINUX_CLA;
-                            }
-                        }
-                        cla = MessageFormat.format(claFormat, exifToolPath.getCanonicalPath(), argsFile.getCanonicalPath());
-                        LOG.trace("Starting ExifTool with command line arguments {}", cla);
-                        p = Runtime.getRuntime().exec(cla);
-                        BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
-                        BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));
-                        DebugHandler debug = new DebugHandler();
-                        bus.register(debug);
-                        inputReaderThread = new Thread(new RunnableReader(bri, bus, false));
-                        inputReaderThread.setName("inputReaderThread");
-                        inputReaderThread.start();
-                        errorReaderThread = new Thread(new RunnableReader(bre, bus, true));
-                        errorReaderThread.setName("errorReaderThread");
-                        errorReaderThread.start();
-                        notify();
-                        LOG.trace("Left the monitor");
-                    } catch (Exception e) {
-                        LOG.error(Cal10nUtil.get(Errors.EXIFTHREAD), e);
-                    }
-                }
-            });
+	/**
+	 * Stops the ExifTool-thread. You <b>ALWAYS</b> have to call this method when you don't need J-ExifTool anymore, otherwise the ExifTool process will continue running in the background.
+	 * @throws JExifException if it failed to stop (there is a Thread.sleep which may throw an InterruptedException).
+	 */
+	@Beta
+	public void stop() throws JExifException {
+		try {
+			LOG.trace("Stopping ExifTool process");
+			argsWriter.append(ExecutionConstant.STAY_OPEN).append("\r\n");
+			argsWriter.append("false\n");
+			argsWriter.flush();
+			boolean stopped = false;
+			while (!stopped) {
+				try {
+					p.exitValue();
+					stopped = true;
+				} catch (IllegalThreadStateException e) {
+					stopped = false;
+					try {
+						Thread.sleep(10);
+					} catch (InterruptedException e1) {
+						LOG.error("An error occured while sleeping while stopping ExifTool process", e);
+						throw new JExifException(e1);
+					}
+				}
+			}
+			LOG.debug("ExifTool process should have stopped");
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_CLOSING), e);
+		}
+	}
 
-            synchronized (exifThread) {
-                exifThread.setName("ExifTool-thread");
-                exifThread.start();
-                exifThread.wait(); // wait unconditionally for the notify, we must be sure all the threads are running.
-                //also: starting the ExifTool process normally takes long enough so that the wait can be reached before the notify is called.
-            }
-            LOG.debug("ExifTool-thread and subthreads started");
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
-        } catch (InterruptedException e) {
-            LOG.error("Failed to join exifThread", e);
-        }
-    }
+	/**
+	 * This method will read out the specified tag from the given file. Default to using the non-exact format.
+	 * @param file the file from which to read.
+	 * @param tag the tag to read out.
+	 * @return the tag value as String or null if nothing found.
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems.
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	String readTagInfo(final File file, final Tag tag) throws JExifException, ExifError {
+		return readTagInfo(file, tag, false);
+	}
 
-    /**
-     * Starts the ExifTool process if needed (if eg. it auto-closed itself after 10 minutes).
-     */
-    private synchronized void startIfNecessary() {
-        if (p != null) {
-            try {
-                p.exitValue();
-            } catch (IllegalThreadStateException e) {
-                LOG.debug("ExifTool process was still running");
-                return;
-            }
-        }
-        LOG.info("ExifTool process was not running, re-starting it");
-        inputReaderThread.interrupt();
-        errorReaderThread.interrupt();
-        start();
-    }
+	/**
+	 * This method will read out the specified tag from the given file. Default to using the non-exact format.
+	 * @param file the file from which to read.
+	 * @param tag the tag to read out.
+	 * @return the tag value as String or null if nothing found.
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	String readTagInfo(final File file, final Tag tag, final boolean exact) throws JExifException, ExifError {
+		startIfNecessary();
+		int i = 0;
+		IAction action;
+		EventHandler handler;
+		try {
+			LOG.trace("Starting readTagInfo");
+			if (exact) {
+				action = ActionFactory.createExactReadAction(file, tag);
+			} else {
+				action = ActionFactory.createReadAction(file, tag);
+			}
+			handler = new EventHandler();
+			bus.register(handler);
+			LOG.trace("Registered the EventHandler");
+			String[] arguments = action.buildArguments();
+			for (String argument : arguments) {
+				argsWriter.append(argument).append("\r\n");
+			}
+			argsWriter.flush();
+			while (!handler.isFinished() && i <= deadLock) {
+				Thread.sleep(50);
+				i += 50;
+			}
+			if (!handler.isFinished()) {
+				LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
+				throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
+			}
+			bus.unregister(handler);
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+			throw new JExifException(e);
+		} catch (InterruptedException e) {
+			LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
+			throw new JExifException(e);
+		}
+		LOG.trace("Handler finished");
+		List<String> results = handler.getResultList();
+		List<String> errors = handler.getErrorList();
+		LOG.trace("Parsing results");
+		ResultHandler.run(action, results, errors);
+		return action.getResult().get(tag);
+	}
 
-    /**
-     * Stops the ExifTool-thread. You <b>ALWAYS</b> have to call this method when you don't need J-ExifTool anymore, otherwise the ExifTool process will continue running in the background.
-     *
-     * @throws JExifException if it failed to stop (there is a Thread.sleep which may throw an InterruptedException).
-     */
-    @Beta
-    public void stop() throws JExifException {
-        try {
-            LOG.trace("Stopping ExifTool process");
-            argsWriter.append(ExecutionConstant.STAY_OPEN).append("\r\n");
-            argsWriter.append("false\n");
-            argsWriter.flush();
-            boolean stopped = false;
-            while (!stopped) {
-                try {
-                    p.exitValue();
-                    stopped = true;
-                } catch (IllegalThreadStateException e) {
-                    stopped = false;
-                    try {
-                        Thread.sleep(10);
-                    } catch (InterruptedException e1) {
-                        LOG.error("An error occured while sleeping while stopping ExifTool process", e);
-                        throw new JExifException(e1);
-                    }
-                }
-            }
-            LOG.debug("ExifTool process should have stopped");
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_CLOSING), e);
-        }
-    }
+	/**
+	 * This method will write a value to a given Tag.
+	 * @param file the file to which the value should be written.
+	 * @param tag the tag that should be written.
+	 * @param value the value to write (if null or empty string, the Tag will be cleared)
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	void writeTagInfo(final File file, final Tag tag, final String value) throws ExifError, JExifException {
+		startIfNecessary();
+		int i = 0;
+		IAction action;
+		EventHandler handler;
+		try {
+			LOG.trace("Starting readTagInfo");
+			Map<Tag, String> valuesToWrite = new HashMap<>(1);
+			valuesToWrite.put(tag, value);
+			action = ActionFactory.createTagWriteAction(file, valuesToWrite);
+			handler = new EventHandler();
+			bus.register(handler);
+			LOG.trace("Registered the EventHandler");
+			String[] arguments = action.buildArguments();
+			for (String argument : arguments) {
+				argsWriter.append(argument).append("\r\n");
+			}
+			argsWriter.flush();
+			while (!handler.isFinished() && i <= deadLock) {
+				Thread.sleep(50);
+				i += 50;
+			}
+			if (!handler.isFinished()) {
+				LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
+				throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
+			}
+			bus.unregister(handler);
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+			throw new JExifException(e);
+		} catch (InterruptedException e) {
+			LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
+			throw new JExifException(e);
+		}
+		LOG.trace("Handler finished");
+		List<String> results = handler.getResultList();
+		List<String> errors = handler.getErrorList();
+		LOG.trace("Parsing results");
+		ResultHandler.run(action, results, errors);
+	}
 
-    /**
-     * This method will read out the specified tag from the given file. Default to using the non-exact format.
-     *
-     * @param file the file from which to read.
-     * @param tag  the tag to read out.
-     * @return the tag value as String or null if nothing found.
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems.
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    String readTagInfo(final File file, final Tag tag) throws JExifException, ExifError {
-        return readTagInfo(file, tag, false);
-    }
+	/**
+	 * This method will write a value to a given Tag.
+	 * @param file the file to which the value should be written.
+	 * @param valuesToWrite the value to write
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	void writeGPSTagInfo(final File file, final Map<Tag, String> valuesToWrite) throws ExifError, JExifException {
+		startIfNecessary();
+		int i = 0;
+		IAction action;
+		EventHandler handler;
+		try {
+			LOG.trace("Starting readTagInfo");
+			GPSUtil.validateGPSValues(valuesToWrite);
+			GPSUtil.formatGPSValues(valuesToWrite);
+			action = ActionFactory.createTagWriteAction(file, valuesToWrite);
+			String[] arguments = action.buildArguments();
+			handler = new EventHandler();
+			bus.register(handler);
+			LOG.trace("Registered the EventHandler");
+			for (String argument : arguments) {
+				argsWriter.append(argument).append("\r\n");
+			}
+			argsWriter.flush();
+			while (!handler.isFinished() && i <= deadLock * 1.2) { // slightly (random) longer delay because of multiple values to write
+				Thread.sleep(50);
+				i += 50;
+			}
+			if (!handler.isFinished()) {
+				LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
+				throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
+			}
+			bus.unregister(handler);
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+			throw new JExifException(e);
+		} catch (InterruptedException e) {
+			LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
+			throw new JExifException(e);
+		}
+		LOG.trace("Handler finished");
+		List<String> results = handler.getResultList();
+		List<String> errors = handler.getErrorList();
+		LOG.trace("Parsing results");
+		ResultHandler.run(action, results, errors);
+	}
 
-    /**
-     * This method will read out the specified tag from the given file. Default to using the non-exact format.
-     *
-     * @param file the file from which to read.
-     * @param tag  the tag to read out.
-     * @return the tag value as String or null if nothing found.
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    String readTagInfo(final File file, final Tag tag, final boolean exact) throws JExifException, ExifError {
-        startIfNecessary();
-        int i = 0;
-        IAction action;
-        EventHandler handler;
-        try {
-            LOG.trace("Starting readTagInfo");
-            if (exact) {
-                action = ActionFactory.createExactReadAction(file, tag);
-            } else {
-                action = ActionFactory.createReadAction(file, tag);
-            }
-            handler = new EventHandler();
-            bus.register(handler);
-            LOG.trace("Registered the EventHandler");
-            String[] arguments = action.buildArguments();
-            for (String argument : arguments) {
-                argsWriter.append(argument).append("\r\n");
-            }
-            argsWriter.flush();
-            while (!handler.isFinished() && i <= deadLock) {
-                Thread.sleep(50);
-                i += 50;
-            }
-            if (!handler.isFinished()) {
-                LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
-                throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
-            }
-            bus.unregister(handler);
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
-            throw new JExifException(e);
-        } catch (InterruptedException e) {
-            LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
-            throw new JExifException(e);
-        }
-        LOG.trace("Handler finished");
-        List<String> results = handler.getResultList();
-        List<String> errors = handler.getErrorList();
-        LOG.trace("Parsing results");
-        ResultHandler.run(action, results, errors);
-        return action.getResult().get(tag);
-    }
+	/**
+	 * Returns all the tags, even the ones not known in J-ExifTool.
+	 * @param file the file from which to read.
+	 * @param exact whether the exact value should be returned or not.
+	 * @return the map with tag-name - tag-value.
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	@SuppressWarnings("unchecked")
+	Map<String, String> getAllTagInfo(final File file, final boolean exact) throws ExifError, JExifException {
+		return (Map<String, String>) getAllTagInfo(file, exact, false);
+	}
 
-    /**
-     * This method will write a value to a given Tag.
-     * @param file the file to which the value should be written.
-     * @param tag the tag that should be written.
-     * @param value the value to write (if null or empty string, the Tag will be cleared)
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    void writeTagInfo(final File file, final Tag tag, final String value) throws ExifError, JExifException {
-        startIfNecessary();
-        int i = 0;
-        IAction action;
-        EventHandler handler;
-        try {
-            LOG.trace("Starting readTagInfo");
-            Map<Tag, String> valuesToWrite = new HashMap<>(1);
-            valuesToWrite.put(tag, value);
-            action = ActionFactory.createTagWriteAction(file, valuesToWrite);
-            handler = new EventHandler();
-            bus.register(handler);
-            LOG.trace("Registered the EventHandler");
-            String[] arguments = action.buildArguments();
-            for (String argument : arguments) {
-                argsWriter.append(argument).append("\r\n");
-            }
-            argsWriter.flush();
-            while (!handler.isFinished() && i <= deadLock) {
-                Thread.sleep(50);
-                i += 50;
-            }
-            if (!handler.isFinished()) {
-                LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
-                throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
-            }
-            bus.unregister(handler);
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
-            throw new JExifException(e);
-        } catch (InterruptedException e) {
-            LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
-            throw new JExifException(e);
-        }
-        LOG.trace("Handler finished");
-        List<String> results = handler.getResultList();
-        List<String> errors = handler.getErrorList();
-        LOG.trace("Parsing results");
-        ResultHandler.run(action, results, errors);
-    }
+	/**
+	 * Returns all the tags known to J-ExifTool
+	 * @param file the file from which to read.
+	 * @param exact whether the exact value should be returned or not.
+	 * @return the map with tag-name - tag-value.
+	 * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
+	 * @throws ExifError if there was a problem in ExifTool
+	 */
+	@SuppressWarnings("unchecked")
+	Map<Tag, String> getAllSupportedTagInfo(final File file, final boolean exact) throws ExifError, JExifException {
+		return (Map<Tag, String>) getAllTagInfo(file, exact, true);
+	}
 
-    /**
-     * This method will write a value to a given Tag.
-     * @param file the file to which the value should be written.
-     * @param valuesToWrite the value to write
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    void writeGPSTagInfo(final File file, final Map<Tag, String> valuesToWrite) throws ExifError, JExifException {
-        startIfNecessary();
-        int i = 0;
-        IAction action;
-        EventHandler handler;
-        try {
-            LOG.trace("Starting readTagInfo");
-            GPSUtil.validateGPSValues(valuesToWrite);
-            GPSUtil.formatGPSValues(valuesToWrite);
-            action = ActionFactory.createTagWriteAction(file, valuesToWrite);
-            String[] arguments = action.buildArguments();
-            handler = new EventHandler();
-            bus.register(handler);
-            LOG.trace("Registered the EventHandler");
-            for (String argument : arguments) {
-                argsWriter.append(argument).append("\r\n");
-            }
-            argsWriter.flush();
-            while (!handler.isFinished() && i <= deadLock * 1.2) {	//slightly (random) longer delay because of multiple values to write
-                Thread.sleep(50);
-                i += 50;
-            }
-            if (!handler.isFinished()) {
-                LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
-                throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
-            }
-            bus.unregister(handler);
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
-            throw new JExifException(e);
-        } catch (InterruptedException e) {
-            LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
-            throw new JExifException(e);
-        }
-        LOG.trace("Handler finished");
-        List<String> results = handler.getResultList();
-        List<String> errors = handler.getErrorList();
-        LOG.trace("Parsing results");
-        ResultHandler.run(action, results, errors);
-    }
-    
-    /**
-     * Returns all the tags, even the ones not known in J-ExifTool.
-     * 
-     * @param file the file from which to read.
-     * @param exact whether the exact value should be returned or not.
-     * @return the map with tag-name - tag-value.
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    @SuppressWarnings("unchecked")
-	Map<String, String> getAllTagInfo(final File file, boolean exact) throws ExifError, JExifException {
-    	return (Map<String, String>) getAllTagInfo(file, exact, false);
-    }
-    
-    /**
-     * Returns all the tags known to J-ExifTool
-     * 
-     * @param file the file from which to read.
-     * @param exact whether the exact value should be returned or not.
-     * @return the map with tag-name - tag-value.
-     * @throws JExifException when writing the argsfile went wrong or when the Tread.sleep caused problems (or the execution took to long).
-     * @throws ExifError      if there was a problem in ExifTool
-     */
-    @SuppressWarnings("unchecked")
-	Map<Tag, String> getAllSupportedTagInfo(final File file, boolean exact) throws ExifError, JExifException {
-    	return (Map<Tag, String>) getAllTagInfo(file, exact, true);
-    }
-    
-    private Map<? extends Object, String> getAllTagInfo(final File file, boolean exact, boolean onlySupported) throws ExifError, JExifException {
-    	startIfNecessary();
-    	int i = 0;
-        IAction action;
-        EventHandler handler;
-        try {
-            LOG.trace("Starting readTagInfo");
-            if (exact) {
-                action = ActionFactory.createTagReadExactAllAction(file);
-            } else {
-            	action = ActionFactory.createTagReadAllAction(file);
-            }
-            handler = new EventHandler();
-            bus.register(handler);
-            LOG.trace("Registered the EventHandler");
-            String[] arguments = action.buildArguments();
-            for (String argument : arguments) {
-                argsWriter.append(argument).append("\r\n");
-            }
-            argsWriter.flush();
-            while (!handler.isFinished() && i <= deadLock) {
-                Thread.sleep(50);
-                i += 50;
-            }
-            if (!handler.isFinished()) {
-                LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
-                throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
-            }
-            bus.unregister(handler);
-        } catch (IOException e) {
-            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
-            throw new JExifException(e);
-        } catch (InterruptedException e) {
-            LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
-            throw new JExifException(e);
-        }
-        LOG.trace("Handler finished");
-        List<String> results = handler.getResultList();
-        List<String> errors = handler.getErrorList();
-        LOG.trace("Parsing results");
-        ResultHandler.run(action, results, errors);
-        if (onlySupported) {
-        	return action.getResult();
-        } else {
-	        Map<String, String> tags = action.getUnsupportedTags();
-	        for (Entry<Tag, String> e : action.getResult().entrySet()) {
-	        	tags.put(e.getKey().getName(), e.getValue());
-	        }
-	        return tags;
-        }
-    }
+	private Map<? extends Object, String> getAllTagInfo(final File file, final boolean exact, final boolean onlySupported) throws ExifError, JExifException {
+		startIfNecessary();
+		int i = 0;
+		IAction action;
+		EventHandler handler;
+		try {
+			LOG.trace("Starting readTagInfo");
+			if (exact) {
+				action = ActionFactory.createTagReadExactAllAction(file);
+			} else {
+				action = ActionFactory.createTagReadAllAction(file);
+			}
+			handler = new EventHandler();
+			bus.register(handler);
+			LOG.trace("Registered the EventHandler");
+			String[] arguments = action.buildArguments();
+			for (String argument : arguments) {
+				argsWriter.append(argument).append("\r\n");
+			}
+			argsWriter.flush();
+			while (!handler.isFinished() && i <= deadLock) {
+				Thread.sleep(50);
+				i += 50;
+			}
+			if (!handler.isFinished()) {
+				LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
+				throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
+			}
+			bus.unregister(handler);
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+			throw new JExifException(e);
+		} catch (InterruptedException e) {
+			LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
+			throw new JExifException(e);
+		}
+		LOG.trace("Handler finished");
+		List<String> results = handler.getResultList();
+		List<String> errors = handler.getErrorList();
+		LOG.trace("Parsing results");
+		ResultHandler.run(action, results, errors);
+		if (onlySupported) {
+			return action.getResult();
+		} else {
+			Map<String, String> tags = action.getUnsupportedTags();
+			for (Entry<Tag, String> e : action.getResult().entrySet()) {
+				tags.put(e.getKey().getName(), e.getValue());
+			}
+			return tags;
+		}
+	}
 
 }

src/be/pw/jexif/enums/DataType.java

  * <li>Float</li>
  * <li>Undefined for any other case</li>
  * </ul>
- * 
  * @author phillip
  */
 public enum DataType {

src/be/pw/jexif/enums/Errors.java

 
 /**
  * Enum which is used in combination with cal10n to i18n the errormessages.
- *
  * @see be.pw.jexif.internal.util.Cal10nUtil
  */
 @BaseName("errorMessages")
-@LocaleData({@Locale("en")})
+@LocaleData({ @Locale("en") })
 public enum Errors {
-    GENERAL, EXIFTHREAD, IO_ARGSFILE, IO_CLOSING, INTERRUPTED_SLEEP, DEADLOCK, VALIDATION_TAGLIST, IO_BUILD_ARGUMENTS, VALIDATION_VALUESLIST, EXIFTOOL_EXECUTION_ERROR, EXIFTOOL_EXECUTION_WARNING, RETREIVE_PARSER_ERROR, PARSER_UNKNOWNTYPE, PARSER_MISMATCH, VALIDATION_WRITE_PROTECTED_TAG, VALIDATION_WRITE_AVOIDED_TAG, VALIDATION_WRITE_UNSAFE_TAG, UNKNOWN_DATATYPE, VALIDATION_NEGATIVE_UNSIGNED, VALIDATION_EXCEEDS_LIMITS, VALIDATION_RAT_FOR_INT, VALIDATION_INVALID_TYPE, IO_FILE_NOT_VALID, GPS_MISSING_FIELD
+	GENERAL, EXIFTHREAD, IO_ARGSFILE, IO_CLOSING, INTERRUPTED_SLEEP, DEADLOCK, VALIDATION_TAGLIST, IO_BUILD_ARGUMENTS, VALIDATION_VALUESLIST, EXIFTOOL_EXECUTION_ERROR, EXIFTOOL_EXECUTION_WARNING, RETREIVE_PARSER_ERROR, PARSER_UNKNOWNTYPE, PARSER_MISMATCH, VALIDATION_WRITE_PROTECTED_TAG, VALIDATION_WRITE_AVOIDED_TAG, VALIDATION_WRITE_UNSAFE_TAG, UNKNOWN_DATATYPE, VALIDATION_NEGATIVE_UNSIGNED, VALIDATION_EXCEEDS_LIMITS, VALIDATION_RAT_FOR_INT, VALIDATION_INVALID_TYPE, IO_FILE_NOT_VALID, GPS_MISSING_FIELD
 }

src/be/pw/jexif/enums/tag/ExifGPS.java

 
 /**
  * Implementation of the GPS group: <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/GPS.html">http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/GPS.html</a>
- * 
  * @author phillip
  */
 public enum ExifGPS implements Tag {

src/be/pw/jexif/enums/tag/ExifIFD.java

 
 /**
  * Implementation of the ExifIFD group: <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html">http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html</a>
- * 
  * @author phillip
  */
 public enum ExifIFD implements Tag {
 
-    APERTUREVALUE("ApertureValue", false, false, false, RAT64U), APPLICATIONNOTES("ApplicationNotes", true, false, false, INT8U), BRIGHTNESS("Brightness", false, true, false, STRING), BRIGHTNESSVALUE("BrightnessValue", false, false, false, RAT64S), CFAPATTERN("CFAPattern", false, false, false, UNDEF), COLORSPACE("ColorSpace", false, false, false, INT16U), COMPONENTSCONFIGURATION("ComponentsConfiguration", true, false, false, UNDEF), COMPRESSEDBITSPERPIXEL("CompressedBitsPerPixel", true, false, false, RAT64U), CONTRAST("Contrast", false, false, false, INT16U), CONVERTER("Converter", false, true, false, STRING), CREATEDATE("CreateDate", false, false, false, STRING), CUSTOMRENDERED("CustomRendered", false, false, false, INT16U), DATETIMEORIGINAL("DateTimeOriginal", false, false, false, STRING), DIGITALZOOMRATIO("DigitalZoomRatio", false, false, false, RAT64U), EXIFIMAGEHEIGHT("ExifImageHeight", false, false, false, INT16U), EXIFIMAGEWIDTH("ExifImageWidth", false, false, false, INT16U), EXIFVERSION("ExifVersion", false, false, false, UNDEF), EXPOSURE("Exposure", false, true, false, STRING), EXPOSURECOMPENSATION("ExposureCompensation", false, false, false, RAT64S), EXPOSUREINDEX("ExposureIndex", false, false, false, RAT64U), EXPOSUREMODE("ExposureMode", false, false, false, INT16U), EXPOSUREPROGRAM("ExposureProgram", false, false, false, INT16U), EXPOSURETIME("ExposureTime", false, false, false, RAT64U), FILESOURCE("FileSource", false, false, false, UNDEF), FLASH("Flash", false, false, false, INT16U), FLASHENERGY("FlashEnergy", false, false, false, RAT64U), FLASHPIXVERSION("FlashpixVersion", false, false, false, UNDEF), FNUMBER("FNumber", false, false, false, RAT64U), FOCALLENGTH("FocalLength", false, false, false, RAT64U), FOCALLENGTHIN35MMFORMAT("FocalLengthIn35mmFormat", false, false, false, INT16U), FOCALPLANERESOLUTIONUNIT("FocalPlaneResolutionUnit", false, false, false, INT16U), FOCALPLANEXRESOLUTION("FocalPlaneXResolution", false, false, false, RAT64U), FOCALPLANEYRESOLUTION("FocalPlaneYResolution", false, false, false, RAT64U), GAINCONTROL("GainControl", false, false, false, INT16U), GAMMA("Gamma", false, false, false, RAT64U), IMAGEHISTORY("ImageHistory", false, false, false, STRING), IMAGENUMBER("ImageNumber", false, false, false, INT32U), IMAGEUNIQUEID("ImageUniqueID", false, false, false, STRING), ISO("ISO", false, false, false, INT16U), ISOSPEED("ISOSpeed", false, false, false, INT32U), ISOSPEEDLATITUDEYYY("ISOSpeedLatitudeyyy", false, false, false, INT32U), ISOSPEEDLATITUDEZZZ("ISOSpeedLatitudezzz", false, false, false, INT32U), LENS("Lens", false, true, false, STRING), LENSINFO("LensInfo", false, false, false, RAT64U), LENSMAKE("LensMake", false, false, false, STRING), LENSMODEL("LensModel", false, false, false, STRING), LENSSERIALNUMBER("LensSerialNumber", false, false, false, STRING), LIGHTSOURCE("LightSource", false, false, false, INT16U), MAXAPERTUREVALUE("MaxApertureValue", false, false, false, RAT64U), METERINGMODE("MeteringMode", false, false, false, INT16U), MOIREFILTER("MoireFilter", false, true, false, STRING), OFFSETSCHEMA("OffsetSchema", false, false, false, INT32S), OWNERNAME("OwnerName", false, false, false, STRING), PADDING("Padding", false, false, false, UNDEF), RAWFILE("RawFile", false, true, false, STRING), RECOMMENDEDEXPOSUREINDEX("RecommendedExposureIndex", false, false, false, INT32U), RELATEDSOUNDFILE("RelatedSoundFile", false, false, false, STRING), SATURATION("Saturation", false, false, false, INT16U), SCENECAPTURETYPE("SceneCaptureType", false, false, false, INT16U), SCENETYPE("SceneType", false, false, false, UNDEF), SECURITYCLASSIFICATION("SecurityClassification", false, false, false, STRING), SELFTIMERMODE("SelfTimerMode", false, false, false, INT16U), SENSINGMETHOD("SensingMethod", false, false, false, INT16U), SENSITIVITYTYPE("SensitivityType", false, false, false, INT16U), SERIALNUMBER("SerialNumber", false, false, false, STRING), SHADOWS("Shadows", false, true, false, STRING), SHARPNESS("Sharpness", false, false, false, INT16U), SHUTTERSPEEDVALUE("ShutterSpeedValue", false, false, false, RAT64S), SMOOTHNESS("Smoothness", false, true, false, STRING), SPECTRALSENSITIVITY("SpectralSensitivity", false, false, false, STRING), STANDARDOUTPUTSENSITIVITY("StandardOutputSensitivity", false, false, false, INT32U), SUBJECTAREA("SubjectArea", false, false, false, INT16U), SUBJECTDISTANCE("SubjectDistance", false, false, false, RAT64U), SUBJECTDISTANCERANGE("SubjectDistanceRange", false, false, false, INT16U), SUBJECTLOCATION("SubjectLocation", false, false, false, INT16U), SUBSECTIME("SubSecTime", false, false, false, STRING), SUBSECTIMEDIGITIZED("SubSecTimeDigitized", false, false, false, STRING), SUBSECTIMEORIGINAL("SubSecTimeOriginal", false, false, false, STRING), TIMEZONEOFFSET("TimeZoneOffset", false, false, false, INT16S), USERCOMMENT("UserComment", false, false, false, UNDEF), WHITEBALANCE("WhiteBalance", false, false, false, INT16U),;
+	APERTUREVALUE("ApertureValue", false, false, false, RAT64U), APPLICATIONNOTES("ApplicationNotes", true, false, false, INT8U), BRIGHTNESS("Brightness", false, true, false, STRING), BRIGHTNESSVALUE("BrightnessValue", false, false, false, RAT64S), CFAPATTERN("CFAPattern", false, false, false, UNDEF), COLORSPACE("ColorSpace", false, false, false, INT16U), COMPONENTSCONFIGURATION("ComponentsConfiguration", true, false, false, UNDEF), COMPRESSEDBITSPERPIXEL("CompressedBitsPerPixel", true, false, false, RAT64U), CONTRAST("Contrast", false, false, false, INT16U), CONVERTER("Converter", false, true, false, STRING), CREATEDATE("CreateDate", false, false, false, STRING), CUSTOMRENDERED("CustomRendered", false, false, false, INT16U), DATETIMEORIGINAL("DateTimeOriginal", false, false, false, STRING), DIGITALZOOMRATIO("DigitalZoomRatio", false, false, false, RAT64U), EXIFIMAGEHEIGHT("ExifImageHeight", false, false, false, INT16U), EXIFIMAGEWIDTH("ExifImageWidth", false, false, false, INT16U), EXIFVERSION("ExifVersion", false, false, false, UNDEF), EXPOSURE("Exposure", false, true, false, STRING), EXPOSURECOMPENSATION("ExposureCompensation", false, false, false, RAT64S), EXPOSUREINDEX("ExposureIndex", false, false, false, RAT64U), EXPOSUREMODE("ExposureMode", false, false, false, INT16U), EXPOSUREPROGRAM("ExposureProgram", false, false, false, INT16U), EXPOSURETIME("ExposureTime", false, false, false, RAT64U), FILESOURCE("FileSource", false, false, false, UNDEF), FLASH("Flash", false, false, false, INT16U), FLASHENERGY("FlashEnergy", false, false, false, RAT64U), FLASHPIXVERSION("FlashpixVersion", false, false, false, UNDEF), FNUMBER("FNumber", false, false, false, RAT64U), FOCALLENGTH("FocalLength", false, false, false, RAT64U), FOCALLENGTHIN35MMFORMAT("FocalLengthIn35mmFormat", false, false, false, INT16U), FOCALPLANERESOLUTIONUNIT("FocalPlaneResolutionUnit", false, false, false, INT16U), FOCALPLANEXRESOLUTION("FocalPlaneXResolution", false, false, false, RAT64U), FOCALPLANEYRESOLUTION("FocalPlaneYResolution", false, false, false, RAT64U), GAINCONTROL("GainControl", false, false, false, INT16U), GAMMA("Gamma", false, false, false, RAT64U), IMAGEHISTORY("ImageHistory", false, false, false, STRING), IMAGENUMBER("ImageNumber", false, false, false, INT32U), IMAGEUNIQUEID("ImageUniqueID", false, false, false, STRING), ISO("ISO", false, false, false, INT16U), ISOSPEED("ISOSpeed", false, false, false, INT32U), ISOSPEEDLATITUDEYYY("ISOSpeedLatitudeyyy", false, false, false, INT32U), ISOSPEEDLATITUDEZZZ("ISOSpeedLatitudezzz", false, false, false, INT32U), LENS("Lens", false, true, false, STRING), LENSINFO("LensInfo", false, false, false, RAT64U), LENSMAKE("LensMake", false, false, false, STRING), LENSMODEL("LensModel", false, false, false, STRING), LENSSERIALNUMBER("LensSerialNumber", false, false, false, STRING), LIGHTSOURCE("LightSource", false, false, false, INT16U), MAXAPERTUREVALUE("MaxApertureValue", false, false, false, RAT64U), METERINGMODE("MeteringMode", false, false, false, INT16U), MOIREFILTER("MoireFilter", false, true, false, STRING), OFFSETSCHEMA("OffsetSchema", false, false, false, INT32S), OWNERNAME("OwnerName", false, false, false, STRING), PADDING("Padding", false, false, false, UNDEF), RAWFILE("RawFile", false, true, false, STRING), RECOMMENDEDEXPOSUREINDEX("RecommendedExposureIndex", false, false, false, INT32U), RELATEDSOUNDFILE("RelatedSoundFile", false, false, false, STRING), SATURATION("Saturation", false, false, false, INT16U), SCENECAPTURETYPE("SceneCaptureType", false, false, false, INT16U), SCENETYPE("SceneType", false, false, false, UNDEF), SECURITYCLASSIFICATION("SecurityClassification", false, false, false, STRING), SELFTIMERMODE("SelfTimerMode", false, false, false, INT16U), SENSINGMETHOD("SensingMethod", false, false, false, INT16U), SENSITIVITYTYPE("SensitivityType", false, false, false, INT16U), SERIALNUMBER("SerialNumber", false, false, false, STRING), SHADOWS("Shadows", false, true, false, STRING), SHARPNESS("Sharpness", false, false, false, INT16U), SHUTTERSPEEDVALUE("ShutterSpeedValue", false, false, false, RAT64S), SMOOTHNESS("Smoothness", false, true, false, STRING), SPECTRALSENSITIVITY("SpectralSensitivity", false, false, false, STRING), STANDARDOUTPUTSENSITIVITY("StandardOutputSensitivity", false, false, false, INT32U), SUBJECTAREA("SubjectArea", false, false, false, INT16U), SUBJECTDISTANCE("SubjectDistance", false, false, false, RAT64U), SUBJECTDISTANCERANGE("SubjectDistanceRange", false, false, false, INT16U), SUBJECTLOCATION("SubjectLocation", false, false, false, INT16U), SUBSECTIME("SubSecTime", false, false, false, STRING), SUBSECTIMEDIGITIZED("SubSecTimeDigitized", false, false, false, STRING), SUBSECTIMEORIGINAL("SubSecTimeOriginal", false, false, false, STRING), TIMEZONEOFFSET("TimeZoneOffset", false, false, false, INT16S), USERCOMMENT("UserComment", false, false, false, UNDEF), WHITEBALANCE("WhiteBalance", false, false, false, INT16U), ;
 
-    private final boolean avoided;
-    private final boolean unsafe;
-    private final boolean protectedField;
-    private final String name;
-    private final DataType type;
+	private final boolean avoided;
+	private final boolean unsafe;
+	private final boolean protectedField;
+	private final String name;
+	private final DataType type;
 
-    /**
-     * @param avoided        indicate that the tag is avoided
-     * @param unsafe         indicated that the tag is unsafe
-     * @param protectedField indicate that the tag is protected
-     * @param name           the name of the tag
-     * @param type           the data type of the tag
-     */
-    private ExifIFD(final String name, final boolean unsafe, final boolean avoided, final boolean protectedField, final DataType type) {
-        this.avoided = avoided;
-        this.unsafe = unsafe;
-        this.protectedField = protectedField;
-        this.name = name;
-        this.type = type;
-    }
+	/**
+	 * @param avoided indicate that the tag is avoided
+	 * @param unsafe indicated that the tag is unsafe
+	 * @param protectedField indicate that the tag is protected
+	 * @param name the name of the tag
+	 * @param type the data type of the tag
+	 */
+	private ExifIFD(final String name, final boolean unsafe, final boolean avoided, final boolean protectedField, final DataType type) {
+		this.avoided = avoided;
+		this.unsafe = unsafe;
+		this.protectedField = protectedField;
+		this.name = name;
+		this.type = type;
+	}
 
-    /**
+	/**
 	 * {@inheritDoc}
 	 */
 	@Override

src/be/pw/jexif/enums/tag/IFD0.java

 
 /**
  * Implementation of the IFD0 group: <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html">http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html</a>
- * 
  * @author phillip
  */
 public enum IFD0 implements Tag {
 
-    ANALOGBALANCE("AnalogBalance", true, false, false, RAT64U), ARTIST("Artist", false, false, false, STRING), ASSHOTICCPROFILE("AsShotICCProfile", true, false, false, UNDEF), ASSHOTNEUTRAL("AsShotNeutral", true, false, false, RAT64U), ASSHOTPREPROFILEMATRIX("AsShotPreProfileMatrix", true, false, false, RAT64S), ASSHOTPROFILENAME("AsShotProfileName", true, false, false, STRING), ASSHOTWHITEXY("AsShotWhiteXY", true, false, false, RAT64U), BASELINEEXPOSURE("BaselineExposure", true, false, false, RAT64S), BASELINENOISE("BaselineNoise", true, false, false, RAT64U), BASELINESHARPNESS("BaselineSharpness", true, false, false, RAT64U), BITSPERSAMPLE("BitsPerSample", true, false, false, INT16U), CALIBRATIONILLUMINANT1("CalibrationIlluminant1", true, false, false, INT16U), CALIBRATIONILLUMINANT2("CalibrationIlluminant2", true, false, false, INT16U), CAMERACALIBRATION1("CameraCalibration1", true, false, false, RAT64S), CAMERACALIBRATION2("CameraCalibration2", true, false, false, RAT64S), CAMERACALIBRATIONSIG("CameraCalibrationSig", true, false, false, STRING), CAMERASERIALNUMBER("CameraSerialNumber", false, false, false, STRING), CELLLENGTH("CellLength", true, false, false, INT16U), CELLWIDTH("CellWidth", true, false, false, INT16U), COLORIMETRICREFERENCE("ColorimetricReference", true, false, false, INT16U), COLORMATRIX1("ColorMatrix1", true, false, false, RAT64S), COLORMATRIX2("ColorMatrix2", true, false, false, RAT64S), COMPRESSION("Compression", true, false, false, INT16U), COPYRIGHT("Copyright", false, false, false, STRING), CURRENTICCPROFILE("CurrentICCProfile", true, false, false, UNDEF), CURRENTPREPROFILEMATRIX("CurrentPreProfileMatrix", true, false, false, RAT64S), DNGBACKWARDVERSION("DNGBackwardVersion", true, false, false, INT8U), DNGLENSINFO("DNGLensInfo", false, false, false, RAT64U), DNGVERSION("DNGVersion", true, false, false, INT8U), DOCUMENTNAME("DocumentName", false, false, false, STRING), DOTRANGE("DotRange", false, false, false, STRING), FILLORDER("FillOrder", true, false, false, INT16U), FORWARDMATRIX1("ForwardMatrix1", true, false, false, RAT64S), FORWARDMATRIX2("ForwardMatrix2", true, false, false, RAT64S), GRAYRESPONSEUNIT("GrayResponseUnit", false, false, false, INT16U), HALFTONEHINTS("HalftoneHints", false, false, false, INT16U), HOSTCOMPUTER("HostComputer", false, false, false, STRING), IMAGEDESCRIPTION("ImageDescription", false, false, false, STRING), IMAGEHEIGHT("ImageHeight", true, false, false, INT32U), IMAGESOURCEDATA("ImageSourceData", true, false, false, UNDEF), IMAGEWIDTH("ImageWidth", true, false, false, INT32U), INKSET("InkSet", false, false, false, INT16U), IPTCNAA("IPTC-NAA", true, false, false, INT32U), LINEARRESPONSELIMIT("LinearResponseLimit", true, false, false, RAT64U), LOCALIZEDCAMERAMODEL("LocalizedCameraModel", false, false, false, STRING), MAKE("Make", false, false, false, STRING), MAKERNOTESAFETY("MakerNoteSafety", false, false, false, INT16U), MAXSAMPLEVALUE("MaxSampleValue", false, false, false, INT16U), MINSAMPLEVALUE("MinSampleValue", false, false, false, INT16U), MODEL("Model", false, false, false, STRING), MODIFYDATE("ModifyDate", false, false, false, STRING), OLDSUBFILETYPE("OldSubfileType", true, false, false, INT16U), ORIENTATION("Orientation", false, false, false, INT16U), ORIGINALRAWFILEDATA("OriginalRawFileData", true, false, false, UNDEF), ORIGINALRAWFILEDIGEST("OriginalRawFileDigest", true, false, false, INT8U), ORIGINALRAWFILENAME("OriginalRawFileName", true, false, false, STRING), PAGENAME("PageName", false, false, false, STRING), PAGENUMBER("PageNumber", false, false, false, INT16U), PANASONICTITLE("PanasonicTitle", false, false, false, UNDEF), PANASONICTITLE2("PanasonicTitle2", false, false, false, UNDEF), PHOTOMETRICINTERPRETATION("PhotometricInterpretation", true, false, false, INT16U), PLANARCONFIGURATION("PlanarConfiguration", true, false, false, INT16U), PREDICTOR("Predictor", true, false, false, INT16U), PREVIEWAPPLICATIONNAME("PreviewApplicationName", true, false, false, STRING), PREVIEWAPPLICATIONVERSION("PreviewApplicationVersion", true, false, false, STRING), PREVIEWCOLORSPACE("PreviewColorSpace", true, false, false, INT32U), PREVIEWDATETIME("PreviewDateTime", true, false, false, STRING), PREVIEWSETTINGSDIGEST("PreviewSettingsDigest", true, false, false, INT8U), PREVIEWSETTINGSNAME("PreviewSettingsName", true, false, false, STRING), PRIMARYCHROMATICITIES("PrimaryChromaticities", false, false, false, RAT64U), PRINTIM("PrintIM", false, false, false, UNDEF), PROCESSINGSOFTWARE("ProcessingSoftware", false, false, false, STRING), PROFILECALIBRATIONSIG("ProfileCalibrationSig", true, false, false, STRING), PROFILECOPYRIGHT("ProfileCopyright", true, false, false, STRING), PROFILEEMBEDPOLICY("ProfileEmbedPolicy", true, false, false, INT32U), PROFILEHUESATMAPDATA1("ProfileHueSatMapData1", true, false, false, FLOAT), PROFILEHUESATMAPDATA2("ProfileHueSatMapData2", true, false, false, FLOAT), PROFILEHUESATMAPDIMS("ProfileHueSatMapDims", true, false, false, INT32U), PROFILELOOKTABLEDATA("ProfileLookTableData", true, false, false, FLOAT), PROFILELOOKTABLEDIMS("ProfileLookTableDims", true, false, false, INT32U), PROFILENAME("ProfileName", true, false, false, STRING), PROFILETONECURVE("ProfileToneCurve", true, false, false, FLOAT), RATING("Rating", false, true, false, INT16U), RATINGPERCENT("RatingPercent", false, true, false, INT16U), RAWDATAUNIQUEID("RawDataUniqueID", true, false, false, INT8U), RAWIMAGEDIGEST("RawImageDigest", true, false, false, INT8U), REDUCTIONMATRIX1("ReductionMatrix1", true, false, false, RAT64S), REDUCTIONMATRIX2("ReductionMatrix2", true, false, false, RAT64S), REFERENCEBLACKWHITE("ReferenceBlackWhite", false, false, false, RAT64U), RESOLUTIONUNIT("ResolutionUnit", false, false, false, INT16U), ROWSPERSTRIP("RowsPerStrip", true, false, false, INT32U), SAMPLESPERPIXEL("SamplesPerPixel", true, false, false, INT16U), SEMINFO("SEMInfo", false, false, false, STRING), SHADOWSCALE("ShadowScale", true, false, false, RAT64U), SOFTWARE("Software", false, false, false, STRING), SUBFILETYPE("SubfileType", true, false, false, INT32U), THRESHOLDING("Thresholding", true, false, false, INT16U), TILELENGTH("TileLength", true, false, false, INT32U), TILEWIDTH("TileWidth", true, false, false, INT32U), TRANSFERFUNCTION("TransferFunction", true, false, false, INT16U), UNIQUECAMERAMODEL("UniqueCameraModel", false, false, false, STRING), WHITEPOINT("WhitePoint", false, false, false, RAT64U), XPAUTHOR("XPAuthor", false, false, false, INT8U), XPCOMMENT("XPComment", false, false, false, INT8U), XPKEYWORDS("XPKeywords", false, false, false, INT8U), XPOSITION("XPosition", false, false, false, RAT64U), XPSUBJECT("XPSubject", false, false, false, INT8U), XPTITLE("XPTitle", false, false, false, INT8U), XRESOLUTION("XResolution", false, false, false, RAT64U), YCBCRCOEFFICIENTS("YCbCrCoefficients", true, false, false, RAT64U), YCBCRPOSITIONING("YCbCrPositioning", true, false, false, INT16U), YCBCRSUBSAMPLING("YCbCrSubSampling", true, false, false, INT16U), YPOSITION("YPosition", false, false, false, RAT64U), YRESOLUTION("YResolution", false, false, false, RAT64U), INTEROPINDEX("InteropIndex", true, false, false, STRING), INTEROPVERSION("InteropVersion", true, false, false, UNDEF), RELATEDIMAGEFILEFORMAT("RelatedImageFileFormat", true, false, false, STRING), RELATEDIMAGEHEIGHT("RelatedImageHeight", true, false, false, INT16U), RELATEDIMAGEWIDTH("RelatedImageWidth", true, false, false, INT16U), ACTIVEAREA("ActiveArea", true, false, false, INT32U), ANTIALIASSTRENGTH("AntiAliasStrength", true, false, false, RAT64U), BAYERGREENSPLIT("BayerGreenSplit", true, false, false, INT32U), BESTQUALITYSCALE("BestQualityScale", true, false, false, RAT64U), BLACKLEVEL("BlackLevel", true, false, false, RAT64U), BLACKLEVELREPEATDIM("BlackLevelRepeatDim", true, false, false, INT16U), CHROMABLURRADIUS("ChromaBlurRadius", true, false, false, RAT64U), DEFAULTCROPORIGIN("DefaultCropOrigin", true, false, false, INT32U), DEFAULTCROPSIZE("DefaultCropSize", true, false, false, INT32U), DEFAULTSCALE("DefaultScale", true, false, false, RAT64U), LINEARIZATIONTABLE("LinearizationTable", true, false, false, INT16U), MASKEDAREAS("MaskedAreas", true, false, false, INT32U), NOISEREDUCTIONAPPLIED("NoiseReductionApplied", true, false, false, RAT64U), WHITELEVEL("WhiteLevel", true, false, false, INT32U);
+	ANALOGBALANCE("AnalogBalance", true, false, false, RAT64U), ARTIST("Artist", false, false, false, STRING), ASSHOTICCPROFILE("AsShotICCProfile", true, false, false, UNDEF), ASSHOTNEUTRAL("AsShotNeutral", true, false, false, RAT64U), ASSHOTPREPROFILEMATRIX("AsShotPreProfileMatrix", true, false, false, RAT64S), ASSHOTPROFILENAME("AsShotProfileName", true, false, false, STRING), ASSHOTWHITEXY("AsShotWhiteXY", true, false, false, RAT64U), BASELINEEXPOSURE("BaselineExposure", true, false, false, RAT64S), BASELINENOISE("BaselineNoise", true, false, false, RAT64U), BASELINESHARPNESS("BaselineSharpness", true, false, false, RAT64U), BITSPERSAMPLE("BitsPerSample", true, false, false, INT16U), CALIBRATIONILLUMINANT1("CalibrationIlluminant1", true, false, false, INT16U), CALIBRATIONILLUMINANT2("CalibrationIlluminant2", true, false, false, INT16U), CAMERACALIBRATION1("CameraCalibration1", true, false, false, RAT64S), CAMERACALIBRATION2("CameraCalibration2", true, false, false, RAT64S), CAMERACALIBRATIONSIG("CameraCalibrationSig", true, false, false, STRING), CAMERASERIALNUMBER("CameraSerialNumber", false, false, false, STRING), CELLLENGTH("CellLength", true, false, false, INT16U), CELLWIDTH("CellWidth", true, false, false, INT16U), COLORIMETRICREFERENCE("ColorimetricReference", true, false, false, INT16U), COLORMATRIX1("ColorMatrix1", true, false, false, RAT64S), COLORMATRIX2("ColorMatrix2", true, false, false, RAT64S), COMPRESSION("Compression", true, false, false, INT16U), COPYRIGHT("Copyright", false, false, false, STRING), CURRENTICCPROFILE("CurrentICCProfile", true, false, false, UNDEF), CURRENTPREPROFILEMATRIX("CurrentPreProfileMatrix", true, false, false, RAT64S), DNGBACKWARDVERSION("DNGBackwardVersion", true, false, false, INT8U), DNGLENSINFO("DNGLensInfo", false, false, false, RAT64U), DNGVERSION("DNGVersion", true, false, false, INT8U), DOCUMENTNAME("DocumentName", false, false, false, STRING), DOTRANGE("DotRange", false, false, false, STRING), FILLORDER("FillOrder", true, false, false, INT16U), FORWARDMATRIX1("ForwardMatrix1", true, false, false, RAT64S), FORWARDMATRIX2("ForwardMatrix2", true, false, false, RAT64S), GRAYRESPONSEUNIT("GrayResponseUnit", false, false, false, INT16U), HALFTONEHINTS("HalftoneHints", false, false, false, INT16U), HOSTCOMPUTER("HostComputer", false, false, false, STRING), IMAGEDESCRIPTION("ImageDescription", false, false, false, STRING), IMAGEHEIGHT("ImageHeight", true, false, false, INT32U), IMAGESOURCEDATA("ImageSourceData", true, false, false, UNDEF), IMAGEWIDTH("ImageWidth", true, false, false, INT32U), INKSET("InkSet", false, false, false, INT16U), IPTCNAA("IPTC-NAA", true, false, false, INT32U), LINEARRESPONSELIMIT("LinearResponseLimit", true, false, false, RAT64U), LOCALIZEDCAMERAMODEL("LocalizedCameraModel", false, false, false, STRING), MAKE("Make", false, false, false, STRING), MAKERNOTESAFETY("MakerNoteSafety", false, false, false, INT16U), MAXSAMPLEVALUE("MaxSampleValue", false, false, false, INT16U), MINSAMPLEVALUE("MinSampleValue", false, false, false, INT16U), MODEL("Model", false, false, false, STRING), MODIFYDATE("ModifyDate", false, false, false, STRING), OLDSUBFILETYPE("OldSubfileType", true, false, false, INT16U), ORIENTATION("Orientation", false, false, false, INT16U), ORIGINALRAWFILEDATA("OriginalRawFileData", true, false, false, UNDEF), ORIGINALRAWFILEDIGEST("OriginalRawFileDigest", true, false, false, INT8U), ORIGINALRAWFILENAME("OriginalRawFileName", true, false, false, STRING), PAGENAME("PageName", false, false, false, STRING), PAGENUMBER("PageNumber", false, false, false, INT16U), PANASONICTITLE("PanasonicTitle", false, false, false, UNDEF), PANASONICTITLE2("PanasonicTitle2", false, false, false, UNDEF), PHOTOMETRICINTERPRETATION("PhotometricInterpretation", true, false, false, INT16U), PLANARCONFIGURATION("PlanarConfiguration", true, false, false, INT16U), PREDICTOR("Predictor", true, false, false, INT16U), PREVIEWAPPLICATIONNAME("PreviewApplicationName", true, false, false, STRING), PREVIEWAPPLICATIONVERSION("PreviewApplicationVersion", true, false, false, STRING), PREVIEWCOLORSPACE("PreviewColorSpace", true, false, false, INT32U), PREVIEWDATETIME("PreviewDateTime", true, false, false, STRING), PREVIEWSETTINGSDIGEST("PreviewSettingsDigest", true, false, false, INT8U), PREVIEWSETTINGSNAME("PreviewSettingsName", true, false, false, STRING), PRIMARYCHROMATICITIES("PrimaryChromaticities", false, false, false, RAT64U), PRINTIM("PrintIM", false, false, false, UNDEF), PROCESSINGSOFTWARE("ProcessingSoftware", false, false, false, STRING), PROFILECALIBRATIONSIG("ProfileCalibrationSig", true, false, false, STRING), PROFILECOPYRIGHT("ProfileCopyright", true, false, false, STRING), PROFILEEMBEDPOLICY("ProfileEmbedPolicy", true, false, false, INT32U), PROFILEHUESATMAPDATA1("ProfileHueSatMapData1", true, false, false, FLOAT), PROFILEHUESATMAPDATA2("ProfileHueSatMapData2", true, false, false, FLOAT), PROFILEHUESATMAPDIMS("ProfileHueSatMapDims", true, false, false, INT32U), PROFILELOOKTABLEDATA("ProfileLookTableData", true, false, false, FLOAT), PROFILELOOKTABLEDIMS("ProfileLookTableDims", true, false, false, INT32U), PROFILENAME("ProfileName", true, false, false, STRING), PROFILETONECURVE("ProfileToneCurve", true, false, false, FLOAT), RATING("Rating", false, true, false, INT16U), RATINGPERCENT("RatingPercent", false, true, false, INT16U), RAWDATAUNIQUEID("RawDataUniqueID", true, false, false, INT8U), RAWIMAGEDIGEST("RawImageDigest", true, false, false, INT8U), REDUCTIONMATRIX1("ReductionMatrix1", true, false, false, RAT64S), REDUCTIONMATRIX2("ReductionMatrix2", true, false, false, RAT64S), REFERENCEBLACKWHITE("ReferenceBlackWhite", false, false, false, RAT64U), RESOLUTIONUNIT("ResolutionUnit", false, false, false, INT16U), ROWSPERSTRIP("RowsPerStrip", true, false, false, INT32U), SAMPLESPERPIXEL("SamplesPerPixel", true, false, false, INT16U), SEMINFO("SEMInfo", false, false, false, STRING), SHADOWSCALE("ShadowScale", true, false, false, RAT64U), SOFTWARE("Software", false, false, false, STRING), SUBFILETYPE("SubfileType", true, false, false, INT32U), THRESHOLDING("Thresholding", true, false, false, INT16U), TILELENGTH("TileLength", true, false, false, INT32U), TILEWIDTH("TileWidth", true, false, false, INT32U), TRANSFERFUNCTION("TransferFunction", true, false, false, INT16U), UNIQUECAMERAMODEL("UniqueCameraModel", false, false, false, STRING), WHITEPOINT("WhitePoint", false, false, false, RAT64U), XPAUTHOR("XPAuthor", false, false, false, INT8U), XPCOMMENT("XPComment", false, false, false, INT8U), XPKEYWORDS("XPKeywords", false, false, false, INT8U), XPOSITION("XPosition", false, false, false, RAT64U), XPSUBJECT("XPSubject", false, false, false, INT8U), XPTITLE("XPTitle", false, false, false, INT8U), XRESOLUTION("XResolution", false, false, false, RAT64U), YCBCRCOEFFICIENTS("YCbCrCoefficients", true, false, false, RAT64U), YCBCRPOSITIONING("YCbCrPositioning", true, false, false, INT16U), YCBCRSUBSAMPLING("YCbCrSubSampling", true, false, false, INT16U), YPOSITION("YPosition", false, false, false, RAT64U), YRESOLUTION("YResolution", false, false, false, RAT64U), INTEROPINDEX("InteropIndex", true, false, false, STRING), INTEROPVERSION("InteropVersion", true, false, false, UNDEF), RELATEDIMAGEFILEFORMAT("RelatedImageFileFormat", true, false, false, STRING), RELATEDIMAGEHEIGHT("RelatedImageHeight", true, false, false, INT16U), RELATEDIMAGEWIDTH("RelatedImageWidth", true, false, false, INT16U), ACTIVEAREA("ActiveArea", true, false, false, INT32U), ANTIALIASSTRENGTH("AntiAliasStrength", true, false, false, RAT64U), BAYERGREENSPLIT("BayerGreenSplit", true, false, false, INT32U), BESTQUALITYSCALE("BestQualityScale", true, false, false, RAT64U), BLACKLEVEL("BlackLevel", true, false, false, RAT64U), BLACKLEVELREPEATDIM("BlackLevelRepeatDim", true, false, false, INT16U), CHROMABLURRADIUS("ChromaBlurRadius", true, false, false, RAT64U), DEFAULTCROPORIGIN("DefaultCropOrigin", true, false, false, INT32U), DEFAULTCROPSIZE("DefaultCropSize", true, false, false, INT32U), DEFAULTSCALE("DefaultScale", true, false, false, RAT64U), LINEARIZATIONTABLE("LinearizationTable", true, false, false, INT16U), MASKEDAREAS("MaskedAreas", true, false, false, INT32U), NOISEREDUCTIONAPPLIED("NoiseReductionApplied", true, false, false, RAT64U), WHITELEVEL("WhiteLevel", true, false, false, INT32U);
 
-    private final boolean avoided;
-    private final boolean unsafe;
-    private final boolean protectedField;
-    private final String name;
-    private final DataType type;
+	private final boolean avoided;
+	private final boolean unsafe;
+	private final boolean protectedField;
+	private final String name;
+	private final DataType type;
 
-    /**
-     * @param avoided        indicate that the tag is avoided
-     * @param unsafe         indicated that the tag is unsafe
-     * @param protectedField indicate that the tag is protected
-     * @param name           the name of the tag
-     * @param type           the data type of the tag
-     */
-    private IFD0(final String name, final boolean unsafe, final boolean avoided, final boolean protectedField, final DataType type) {
-        this.avoided = avoided;
-        this.unsafe = unsafe;
-        this.protectedField = protectedField;
-        this.name = name;
-        this.type = type;
-    }
+	/**
+	 * @param avoided indicate that the tag is avoided
+	 * @param unsafe indicated that the tag is unsafe
+	 * @param protectedField indicate that the tag is protected
+	 * @param name the name of the tag
+	 * @param type the data type of the tag
+	 */
+	private IFD0(final String name, final boolean unsafe, final boolean avoided, final boolean protectedField, final DataType type) {
+		this.avoided = avoided;
+		this.unsafe = unsafe;
+		this.protectedField = protectedField;
+		this.name = name;
+		this.type = type;
+	}
 
-    /**
+	/**
 	 * {@inheritDoc}
 	 */
 	@Override

src/be/pw/jexif/enums/tag/Tag.java

  */
 public interface Tag {
 
-    /**
-     * An avoided tags is a tag that is not created when writing if another same-named tag may be created instead.
-     *
-     * @return true if the tag is avoided.
-     */
-    boolean isAvoided();
-
-    /**
-     * Indicates a tag that is considered unsafe to write under normal circumstances.
-     *
-     * @return true if the tag is unsafe.
-     */
-    boolean isUnsafe();
-
-    /**
-     * Indicates a protected tag which is not writable directly, but is written automatically by ExifTool (often when a corresponding Composite or Extra tag is written)
-     *
-     * @return true if the tag is protected.
-     */
-    boolean isProtectedField();
-
-    /**
-     * @return the name of the tag (as it should be given on the command line)
-     */
-    String getName();
-
-    /**
-     * @return the data type of the tag
-     */
-    DataType getType();
+	/**
+	 * An avoided tags is a tag that is not created when writing if another same-named tag may be created instead.
+	 * @return true if the tag is avoided.
+	 */
+	boolean isAvoided();
+
+	/**
+	 * Indicates a tag that is considered unsafe to write under normal circumstances.
+	 * @return true if the tag is unsafe.
+	 */
+	boolean isUnsafe();
+
+	/**
+	 * Indicates a protected tag which is not writable directly, but is written automatically by ExifTool (often when a corresponding Composite or Extra tag is written)
+	 * @return true if the tag is protected.
+	 */
+	boolean isProtectedField();
+
+	/**
+	 * @return the name of the tag (as it should be given on the command line)
+	 */
+	String getName();
+
+	/**
+	 * @return the data type of the tag
+	 */
+	DataType getType();
 
 }

src/be/pw/jexif/internal/action/AbstractAction.java

 	public void addResult(final Tag tag, final String result) {
 		results.put(tag, result);
 	}
-	
 
 	@Override
 	public void addUnsupportedResult(final String tag, final String result) {

src/be/pw/jexif/internal/action/IAction.java

  * <li>Create the arguments for ExifTool</li>
  * <li>Wait for results to be returned by the {@link ResultHandler}
  * </ol>
- * 
- * 
  * The IAction interface describes such action.<br />
  * An action may only be instantiated by the {@link ActionFactory} and for each action an {@link IResultParser} should be created.
- * 
  * @author phillip
  */
 public interface IAction {
 
 	/**
 	 * Returns the result of the execution as a String.
-	 * 
 	 * @return the map with as key the Tag and as value the result of the execution
 	 */
 	Map<Tag, String> getResult();
 
 	/**
 	 * Adds the result for a Tag.
-	 * 
 	 * @param tag the tag for which the result is added
 	 * @param result the result of the action
 	 */
 
 	/**
 	 * Returns the list of tags that were read but are not supported by J-ExifTool.
-	 * 
 	 * @return the list of unsupported tags.
 	 */
 	public abstract Map<String, String> getUnsupportedTags();
 
 	/**
 	 * Adds the result for an unsupported tag.
-	 * 
 	 * @param tagName the name of the unsupported tag (as returned by ExifTool)
 	 * @param result the result
 	 */

src/be/pw/jexif/internal/action/ITagReadAction.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
 package be.pw.jexif.internal.action;
 
 public interface ITagReadAction extends IAction {

src/be/pw/jexif/internal/action/ITagReadAllAction.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
 package be.pw.jexif.internal.action;
 
 public interface ITagReadAllAction extends IAction {

src/be/pw/jexif/internal/action/ITagReadExactAction.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
 package be.pw.jexif.internal.action;
 
 public interface ITagReadExactAction extends IAction {

src/be/pw/jexif/internal/action/ITagReadExactAllAction.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
 package be.pw.jexif.internal.action;
 
-
 public interface ITagReadExactAllAction extends IAction {
 
 }

src/be/pw/jexif/internal/action/ITagWriteAction.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
 package be.pw.jexif.internal.action;
 
 public interface ITagWriteAction extends IAction {

src/be/pw/jexif/internal/action/impl/ActionFactory.java

 		read.setParams(file, valuesToWrite);
 		return read;
 	}
-	
+
 	public static ITagReadAllAction createTagReadAllAction(final File file) {
 		TagReadAllAction readAll = new TagReadAllAction();
 		readAll.setParams(file);
 		return readAll;
 	}
-	
+
 	public static ITagReadExactAllAction createTagReadExactAllAction(final File file) {
 		TagReadExactAllAction readExactAll = new TagReadExactAllAction();
 		readExactAll.setParams(file);

src/be/pw/jexif/internal/action/impl/TagReadAction.java

 	 */
 	void setParams(final File file, final Tag... tags) throws IOException {
 		Preconditions.checkNotNull(file);
-		if (!file.exists())  {
+		if (!file.exists()) {
 			throw new IOException(Cal10nUtil.get(Errors.IO_FILE_NOT_VALID, file.getAbsolutePath()));
 		}
 		Preconditions.checkNotNull(tags);
 		} catch (IOException e) {
 			LOG.error(Cal10nUtil.get(Errors.IO_BUILD_ARGUMENTS), e);
 			throw new JExifException(e);
-		} 
+		}
 	}
 }

src/be/pw/jexif/internal/action/impl/TagReadAllAction.java

 /**
  * Action that reads all the tag values from an image.
  * @author phillip
- *
  */
 class TagReadAllAction extends AbstractAction implements ITagReadAllAction {
 
 	 * The logger for this class.
 	 */
 	private static final Logger LOG = LoggerFactory.getLogger(TagReadAllAction.class);
-	
 
-	
 	/**
 	 * {@inheritDoc}
 	 */
 		} catch (IOException e) {
 			LOG.error(Cal10nUtil.get(Errors.IO_BUILD_ARGUMENTS), e);
 			throw new JExifException(e);
-		} 
+		}
 	}
 
-	void setParams(File file) {
+	void setParams(final File file) {
 		this.file = file;
 	}
 
-	
 }

src/be/pw/jexif/internal/action/impl/TagReadExactAllAction.java

 /**
  * Action that reads all the tag values from an image.
  * @author phillip
- *
  */
 class TagReadExactAllAction extends TagReadAllAction implements ITagReadExactAllAction {
 
 		return newArguments;
 	}
 
-	
 }

src/be/pw/jexif/internal/action/impl/TagWriteAction.java

 	 */
 	void setParams(final File file, final Map<Tag, String> valuesToWrite) throws JExifValidationException, IOException {
 		Preconditions.checkNotNull(file);
-		if (!file.exists())  {
+		if (!file.exists()) {
 			throw new IOException(Cal10nUtil.get(Errors.IO_FILE_NOT_VALID, file.getAbsolutePath()));
 		}
 		Preconditions.checkNotNull(valuesToWrite);
 		} catch (IOException e) {
 			LOG.error(Cal10nUtil.get(Errors.IO_BUILD_ARGUMENTS), e);
 			throw new JExifException(e);
-		} 
+		}
 	}
 }

src/be/pw/jexif/internal/constants/ExecutionConstant.java

 /**
  * Some constants used before, during and after the execution of ExifTool.<br />
  * For the different Tags, see {@link be.pw.jexif.enums.tag}
- *
  * @author phillip
  */
 public class ExecutionConstant {
-    /**
-     * Echo parameter to indicate that an action was started.
-     */
-    public static final String START = "**START**";
-    /**
-     * Echo parameter to indicate that an action was finished.
-     */
-    public static final String STOP = "**STOP**";
-    /**
-     * Strings that ExifTool outputs to indicate that it has finished it's execution.
-     */
-    public static final String EXIFTOOLREADY = "{ready}";
-    /**
-     * System property key for defining the path to Exif tool.
-     */
-    public static final String EXIFTOOLPATH = "exiftool.path";
+	/**
+	 * Echo parameter to indicate that an action was started.
+	 */
+	public static final String START = "**START**";
+	/**
+	 * Echo parameter to indicate that an action was finished.
+	 */
+	public static final String STOP = "**STOP**";
+	/**
+	 * Strings that ExifTool outputs to indicate that it has finished it's execution.
+	 */
+	public static final String EXIFTOOLREADY = "{ready}";
+	/**
+	 * System property key for defining the path to Exif tool.
+	 */
+	public static final String EXIFTOOLPATH = "exiftool.path";
 
-    /**
-     * System property key for the deadlock-time in milliseconds.
-     */
-    public static final String EXIFTOOLDEADLOCK = "exiftool.deadlock";
-    /**
-     * Command line argument to keep ExifTool open.
-     */
-    public static final String STAY_OPEN = "-stay_open";
+	/**
+	 * System property key for the deadlock-time in milliseconds.
+	 */
+	public static final String EXIFTOOLDEADLOCK = "exiftool.deadlock";
+	/**
+	 * Command line argument to keep ExifTool open.
+	 */
+	public static final String STAY_OPEN = "-stay_open";
 
-    /**
-     * Command line argument to let ExifTool print a provided line of text.
-     */
-    public static final String ECHO = "-echo";
+	/**
+	 * Command line argument to let ExifTool print a provided line of text.
+	 */
+	public static final String ECHO = "-echo";
 
-    /**
-     * Command line argument to have ExifTool output the exact values.
-     */
-    public static final String EXACT_VALUE = "-n";
+	/**
+	 * Command line argument to have ExifTool output the exact values.
+	 */
+	public static final String EXACT_VALUE = "-n";
 
-    /**
-     * Command line argument to have ExifTool start processing the provided arguments.
-     */
-    public static final String EXECUTE = "-execute";
+	/**
+	 * Command line argument to have ExifTool start processing the provided arguments.
+	 */
+	public static final String EXECUTE = "-execute";
 
-    /**
-     * Command line argument to have ExifTool output it's data in short format.
-     */
-    public static final String SHORT_FORMAT = "-S";
-    /**
-     * Command line argument to start ExifTool on a Windows based computer.
-     */
-    public static final String WINDOWS_CLA = "\"{0}\" " + STAY_OPEN + " true -@ \"{1}\"";
+	/**
+	 * Command line argument to have ExifTool output it's data in short format.
+	 */
+	public static final String SHORT_FORMAT = "-S";
+	/**
+	 * Command line argument to start ExifTool on a Windows based computer.
+	 */
+	public static final String WINDOWS_CLA = "\"{0}\" " + STAY_OPEN + " true -@ \"{1}\"";
 
-    /**
-     * Command line argument to start ExifTool on a Linux based computer.
-     */
-    public static final String LINUX_CLA = "{0} " + STAY_OPEN + " true -@ {1}";
+	/**
+	 * Command line argument to start ExifTool on a Linux based computer.
+	 */
+	public static final String LINUX_CLA = "{0} " + STAY_OPEN + " true -@ {1}";
 
-    /**
-     * Command line argument to start ExifTool on a Mac based computer.
-     */
-    public static final String MAC_CLA = "{0} " + STAY_OPEN + " true -@ \"{1}\"";
+	/**
+	 * Command line argument to start ExifTool on a Mac based computer.
+	 */
+	public static final String MAC_CLA = "{0} " + STAY_OPEN + " true -@ \"{1}\"";
 
-    /**
-     * A list of ExifTool warnings that should be ignored by the result parser.
-     */
-    public static final String[] WARNINGS_TO_IGNORE = {};
+	/**
+	 * A list of ExifTool warnings that should be ignored by the result parser.
+	 */
+	public static final String[] WARNINGS_TO_IGNORE = {};
 
 }

src/be/pw/jexif/internal/result/IResultParser.java

 	 * @param actionUID the UID of the action.
 	 * @param result the list with the output of ExifTool. Each line printed by ExifTool should represent a single String in the list.
 	 */
-	void parse(final IAction action, final String actionUID, final List<String> result) ;
+	void parse(final IAction action, final String actionUID, final List<String> result);
 
 	/**
 	 * Returns the {@link IAction} for which this parser can be used.

src/be/pw/jexif/internal/result/ResultHandler.java

 				LOG.trace("[{}] - {} results were found", uid, result.size());
 				parser = ParserFactory.getInstance(action);
 				LOG.trace("[{}] - Parser {} was retreived", uid, parser.getClass().getSimpleName());
-				List<String> fixedResult = new ArrayList<>();	//quick fix for concurrent modification exception
+				List<String> fixedResult = new ArrayList<>(); // quick fix for concurrent modification exception
 				fixedResult.addAll(result);
 				parser.parse(action, uid, fixedResult);
 			} catch (JExifException e) {

src/be/pw/jexif/internal/result/impl/TagReadAllParser.java

 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
+
 /**
  * Parses the result for the {@link TagReadAllAction}
  * @author phillip
- *
  */
 class TagReadAllParser implements IResultParser {
 	/**
 	 * Logger for this class
 	 */
 	private static final Logger LOG = LoggerFactory.getLogger(TagReadAllParser.class);
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public void parse(IAction action, String actionUID, List<String> result) {
+	public void parse(final IAction action, final String actionUID, final List<String> result) {
 		Preconditions.checkArgument(validFor().isAssignableFrom(action.getClass()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
 		Preconditions.checkArgument(action.getId().equals(actionUID), "Invalid action UID");
-		
+
 		Tag t;
 		String r;
 		for (String line : result) {

src/be/pw/jexif/internal/result/impl/TagReadExactAllParser.java

 import be.pw.jexif.internal.action.IAction;
 import be.pw.jexif.internal.action.ITagReadExactAllAction;
 import be.pw.jexif.internal.result.IResultParser;
+
 /**
  * Parses the result for the {@link TagReadExactAllAction}
  * @author phillip
- *
  */
 class TagReadExactAllParser extends TagReadAllParser implements IResultParser {
 

src/be/pw/jexif/internal/result/impl/TagReadExactParser.java

 /**
  * Parses the result for the {@link TagReadExactAction}
  * @author phillip
- *
  */
 class TagReadExactParser extends TagReadParser {
 

src/be/pw/jexif/internal/result/impl/TagReadParser.java

 /**
  * Parses the result for the {@link TagReadAction}
  * @author phillip
- *
  */
 class TagReadParser implements IResultParser {
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final void parse(final IAction action, final String actionUID, final List<String> result)  {
+	public final void parse(final IAction action, final String actionUID, final List<String> result) {
 		Preconditions.checkArgument(validFor().isAssignableFrom(action.getClass()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
 		Preconditions.checkArgument(action.getId().equals(actionUID), "Invalid action UID");
-		
+
 		Tag t;
 		String r;
 		for (String line : result) {
<