diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..3cc93fb
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,2 @@
+# Include the makefiles under this directory.
+include $(call all-makefiles-under,$(call my-dir))
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..43029dd
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,32 @@
+The BSD License
+
+Copyright (c) 1999 - 2010, Adobe Systems Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or 
+without modification, are permitted provided that the following 
+conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, 
+this list of conditions and the following disclaimer.
+ 
+* Redistributions in binary form must reproduce the above copyright notice, 
+this list of conditions and the following disclaimer in the documentation 
+and/or other materials provided with the distribution.
+ 
+* Neither the name of Adobe Systems Incorporated, nor the names of its 
+contributors may be used to endorse or promote products derived from this 
+software without specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/XMPCore/Android.mk b/XMPCore/Android.mk
new file mode 100644
index 0000000..955d296
--- /dev/null
+++ b/XMPCore/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# Include all the java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 8
+
+# The name of the jar file to create.
+LOCAL_MODULE := xmp_toolkit
+
+# Build a static jar file.
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/XMPCore/src/com/adobe/xmp/XMPConst.java b/XMPCore/src/com/adobe/xmp/XMPConst.java
new file mode 100644
index 0000000..61a5ca8
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPConst.java
@@ -0,0 +1,167 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+
+/**
+ * Common constants for the XMP Toolkit. 
+ * 
+ * @since 20.01.2006
+ */
+public interface XMPConst
+{
+	// ---------------------------------------------------------------------------------------------
+	// Standard namespace URI constants
+
+
+	// Standard namespaces
+
+	/** The XML namespace for XML. */
+	String NS_XML = "http://www.w3.org/XML/1998/namespace";
+	/** The XML namespace for RDF. */
+	String NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+	/** The XML namespace for the Dublin Core schema. */
+	String NS_DC = "http://purl.org/dc/elements/1.1/";
+	/** The XML namespace for the IPTC Core schema. */
+	String NS_IPTCCORE = "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/";
+	
+	// Adobe standard namespaces
+
+	/** The XML namespace Adobe XMP Metadata. */
+	String NS_X = "adobe:ns:meta/";
+	/** */
+	String NS_IX = "http://ns.adobe.com/iX/1.0/";
+	/** The XML namespace for the XMP "basic" schema. */
+	String NS_XMP = "http://ns.adobe.com/xap/1.0/";
+	/** The XML namespace for the XMP copyright schema. */
+	String NS_XMP_RIGHTS = "http://ns.adobe.com/xap/1.0/rights/";
+	/** The XML namespace for the XMP digital asset management schema. */
+	String NS_XMP_MM = "http://ns.adobe.com/xap/1.0/mm/";
+	/** The XML namespace for the job management schema. */
+	String NS_XMP_BJ = "http://ns.adobe.com/xap/1.0/bj/";
+	/** The XML namespace for the job management schema. */
+	String NS_XMP_NOTE = "http://ns.adobe.com/xmp/note/";
+	
+	/** The XML namespace for the PDF schema. */
+	String NS_PDF = "http://ns.adobe.com/pdf/1.3/";
+	/** The XML namespace for the PDF schema. */
+	String NS_PDFX = "http://ns.adobe.com/pdfx/1.3/";
+	/** */
+	String NS_PDFX_ID = "http://www.npes.org/pdfx/ns/id/";
+	/** */
+	String NS_PDFA_SCHEMA = "http://www.aiim.org/pdfa/ns/schema#";
+	/** */
+	String NS_PDFA_PROPERTY = "http://www.aiim.org/pdfa/ns/property#";
+	/** */
+	String NS_PDFA_TYPE = "http://www.aiim.org/pdfa/ns/type#";
+	/** */
+	String NS_PDFA_FIELD = "http://www.aiim.org/pdfa/ns/field#";
+	/** */
+	String NS_PDFA_ID = "http://www.aiim.org/pdfa/ns/id/";
+	/** */
+	String NS_PDFA_EXTENSION = "http://www.aiim.org/pdfa/ns/extension/";
+	/** The XML namespace for the Photoshop custom schema. */
+	String NS_PHOTOSHOP = "http://ns.adobe.com/photoshop/1.0/";
+	/** The XML namespace for the Photoshop Album schema. */
+	String NS_PSALBUM = "http://ns.adobe.com/album/1.0/";
+	/** The XML namespace for Adobe's EXIF schema. */
+	String NS_EXIF = "http://ns.adobe.com/exif/1.0/";
+	/** */
+	String NS_EXIF_AUX = "http://ns.adobe.com/exif/1.0/aux/";
+	/** The XML namespace for Adobe's TIFF schema. */
+	String NS_TIFF = "http://ns.adobe.com/tiff/1.0/";
+	/** */
+	String NS_PNG = "http://ns.adobe.com/png/1.0/";
+	/** */
+	String NS_JPEG = "http://ns.adobe.com/jpeg/1.0/";
+	/** */
+	String NS_JP2K = "http://ns.adobe.com/jp2k/1.0/";
+	/** */
+	String NS_CAMERARAW = "http://ns.adobe.com/camera-raw-settings/1.0/";
+	/** */
+	String NS_ADOBESTOCKPHOTO = "http://ns.adobe.com/StockPhoto/1.0/";
+	/** */
+	String NS_CREATOR_ATOM = "http://ns.adobe.com/creatorAtom/1.0/";
+	/** */
+	String NS_ASF = "http://ns.adobe.com/asf/1.0/";
+	/** */
+	String NS_WAV = "http://ns.adobe.com/xmp/wav/1.0/";
+	
+	
+	// XMP namespaces that are Adobe private
+	
+	/** */
+	String NS_DM = "http://ns.adobe.com/xmp/1.0/DynamicMedia/";
+	/** */
+	String NS_TRANSIENT = "http://ns.adobe.com/xmp/transient/1.0/";	
+	/** legaciy dublin core NS, will be converted to NS_DC */
+	String NS_DC_DEPRECATED = "http://purl.org/dc/1.1/";
+	
+	
+	// XML namespace constants for qualifiers and structured property fields.
+
+	/** The XML namespace for qualifiers of the xmp:Identifier property. */
+	String TYPE_IDENTIFIERQUAL = "http://ns.adobe.com/xmp/Identifier/qual/1.0/";
+	/** The XML namespace for fields of the Dimensions type. */
+	String TYPE_DIMENSIONS = "http://ns.adobe.com/xap/1.0/sType/Dimensions#";
+	/** */
+	String TYPE_TEXT = "http://ns.adobe.com/xap/1.0/t/";
+	/** */
+	String TYPE_PAGEDFILE = "http://ns.adobe.com/xap/1.0/t/pg/";
+	/** */
+	String TYPE_GRAPHICS = "http://ns.adobe.com/xap/1.0/g/";
+	/** The XML namespace for fields of a graphical image. Used for the Thumbnail type. */
+	String TYPE_IMAGE = "http://ns.adobe.com/xap/1.0/g/img/";
+	/** */
+	String TYPE_FONT = "http://ns.adobe.com/xap/1.0/sType/Font#";
+	/** The XML namespace for fields of the ResourceEvent type. */
+	String TYPE_RESOURCEEVENT = "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#";
+	/** The XML namespace for fields of the ResourceRef type. */
+	String TYPE_RESOURCEREF = "http://ns.adobe.com/xap/1.0/sType/ResourceRef#";
+	/** The XML namespace for fields of the Version type. */
+	String TYPE_ST_VERSION = "http://ns.adobe.com/xap/1.0/sType/Version#";
+	/** The XML namespace for fields of the JobRef type. */
+	String TYPE_ST_JOB = "http://ns.adobe.com/xap/1.0/sType/Job#";
+	/** */
+	String TYPE_MANIFESTITEM = "http://ns.adobe.com/xap/1.0/sType/ManifestItem#";
+
+	
+
+	// ---------------------------------------------------------------------------------------------
+	// Basic types and constants
+
+	/**
+	 * The canonical true string value for Booleans in serialized XMP. Code that converts from the
+	 * string to a bool should be case insensitive, and even allow "1".
+	 */
+	String TRUESTR = "True";
+	/**
+	 * The canonical false string value for Booleans in serialized XMP. Code that converts from the
+	 * string to a bool should be case insensitive, and even allow "0".
+	 */
+	String FALSESTR = "False";
+	/** Index that has the meaning to be always the last item in an array. */
+	int ARRAY_LAST_ITEM = -1;
+	/** Node name of an array item. */
+	String ARRAY_ITEM_NAME = "[]";
+	/** The x-default string for localized properties */
+	String X_DEFAULT = "x-default";
+	/** xml:lang qualfifier */
+	String XML_LANG = "xml:lang";
+	/** rdf:type qualfifier */
+	String RDF_TYPE = "rdf:type";
+	
+	/** Processing Instruction (PI) for xmp packet */
+	String XMP_PI = "xpacket";
+	/** XMP meta tag version new */
+	String TAG_XMPMETA = "xmpmeta";
+	/** XMP meta tag version old */
+	String TAG_XAPMETA = "xapmeta";
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPDateTime.java b/XMPCore/src/com/adobe/xmp/XMPDateTime.java
new file mode 100644
index 0000000..505d580
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPDateTime.java
@@ -0,0 +1,102 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+
+/**
+ * The <code>XMPDateTime</code>-class represents a point in time up to a resolution of nano
+ * seconds. Dates and time in the serialized XMP are ISO 8601 strings. There are utility functions
+ * to convert to the ISO format, a <code>Calendar</code> or get the Timezone. The fields of
+ * <code>XMPDateTime</code> are:
+ * <ul>
+ * <li> month - The month in the range 1..12.
+ * <li> day - The day of the month in the range 1..31.
+ * <li> minute - The minute in the range 0..59.
+ * <li> hour - The time zone hour in the range 0..23.
+ * <li> minute - The time zone minute in the range 0..59.
+ * <li> nanoSecond - The nano seconds within a second. <em>Note:</em> if the XMPDateTime is
+ * converted into a calendar, the resolution is reduced to milli seconds.
+ * <li> timeZone - a <code>TimeZone</code>-object.
+ * </ul>
+ * DateTime values are occasionally used in cases with only a date or only a time component. A date
+ * without a time has zeros for all the time fields. A time without a date has zeros for all date
+ * fields (year, month, and day).
+ */
+public interface XMPDateTime extends Comparable
+{
+	/** @return Returns the year, can be negative. */
+	int getYear();
+	
+	/** @param year Sets the year */
+	void setYear(int year);
+
+	/** @return Returns The month in the range 1..12. */
+	int getMonth();
+
+	/** @param month Sets the month 1..12 */
+	void setMonth(int month);
+	
+	/** @return Returns the day of the month in the range 1..31. */
+	int getDay();
+	
+	/** @param day Sets the day 1..31 */
+	void setDay(int day);
+
+	/** @return Returns hour - The hour in the range 0..23. */
+	int getHour();
+
+	/** @param hour Sets the hour in the range 0..23. */
+	void setHour(int hour);
+	
+	/** @return Returns the minute in the range 0..59. */ 
+	int getMinute();
+
+	/** @param minute Sets the minute in the range 0..59. */
+	void setMinute(int minute);
+	
+	/** @return Returns the second in the range 0..59. */
+	int getSecond();
+
+	/** @param second Sets the second in the range 0..59. */
+	void setSecond(int second);
+	
+	/**
+	 * @return Returns milli-, micro- and nano seconds.
+	 * 		   Nanoseconds within a second, often left as zero?
+	 */
+	int getNanoSecond();
+
+	/**
+	 * @param nanoSecond Sets the milli-, micro- and nano seconds.
+	 *		Granularity goes down to milli seconds. 		   
+	 */
+	void setNanoSecond(int nanoSecond);
+	
+	/** @return Returns the time zone. */
+	TimeZone getTimeZone();
+
+	/** @param tz a time zone to set */
+	void setTimeZone(TimeZone tz);
+	
+	/** 
+	 * @return Returns a <code>Calendar</code> (only with milli second precision). <br>
+	 *  		<em>Note:</em> the dates before Oct 15th 1585 (which normally fall into validity of 
+	 *  		the Julian calendar) are also rendered internally as Gregorian dates. 
+	 */
+	Calendar getCalendar();
+	
+	/**
+	 * @return Returns the ISO 8601 string representation of the date and time.
+	 */
+	String getISO8601String();
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPDateTimeFactory.java b/XMPCore/src/com/adobe/xmp/XMPDateTimeFactory.java
new file mode 100644
index 0000000..ec0a116
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPDateTimeFactory.java
@@ -0,0 +1,153 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import com.adobe.xmp.impl.XMPDateTimeImpl;
+
+
+/**
+ * A factory to create <code>XMPDateTime</code>-instances from a <code>Calendar</code> or an
+ * ISO 8601 string or for the current time.
+ * 
+ * @since 16.02.2006
+ */
+public final class XMPDateTimeFactory
+{
+	/** The UTC TimeZone */
+	private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
+
+	
+
+	/** Private constructor */
+	private XMPDateTimeFactory()
+	{
+		// EMPTY
+	}
+
+
+	/**
+	 * Creates an <code>XMPDateTime</code> from a <code>Calendar</code>-object.
+	 * 
+	 * @param calendar a <code>Calendar</code>-object.
+	 * @return An <code>XMPDateTime</code>-object.
+	 */
+	public static XMPDateTime createFromCalendar(Calendar calendar)
+	{
+		return new XMPDateTimeImpl(calendar);
+	}
+
+	
+	/**
+	 * Creates an <code>XMPDateTime</code>-object from initial values.
+	 * @param year years
+	 * @param month months from 1 to 12<br>
+	 * <em>Note:</em> Remember that the month in {@link Calendar} is defined from 0 to 11.
+	 * @param day days
+	 * @param hour hours
+	 * @param minute minutes
+	 * @param second seconds
+	 * @param nanoSecond nanoseconds 
+	 * @return Returns an <code>XMPDateTime</code>-object.
+	 */
+	public static XMPDateTime create(int year, int month, int day, 
+		int hour, int minute, int second, int nanoSecond)
+	{
+		XMPDateTime dt = new XMPDateTimeImpl();
+		dt.setYear(year);
+		dt.setMonth(month);
+		dt.setDay(day);
+		dt.setHour(hour);
+		dt.setMinute(minute);
+		dt.setSecond(second);
+		dt.setNanoSecond(nanoSecond);
+		return dt;
+	}
+	
+
+	/**
+	 * Creates an <code>XMPDateTime</code> from an ISO 8601 string.
+	 * 
+	 * @param strValue The ISO 8601 string representation of the date/time.
+	 * @return An <code>XMPDateTime</code>-object.
+	 * @throws XMPException When the ISO 8601 string is non-conform
+	 */
+	public static XMPDateTime createFromISO8601(String strValue) throws XMPException
+	{
+		return new XMPDateTimeImpl(strValue);
+	}
+
+
+	/**
+	 * Obtain the current date and time.
+	 * 
+	 * @return Returns The returned time is UTC, properly adjusted for the local time zone. The
+	 *         resolution of the time is not guaranteed to be finer than seconds.
+	 */
+	public static XMPDateTime getCurrentDateTime()
+	{
+		return new XMPDateTimeImpl(new GregorianCalendar());
+	}
+
+
+	/**
+	 * Sets the local time zone without touching any other Any existing time zone value is replaced,
+	 * the other date/time fields are not adjusted in any way.
+	 * 
+	 * @param dateTime the <code>XMPDateTime</code> variable containing the value to be modified.
+	 * @return Returns an updated <code>XMPDateTime</code>-object.
+	 */
+	public static XMPDateTime setLocalTimeZone(XMPDateTime dateTime)
+	{
+		Calendar cal = dateTime.getCalendar();
+		cal.setTimeZone(TimeZone.getDefault());
+		return new XMPDateTimeImpl(cal);
+	}
+
+
+	/**
+	 * Make sure a time is UTC. If the time zone is not UTC, the time is
+	 * adjusted and the time zone set to be UTC.
+	 * 
+	 * @param dateTime
+	 *            the <code>XMPDateTime</code> variable containing the time to
+	 *            be modified.
+	 * @return Returns an updated <code>XMPDateTime</code>-object.
+	 */
+	public static XMPDateTime convertToUTCTime(XMPDateTime dateTime)
+	{
+		long timeInMillis = dateTime.getCalendar().getTimeInMillis();
+		GregorianCalendar cal = new GregorianCalendar(UTC);
+		cal.setGregorianChange(new Date(Long.MIN_VALUE));		
+		cal.setTimeInMillis(timeInMillis);
+		return new XMPDateTimeImpl(cal);
+	}
+
+
+	/**
+	 * Make sure a time is local. If the time zone is not the local zone, the time is adjusted and
+	 * the time zone set to be local.
+	 * 
+	 * @param dateTime the <code>XMPDateTime</code> variable containing the time to be modified.
+	 * @return Returns an updated <code>XMPDateTime</code>-object.
+	 */
+	public static XMPDateTime convertToLocalTime(XMPDateTime dateTime)
+	{
+		long timeInMillis = dateTime.getCalendar().getTimeInMillis();
+		// has automatically local timezone
+		GregorianCalendar cal = new GregorianCalendar(); 
+		cal.setTimeInMillis(timeInMillis);
+		return new XMPDateTimeImpl(cal);
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPError.java b/XMPCore/src/com/adobe/xmp/XMPError.java
new file mode 100644
index 0000000..c04c834
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPError.java
@@ -0,0 +1,44 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+
+/**
+ * @since   21.09.2006
+ */
+public interface XMPError
+{
+	/** */
+	int UNKNOWN = 0;
+	/** */
+	int BADPARAM = 4;
+	/** */
+	int BADVALUE = 5;
+	/** */
+	int INTERNALFAILURE = 9;
+	/** */
+	int BADSCHEMA = 101;
+	/** */
+	int BADXPATH = 102;
+	/** */
+	int BADOPTIONS = 103;
+	/** */
+	int BADINDEX = 104;
+	/** */
+	int BADSERIALIZE = 107;
+	/** */
+	int BADXML = 201;
+	/** */
+	int BADRDF = 202;
+	/** */
+	int BADXMP = 203;
+	/** <em>Note:</em> This is an error code introduced by Java. */
+	int BADSTREAM = 204;
+}
diff --git a/XMPCore/src/com/adobe/xmp/XMPException.java b/XMPCore/src/com/adobe/xmp/XMPException.java
new file mode 100644
index 0000000..087b0e8
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPException.java
@@ -0,0 +1,55 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+/**
+ * This exception wraps all errors that occur in the XMP Toolkit.
+ * 
+ * @since   16.02.2006
+ */
+public class XMPException extends Exception
+{
+	/** the errorCode of the XMP toolkit */
+	private int errorCode;
+
+
+	/**
+	 * Constructs an exception with a message and an error code. 
+	 * @param message the message
+	 * @param errorCode the error code
+	 */
+	public XMPException(String message, int errorCode)
+	{
+		super(message);
+		this.errorCode = errorCode;
+	}
+
+
+	/**
+	 * Constructs an exception with a message, an error code and a <code>Throwable</code>
+	 * @param message the error message.
+	 * @param errorCode the error code
+	 * @param t the exception source
+	 */
+	public XMPException(String message, int errorCode, Throwable t)
+	{
+		super(message, t);
+		this.errorCode = errorCode;
+	}
+
+
+	/**
+	 * @return Returns the errorCode.
+	 */
+	public int getErrorCode()
+	{
+		return errorCode;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPIterator.java b/XMPCore/src/com/adobe/xmp/XMPIterator.java
new file mode 100644
index 0000000..fa4edf6
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPIterator.java
@@ -0,0 +1,82 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import java.util.Iterator;
+
+
+/**
+ * Interface for the <code>XMPMeta</code> iteration services.
+ * <code>XMPIterator</code> provides a uniform means to iterate over the
+ * schema and properties within an XMP object.
+ * <p>
+ * The iteration over the schema and properties within an XMP object is very
+ * complex. It is helpful to have a thorough understanding of the XMP data tree.
+ * One way to learn this is to create some complex XMP and examine the output of
+ * <code>XMPMeta#toString</code>. This is also described in the XMP
+ * Specification, in the XMP Data Model chapter.
+ * <p>
+ * The top of the XMP data tree is a single root node. This does not explicitly
+ * appear in the dump and is never visited by an iterator (that is, it is never
+ * returned from <code>XMPIterator#next()</code>). Beneath the root are
+ * schema nodes. These are just collectors for top level properties in the same
+ * namespace. They are created and destroyed implicitly. Beneath the schema
+ * nodes are the property nodes. The nodes below a property node depend on its
+ * type (simple, struct, or array) and whether it has qualifiers.
+ * <p>
+ * An <code>XMPIterator</code> is created by XMPMeta#interator() constructor
+ * defines a starting point for the iteration and options that control how it
+ * proceeds. By default the iteration starts at the root and visits all nodes
+ * beneath it in a depth first manner. The root node is not visited, the first
+ * visited node is a schema node. You can provide a schema name or property path
+ * to select a different starting node. By default this visits the named root
+ * node first then all nodes beneath it in a depth first manner.
+ * <p>
+ * The <code>XMPIterator#next()</code> method delivers the schema URI, path,
+ * and option flags for the node being visited. If the node is simple it also
+ * delivers the value. Qualifiers for this node are visited next. The fields of
+ * a struct or items of an array are visited after the qualifiers of the parent.
+ * <p>
+ * The options to control the iteration are:
+ * <ul>
+ * <li>JUST_CHILDREN - Visit just the immediate children of the root. Skip
+ * the root itself and all nodes below the immediate children. This omits the
+ * qualifiers of the immediate children, the qualifier nodes being below what
+ * they qualify, default is to visit the complete subtree.
+ * <li>UST_LEAFNODES - Visit just the leaf property nodes and their
+ * qualifiers.
+ * <li>JUST_LEAFNAME - Return just the leaf component of the node names.
+ * The default is to return the full xmp path.
+ * <li>OMIT_QUALIFIERS - Do not visit the qualifiers.
+ * <li>INCLUDE_ALIASES - Adds known alias properties to the properties in the iteration.
+ * 		<em>Note:</em> Not supported in Java XMPCore! 
+ * </ul>
+ * <p>
+ * <code>next()</code> returns <code>XMPPropertyInfo</code>-objects and throws
+ * a <code>NoSuchElementException</code> if there are no more properties to
+ * return.
+ * 
+ * @since 25.01.2006
+ */
+public interface XMPIterator extends Iterator
+{
+	/**
+	 * Skip the subtree below the current node when <code>next()</code> is
+	 * called.
+	 */
+	void skipSubtree();
+
+
+	/**
+	 * Skip the subtree below and remaining siblings of the current node when
+	 * <code>next()</code> is called.
+	 */
+	void skipSiblings();
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPMeta.java b/XMPCore/src/com/adobe/xmp/XMPMeta.java
new file mode 100644
index 0000000..dab0502
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPMeta.java
@@ -0,0 +1,1176 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import java.util.Calendar;
+
+import com.adobe.xmp.options.IteratorOptions;
+import com.adobe.xmp.options.ParseOptions;
+import com.adobe.xmp.options.PropertyOptions;
+import com.adobe.xmp.properties.XMPProperty;
+
+
+/**
+ * This class represents the set of XMP metadata as a DOM representation. It has methods to read and
+ * modify all kinds of properties, create an iterator over all properties and serialize the metadata
+ * to a String, byte-array or <code>OutputStream</code>.
+ * 
+ * @since 20.01.2006
+ */
+public interface XMPMeta extends Cloneable
+{
+	// ---------------------------------------------------------------------------------------------
+	// Basic property manipulation functions
+
+	/**
+	 * The property value getter-methods all take a property specification: the first two parameters
+	 * are always the top level namespace URI (the &quot;schema&quot; namespace) and the basic name
+	 * of the property being referenced. See the introductory discussion of path expression usage
+	 * for more information.
+	 * <p>
+	 * All of the functions return an object inherited from <code>PropertyBase</code> or
+	 * <code>null</code> if the property does not exists. The result object contains the value of
+	 * the property and option flags describing the property. Arrays and the non-leaf levels of
+	 * nodes do not have values.
+	 * <p>
+	 * See {@link PropertyOptions} for detailed information about the options.
+	 * <p>
+	 * This is the simplest property getter, mainly for top level simple properties or after using
+	 * the path composition functions in XMPPathFactory.
+	 * 
+	 * @param schemaNS The namespace URI for the property. May be <code>null</code> or the empty
+	 *        string if the first component of the propName path contains a namespace prefix. The
+	 *        URI must be for a registered namespace.
+	 * @param propName The name of the property. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Using a namespace prefix on the first
+	 *        component is optional. If present without a schemaNS value then the prefix specifies
+	 *        the namespace. The prefix must be for a registered namespace. If both a schemaNS URI
+	 *        and propName prefix are present, they must be corresponding parts of a registered
+	 *        namespace.
+	 * @return Returns a <code>XMPProperty</code> containing the value and the options or
+	 *         <code>null</code> if the property does not exist.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPProperty getProperty(String schemaNS, String propName) throws XMPException;
+
+	
+	/**
+	 * Provides access to items within an array. The index is passed as an integer, you need not
+	 * worry about the path string syntax for array items, convert a loop index to a string, etc.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param itemIndex The index of the desired item. Arrays in XMP are indexed from 1. The
+	 *        constant {@link XMPConst#ARRAY_LAST_ITEM} always refers to the last existing array
+	 *        item.
+	 * @return Returns a <code>XMPProperty</code> containing the value and the options or
+	 *         <code>null</code> if the property does not exist.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPProperty getArrayItem(String schemaNS, String arrayName, int itemIndex) throws XMPException;
+
+
+	/**
+	 * Returns the number of items in the array.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @return Returns the number of items in the array.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	int countArrayItems(String schemaNS, String arrayName) throws XMPException;
+
+
+	/**
+	 * Provides access to fields within a nested structure. The namespace for the field is passed as
+	 * a URI, you need not worry about the path string syntax.
+	 * <p>
+	 * The names of fields should be XML qualified names, that is within an XML namespace. The path
+	 * syntax for a qualified name uses the namespace prefix. This is unreliable since the prefix is
+	 * never guaranteed. The URI is the formal name, the prefix is just a local shorthand in a given
+	 * sequence of XML text.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in getProperty.
+	 * @param structName The name of the struct. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param fieldNS The namespace URI for the field. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param fieldName The name of the field. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        structName parameter.
+	 * @return Returns a <code>XMPProperty</code> containing the value and the options or
+	 *         <code>null</code> if the property does not exist. Arrays and non-leaf levels of
+	 *         structs do not have values.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPProperty getStructField(
+		String schemaNS,
+		String structName,
+		String fieldNS,
+		String fieldName) throws XMPException;
+
+
+	/**
+	 * Provides access to a qualifier attached to a property. The namespace for the qualifier is
+	 * passed as a URI, you need not worry about the path string syntax. In many regards qualifiers
+	 * are like struct fields. See the introductory discussion of qualified properties for more
+	 * information.
+	 * <p>
+	 * The names of qualifiers should be XML qualified names, that is within an XML namespace. The
+	 * path syntax for a qualified name uses the namespace prefix. This is unreliable since the
+	 * prefix is never guaranteed. The URI is the formal name, the prefix is just a local shorthand
+	 * in a given sequence of XML text.
+	 * <p>
+	 * <em>Note:</em> Qualifiers are only supported for simple leaf properties at this time.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in getProperty.
+	 * @param propName The name of the property to which the qualifier is attached. May be a general
+	 *        path expression, must not be <code>null</code> or the empty string. Has the same
+	 *        namespace prefix usage as in <code>getProperty()</code>.
+	 * @param qualNS The namespace URI for the qualifier. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param qualName The name of the qualifier. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        propName parameter.
+	 * @return Returns a <code>XMPProperty</code> containing the value and the options of the
+	 *         qualifier or <code>null</code> if the property does not exist. The name of the
+	 *         qualifier must be a single XML name, must not be <code>null</code> or the empty
+	 *         string. Has the same namespace prefix usage as the propName parameter.
+	 *         <p>
+	 *         The value of the qualifier is only set if it has one (Arrays and non-leaf levels of
+	 *         structs do not have values).
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPProperty getQualifier(
+		String schemaNS,
+		String propName,
+		String qualNS,
+		String qualName) throws XMPException;
+
+	
+
+	// ---------------------------------------------------------------------------------------------
+	// Functions for setting property values
+
+	/**
+	 * The property value <code>setters</code> all take a property specification, their
+	 * differences are in the form of this. The first two parameters are always the top level
+	 * namespace URI (the <code>schema</code> namespace) and the basic name of the property being
+	 * referenced. See the introductory discussion of path expression usage for more information.
+	 * <p>
+	 * All of the functions take a string value for the property and option flags describing the
+	 * property. The value must be Unicode in UTF-8 encoding. Arrays and non-leaf levels of structs
+	 * do not have values. Empty arrays and structs may be created using appropriate option flags.
+	 * All levels of structs that is assigned implicitly are created if necessary. appendArayItem
+	 * implicitly creates the named array if necessary.
+	 * <p>
+	 * See {@link PropertyOptions} for detailed information about the options.
+	 * <p>
+	 * This is the simplest property setter, mainly for top level simple properties or after using
+	 * the path composition functions in {@link XMPPathFactory}.
+	 * 
+	 * @param schemaNS The namespace URI for the property. Has the same usage as in getProperty.
+	 * @param propName The name of the property. 
+	 * 				   Has the same usage as in <code>getProperty()</code>.
+	 * @param propValue the value for the property (only leaf properties have a value). 
+	 *        Arrays and non-leaf levels of structs do not have values. 
+	 *        Must be <code>null</code> if the value is not relevant.<br/>
+	 *        The value is automatically detected: Boolean, Integer, Long, Double, XMPDateTime and
+	 *        byte[] are handled, on all other <code>toString()</code> is called.   
+	 *        
+	 * @param options Option flags describing the property. See the earlier description.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void setProperty(
+		String schemaNS,
+		String propName, 
+		Object propValue, 
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setProperty(String, String, Object, PropertyOptions)
+	 *  
+	 * @param schemaNS The namespace URI
+	 * @param propName The name of the property 
+	 * @param propValue the value for the property   
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void setProperty(
+			String schemaNS,
+			String propName, 
+			Object propValue) throws XMPException;
+
+	
+	/**
+	 * Replaces an item within an array. The index is passed as an integer, you need not worry about
+	 * the path string syntax for array items, convert a loop index to a string, etc. The array
+	 * passed must already exist. In normal usage the selected array item is modified. A new item is
+	 * automatically appended if the index is the array size plus 1.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in getProperty.
+	 * @param itemIndex The index of the desired item. Arrays in XMP are indexed from 1. To address
+	 *        the last existing item, use {@link XMPMeta#countArrayItems(String, String)} to find
+	 *        out the length of the array.
+	 * @param itemValue the new value of the array item. Has the same usage as propValue in
+	 *        <code>setProperty()</code>.
+	 * @param options the set options for the item. 
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void setArrayItem(
+		String schemaNS,
+		String arrayName,
+		int itemIndex,
+		String itemValue,
+		PropertyOptions options) throws XMPException;	
+
+	
+	/**
+	 * @see XMPMeta#setArrayItem(String, String, int, String, PropertyOptions)
+	 *  
+	 * @param schemaNS The namespace URI
+	 * @param arrayName The name of the array
+	 * @param itemIndex The index to insert the new item
+	 * @param itemValue the new value of the array item
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void setArrayItem(
+			String schemaNS,
+			String arrayName,
+			int itemIndex,
+			String itemValue) throws XMPException;	
+
+	
+	/**
+	 * Inserts an item into an array previous to the given index. The index is passed as an integer,
+	 * you need not worry about the path string syntax for array items, convert a loop index to a
+	 * string, etc. The array passed must already exist. In normal usage the selected array item is
+	 * modified. A new item is automatically appended if the index is the array size plus 1.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in getProperty.
+	 * @param itemIndex The index to insert the new item. Arrays in XMP are indexed from 1. Use
+	 * 		  <code>XMPConst.ARRAY_LAST_ITEM</code> to append items.
+	 * @param itemValue the new value of the array item. Has the same usage as
+	 *        propValue in <code>setProperty()</code>.
+	 * @param options the set options that decide about the kind of the node.
+ 	 * @throws XMPException Wraps all errors and exceptions that may occur.
+ 	 */
+	void insertArrayItem(
+		String schemaNS,
+		String arrayName,
+		int itemIndex,
+		String itemValue,
+		PropertyOptions options) throws XMPException;	
+	
+	
+	/**
+	 * @see XMPMeta#insertArrayItem(String, String, int, String, PropertyOptions)
+	 * 
+	 * @param schemaNS The namespace URI for the array
+	 * @param arrayName The name of the array
+	 * @param itemIndex The index to insert the new item
+	 * @param itemValue the value of the array item
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void insertArrayItem(
+			String schemaNS,
+			String arrayName,
+			int itemIndex,
+			String itemValue) throws XMPException;	
+
+	
+	/**
+	 * Simplifies the construction of an array by not requiring that you pre-create an empty array.
+	 * The array that is assigned is created automatically if it does not yet exist. Each call to
+	 * appendArrayItem() appends an item to the array. The corresponding parameters have the same
+	 * use as setArrayItem(). The arrayOptions parameter is used to specify what kind of array. If
+	 * the array exists, it must have the specified form.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be null or
+	 *        the empty string. Has the same namespace prefix usage as propPath in getProperty.
+	 * @param arrayOptions Option flags describing the array form. The only valid options are
+	 *        <ul>
+	 *        <li> {@link PropertyOptions#ARRAY},
+	 *        <li> {@link PropertyOptions#ARRAY_ORDERED},
+	 *        <li> {@link PropertyOptions#ARRAY_ALTERNATE} or
+	 *        <li> {@link PropertyOptions#ARRAY_ALT_TEXT}.
+	 *        </ul>
+	 *        <em>Note:</em> the array options only need to be provided if the array is not 
+	 *        already existing, otherwise you can set them to <code>null</code> or use
+	 *        {@link XMPMeta#appendArrayItem(String, String, String)}.
+	 * @param itemValue the value of the array item. Has the same usage as propValue in getProperty.
+	 * @param itemOptions Option flags describing the item to append ({@link PropertyOptions})
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void appendArrayItem(
+		String schemaNS,
+		String arrayName,
+		PropertyOptions arrayOptions,
+		String itemValue,
+		PropertyOptions itemOptions) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#appendArrayItem(String, String, PropertyOptions, String, PropertyOptions)
+	 * 
+	 * @param schemaNS The namespace URI for the array
+	 * @param arrayName The name of the array
+	 * @param itemValue the value of the array item
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void appendArrayItem(
+			String schemaNS,
+			String arrayName,
+			String itemValue) throws XMPException;
+	
+
+	/**
+	 * Provides access to fields within a nested structure. The namespace for the field is passed as
+	 * a URI, you need not worry about the path string syntax. The names of fields should be XML
+	 * qualified names, that is within an XML namespace. The path syntax for a qualified name uses
+	 * the namespace prefix, which is unreliable because the prefix is never guaranteed. The URI is
+	 * the formal name, the prefix is just a local shorthand in a given sequence of XML text.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in getProperty.
+	 * @param structName The name of the struct. May be a general path expression, must not be null
+	 *        or the empty string. Has the same namespace prefix usage as propName in getProperty.
+	 * @param fieldNS The namespace URI for the field. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param fieldName The name of the field. Must be a single XML name, must not be null or the
+	 *        empty string. Has the same namespace prefix usage as the structName parameter.
+	 * @param fieldValue the value of thefield, if the field has a value. 
+	 *        Has the same usage as propValue in getProperty.
+	 * @param options Option flags describing the field. See the earlier description.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void setStructField(
+		String schemaNS,
+		String structName,
+		String fieldNS,
+		String fieldName,
+		String fieldValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setStructField(String, String, String, String, String, PropertyOptions)
+	 * 
+	 * @param schemaNS The namespace URI for the struct
+	 * @param structName The name of the struct
+	 * @param fieldNS The namespace URI for the field
+	 * @param fieldName The name of the field
+	 * @param fieldValue the value of the field
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void setStructField(
+			String schemaNS,
+			String structName,
+			String fieldNS,
+			String fieldName,
+			String fieldValue) throws XMPException;
+	
+
+	/**
+	 * Provides access to a qualifier attached to a property. The namespace for the qualifier is
+	 * passed as a URI, you need not worry about the path string syntax. In many regards qualifiers
+	 * are like struct fields. See the introductory discussion of qualified properties for more
+	 * information. The names of qualifiers should be XML qualified names, that is within an XML
+	 * namespace. The path syntax for a qualified name uses the namespace prefix, which is
+	 * unreliable because the prefix is never guaranteed. The URI is the formal name, the prefix is
+	 * just a local shorthand in a given sequence of XML text. The property the qualifier
+	 * will be attached has to exist.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in getProperty.
+	 * @param propName The name of the property to which the qualifier is attached. Has the same
+	 *        usage as in getProperty.
+	 * @param qualNS The namespace URI for the qualifier. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param qualName The name of the qualifier. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        propName parameter.
+	 * @param qualValue A pointer to the <code>null</code> terminated UTF-8 string that is the
+	 *        value of the qualifier, if the qualifier has a value. Has the same usage as propValue
+	 *        in getProperty.
+	 * @param options Option flags describing the qualifier. See the earlier description.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void setQualifier(
+		String schemaNS,
+		String propName,
+		String qualNS,
+		String qualName,
+		String qualValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setQualifier(String, String, String, String, String, PropertyOptions)
+	 * 
+	 * @param schemaNS The namespace URI for the struct
+	 * @param propName The name of the property to which the qualifier is attached
+	 * @param qualNS The namespace URI for the qualifier
+	 * @param qualName The name of the qualifier
+	 * @param qualValue the value of the qualifier
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void setQualifier(
+			String schemaNS,
+			String propName,
+			String qualNS,
+			String qualName,
+			String qualValue) throws XMPException;
+	
+	
+	
+	// ---------------------------------------------------------------------------------------------
+	// Functions for deleting and detecting properties. These should be obvious from the
+	// descriptions of the getters and setters.
+
+	/**
+	 * Deletes the given XMP subtree rooted at the given property. It is not an error if the
+	 * property does not exist.
+	 * 
+	 * @param schemaNS The namespace URI for the property. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param propName The name of the property. Has the same usage as in getProperty.
+	 */
+	void deleteProperty(String schemaNS, String propName);
+
+
+	/**
+	 * Deletes the given XMP subtree rooted at the given array item. It is not an error if the array
+	 * item does not exist.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in getProperty.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param itemIndex The index of the desired item. Arrays in XMP are indexed from 1. The
+	 *        constant <code>XMPConst.ARRAY_LAST_ITEM</code> always refers to the last
+	 *        existing array item.
+	 */
+	void deleteArrayItem(String schemaNS, String arrayName, int itemIndex);
+
+
+	/**
+	 * Deletes the given XMP subtree rooted at the given struct field. It is not an error if the
+	 * field does not exist.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param structName The name of the struct. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in getProperty.
+	 * @param fieldNS The namespace URI for the field. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param fieldName The name of the field. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        structName parameter.
+	 */
+	void deleteStructField(String schemaNS, String structName, String fieldNS, String fieldName);
+
+
+	/**
+	 * Deletes the given XMP subtree rooted at the given qualifier. It is not an error if the
+	 * qualifier does not exist.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param propName The name of the property to which the qualifier is attached. Has the same
+	 *        usage as in getProperty.
+	 * @param qualNS The namespace URI for the qualifier. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param qualName The name of the qualifier. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        propName parameter.
+	 */
+	void deleteQualifier(String schemaNS, String propName, String qualNS, String qualName);
+
+
+	/**
+	 * Returns whether the property exists.
+	 * 
+	 * @param schemaNS The namespace URI for the property. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param propName The name of the property. 
+	 * 		  Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns true if the property exists.
+	 */
+	boolean doesPropertyExist(String schemaNS, String propName);
+
+
+	/**
+	 * Tells if the array item exists.
+	 * 
+	 * @param schemaNS The namespace URI for the array. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param itemIndex The index of the desired item. Arrays in XMP are indexed from 1. The
+	 *        constant <code>XMPConst.ARRAY_LAST_ITEM</code> always refers to the last
+	 *        existing array item.
+	 * @return Returns <code>true</code> if the array exists, <code>false</code> otherwise.
+	 */
+	boolean doesArrayItemExist(String schemaNS, String arrayName, int itemIndex);
+
+
+	/**
+	 * DoesStructFieldExist tells if the struct field exists.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param structName The name of the struct. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param fieldNS The namespace URI for the field. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param fieldName The name of the field. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        structName parameter.
+	 * @return Returns true if the field exists.
+	 */
+	boolean doesStructFieldExist(
+		String schemaNS, 
+		String structName, 
+		String fieldNS,
+		String fieldName);
+
+
+	/**
+	 * DoesQualifierExist tells if the qualifier exists.
+	 * 
+	 * @param schemaNS The namespace URI for the struct. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param propName The name of the property to which the qualifier is attached. Has the same
+	 *        usage as in <code>getProperty()</code>.
+	 * @param qualNS The namespace URI for the qualifier. Has the same URI and prefix usage as the
+	 *        schemaNS parameter.
+	 * @param qualName The name of the qualifier. Must be a single XML name, must not be
+	 *        <code>null</code> or the empty string. Has the same namespace prefix usage as the
+	 *        propName parameter.
+	 * @return Returns true if the qualifier exists.
+	 */
+	boolean doesQualifierExist(String schemaNS, String propName, String qualNS, String qualName);
+
+
+	// ---------------------------------------------------------------------------------------------
+	// Specialized Get and Set functions
+
+	/**
+	 * These functions provide convenient support for localized text properties, including a number
+	 * of special and obscure aspects. Localized text properties are stored in alt-text arrays. They
+	 * allow multiple concurrent localizations of a property value, for example a document title or
+	 * copyright in several languages. The most important aspect of these functions is that they
+	 * select an appropriate array item based on one or two RFC 3066 language tags. One of these
+	 * languages, the "specific" language, is preferred and selected if there is an exact match. For
+	 * many languages it is also possible to define a "generic" language that may be used if there
+	 * is no specific language match. The generic language must be a valid RFC 3066 primary subtag,
+	 * or the empty string. For example, a specific language of "en-US" should be used in the US,
+	 * and a specific language of "en-UK" should be used in England. It is also appropriate to use
+	 * "en" as the generic language in each case. If a US document goes to England, the "en-US"
+	 * title is selected by using the "en" generic language and the "en-UK" specific language. It is
+	 * considered poor practice, but allowed, to pass a specific language that is just an RFC 3066
+	 * primary tag. For example "en" is not a good specific language, it should only be used as a
+	 * generic language. Passing "i" or "x" as the generic language is also considered poor practice
+	 * but allowed. Advice from the W3C about the use of RFC 3066 language tags can be found at:
+	 * http://www.w3.org/International/articles/language-tags/
+	 * <p>
+	 * <em>Note:</em> RFC 3066 language tags must be treated in a case insensitive manner. The XMP
+	 * Toolkit does this by normalizing their capitalization:
+	 * <ul>
+	 * <li> The primary subtag is lower case, the suggested practice of ISO 639.
+	 * <li> All 2 letter secondary subtags are upper case, the suggested practice of ISO 3166.
+	 * <li> All other subtags are lower case. The XMP specification defines an artificial language,
+	 * <li>"x-default", that is used to explicitly denote a default item in an alt-text array.
+	 * </ul>
+	 * The XMP toolkit normalizes alt-text arrays such that the x-default item is the first item.
+	 * The SetLocalizedText function has several special features related to the x-default item, see
+	 * its description for details. The selection of the array item is the same for GetLocalizedText
+	 * and SetLocalizedText:
+	 * <ul>
+	 * <li> Look for an exact match with the specific language.
+	 * <li> If a generic language is given, look for a partial match.
+	 * <li> Look for an x-default item.
+	 * <li> Choose the first item.
+	 * </ul>
+	 * A partial match with the generic language is where the start of the item's language matches
+	 * the generic string and the next character is '-'. An exact match is also recognized as a
+	 * degenerate case. It is fine to pass x-default as the specific language. In this case,
+	 * selection of an x-default item is an exact match by the first rule, not a selection by the
+	 * 3rd rule. The last 2 rules are fallbacks used when the specific and generic languages fail to
+	 * produce a match. <code>getLocalizedText</code> returns information about a selected item in
+	 * an alt-text array. The array item is selected according to the rules given above.
+	 * 
+	 * <em>Note:</em> In a future version of this API a method 
+	 * 		using Java <code>java.lang.Locale</code> will be added.
+	 * 
+	 * @param schemaNS The namespace URI for the alt-text array. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param altTextName The name of the alt-text array. May be a general path expression, must not
+	 *        be <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param genericLang The name of the generic language as an RFC 3066 primary subtag. May be
+	 *        <code>null</code> or the empty string if no generic language is wanted.
+	 * @param specificLang The name of the specific language as an RFC 3066 tag. Must not be
+	 *        <code>null</code> or the empty string.
+	 * @return Returns an <code>XMPProperty</code> containing the value, the actual language and 
+	 * 		   the options if an appropriate alternate collection item exists, <code>null</code> 
+	 * 		  if the property.
+	 *         does not exist.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPProperty getLocalizedText(
+		String schemaNS, 
+		String altTextName,
+		String genericLang,
+		String specificLang) throws XMPException;
+
+
+	/**
+	 * Modifies the value of a selected item in an alt-text array. Creates an appropriate array item
+	 * if necessary, and handles special cases for the x-default item. If the selected item is from
+	 * a match with the specific language, the value of that item is modified. If the existing value
+	 * of that item matches the existing value of the x-default item, the x-default item is also
+	 * modified. If the array only has 1 existing item (which is not x-default), an x-default item
+	 * is added with the given value. If the selected item is from a match with the generic language
+	 * and there are no other generic matches, the value of that item is modified. If the existing
+	 * value of that item matches the existing value of the x-default item, the x-default item is
+	 * also modified. If the array only has 1 existing item (which is not x-default), an x-default
+	 * item is added with the given value. If the selected item is from a partial match with the
+	 * generic language and there are other partial matches, a new item is created for the specific
+	 * language. The x-default item is not modified. If the selected item is from the last 2 rules
+	 * then a new item is created for the specific language. If the array only had an x-default
+	 * item, the x-default item is also modified. If the array was empty, items are created for the
+	 * specific language and x-default.
+	 * 
+	 * <em>Note:</em> In a future version of this API a method 
+	 * 		using Java <code>java.lang.Locale</code> will be added.
+	 * 
+	 * 
+	 * @param schemaNS The namespace URI for the alt-text array. Has the same usage as in
+	 *        <code>getProperty()</code>.
+	 * @param altTextName The name of the alt-text array. May be a general path expression, must not
+	 *        be <code>null</code> or the empty string. Has the same namespace prefix usage as
+	 *        propName in <code>getProperty()</code>.
+	 * @param genericLang The name of the generic language as an RFC 3066 primary subtag. May be
+	 *        <code>null</code> or the empty string if no generic language is wanted.
+	 * @param specificLang The name of the specific language as an RFC 3066 tag. Must not be
+	 *        <code>null</code> or the empty string.
+	 * @param itemValue A pointer to the <code>null</code> terminated UTF-8 string that is the new
+	 *        value for the appropriate array item.
+	 * @param options Option flags, none are defined at present.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void setLocalizedText(
+		String schemaNS,
+		String altTextName,
+		String genericLang,
+		String specificLang,
+		String itemValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setLocalizedText(String, String, String, String, String, PropertyOptions)
+	 * 
+	 * @param schemaNS The namespace URI for the alt-text array
+	 * @param altTextName The name of the alt-text array
+	 * @param genericLang The name of the generic language
+	 * @param specificLang The name of the specific language
+	 * @param itemValue the new value for the appropriate array item
+	 * @throws XMPException Wraps all errors and exceptions
+	 */
+	void setLocalizedText(
+			String schemaNS,
+			String altTextName,
+			String genericLang,
+			String specificLang,
+			String itemValue) throws XMPException;
+
+	
+	
+	// ---------------------------------------------------------------------------------------------
+	// Functions accessing properties as binary values.
+
+	
+	/**
+	 * These are very similar to <code>getProperty()</code> and <code>SetProperty()</code> above, 
+	 * but the value is returned or provided in a literal form instead of as a UTF-8 string. 
+	 * The path composition functions in <code>XMPPathFactory</code> may be used to compose an path 
+	 * expression for fields in nested structures, items in arrays, or qualifiers.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>Boolean</code> value or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	Boolean getPropertyBoolean(String schemaNS, String propName) throws XMPException;
+	
+
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns an <code>Integer</code> value or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	Integer getPropertyInteger(String schemaNS, String propName) throws XMPException;
+	
+
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>Long</code> value or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	Long getPropertyLong(String schemaNS, String propName) throws XMPException;
+	
+
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>Double</code> value or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	Double getPropertyDouble(String schemaNS, String propName) throws XMPException;
+	
+
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>XMPDateTime</code>-object or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	XMPDateTime getPropertyDate(String schemaNS, String propName) throws XMPException;
+
+	
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a Java <code>Calendar</code>-object or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	Calendar getPropertyCalendar(String schemaNS, String propName) throws XMPException;
+
+	
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>byte[]</code>-array contained the decoded base64 value 
+	 * 		   or <code>null</code> if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	byte[] getPropertyBase64(String schemaNS, String propName) throws XMPException;
+
+	
+	/**
+	 * Convenience method to retrieve the literal value of a property.
+	 * <em>Note:</em> There is no <code>setPropertyString()</code>, 
+	 * because <code>setProperty()</code> sets a string value.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>getProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @return Returns a <code>String</code> value or <code>null</code> 
+	 * 		   if the property does not exist.
+	 * @throws XMPException Wraps all exceptions that may occur, 
+	 * 		   especially conversion errors.
+	 */
+	String getPropertyString(String schemaNS, String propName) throws XMPException;
+	
+
+	/**
+	 * Convenience method to set a property to a literal <code>boolean</code> value.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the literal property value as <code>boolean</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyBoolean(
+		String schemaNS,
+		String propName,
+		boolean propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyBoolean(String, String, boolean, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the literal property value as <code>boolean</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyBoolean(
+			String schemaNS,
+			String propName,
+			boolean propValue) throws XMPException;
+	
+	
+	/**
+	 * Convenience method to set a property to a literal <code>int</code> value.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the literal property value as <code>int</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyInteger(
+		String schemaNS,
+		String propName,
+		int propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyInteger(String, String, int, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the literal property value as <code>int</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyInteger(
+			String schemaNS,
+			String propName,
+			int propValue) throws XMPException;
+	
+
+	/**
+	 * Convenience method to set a property to a literal <code>long</code> value.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the literal property value as <code>long</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyLong(
+		String schemaNS,
+		String propName,
+		long propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyLong(String, String, long, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the literal property value as <code>long</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyLong(
+			String schemaNS,
+			String propName,
+			long propValue) throws XMPException;
+	
+
+	/**
+	 * Convenience method to set a property to a literal <code>double</code> value.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the literal property value as <code>double</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyDouble(
+		String schemaNS,
+		String propName,
+		double propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyDouble(String, String, double, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the literal property value as <code>double</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyDouble(
+			String schemaNS,
+			String propName,
+			double propValue) throws XMPException;
+	
+
+	/**
+	 * Convenience method to set a property with an XMPDateTime-object, 
+	 * which is serialized to an ISO8601 date.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the property value as <code>XMPDateTime</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyDate(
+		String schemaNS,
+		String propName,
+		XMPDateTime propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyDate(String, String, XMPDateTime, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the property value as <code>XMPDateTime</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyDate(
+			String schemaNS,
+			String propName,
+			XMPDateTime propValue) throws XMPException;
+	
+	
+	/**
+	 * Convenience method to set a property with a Java Calendar-object, 
+	 * which is serialized to an ISO8601 date.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the property value as Java <code>Calendar</code>.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyCalendar(
+		String schemaNS,
+		String propName,
+		Calendar propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyCalendar(String, String, Calendar, PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the property value as <code>Calendar</code>
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyCalendar(
+			String schemaNS,
+			String propName,
+			Calendar propValue) throws XMPException;
+	
+
+	/**
+	 * Convenience method to set a property from a binary <code>byte[]</code>-array, 
+	 * which is serialized as base64-string.
+	 * 
+	 * @param  schemaNS The namespace URI for the property. Has the same usage as in
+	 *         <code>setProperty()</code>.
+	 * @param  propName The name of the property.
+	 * 		   Has the same usage as in <code>getProperty()</code>.
+	 * @param  propValue the literal property value as byte array.
+	 * @param  options options of the property to set (optional).
+	 * @throws XMPException Wraps all exceptions that may occur.
+	 */
+	void setPropertyBase64(
+		String schemaNS,
+		String propName,
+		byte[] propValue,
+		PropertyOptions options) throws XMPException;
+
+	
+	/**
+	 * @see XMPMeta#setPropertyBase64(String, String, byte[], PropertyOptions)
+	 *  
+	 * @param  schemaNS The namespace URI for the property
+	 * @param  propName The name of the property
+	 * @param  propValue the literal property value as byte array
+	 * @throws XMPException Wraps all exceptions
+	 */
+	void setPropertyBase64(
+			String schemaNS,
+			String propName,
+			byte[] propValue) throws XMPException;
+	
+
+	/**
+	 * Constructs an iterator for the properties within this XMP object.
+	 * 
+	 * @return Returns an <code>XMPIterator</code>.
+	 * @see XMPMeta#iterator(String, String, IteratorOptions)
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPIterator iterator() throws XMPException;
+
+
+	/**
+	 * Constructs an iterator for the properties within this XMP object using some options.
+	 * 
+	 * @param options Option flags to control the iteration.
+	 * @return Returns an <code>XMPIterator</code>.
+	 * @see XMPMeta#iterator(String, String, IteratorOptions)
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPIterator iterator(IteratorOptions options) throws XMPException;
+
+
+	/**
+	 * Construct an iterator for the properties within an XMP object. The general operation of an
+	 * XMP object iterator was. According to the parameters it iterates the entire data tree,
+	 * properties within a specific schema, or a subtree rooted at a specific node.
+	 * 
+	 * @param schemaNS Optional schema namespace URI to restrict the iteration. Omitted (visit all
+	 *        schema) by passing <code>null</code> or empty String.
+	 * @param propName Optional property name to restrict the iteration. May be an arbitrary path
+	 *        expression. Omitted (visit all properties) by passing <code>null</code> or empty
+	 *        String. If no schema URI is given, it is ignored.
+	 * @param options Option flags to control the iteration. See {@link IteratorOptions} for
+	 *        details.
+	 * @return Returns an <code>XMPIterator</code> for this <code>XMPMeta</code>-object
+	 *         considering the given options.
+	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	XMPIterator iterator(
+		String schemaNS,
+		String propName,
+		IteratorOptions options) throws XMPException;
+
+
+	/**
+	 * This correlates to the about-attribute,
+	 * returns the empty String if no name is set.
+	 * 
+	 * @return Returns the name of the XMP object.
+	 */
+	String getObjectName();
+
+
+	/**
+	 * @param name Sets the name of the XMP object.
+	 */
+	void setObjectName(String name);
+
+	
+	/**
+	 * @return Returns the unparsed content of the &lt;?xpacket&gt; processing instruction.
+	 * 		This contains normally the attribute-like elements 'begin="&lt;BOM&gt;"
+	 *		id="W5M0MpCehiHzreSzNTczkc9d"' and possibly the deprecated elements 'bytes="1234"' or
+	 * 		'encoding="XXX"'. If the parsed packet has not been wrapped into an xpacket,
+	 * 		<code>null</code> is returned.   
+	 */
+	String getPacketHeader();
+	
+
+	/**
+	 * Clones the complete metadata tree.
+	 * 
+	 * @return Returns a deep copy of this instance.
+	 */
+	Object clone();
+
+	
+	/**
+	 * Sorts the complete datamodel according to the following rules:
+	 * <ul>
+	 * 		<li>Schema nodes are sorted by prefix. 
+	 * 		<li>Properties at top level and within structs are sorted by full name, that is 
+	 * 			prefix + local name.
+	 * 		<li>Array items are not sorted, even if they have no certain order such as bags.
+	 * 		<li>Qualifier are sorted, with the exception of "xml:lang" and/or "rdf:type" 
+	 * 			that stay at the top of the list in that order.  
+	 * </ul>
+	 */
+	void sort();
+	
+	
+	/**
+	 * Perform the normalization as a separate parsing step.
+	 * Normally it is done during parsing, unless the parsing option
+	 * {@link ParseOptions#OMIT_NORMALIZATION} is set to <code>true</code>.
+	 * <em>Note:</em> It does no harm to call this method to an already normalized xmp object. 
+	 * It was a PDF/A requirement to get hand on the unnormalized <code>XMPMeta</code> object.
+	 * 
+	 * @param options optional parsing options.
+ 	 * @throws XMPException Wraps all errors and exceptions that may occur.
+	 */
+	void normalize(ParseOptions options) throws XMPException;
+	
+	
+	/**
+	 * Renders this node and the tree unter this node in a human readable form.
+	 * @return Returns a multiline string containing the dump.
+	 */
+	String dumpObject();
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPMetaFactory.java b/XMPCore/src/com/adobe/xmp/XMPMetaFactory.java
new file mode 100644
index 0000000..afd437a
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPMetaFactory.java
@@ -0,0 +1,320 @@
+//=================================================================================================
+//ADOBE SYSTEMS INCORPORATED
+//Copyright 2006-2007 Adobe Systems Incorporated
+//All Rights Reserved
+//
+//NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+//of the Adobe license agreement accompanying it.
+//=================================================================================================
+
+package com.adobe.xmp;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.adobe.xmp.impl.XMPMetaImpl;
+import com.adobe.xmp.impl.XMPMetaParser;
+import com.adobe.xmp.impl.XMPSchemaRegistryImpl;
+import com.adobe.xmp.impl.XMPSerializerHelper;
+import com.adobe.xmp.options.ParseOptions;
+import com.adobe.xmp.options.SerializeOptions;
+
+
+/**
+ * Creates <code>XMPMeta</code>-instances from an <code>InputStream</code>
+ * 
+ * @since 30.01.2006
+ */
+public final class XMPMetaFactory
+{
+	/** The singleton instance of the <code>XMPSchemaRegistry</code>. */ 
+	private static XMPSchemaRegistry schema = new XMPSchemaRegistryImpl();
+	/** cache for version info */
+	private static XMPVersionInfo versionInfo = null;
+	
+	/**
+	 * Hides public constructor
+	 */
+	private XMPMetaFactory()
+	{
+		// EMPTY
+	}
+
+
+	/**
+	 * @return Returns the singleton instance of the <code>XMPSchemaRegistry</code>.
+	 */
+	public static XMPSchemaRegistry getSchemaRegistry()
+	{
+		return schema;
+	}
+
+	
+	/**
+	 * @return Returns an empty <code>XMPMeta</code>-object.
+	 */
+	public static XMPMeta create()
+	{
+		return new XMPMetaImpl();
+	}
+
+	
+	/**
+	 * Parsing with default options.
+	 * @see XMPMetaFactory#parse(InputStream, ParseOptions)
+	 * 
+	 * @param in an <code>InputStream</code>
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parse(InputStream in) throws XMPException
+	{
+		return parse(in, null);
+	}
+	
+
+	/**
+	 * These functions support parsing serialized RDF into an XMP object, and serailizing an XMP
+	 * object into RDF. The input for parsing may be any valid Unicode
+	 * encoding. ISO Latin-1 is also recognized, but its use is strongly discouraged. Serialization
+	 * is always as UTF-8.
+	 * <p>
+	 * <code>parseFromBuffer()</code> parses RDF from an <code>InputStream</code>. The encoding
+	 * is recognized automatically.
+	 * 
+	 * @param in an <code>InputStream</code>
+	 * @param options Options controlling the parsing.<br>
+	 *        The available options are:
+	 *        <ul>
+	 *        <li> XMP_REQUIRE_XMPMETA - The &lt;x:xmpmeta&gt; XML element is required around
+	 *        <tt>&lt;rdf:RDF&gt;</tt>.
+	 *        <li> XMP_STRICT_ALIASING - Do not reconcile alias differences, throw an exception.
+	 *        </ul>
+	 *        <em>Note:</em>The XMP_STRICT_ALIASING option is not yet implemented.
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.	
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parse(InputStream in, ParseOptions options)
+			throws XMPException
+	{
+		return XMPMetaParser.parse(in, options);
+	}
+
+	
+	/**
+	 * Parsing with default options.
+	 * @see XMPMetaFactory#parse(InputStream)
+	 * 
+	 * @param packet a String contain an XMP-file.
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parseFromString(String packet) throws XMPException
+	{
+		return parseFromString(packet, null);
+	}
+	
+
+	/**
+	 * Creates an <code>XMPMeta</code>-object from a string.
+	 * @see XMPMetaFactory#parseFromString(String, ParseOptions)
+	 * 
+	 * @param packet a String contain an XMP-file.
+	 * @param options Options controlling the parsing.
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parseFromString(String packet, ParseOptions options)
+			throws XMPException
+	{
+		return XMPMetaParser.parse(packet, options);
+	}
+
+
+	/**
+	 * Parsing with default options.
+	 * @see XMPMetaFactory#parseFromBuffer(byte[], ParseOptions)
+	 * 
+	 * @param buffer a String contain an XMP-file.
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parseFromBuffer(byte[] buffer) throws XMPException
+	{
+		return parseFromBuffer(buffer, null);
+	}
+	
+	
+	/**
+	 * Creates an <code>XMPMeta</code>-object from a byte-buffer.
+	 * @see XMPMetaFactory#parse(InputStream, ParseOptions)
+	 * 
+	 * @param buffer a String contain an XMP-file.
+	 * @param options Options controlling the parsing.
+	 * @return Returns the <code>XMPMeta</code>-object created from the input.
+	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
+	 */
+	public static XMPMeta parseFromBuffer(byte[] buffer, 
+		ParseOptions options) throws XMPException
+	{
+		return XMPMetaParser.parse(buffer, options);
+	}
+
+	
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into an <code>OutputStream</code>
+	 * with default options.
+	 * 
+	 * @param xmp a metadata object 
+	 * @param out an <code>OutputStream</code> to write the serialized RDF to.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static void serialize(XMPMeta xmp, OutputStream out) throws XMPException
+	{
+		serialize(xmp, out, null);
+	}
+
+
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into an <code>OutputStream</code>.
+	 * 
+	 * @param xmp a metadata object 
+	 * @param options Options to control the serialization (see {@link SerializeOptions}).
+	 * @param out an <code>OutputStream</code> to write the serialized RDF to.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static void serialize(XMPMeta xmp, OutputStream out, SerializeOptions options)
+			throws XMPException
+	{
+		assertImplementation(xmp);
+		XMPSerializerHelper.serialize((XMPMetaImpl) xmp, out, options);
+	}	
+	
+	
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into a byte buffer.
+	 * 
+	 * @param xmp a metadata object 
+	 * @param options Options to control the serialization (see {@link SerializeOptions}).
+	 * @return Returns a byte buffer containing the serialized RDF.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static byte[] serializeToBuffer(XMPMeta xmp, SerializeOptions options)
+			throws XMPException
+	{
+		assertImplementation(xmp);
+		return XMPSerializerHelper.serializeToBuffer((XMPMetaImpl) xmp, options);
+	}
+
+
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into a string. <em>Note:</em> Encoding
+	 * is ignored when serializing to a string.
+	 * 
+	 * @param xmp a metadata object 
+	 * @param options Options to control the serialization (see {@link SerializeOptions}).
+	 * @return Returns a string containing the serialized RDF.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static String serializeToString(XMPMeta xmp, SerializeOptions options)
+			throws XMPException
+	{
+		assertImplementation(xmp);
+		return XMPSerializerHelper.serializeToString((XMPMetaImpl) xmp, options);
+	}
+
+
+	/**
+	 * @param xmp Asserts that xmp is compatible to <code>XMPMetaImpl</code>.s
+	 */
+	private static void assertImplementation(XMPMeta xmp)
+	{
+		if (!(xmp instanceof XMPMetaImpl))
+		{
+			throw new UnsupportedOperationException("The serializing service works only" +
+				"with the XMPMeta implementation of this library");
+		}
+	}
+
+
+	/**
+	 * Resets the schema registry to its original state (creates a new one).
+	 * Be careful this might break all existing XMPMeta-objects and should be used
+	 * only for testing purpurses. 
+	 */
+	public static void reset()
+	{
+		schema = new XMPSchemaRegistryImpl();
+	}
+	
+	
+	/**
+	 * Obtain version information. The XMPVersionInfo singleton is created the first time
+	 * its requested.
+	 * 
+	 * @return Returns the version information.
+	 */
+	public static synchronized XMPVersionInfo getVersionInfo()
+	{
+		if (versionInfo == null)
+		{
+			try
+			{
+				final int major = 5;
+				final int minor = 1;
+				final int micro = 0;
+				final int engBuild = 3;
+				final boolean debug = false;
+				
+				// Adobe XMP Core 5.0-jc001 DEBUG-<branch>.<changelist>, 2009 Jan 28 15:22:38-CET
+				final String message = "Adobe XMP Core 5.1.0-jc003";
+					
+
+				versionInfo = new XMPVersionInfo()
+				{
+					public int getMajor()
+					{
+						return major;
+					}
+
+					public int getMinor()
+					{
+						return minor;
+					}
+
+					public int getMicro()
+					{
+						return micro;
+					}
+
+					public boolean isDebug()
+					{
+						return debug;
+					}
+
+					public int getBuild()
+					{
+						return engBuild;
+					}
+
+					public String getMessage()
+					{
+						return message;
+					}
+					
+					public String toString()
+					{
+						return message;
+					}
+				};
+				
+			}	
+			catch (Throwable e)
+			{
+				// EMTPY, severe error would be detected during the tests
+				System.out.println(e);
+			}
+		}
+		return versionInfo;
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/XMPPathFactory.java b/XMPCore/src/com/adobe/xmp/XMPPathFactory.java
new file mode 100644
index 0000000..9d8f632
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPPathFactory.java
@@ -0,0 +1,291 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import com.adobe.xmp.impl.Utils;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathParser;
+
+/**
+ * Utility services for the metadata object. It has only public static functions, you cannot create
+ * an object. These are all functions that layer cleanly on top of the core XMP toolkit.
+ * <p>
+ * These functions provide support for composing path expressions to deeply nested properties. The
+ * functions <code>XMPMeta</code> such as <code>getProperty()</code>,
+ * <code>getArrayItem()</code> and <code>getStructField()</code> provide easy access to top
+ * level simple properties, items in top level arrays, and fields of top level structs. They do not
+ * provide convenient access to more complex things like fields several levels deep in a complex
+ * struct, or fields within an array of structs, or items of an array that is a field of a struct.
+ * These functions can also be used to compose paths to top level array items or struct fields so
+ * that you can use the binary accessors like <code>getPropertyAsInteger()</code>.
+ * <p>
+ * You can use these functions is to compose a complete path expression, or all but the last
+ * component. Suppose you have a property that is an array of integers within a struct. You can
+ * access one of the array items like this:
+ * <p>
+ * <blockquote>
+ * 
+ * <pre>
+ *      String path = XMPPathFactory.composeStructFieldPath (schemaNS, &quot;Struct&quot;, fieldNS,
+ *          &quot;Array&quot;);
+ *      String path += XMPPathFactory.composeArrayItemPath (schemaNS, &quot;Array&quot; index);
+ *      PropertyInteger result = xmpObj.getPropertyAsInteger(schemaNS, path);
+ * </pre>
+ * 
+ * </blockquote> You could also use this code if you want the string form of the integer:
+ * <blockquote>
+ * 
+ * <pre>
+ *      String path = XMPPathFactory.composeStructFieldPath (schemaNS, &quot;Struct&quot;, fieldNS,
+ *          &quot;Array&quot;);
+ *      PropertyText xmpObj.getArrayItem (schemaNS, path, index);
+ * </pre>
+ * 
+ * </blockquote>
+ * <p>
+ * <em>Note:</em> It might look confusing that the schemaNS is passed in all of the calls above.
+ * This is because the XMP toolkit keeps the top level &quot;schema&quot; namespace separate from
+ * the rest of the path expression.
+ * <em>Note:</em> These methods are much simpler than in the C++-API, they don't check the given
+ * path or array indices.
+ * 
+ * @since 25.01.2006
+ */
+public final class XMPPathFactory
+{
+	/** Private constructor */
+	private XMPPathFactory()
+	{
+		// EMPTY
+	}
+
+
+	/**
+	 * Compose the path expression for an item in an array.
+	 * 
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string.
+	 * @param itemIndex The index of the desired item. Arrays in XMP are indexed from 1.
+	 * 		  0 and below means last array item and renders as <code>[last()]</code>.	
+	 * 					
+	 * @return Returns the composed path basing on fullPath. This will be of the form
+	 *         <tt>ns:arrayName[i]</tt>, where &quot;ns&quot; is the prefix for schemaNS and
+	 *         &quot;i&quot; is the decimal representation of itemIndex.
+	 * @throws XMPException Throws exeption if index zero is used.
+	 */
+	public static String composeArrayItemPath(String arrayName, int itemIndex) throws XMPException
+	{
+		if (itemIndex > 0)
+		{
+			return arrayName + '[' + itemIndex + ']';
+		}
+		else  if (itemIndex == XMPConst.ARRAY_LAST_ITEM)
+		{
+			return arrayName + "[last()]";
+		}
+		else
+		{
+			throw new XMPException("Array index must be larger than zero", XMPError.BADINDEX);
+		}
+	}
+
+	
+	/**
+	 * Compose the path expression for a field in a struct. The result can be added to the
+	 * path of 
+	 * 
+	 * 
+	 * @param fieldNS The namespace URI for the field. Must not be <code>null</code> or the empty
+	 *        string.
+	 * @param fieldName The name of the field. Must be a simple XML name, must not be
+	 *        <code>null</code> or the empty string.
+	 * @return Returns the composed path. This will be of the form
+	 *         <tt>ns:structName/fNS:fieldName</tt>, where &quot;ns&quot; is the prefix for
+	 *         schemaNS and &quot;fNS&quot; is the prefix for fieldNS.
+	 * @throws XMPException Thrown if the path to create is not valid.
+	 */
+	public static String composeStructFieldPath(String fieldNS,
+			String fieldName) throws XMPException
+	{
+		assertFieldNS(fieldNS);
+		assertFieldName(fieldName);
+		
+		XMPPath fieldPath = XMPPathParser.expandXPath(fieldNS, fieldName);
+		if (fieldPath.size() != 2) 
+		{
+			throw new XMPException("The field name must be simple", XMPError.BADXPATH);
+		}
+		
+		return '/' + fieldPath.getSegment(XMPPath.STEP_ROOT_PROP).getName(); 
+	}
+
+
+	/**
+	 * Compose the path expression for a qualifier.
+	 * 
+	 * @param qualNS The namespace URI for the qualifier. May be <code>null</code> or the empty
+	 *        string if the qualifier is in the XML empty namespace.
+	 * @param qualName The name of the qualifier. Must be a simple XML name, must not be
+	 *        <code>null</code> or the empty string.
+	 * @return Returns the composed path. This will be of the form
+	 *         <tt>ns:propName/?qNS:qualName</tt>, where &quot;ns&quot; is the prefix for
+	 *         schemaNS and &quot;qNS&quot; is the prefix for qualNS.
+	 * @throws XMPException Thrown if the path to create is not valid.
+	 */
+	public static String composeQualifierPath(
+			String qualNS,
+			String qualName) throws XMPException
+	{
+		assertQualNS(qualNS);
+		assertQualName(qualName);
+		
+		XMPPath qualPath = XMPPathParser.expandXPath(qualNS, qualName);
+		if (qualPath.size() != 2)
+		{
+			throw new XMPException("The qualifier name must be simple", XMPError.BADXPATH);
+		}
+
+		return "/?" + qualPath.getSegment(XMPPath.STEP_ROOT_PROP).getName();
+	}
+
+
+	/**
+	 * Compose the path expression to select an alternate item by language. The
+	 * path syntax allows two forms of &quot;content addressing&quot; that may
+	 * be used to select an item in an array of alternatives. The form used in
+	 * ComposeLangSelector lets you select an item in an alt-text array based on
+	 * the value of its <tt>xml:lang</tt> qualifier. The other form of content
+	 * addressing is shown in ComposeFieldSelector. \note ComposeLangSelector
+	 * does not supplant SetLocalizedText or GetLocalizedText. They should
+	 * generally be used, as they provide extra logic to choose the appropriate
+	 * language and maintain consistency with the 'x-default' value.
+	 * ComposeLangSelector gives you an path expression that is explicitly and
+	 * only for the language given in the langName parameter.
+	 * 
+	 * @param arrayName
+	 *            The name of the array. May be a general path expression, must
+	 *            not be <code>null</code> or the empty string.
+	 * @param langName
+	 *            The RFC 3066 code for the desired language.
+	 * @return Returns the composed path. This will be of the form
+	 *         <tt>ns:arrayName[@xml:lang='langName']</tt>, where
+	 *         &quot;ns&quot; is the prefix for schemaNS.
+	 */
+	public static String composeLangSelector(String arrayName,
+			String langName)
+	{
+		return arrayName + "[?xml:lang=\"" + Utils.normalizeLangValue(langName) + "\"]";
+	}
+
+
+	/**
+	 * Compose the path expression to select an alternate item by a field's value. The path syntax
+	 * allows two forms of &quot;content addressing&quot; that may be used to select an item in an
+	 * array of alternatives. The form used in ComposeFieldSelector lets you select an item in an
+	 * array of structs based on the value of one of the fields in the structs. The other form of
+	 * content addressing is shown in ComposeLangSelector. For example, consider a simple struct
+	 * that has two fields, the name of a city and the URI of an FTP site in that city. Use this to
+	 * create an array of download alternatives. You can show the user a popup built from the values
+	 * of the city fields. You can then get the corresponding URI as follows:
+	 * <p>
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 *      String path = composeFieldSelector ( schemaNS, &quot;Downloads&quot;, fieldNS, 
+	 *          &quot;City&quot;, chosenCity ); 
+	 *      XMPProperty prop = xmpObj.getStructField ( schemaNS, path, fieldNS, &quot;URI&quot; );
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * @param arrayName The name of the array. May be a general path expression, must not be
+	 *        <code>null</code> or the empty string.
+	 * @param fieldNS The namespace URI for the field used as the selector. Must not be
+	 *        <code>null</code> or the empty string.
+	 * @param fieldName The name of the field used as the selector. Must be a simple XML name, must
+	 *        not be <code>null</code> or the empty string. It must be the name of a field that is
+	 *        itself simple.
+	 * @param fieldValue The desired value of the field.
+	 * @return Returns the composed path. This will be of the form
+	 *         <tt>ns:arrayName[fNS:fieldName='fieldValue']</tt>, where &quot;ns&quot; is the
+	 *         prefix for schemaNS and &quot;fNS&quot; is the prefix for fieldNS.
+	 * @throws XMPException Thrown if the path to create is not valid.
+	 */
+	public static String composeFieldSelector(String arrayName, String fieldNS,
+			String fieldName, String fieldValue) throws XMPException
+	{
+		XMPPath fieldPath = XMPPathParser.expandXPath(fieldNS, fieldName);
+		if (fieldPath.size() != 2) 
+		{
+			throw new XMPException("The fieldName name must be simple", XMPError.BADXPATH);
+		}
+		
+		return arrayName + '[' + fieldPath.getSegment(XMPPath.STEP_ROOT_PROP).getName() +
+			"=\"" + fieldValue + "\"]"; 
+	}
+	
+	
+	/**
+	 * ParameterAsserts that a qualifier namespace is set.
+	 * @param qualNS a qualifier namespace
+	 * @throws XMPException Qualifier schema is null or empty
+	 */
+	private static void assertQualNS(String qualNS) throws XMPException
+	{
+		if (qualNS == null  ||  qualNS.length() == 0)
+		{
+			throw new XMPException("Empty qualifier namespace URI", XMPError.BADSCHEMA);
+		}
+		
+	}
+	
+	
+	/**
+	 * ParameterAsserts that a qualifier name is set.
+	 * @param qualName a qualifier name or path
+	 * @throws XMPException Qualifier name is null or empty
+	 */
+	private static void assertQualName(String qualName) throws XMPException
+	{
+		if (qualName == null  ||  qualName.length() == 0)
+		{
+			throw new XMPException("Empty qualifier name", XMPError.BADXPATH);
+		}
+	}
+
+	
+	/**
+	 * ParameterAsserts that a struct field namespace is set.
+	 * @param fieldNS a struct field namespace
+	 * @throws XMPException Struct field schema is null or empty
+	 */
+	private static void assertFieldNS(String fieldNS) throws XMPException
+	{
+		if (fieldNS == null  ||  fieldNS.length() == 0)
+		{
+			throw new XMPException("Empty field namespace URI", XMPError.BADSCHEMA);
+		}
+		
+	}
+	
+	
+	/**
+	 * ParameterAsserts that a struct field name is set.
+	 * @param fieldName a struct field name or path
+	 * @throws XMPException Struct field name is null or empty
+	 */
+	private static void assertFieldName(String fieldName) throws XMPException
+	{
+		if (fieldName == null  ||  fieldName.length() == 0)
+		{
+			throw new XMPException("Empty f name", XMPError.BADXPATH);
+		}
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPSchemaRegistry.java b/XMPCore/src/com/adobe/xmp/XMPSchemaRegistry.java
new file mode 100644
index 0000000..4608a8e
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPSchemaRegistry.java
@@ -0,0 +1,180 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import java.util.Map;
+
+import com.adobe.xmp.properties.XMPAliasInfo;
+
+/**
+ * The schema registry keeps track of all namespaces and aliases used in the XMP
+ * metadata. At initialisation time, the default namespaces and default aliases
+ * are automatically registered. <b>Namespaces</b> must be registered before
+ * used in namespace URI parameters or path expressions. Within the XMP Toolkit
+ * the registered namespace URIs and prefixes must be unique. Additional
+ * namespaces encountered when parsing RDF are automatically registered. The
+ * namespace URI should always end in an XML name separator such as '/' or '#'.
+ * This is because some forms of RDF shorthand catenate a namespace URI with an
+ * element name to form a new URI.
+ * <p>
+ * <b>Aliases</b> in XMP serve the same purpose as Windows file shortcuts,
+ * Macintosh file aliases, or UNIX file symbolic links. The aliases are simply
+ * multiple names for the same property. One distinction of XMP aliases is that
+ * they are ordered, there is an alias name pointing to an actual name. The
+ * primary significance of the actual name is that it is the preferred name for
+ * output, generally the most widely recognized name.
+ * <p>
+ * The names that can be aliased in XMP are restricted. The alias must be a top
+ * level property name, not a field within a structure or an element within an
+ * array. The actual may be a top level property name, the first element within
+ * a top level array, or the default element in an alt-text array. This does not
+ * mean the alias can only be a simple property. It is OK to alias a top level
+ * structure or array to an identical top level structure or array, or to the
+ * first item of an array of structures.
+ * 
+ * @since 27.01.2006
+ */
+public interface XMPSchemaRegistry
+{
+	// ---------------------------------------------------------------------------------------------
+	// Namespace Functions
+
+	/**
+	 * Register a namespace URI with a suggested prefix. It is not an error if
+	 * the URI is already registered, no matter what the prefix is. If the URI
+	 * is not registered but the suggested prefix is in use, a unique prefix is
+	 * created from the suggested one. The actual registeed prefix is always
+	 * returned. The function result tells if the registered prefix is the
+	 * suggested one.
+	 * <p>
+	 * Note: No checking is presently done on either the URI or the prefix.
+	 * 
+	 * @param namespaceURI
+	 *            The URI for the namespace. Must be a valid XML URI.
+	 * @param suggestedPrefix
+	 *            The suggested prefix to be used if the URI is not yet
+	 *            registered. Must be a valid XML name.
+	 * @return Returns the registered prefix for this URI, is equal to the
+	 *         suggestedPrefix if the namespace hasn't been registered before,
+	 *         otherwise the existing prefix.
+	 * @throws XMPException If the parameters are not accordingly set
+	 */
+	String registerNamespace(String namespaceURI, String suggestedPrefix) throws XMPException;
+
+	
+	/**
+	 * Obtain the prefix for a registered namespace URI.
+	 * <p>
+	 * It is not an error if the namespace URI is not registered. The output
+	 * namespacePrefix string is not modified if the namespace URI is not
+	 * registered.
+	 * 
+	 * @param namespaceURI
+	 *            The URI for the namespace. Must not be null or the empty
+	 *            string.
+	 * @return Returns true if the namespace URI is registered.
+	 */
+	String getNamespacePrefix(String namespaceURI);
+
+	
+	/**
+	 * Obtain the URI for a registered namespace prefix.
+	 * <p>
+	 * It is not an error if the namespace prefix is not registered. The output
+	 * namespaceURI string is not modified if the namespace prefix is not
+	 * registered.
+	 * 
+	 * @param namespacePrefix
+	 *            The prefix for the namespace. Must not be null or the empty
+	 *            string.
+	 * @return Returns the URI registered for this prefix.
+	 */
+	String getNamespaceURI(String namespacePrefix);
+
+	
+	/**
+	 * @return Returns the registered prefix/namespace-pairs as map, where the keys are the
+	 *         namespaces and the values are the prefixes.
+	 */
+	Map getNamespaces();
+
+	
+	/**
+	 * @return Returns the registered namespace/prefix-pairs as map, where the keys are the
+	 *         prefixes and the values are the namespaces.
+	 */
+	Map getPrefixes();
+	
+	
+	/**
+	 * Deletes a namespace from the registry.
+	 * <p>
+	 * Does nothing if the URI is not registered, or if the namespaceURI
+	 * parameter is null or the empty string.
+	 * <p>
+	 * Note: Not yet implemented.
+	 * 
+	 * @param namespaceURI
+	 *            The URI for the namespace.
+	 */
+	void deleteNamespace(String namespaceURI);
+
+	
+	
+	
+	
+	// ---------------------------------------------------------------------------------------------
+	// Alias Functions
+
+		
+	/**
+	 * Determines if a name is an alias, and what it is aliased to.
+	 * 
+	 * @param aliasNS
+	 *            The namespace URI of the alias. Must not be <code>null</code> or the empty
+	 *            string.
+	 * @param aliasProp
+	 *            The name of the alias. May be an arbitrary path expression
+	 *            path, must not be <code>null</code> or the empty string.
+	 * @return Returns the <code>XMPAliasInfo</code> for the given alias namespace and property or
+	 * 		<code>null</code> if there is no such alias.
+	 */
+	XMPAliasInfo resolveAlias(String aliasNS, String aliasProp);
+
+	
+	/**
+	 * Collects all aliases that are contained in the provided namespace.
+	 * If nothing is found, an empty array is returned. 
+	 * 
+	 * @param aliasNS a schema namespace URI
+	 * @return Returns all alias infos from aliases that are contained in the provided namespace. 
+	 */
+	XMPAliasInfo[] findAliases(String aliasNS);
+	
+	
+	/**
+	 * Searches for registered aliases.
+	 * 
+	 * @param qname
+	 *            an XML conform qname
+	 * @return Returns if an alias definition for the given qname to another
+	 *         schema and property is registered.
+	 */
+	XMPAliasInfo findAlias(String qname);
+	
+		
+	/**
+	 * @return Returns the registered aliases as map, where the key is the "qname" (prefix and name)
+	 * and the value an <code>XMPAliasInfo</code>-object.
+	 */
+	Map getAliases();
+
+
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPUtils.java b/XMPCore/src/com/adobe/xmp/XMPUtils.java
new file mode 100644
index 0000000..043d533
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPUtils.java
@@ -0,0 +1,506 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+import com.adobe.xmp.impl.Base64;
+import com.adobe.xmp.impl.ISO8601Converter;
+import com.adobe.xmp.impl.XMPUtilsImpl;
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * Utility methods for XMP. I included only those that are different from the
+ * Java default conversion utilities.
+ * 
+ * @since 21.02.2006
+ */
+public class XMPUtils
+{
+	/** Private constructor */
+	private XMPUtils()
+	{
+		// EMPTY
+	}
+
+
+	/**
+	 * Create a single edit string from an array of strings.
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the array to be catenated.
+	 * @param schemaNS
+	 *            The schema namespace URI for the array. Must not be null or
+	 *            the empty string.
+	 * @param arrayName
+	 *            The name of the array. May be a general path expression, must
+	 *            not be null or the empty string. Each item in the array must
+	 *            be a simple string value.
+	 * @param separator
+	 *            The string to be used to separate the items in the catenated
+	 *            string. Defaults to &quot;; &quot;, ASCII semicolon and space
+	 *            (U+003B, U+0020).
+	 * @param quotes
+	 *            The characters to be used as quotes around array items that
+	 *            contain a separator. Defaults to &apos;&quot;&apos;
+	 * @param allowCommas
+	 *            Option flag to control the catenation.
+	 * @return Returns the string containing the catenated array items.
+	 * @throws XMPException Forwards the Exceptions from the metadata processing
+	 */
+	public static String catenateArrayItems(XMPMeta xmp, String schemaNS, String arrayName,
+			String separator, String quotes, boolean allowCommas) throws XMPException
+	{
+		return XMPUtilsImpl
+				.catenateArrayItems(xmp, schemaNS, arrayName, separator, quotes, allowCommas);
+	}
+
+
+	/**
+	 * Separate a single edit string into an array of strings.
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the array to be updated.
+	 * @param schemaNS
+	 *            The schema namespace URI for the array. Must not be null or
+	 *            the empty string.
+	 * @param arrayName
+	 *            The name of the array. May be a general path expression, must
+	 *            not be null or the empty string. Each item in the array must
+	 *            be a simple string value.
+	 * @param catedStr
+	 *            The string to be separated into the array items.
+	 * @param arrayOptions Option flags to control the separation. 
+	 * @param preserveCommas Flag if commas shall be preserved
+	 * @throws XMPException Forwards the Exceptions from the metadata processing 
+	 */
+	public static void separateArrayItems(XMPMeta xmp, String schemaNS, String arrayName,
+			String catedStr, PropertyOptions arrayOptions, boolean preserveCommas) 
+				throws XMPException
+	{
+		XMPUtilsImpl.separateArrayItems(xmp, schemaNS, arrayName, catedStr, arrayOptions,
+				preserveCommas);
+	}
+
+
+	/**
+	 * Remove multiple properties from an XMP object.
+	 * 
+	 * RemoveProperties was created to support the File Info dialog's Delete
+	 * button, and has been been generalized somewhat from those specific needs.
+	 * It operates in one of three main modes depending on the schemaNS and
+	 * propName parameters:
+	 * 
+	 * <ul>
+	 * <li> Non-empty <code>schemaNS</code> and <code>propName</code> - The named property is
+	 * removed if it is an external property, or if the 
+	 * flag <code>doAllProperties</code> option is true. It does not matter whether the
+	 * named property is an actual property or an alias.
+	 * 
+	 * <li> Non-empty <code>schemaNS</code> and empty <code>propName</code> - The all external
+	 * properties in the named schema are removed. Internal properties are also
+	 * removed if the flag <code>doAllProperties</code> option is set. In addition,
+	 * aliases from the named schema will be removed if the flag <code>includeAliases</code> 
+	 * option is set.
+	 * 
+	 * <li> Empty <code>schemaNS</code> and empty <code>propName</code> - All external properties in
+	 * all schema are removed. Internal properties are also removed if the 
+	 * flag <code>doAllProperties</code> option is passed. Aliases are implicitly handled
+	 * because the associated actuals are internal if the alias is.
+	 * </ul>
+	 * 
+	 * It is an error to pass an empty <code>schemaNS</code> and non-empty <code>propName</code>.
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the properties to be removed.
+	 * 
+	 * @param schemaNS
+	 *            Optional schema namespace URI for the properties to be
+	 *            removed.
+	 * 
+	 * @param propName
+	 *            Optional path expression for the property to be removed.
+	 * 
+	 * @param doAllProperties Option flag to control the deletion: do internal properties in
+	 *          addition to external properties.
+	 *            
+	 * @param includeAliases Option flag to control the deletion: 
+	 * 			Include aliases in the "named schema" case above.
+	 * 			<em>Note:</em> Currently not supported.
+	 * @throws XMPException Forwards the Exceptions from the metadata processing 
+	 */
+	public static void removeProperties(XMPMeta xmp, String schemaNS, String propName,
+			boolean doAllProperties, boolean includeAliases) throws XMPException
+	{
+		XMPUtilsImpl.removeProperties(xmp, schemaNS, propName, doAllProperties, includeAliases);
+	}
+
+	
+
+	/**
+	 * Alias without the new option <code>deleteEmptyValues</code>.
+	 * @param source The source XMP object.
+	 * @param dest The destination XMP object.
+	 * @param doAllProperties Do internal properties in addition to external properties.
+	 * @param replaceOldValues Replace the values of existing properties.
+	 * @throws XMPException Forwards the Exceptions from the metadata processing 
+	 */
+	public static void appendProperties(XMPMeta source, XMPMeta dest, boolean doAllProperties,
+			boolean replaceOldValues) throws XMPException
+	{
+		appendProperties(source, dest, doAllProperties, replaceOldValues, false);
+	}
+	
+
+	/**
+	 * <p>Append properties from one XMP object to another.
+	 * 
+	 * <p>XMPUtils#appendProperties was created to support the File Info dialog's Append button, and
+	 * has been been generalized somewhat from those specific needs. It appends information from one
+	 * XMP object (source) to another (dest). The default operation is to append only external
+	 * properties that do not already exist in the destination. The flag 
+	 * <code>doAllProperties</code> can be used to operate on all properties, external and internal.
+	 * The flag <code>replaceOldValues</code> option can be used to replace the values 
+	 * of existing properties. The notion of external
+	 * versus internal applies only to top level properties. The keep-or-replace-old notion applies
+	 * within structs and arrays as described below.
+	 * <ul>
+	 * <li>If <code>replaceOldValues</code> is true then the processing is restricted to the top 
+	 * level properties. The processed properties from the source (according to 
+	 * <code>doAllProperties</code>) are propagated to the destination, 
+	 * replacing any existing values.Properties in the destination that are not in the source 
+	 * are left alone.
+	 *
+	 * <li>If <code>replaceOldValues</code> is not passed then the processing is more complicated. 
+	 * Top level properties are added to the destination if they do not already exist. 
+	 * If they do exist but differ in form (simple/struct/array) then the destination is left alone.
+	 * If the forms match, simple properties are left unchanged while structs and arrays are merged.
+	 * 
+	 * <li>If <code>deleteEmptyValues</code> is passed then an empty value in the source XMP causes
+	 * the corresponding destination XMP property to be deleted. The default is to treat empty 
+	 * values the same as non-empty values. An empty value is any of a simple empty string, an array
+	 * with no items, or a struct with no fields. Qualifiers are ignored.
+	 * </ul>
+	 * 
+	 * <p>The detailed behavior is defined by the following pseudo-code:
+	 * <blockquote>
+	 * <pre>
+     *    appendProperties ( sourceXMP, destXMP, doAllProperties, 
+     *    			replaceOldValues, deleteEmptyValues ):
+     *       for all source schema (top level namespaces):
+     *          for all top level properties in sourceSchema:
+     *             if doAllProperties or prop is external:
+     *                appendSubtree ( sourceNode, destSchema, replaceOldValues, deleteEmptyValues )
+     * 
+     *    appendSubtree ( sourceNode, destParent, replaceOldValues, deleteEmptyValues ):
+     *        if deleteEmptyValues and source value is empty:
+     *            delete the corresponding child from destParent
+     *        else if sourceNode not in destParent (by name):
+     *           copy sourceNode's subtree to destParent
+     *        else if replaceOld:
+     *            delete subtree from destParent
+     *            copy sourceNode's subtree to destParent
+     *        else:
+     *            // Already exists in dest and not replacing, merge structs and arrays
+     *            if sourceNode and destNode forms differ:
+     *                return, leave the destNode alone
+     *            else if form is a struct:
+     *                for each field in sourceNode:
+     *                    AppendSubtree ( sourceNode.field, destNode, replaceOldValues )
+     *            else if form is an alt-text array:
+     *                copy new items by "xml:lang" value into the destination
+     *            else if form is an array:
+     *                copy new items by value into the destination, ignoring order and duplicates
+     * </pre>
+	 * </blockquote>
+	 *
+	 * <p><em>Note:</em> appendProperties can be expensive if replaceOldValues is not passed and 
+	 * the XMP contains large arrays. The array item checking described above is n-squared. 
+	 * Each source item is checked to see if it already exists in the destination, 
+	 * without regard to order or duplicates.
+	 * <p>Simple items are compared by value and "xml:lang" qualifier, other qualifiers are ignored.
+	 * Structs are recursively compared by field names, without regard to field order. Arrays are
+	 * compared by recursively comparing all items.
+	 *
+	 * @param source The source XMP object.
+	 * @param dest The destination XMP object.
+	 * @param doAllProperties Do internal properties in addition to external properties.
+	 * @param replaceOldValues Replace the values of existing properties.
+	 * @param deleteEmptyValues Delete destination values if source property is empty.
+	 * @throws XMPException Forwards the Exceptions from the metadata processing 
+	 */
+	public static void appendProperties(XMPMeta source, XMPMeta dest, boolean doAllProperties,
+			boolean replaceOldValues, boolean deleteEmptyValues) throws XMPException
+	{
+		XMPUtilsImpl.appendProperties(source, dest, doAllProperties, replaceOldValues, 
+			deleteEmptyValues);
+	}
+
+
+	/**
+	 * Convert from string to Boolean.
+	 * 
+	 * @param value
+	 *            The string representation of the Boolean.
+	 * @return The appropriate boolean value for the string. The checked values
+	 *         for <code>true</code> and <code>false</code> are:
+	 *         <ul>
+	 *    	    	<li>{@link XMPConst#TRUESTR} and {@link XMPConst#FALSESTR}
+	 *    		    <li>&quot;t&quot; and &quot;f&quot;
+	 *    		    <li>&quot;on&quot; and &quot;off&quot;
+	 *    		    <li>&quot;yes&quot; and &quot;no&quot;
+	 *   		  	<li>&quot;value <> 0&quot; and &quot;value == 0&quot;
+	 *         </ul>
+	 * @throws XMPException If an empty string is passed.
+	 */
+	public static boolean convertToBoolean(String value) throws XMPException
+	{
+		if (value == null  ||  value.length() == 0)
+		{
+			throw new XMPException("Empty convert-string", XMPError.BADVALUE);
+		}
+		value = value.toLowerCase();
+		
+		try
+		{
+			// First try interpretation as Integer (anything not 0 is true)
+			return Integer.parseInt(value) != 0;
+		}
+		catch (NumberFormatException e)
+		{
+			return
+				"true".equals(value)  ||
+				"t".equals(value)  ||
+				"on".equals(value)  ||
+				"yes".equals(value);
+		}	
+	}
+
+	
+	/**
+	 * Convert from boolean to string.
+	 * 
+	 * @param value
+	 *            a boolean value
+	 * @return The XMP string representation of the boolean. The values used are
+	 *         given by the constnts {@link XMPConst#TRUESTR} and
+	 *         {@link XMPConst#FALSESTR}.
+	 */
+	public static String convertFromBoolean(boolean value)
+	{
+		return value ? XMPConst.TRUESTR : XMPConst.FALSESTR;
+	}
+
+
+	/**
+	 * Converts a string value to an <code>int</code>.
+	 * 
+	 * @param rawValue
+	 *            the string value
+	 * @return Returns an int.
+	 * @throws XMPException
+	 *             If the <code>rawValue</code> is <code>null</code> or empty or the
+	 *             conversion fails.
+	 */
+	public static int convertToInteger(String rawValue) throws XMPException
+	{
+		try
+		{
+			if (rawValue == null  ||  rawValue.length() == 0)
+			{
+				throw new XMPException("Empty convert-string", XMPError.BADVALUE);
+			}
+			if (rawValue.startsWith("0x"))
+			{
+				return Integer.parseInt(rawValue.substring(2), 16);
+			}	
+			else
+			{
+				return Integer.parseInt(rawValue);
+			}
+		}
+		catch (NumberFormatException e)
+		{
+			throw new XMPException("Invalid integer string", XMPError.BADVALUE);
+		}
+	}
+
+
+	/**
+	 * Convert from int to string.
+	 * 
+	 * @param value
+	 *            an int value
+	 * @return The string representation of the int.
+	 */
+	public static String convertFromInteger(int value)
+	{
+		return String.valueOf(value);
+	}
+	
+
+	/**
+	 * Converts a string value to a <code>long</code>.
+	 * 
+	 * @param rawValue
+	 *            the string value
+	 * @return Returns a long.
+	 * @throws XMPException
+	 *             If the <code>rawValue</code> is <code>null</code> or empty or the
+	 *             conversion fails.
+	 */
+	public static long convertToLong(String rawValue) throws XMPException
+	{
+		try
+		{
+			if (rawValue == null  ||  rawValue.length() == 0)
+			{
+				throw new XMPException("Empty convert-string", XMPError.BADVALUE);
+			}
+			if (rawValue.startsWith("0x"))
+			{	
+				return Long.parseLong(rawValue.substring(2), 16);
+			}	
+			else
+			{
+				return Long.parseLong(rawValue);
+			}
+		}
+		catch (NumberFormatException e)
+		{
+			throw new XMPException("Invalid long string", XMPError.BADVALUE);
+		}
+	}
+
+
+	/**
+	 * Convert from long to string.
+	 * 
+	 * @param value
+	 *            a long value
+	 * @return The string representation of the long.
+	 */
+	public static String convertFromLong(long value)
+	{
+		return String.valueOf(value);
+	}
+
+	
+	/**
+	 * Converts a string value to a <code>double</code>.
+	 * 
+	 * @param rawValue
+	 *            the string value
+	 * @return Returns a double.
+	 * @throws XMPException
+	 *             If the <code>rawValue</code> is <code>null</code> or empty or the
+	 *             conversion fails.
+	 */
+	public static double convertToDouble(String rawValue) throws XMPException
+	{
+		try
+		{
+			if (rawValue == null  ||  rawValue.length() == 0)
+			{
+				throw new XMPException("Empty convert-string", XMPError.BADVALUE);
+			}
+			else
+			{
+				return Double.parseDouble(rawValue);
+			}
+		}
+		catch (NumberFormatException e)
+		{
+			throw new XMPException("Invalid double string", XMPError.BADVALUE);
+		}
+	}
+
+	
+	/**
+	 * Convert from long to string.
+	 * 
+	 * @param value
+	 *            a long value
+	 * @return The string representation of the long.
+	 */
+	public static String convertFromDouble(double value)
+	{
+		return String.valueOf(value);
+	}
+	
+
+	/**
+	 * Converts a string value to an <code>XMPDateTime</code>.
+	 * 
+	 * @param rawValue
+	 *            the string value
+	 * @return Returns an <code>XMPDateTime</code>-object.
+	 * @throws XMPException
+	 *             If the <code>rawValue</code> is <code>null</code> or empty or the
+	 *             conversion fails.
+	 */
+	public static XMPDateTime convertToDate(String rawValue) throws XMPException
+	{
+		if (rawValue == null  ||  rawValue.length() == 0)
+		{
+			throw new XMPException("Empty convert-string", XMPError.BADVALUE);
+		}
+		else
+		{	
+			return ISO8601Converter.parse(rawValue);
+		}	
+	}
+	
+	
+	/**
+	 * Convert from <code>XMPDateTime</code> to string.
+	 * 
+	 * @param value
+	 *            an <code>XMPDateTime</code>
+	 * @return The string representation of the long.
+	 */
+	public static String convertFromDate(XMPDateTime value)
+	{
+		return ISO8601Converter.render(value);
+	}
+	
+	
+	 /**
+	  * Convert from a byte array to a base64 encoded string.
+	  * 
+	  * @param buffer
+	  *            the byte array to be converted
+	  * @return Returns the base64 string.
+	  */
+	public static String encodeBase64(byte[] buffer)
+	{
+		return new String(Base64.encode(buffer));
+	}
+
+
+	/**
+	 * Decode from Base64 encoded string to raw data.
+	 * 
+	 * @param base64String
+	 *            a base64 encoded string
+	 * @return Returns a byte array containg the decoded string.
+	 * @throws XMPException Thrown if the given string is not property base64 encoded
+	 */
+	public static byte[] decodeBase64(String base64String) throws XMPException
+	{
+		try
+		{
+			return Base64.decode(base64String.getBytes());
+		}
+		catch (Throwable e)
+		{
+			throw new XMPException("Invalid base64 string", XMPError.BADVALUE, e);
+		}
+	}			
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/XMPVersionInfo.java b/XMPCore/src/com/adobe/xmp/XMPVersionInfo.java
new file mode 100644
index 0000000..24b7c20
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/XMPVersionInfo.java
@@ -0,0 +1,45 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp;
+
+/**
+ * XMP Toolkit Version Information.
+ * <p>
+ * Version information for the XMP toolkit is stored in the jar-library and available through a
+ * runtime call, {@link XMPMetaFactory#getVersionInfo()},  addition static version numbers are
+ * defined in "version.properties". 
+ * 
+ * @since 23.01.2006
+ */
+public interface XMPVersionInfo
+{
+	/** @return Returns the primary release number, the "1" in version "1.2.3". */
+	int getMajor();
+
+
+	/** @return Returns the secondary release number, the "2" in version "1.2.3". */
+	int getMinor();
+
+
+	/** @return Returns the tertiary release number, the "3" in version "1.2.3". */
+	int getMicro();
+
+
+	/** @return Returns a rolling build number, monotonically increasing in a release. */
+	int getBuild();
+
+
+	/** @return Returns true if this is a debug build. */
+	boolean isDebug();
+	
+	
+	/** @return Returns a comprehensive version information string. */
+	String getMessage();
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/Base64.java b/XMPCore/src/com/adobe/xmp/impl/Base64.java
new file mode 100644
index 0000000..a327876
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/Base64.java
@@ -0,0 +1,251 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2001 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+
+
+
+/**
+ * A utility class to perform base64 encoding and decoding as specified
+ * in RFC-1521. See also RFC 1421.
+ *
+ * @version     $Revision: 1.4 $
+ */
+public class  Base64
+{
+	/** marker for invalid bytes */
+	private static final byte INVALID = -1; 
+	/** marker for accepted whitespace bytes */
+	private static final byte WHITESPACE = -2;
+	/** marker for an equal symbol */
+	private static final byte EQUAL = -3;
+	
+	/** */
+    private static byte[] base64 = {
+        (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D',   //  0 to  3
+        (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H',   //  4 to  7
+        (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',   //  8 to 11
+        (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',   // 11 to 15
+        (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T',   // 16 to 19
+        (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X',   // 20 to 23
+        (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b',   // 24 to 27
+        (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',   // 28 to 31
+        (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',   // 32 to 35
+        (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',   // 36 to 39
+        (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r',   // 40 to 43
+        (byte) 's', (byte) 't', (byte) 'u', (byte) 'v',   // 44 to 47
+        (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',   // 48 to 51
+        (byte) '0', (byte) '1', (byte) '2', (byte) '3',   // 52 to 55
+        (byte) '4', (byte) '5', (byte) '6', (byte) '7',   // 56 to 59
+        (byte) '8', (byte) '9', (byte) '+', (byte) '/'    // 60 to 63
+    };
+    /** */
+    private static byte[] ascii = new byte[255];
+    /** */
+    static {
+    	// not valid bytes
+        for (int idx = 0; idx < 255; idx++)
+		{
+			ascii[idx] = INVALID;
+		}
+    	// valid bytes
+		for (int idx = 0; idx < base64.length; idx++)
+		{
+			ascii[base64[idx]] = (byte) idx;
+		}
+		// whitespaces
+		ascii[0x09] = WHITESPACE;
+		ascii[0x0A] = WHITESPACE;
+		ascii[0x0D] = WHITESPACE;
+		ascii[0x20] = WHITESPACE;
+		
+		// trailing equals
+		ascii[0x3d] = EQUAL;
+    }
+
+    
+    /**
+	 * Encode the given byte[].
+	 * 
+	 * @param src the source string.
+	 * @return the base64-encoded data.
+	 */
+    public static final byte[] encode(byte[] src)
+	{
+    	return encode(src, 0);
+	}
+    	
+
+    /**
+	 * Encode the given byte[].
+	 * 
+	 * @param src the source string.
+	 * @param lineFeed a linefeed is added after <code>linefeed</code> characters;
+	 *            must be dividable by four; 0 means no linefeeds
+	 * @return the base64-encoded data.
+	 */
+    public static final byte[] encode(byte[] src, int lineFeed)
+	{
+    	// linefeed must be dividable by 4
+    	lineFeed = lineFeed / 4 * 4;
+    	if (lineFeed < 0)
+    	{
+    		lineFeed = 0;
+    	}
+    	
+		// determine code length
+    	int codeLength = ((src.length + 2) / 3) * 4;
+		if (lineFeed > 0)
+		{
+			codeLength += (codeLength - 1) / lineFeed;
+		}
+		
+		byte[] dst = new byte[codeLength];
+		int bits24;
+		int bits6;
+		//
+		// Do 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
+		//
+		int didx = 0;
+		int sidx = 0;
+		int lf = 0;
+		while (sidx + 3 <= src.length)
+		{
+            bits24  = (src[sidx++] & 0xFF) << 16; 
+            bits24 |= (src[sidx++] & 0xFF) <<  8; 
+            bits24 |= (src[sidx++] & 0xFF) <<  0;
+            bits6   = (bits24 & 0x00FC0000) >> 18; 
+            dst[didx++] = base64[bits6];
+            bits6   = (bits24 & 0x0003F000) >> 12; 
+            dst[didx++] = base64[bits6];
+            bits6   = (bits24 & 0x00000FC0) >>  6; 
+            dst[didx++] = base64[bits6];
+            bits6   = (bits24 & 0x0000003F);
+            dst[didx++] = base64[bits6];
+            
+            lf += 4;
+            if (didx < codeLength  &&  lineFeed > 0  &&  lf % lineFeed == 0)
+            {
+            	dst[didx++] = 0x0A;
+            }
+        }
+        if (src.length - sidx == 2)
+		{
+            bits24  = (src[sidx    ] & 0xFF) << 16; 
+            bits24 |= (src[sidx + 1] & 0xFF) <<  8;
+            bits6 = (bits24 & 0x00FC0000) >> 18;
+            dst[didx++] = base64[bits6]; 
+            bits6 = (bits24 & 0x0003F000) >> 12; 
+            dst[didx++] = base64[bits6]; 
+            bits6 = (bits24 & 0x00000FC0) >>  6; 
+            dst[didx++] = base64[bits6];
+            dst[didx++] = (byte) '='; 
+        }
+        else if (src.length - sidx == 1)
+		{
+            bits24 = (src[sidx] & 0xFF) << 16;
+            bits6  = (bits24 & 0x00FC0000) >> 18;
+            dst[didx++] = base64[bits6];
+            bits6  = (bits24 & 0x0003F000) >> 12; 
+            dst[didx++] = base64[bits6];
+            dst[didx++] = (byte) '='; 
+            dst[didx++] = (byte) '='; 
+        }
+        return dst;
+    }
+
+
+    /**
+     * Encode the given string.
+     * @param src the source string.
+     * @return the base64-encoded string.
+     */
+    public static final String encode(String src)
+	{
+		return new String(encode(src.getBytes()));
+	}
+
+
+    /**
+	 * Decode the given byte[].
+	 * 
+	 * @param src
+	 *            the base64-encoded data.
+	 * @return the decoded data.
+     * @throws IllegalArgumentException Thrown if the base 64 strings contains non-valid characters,
+     * 		beside the bas64 chars, LF, CR, tab and space are accepted.
+	 */
+    public static final byte[] decode(byte[] src) throws IllegalArgumentException
+	{
+        //
+        // Do ascii printable to 0-63 conversion.
+        //
+        int sidx;
+        int srcLen = 0;
+        for (sidx = 0; sidx < src.length; sidx++)
+        {
+        	byte val = ascii[src[sidx]];
+        	if (val >= 0)
+        	{	
+        		src[srcLen++] = val;
+        	}
+        	else if (val == INVALID)
+        	{
+        		throw new IllegalArgumentException("Invalid base 64 string");
+        	}
+        }
+    	
+		//
+		// Trim any padding.
+		//
+		while (srcLen > 0  &&  src[srcLen - 1] == EQUAL)
+		{
+			srcLen--;
+		}
+		byte[] dst = new byte[srcLen * 3 / 4];
+
+		//
+        // Do 4-byte to 3-byte conversion.
+        //
+        int didx;
+        for (sidx = 0, didx = 0; didx < dst.length - 2; sidx += 4, didx += 3)
+        {
+            dst[didx    ] = (byte) (((src[sidx    ] << 2) & 0xFF)
+                            | ((src[sidx + 1] >>> 4) & 0x03));
+            dst[didx + 1] = (byte) (((src[sidx + 1] << 4) & 0xFF)
+                            | ((src[sidx + 2] >>> 2) & 0x0F));
+            dst[didx + 2] = (byte) (((src[sidx + 2] << 6) & 0xFF)
+                            | ((src[sidx + 3]) & 0x3F));
+        }
+        if (didx < dst.length)
+        {
+            dst[didx]     = (byte) (((src[sidx    ] << 2) & 0xFF)
+                            | ((src[sidx + 1] >>> 4) & 0x03));
+        }
+        if (++didx < dst.length)
+        {
+            dst[didx]     = (byte) (((src[sidx + 1] << 4) & 0xFF)
+                            | ((src[sidx + 2] >>> 2) & 0x0F));
+        }
+        return dst;
+    }
+
+
+    /**
+	 * Decode the given string.
+	 * 
+	 * @param src the base64-encoded string.
+	 * @return the decoded string.
+	 */
+	public static final String decode(String src)
+	{
+		return new String(decode(src.getBytes()));
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/ByteBuffer.java b/XMPCore/src/com/adobe/xmp/impl/ByteBuffer.java
new file mode 100644
index 0000000..22cbc4b
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/ByteBuffer.java
@@ -0,0 +1,326 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+
+
+package com.adobe.xmp.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Byte buffer container including length of valid data.
+ * 
+ * @since   11.10.2006
+ */
+public class ByteBuffer
+{
+	/** */
+	private byte[] buffer;
+	/** */
+	private int length;
+	/** */
+	private String encoding = null;
+	
+
+	/**
+	 * @param initialCapacity the initial capacity for this buffer
+	 */
+	public ByteBuffer(int initialCapacity)
+	{
+		this.buffer = new byte[initialCapacity];
+		this.length = 0;
+	}
+
+	
+	/**
+	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
+	 */
+	public ByteBuffer(byte[] buffer)
+	{
+		this.buffer = buffer;
+		this.length = buffer.length;
+	}
+	
+	
+	/**
+	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
+	 * @param length the length of valid bytes in the array
+	 */
+	public ByteBuffer(byte[] buffer, int length)
+	{
+		if (length > buffer.length)
+		{
+			throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
+		}
+		this.buffer = buffer;
+		this.length = length;
+	}
+
+	
+	/**
+	 * Loads the stream into a buffer. 
+	 * 
+	 * @param in an InputStream
+	 * @throws IOException If the stream cannot be read.
+	 */
+	public ByteBuffer(InputStream in) throws IOException
+	{
+		// load stream into buffer
+		int chunk = 16384;
+		this.length = 0;
+		this.buffer = new byte[chunk];
+		
+		int read;
+		while ((read = in.read(this.buffer, this.length, chunk)) > 0)
+		{
+			this.length += read;
+			if (read == chunk)
+			{
+				ensureCapacity(length + chunk);
+			}
+			else
+			{
+				break;
+			}
+		}
+	}	
+	
+	
+	/**
+	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
+	 * @param offset the offset of the provided buffer.
+	 * @param length the length of valid bytes in the array
+	 */
+	public ByteBuffer(byte[] buffer, int offset, int length)
+	{
+		if (length > buffer.length - offset)
+		{
+			throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
+		}
+		this.buffer = new byte[length];
+		System.arraycopy(buffer, offset, this.buffer, 0, length);
+		this.length = length;
+	}
+	
+	
+	/**
+	 * @return Returns a byte stream that is limited to the valid amount of bytes.
+	 */
+	public InputStream getByteStream()
+	{
+		return new ByteArrayInputStream(buffer, 0, length);
+	}
+	
+	
+	/**
+	 * @return Returns the length, that means the number of valid bytes, of the buffer;
+	 * the inner byte array might be bigger than that.
+	 */
+	public int length()
+	{
+		return length;
+	}
+
+
+//	/**
+//	 * <em>Note:</em> Only the byte up to length are valid!
+//	 * @return Returns the inner byte buffer.
+//	 */
+//	public byte[] getBuffer()
+//	{
+//		return buffer;
+//	}
+
+	
+	/**
+	 * @param index the index to retrieve the byte from
+	 * @return Returns a byte from the buffer
+	 */
+	public byte byteAt(int index)
+	{
+		if (index < length)
+		{	
+			return buffer[index];
+		}
+		else
+		{
+			throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
+		}
+	}
+
+	
+	/**
+	 * @param index the index to retrieve a byte as int or char.
+	 * @return Returns a byte from the buffer
+	 */
+	public int charAt(int index)
+	{
+		if (index < length)
+		{	
+			return buffer[index] & 0xFF;
+		}
+		else
+		{
+			throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
+		}
+	}
+	
+	
+	/**
+	 * Appends a byte to the buffer.
+	 * @param b a byte
+	 */
+	public void append(byte b)
+	{
+		ensureCapacity(length + 1);
+		buffer[length++] = b;
+	}
+	
+	
+	/**
+	 * Appends a byte array or part of to the buffer.
+	 * 
+	 * @param bytes a byte array
+	 * @param offset an offset with
+	 * @param len
+	 */
+	public void append(byte[] bytes, int offset, int len)
+	{
+		ensureCapacity(length + len);
+		System.arraycopy(bytes, offset, buffer, length, len);
+		length += len;
+	}
+	
+	
+	/**
+	 * Append a byte array to the buffer 
+	 * @param bytes a byte array
+	 */
+	public void append(byte[] bytes)
+	{
+		append(bytes, 0, bytes.length);
+	}
+	
+	
+	/**
+	 * Append another buffer to this buffer. 
+	 * @param anotherBuffer another <code>ByteBuffer</code>
+	 */
+	public void append(ByteBuffer anotherBuffer)
+	{
+		append(anotherBuffer.buffer, 0, anotherBuffer.length); 
+	}
+	
+	
+	/**
+	 * Detects the encoding of the byte buffer, stores and returns it. 
+	 * Only UTF-8, UTF-16LE/BE and UTF-32LE/BE are recognized.
+	 * <em>Note:</em> UTF-32 flavors are not supported by Java, the XML-parser will complain.
+	 *
+	 * @return Returns the encoding string.
+	 */
+	public String getEncoding()
+	{
+		if (encoding == null)
+		{	
+			// needs four byte at maximum to determine encoding
+			if (length < 2)
+			{
+				// only one byte length must be UTF-8
+				encoding = "UTF-8";
+			}
+			else if (buffer[0] == 0)
+			{
+				// These cases are:
+				//   00 nn -- -- - Big endian UTF-16
+				//   00 00 00 nn - Big endian UTF-32
+				//   00 00 FE FF - Big endian UTF 32
+		
+				if (length < 4  ||  buffer[1] != 0)
+				{
+					encoding =  "UTF-16BE";
+				}
+				else if ((buffer[2] & 0xFF) == 0xFE  &&  (buffer[3] & 0xFF) == 0xFF)
+				{
+					encoding = "UTF-32BE";
+				}
+				else
+				{
+					encoding = "UTF-32";
+				}
+			} 
+			else if ((buffer[0] & 0xFF) < 0x80)
+			{
+				// These cases are:
+				//   nn mm -- -- - UTF-8, includes EF BB BF case
+				//   nn 00 -- -- - Little endian UTF-16
+		
+				if (buffer[1] != 0)
+				{
+					encoding = "UTF-8";
+				}
+				else if (length < 4  ||  buffer[2] != 0) 
+				{
+					encoding = "UTF-16LE";
+				}
+				else
+				{
+					encoding = "UTF-32LE";
+				}
+			}
+			else
+			{
+				// These cases are:
+				//   EF BB BF -- - UTF-8
+				//   FE FF -- -- - Big endian UTF-16
+				//   FF FE 00 00 - Little endian UTF-32
+				//   FF FE -- -- - Little endian UTF-16
+		
+				if ((buffer[0] & 0xFF) == 0xEF)
+				{
+					encoding = "UTF-8";
+				}
+				else if ((buffer[0] & 0xFF) == 0xFE)
+				{
+					encoding = "UTF-16"; // in fact BE 
+				}
+				else if (length < 4  ||  buffer[2] != 0)
+				{
+					encoding = "UTF-16"; // in fact LE
+				}
+				else
+				{
+					encoding = "UTF-32"; // in fact LE
+				}
+			}
+		}
+		
+		return encoding;
+	}
+	
+	
+	/**
+	 * Ensures the requested capacity by increasing the buffer size when the
+	 * current length is exceeded.
+	 * 
+	 * @param requestedLength requested new buffer length
+	 */
+	private void ensureCapacity(int requestedLength)
+	{
+		if (requestedLength > buffer.length)
+		{
+			byte[] oldBuf = buffer;
+			buffer = new byte[oldBuf.length * 2];
+			System.arraycopy(oldBuf, 0, buffer, 0, oldBuf.length);
+		}
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/CountOutputStream.java b/XMPCore/src/com/adobe/xmp/impl/CountOutputStream.java
new file mode 100644
index 0000000..ded1296
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/CountOutputStream.java
@@ -0,0 +1,79 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * An <code>OutputStream</code> that counts the written bytes.
+ * 
+ * @since   08.11.2006
+ */
+public final class CountOutputStream extends OutputStream
+{
+	/** the decorated output stream */
+	private final OutputStream out;
+	/** the byte counter */
+	private int bytesWritten = 0;
+
+
+	/**
+	 * Constructor with providing the output stream to decorate.
+	 * @param out an <code>OutputStream</code>
+	 */
+	CountOutputStream(OutputStream out)
+	{
+		this.out = out;
+	}
+
+
+	/**
+	 * Counts the written bytes.
+	 * @see java.io.OutputStream#write(byte[], int, int)
+	 */
+	public void write(byte[] buf, int off, int len) throws IOException
+	{
+		out.write(buf, off, len);
+		bytesWritten += len;
+	}
+
+
+	/**
+	 * Counts the written bytes.
+	 * @see java.io.OutputStream#write(byte[])
+	 */
+	public void write(byte[] buf) throws IOException
+	{
+		out.write(buf);
+		bytesWritten += buf.length;
+	}
+
+
+	/**
+	 * Counts the written bytes.
+	 * @see java.io.OutputStream#write(int)
+	 */
+	public void write(int b) throws IOException
+	{
+		out.write(b);
+		bytesWritten++;
+	}
+
+
+	/**
+	 * @return the bytesWritten
+	 */
+	public int getBytesWritten()
+	{
+		return bytesWritten;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/FixASCIIControlsReader.java b/XMPCore/src/com/adobe/xmp/impl/FixASCIIControlsReader.java
new file mode 100644
index 0000000..c6ac7d4
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/FixASCIIControlsReader.java
@@ -0,0 +1,214 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+
+
+/**
+ * @since   22.08.2006
+ */
+public class FixASCIIControlsReader extends PushbackReader
+{
+	/** */
+	private static final int STATE_START = 0;
+	/** */
+	private static final int STATE_AMP = 1;
+	/** */
+	private static final int STATE_HASH = 2;
+	/** */
+	private static final int STATE_HEX = 3;
+	/** */
+	private static final int STATE_DIG1 = 4;
+	/** */
+	private static final int STATE_ERROR = 5;
+	/** */
+	private static final int BUFFER_SIZE = 8;
+	/** the state of the automaton */
+	private int state = STATE_START;
+	/** the result of the escaping sequence */
+	private int control = 0;
+	/** count the digits of the sequence */
+	private int digits = 0; 
+	
+	/**
+	 * The look-ahead size is 6 at maximum (&amp;#xAB;)
+	 * @see PushbackReader#PushbackReader(Reader, int)
+	 * @param in a Reader
+	 */
+	public FixASCIIControlsReader(Reader in)
+	{
+		super(in, BUFFER_SIZE);
+	}
+
+	
+	/**
+	 * @see Reader#read(char[], int, int)
+	 */
+	public int read(char[] cbuf, int off, int len) throws IOException
+	{
+		int readAhead = 0;
+		int read = 0;
+		int pos = off;
+		char[] readAheadBuffer = new char[BUFFER_SIZE];
+		
+		boolean available = true;
+		while (available  &&  read < len)
+		{
+			available = super.read(readAheadBuffer, readAhead, 1) == 1;
+			if (available)
+			{
+				char c = processChar(readAheadBuffer[readAhead]);
+				if (state == STATE_START)
+				{
+					// replace control chars with space
+					if (Utils.isControlChar(c))
+					{	
+						c = ' ';
+					}	
+					cbuf[pos++] = c;
+					readAhead = 0;
+					read++;
+				}
+				else if (state == STATE_ERROR)
+				{
+					unread(readAheadBuffer, 0, readAhead + 1);
+					readAhead = 0;
+				}
+				else
+				{
+					readAhead++;
+				}
+			}
+			else if (readAhead > 0)
+			{
+				// handles case when file ends within excaped sequence
+				unread(readAheadBuffer, 0, readAhead);
+				state = STATE_ERROR;
+				readAhead = 0;
+				available = true;
+			}
+		}
+		
+		
+		return read > 0  ||  available ? read : -1; 
+	}
+	
+	
+	/**
+	 * Processes numeric escaped chars to find out if they are a control character.
+	 * @param ch a char
+	 * @return Returns the char directly or as replacement for the escaped sequence.
+	 */
+	private char processChar(char ch)
+	{
+		switch (state)
+		{
+			case STATE_START:
+				if (ch == '&')
+				{
+					state = STATE_AMP;
+				}
+				return ch;
+				
+			case STATE_AMP:
+				if (ch == '#')
+				{
+					state = STATE_HASH;
+				}
+				else
+				{
+					state = STATE_ERROR;
+				}	
+				return ch;
+				
+			case STATE_HASH:
+				if (ch == 'x')
+				{
+					control = 0;
+					digits = 0;
+					state = STATE_HEX;
+				}
+				else if ('0' <= ch  &&  ch <= '9')
+				{	
+					control = Character.digit(ch, 10);
+					digits = 1;
+					state = STATE_DIG1;
+				}
+				else
+				{
+					state = STATE_ERROR;
+				}
+				return ch;
+				
+			case STATE_DIG1:
+				if ('0' <= ch  &&  ch <= '9')
+				{	
+					control = control * 10 + Character.digit(ch, 10);
+					digits++;
+					if (digits <= 5)
+					{	
+						state = STATE_DIG1;
+					}
+					else
+					{
+						state = STATE_ERROR; // sequence too long
+					}
+				}
+				else if (ch == ';'  &&  Utils.isControlChar((char) control))
+				{
+					state = STATE_START;
+					return (char) control;
+				}
+				else
+				{
+					state = STATE_ERROR;
+				}	
+				return ch;
+				
+			case STATE_HEX:
+				if (('0' <= ch  &&  ch <= '9')  ||
+					('a' <= ch  &&  ch <= 'f')  ||
+					('A' <= ch  &&  ch <= 'F'))
+				{	
+					control = control * 16 + Character.digit(ch, 16);
+					digits++;
+					if (digits <= 4)
+					{	
+						state = STATE_HEX;
+					}
+					else
+					{
+						state = STATE_ERROR; // sequence too long
+					}
+				}
+				else if (ch == ';'  &&   Utils.isControlChar((char) control))
+				{
+					state = STATE_START;
+					return (char) control;
+				}
+				else
+				{
+					state = STATE_ERROR;
+				}	
+				return ch;
+
+			case STATE_ERROR:
+				state = STATE_START;
+				return ch;
+				
+			default:
+				// not reachable
+				return ch;
+		}
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/ISO8601Converter.java b/XMPCore/src/com/adobe/xmp/impl/ISO8601Converter.java
new file mode 100644
index 0000000..b38bb16
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/ISO8601Converter.java
@@ -0,0 +1,505 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+
+import com.adobe.xmp.XMPDateTime;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+
+
+/**
+ * Converts between ISO 8601 Strings and <code>Calendar</code> with millisecond resolution.
+ *
+ * @since   16.02.2006
+ */
+public final class ISO8601Converter
+{
+	/** Hides public constructor */
+	private ISO8601Converter()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Converts an ISO 8601 string to an <code>XMPDateTime</code>.
+	 * 
+	 * Parse a date according to ISO 8601 and
+	 * http://www.w3.org/TR/NOTE-datetime:
+	 * <ul>
+	 * <li>YYYY
+	 * <li>YYYY-MM
+	 * <li>YYYY-MM-DD
+	 * <li>YYYY-MM-DDThh:mmTZD
+	 * <li>YYYY-MM-DDThh:mm:ssTZD
+	 * <li>YYYY-MM-DDThh:mm:ss.sTZD
+	 * </ul>
+	 * 
+	 * Data fields:
+	 * <ul>
+	 * <li>YYYY = four-digit year
+	 * <li>MM = two-digit month (01=January, etc.)
+	 * <li>DD = two-digit day of month (01 through 31)
+	 * <li>hh = two digits of hour (00 through 23)
+	 * <li>mm = two digits of minute (00 through 59)
+	 * <li>ss = two digits of second (00 through 59)
+	 * <li>s = one or more digits representing a decimal fraction of a second
+	 * <li>TZD = time zone designator (Z or +hh:mm or -hh:mm)
+	 * </ul>
+	 * 
+	 * Note that ISO 8601 does not seem to allow years less than 1000 or greater
+	 * than 9999. We allow any year, even negative ones. The year is formatted
+	 * as "%.4d".
+	 * <p>
+	 * <em>Note:</em> Tolerate missing TZD, assume is UTC. Photoshop 8 writes
+	 * dates like this for exif:GPSTimeStamp.<br>
+	 * <em>Note:</em> Tolerate missing date portion, in case someone foolishly
+	 * writes a time-only value that way.
+	 * 
+	 * @param iso8601String a date string that is ISO 8601 conform.
+	 * @return Returns a <code>Calendar</code>.
+	 * @throws XMPException Is thrown when the string is non-conform.
+	 */
+	public static XMPDateTime parse(String iso8601String) throws XMPException
+	{
+		return parse(iso8601String, new XMPDateTimeImpl());
+	}
+	
+
+	/**
+	 * @param iso8601String a date string that is ISO 8601 conform.
+	 * @param binValue an existing XMPDateTime to set with the parsed date
+	 * @return Returns an XMPDateTime-object containing the ISO8601-date.
+	 * @throws XMPException Is thrown when the string is non-conform.
+	 */
+	public static XMPDateTime parse(String iso8601String, XMPDateTime binValue) throws XMPException
+	{
+		ParameterAsserts.assertNotNull(iso8601String);
+		
+		ParseState input = new ParseState(iso8601String);
+		int value;
+		
+		boolean timeOnly =  
+			 input.ch(0) == 'T'  ||
+			(input.length() >= 2  &&  input.ch(1) == ':'  ||
+			(input.length() >= 3  &&  input.ch(2) == ':'));
+		
+		if (!timeOnly)
+		{
+			if (input.ch(0) == '-')
+			{
+				input.skip();
+			}
+
+			
+			// Extract the year.
+			value = input.gatherInt("Invalid year in date string", 9999);
+			if (input.hasNext()  &&  input.ch() != '-')
+			{
+				throw new XMPException("Invalid date string, after year", XMPError.BADVALUE);
+			}
+
+			if (input.ch(0) == '-')
+			{
+				value = -value;
+			}
+			binValue.setYear(value);
+			if (!input.hasNext())
+			{
+				return binValue;
+			}
+			input.skip();
+			
+			
+			// Extract the month.
+			value = input.gatherInt("Invalid month in date string", 12);
+			if (input.hasNext()  &&  input.ch() != '-')
+			{
+				throw new XMPException("Invalid date string, after month", XMPError.BADVALUE);
+			}
+			binValue.setMonth(value);
+			if (!input.hasNext())
+			{
+				return binValue;
+			}
+			input.skip();
+
+			
+			// Extract the day.
+			value = input.gatherInt("Invalid day in date string", 31);
+			if (input.hasNext()  &&  input.ch() != 'T')
+			{
+				throw new XMPException("Invalid date string, after day", XMPError.BADVALUE);
+			}
+			binValue.setDay(value);
+			if (!input.hasNext())
+			{
+				return binValue;
+			}
+		}
+		else
+		{
+			// set default day and month in the year 0000
+			binValue.setMonth(1);
+			binValue.setDay(1);
+		}
+			
+		if (input.ch() == 'T')
+		{
+			input.skip();
+		}
+		else if (!timeOnly)
+		{
+			throw new XMPException("Invalid date string, missing 'T' after date",
+					XMPError.BADVALUE);
+		}
+
+		
+		// Extract the hour.
+		value = input.gatherInt("Invalid hour in date string", 23);
+		if (input.ch() != ':')
+		{
+			throw new XMPException("Invalid date string, after hour", XMPError.BADVALUE);
+		}
+		binValue.setHour(value);
+		
+		// Don't check for done, we have to work up to the time zone.
+		input.skip();
+		
+		
+		// Extract the minute.
+		value = input.gatherInt("Invalid minute in date string", 59);
+		if (input.hasNext()  &&
+			input.ch() != ':' && input.ch() != 'Z' && input.ch() != '+' && input.ch() != '-')
+		{
+			throw new XMPException("Invalid date string, after minute", XMPError.BADVALUE);
+		}
+		binValue.setMinute(value);
+		
+		if (input.ch() == ':')
+		{
+			input.skip();
+			value = input.gatherInt("Invalid whole seconds in date string", 59);
+			if (input.hasNext()  &&  input.ch() != '.'  &&  input.ch() != 'Z'  && 
+				input.ch() != '+' && input.ch() != '-')
+			{
+				throw new XMPException("Invalid date string, after whole seconds",
+						XMPError.BADVALUE);
+			}
+			binValue.setSecond(value);
+			if (input.ch() == '.')
+			{
+				input.skip();
+				int digits = input.pos();
+				value = input.gatherInt("Invalid fractional seconds in date string", 999999999);
+				if (input.ch() != 'Z'  &&  input.ch() != '+'  &&  input.ch() != '-')
+				{
+					throw new XMPException("Invalid date string, after fractional second",
+							XMPError.BADVALUE);
+				}
+				digits = input.pos() - digits;
+				for (; digits > 9; --digits)
+				{	
+					value = value / 10;
+				}	
+				for (; digits < 9; ++digits)
+				{	
+					value = value * 10;
+				}	
+				binValue.setNanoSecond(value);
+			}
+		}
+		
+		int tzSign = 0;
+		int tzHour = 0;
+		int tzMinute = 0;
+		if (input.ch() == 'Z')
+		{
+			input.skip();
+		}
+		else if (input.hasNext())
+		{
+			if (input.ch() == '+')
+			{
+				tzSign = 1;
+			}
+			else if (input.ch() == '-')
+			{
+				tzSign = -1;
+			}
+			else
+			{
+				throw new XMPException("Time zone must begin with 'Z', '+', or '-'",
+						XMPError.BADVALUE);
+			}
+
+			input.skip();
+			// Extract the time zone hour.
+			tzHour = input.gatherInt("Invalid time zone hour in date string", 23);
+			if (input.ch() != ':')
+			{
+				throw new XMPException("Invalid date string, after time zone hour",
+						XMPError.BADVALUE);
+			}
+			input.skip();
+
+			// Extract the time zone minute.
+			tzMinute = input.gatherInt("Invalid time zone minute in date string", 59);
+		}
+		
+		// create a corresponding TZ and set it time zone
+		int offset = (tzHour * 3600 * 1000 + tzMinute * 60 * 1000) * tzSign;   
+		binValue.setTimeZone(new SimpleTimeZone(offset, ""));
+		
+
+		if (input.hasNext())
+		{
+			throw new XMPException(
+				"Invalid date string, extra chars at end", XMPError.BADVALUE);
+		}
+		
+		return binValue;
+	}
+
+	
+	/**
+	 * Converts a <code>Calendar</code> into an ISO 8601 string.
+	 * Format a date according to ISO 8601 and http://www.w3.org/TR/NOTE-datetime:
+	 * <ul>
+	 * <li>YYYY
+	 * <li>YYYY-MM
+	 * <li>YYYY-MM-DD
+	 * <li>YYYY-MM-DDThh:mmTZD
+	 * <li>YYYY-MM-DDThh:mm:ssTZD
+	 * <li>YYYY-MM-DDThh:mm:ss.sTZD
+	 * </ul>
+	 * 
+	 * Data fields:
+	 * <ul>
+	 * <li>YYYY = four-digit year
+	 * <li>MM	 = two-digit month (01=January, etc.)
+	 * <li>DD	 = two-digit day of month (01 through 31)
+	 * <li>hh	 = two digits of hour (00 through 23)
+	 * <li>mm	 = two digits of minute (00 through 59)
+	 * <li>ss	 = two digits of second (00 through 59)
+	 * <li>s	 = one or more digits representing a decimal fraction of a second
+	 * <li>TZD	 = time zone designator (Z or +hh:mm or -hh:mm)
+	 * </ul>
+	 * <p>
+	 * <em>Note:</em> ISO 8601 does not seem to allow years less than 1000 or greater than 9999. 
+	 * We allow any year, even negative ones. The year is formatted as "%.4d".<p>
+	 * <em>Note:</em> Fix for bug 1269463 (silently fix out of range values) included in parsing.
+	 * The quasi-bogus "time only" values from Photoshop CS are not supported.
+	 * 
+	 * @param dateTime an XMPDateTime-object.
+	 * @return Returns an ISO 8601 string.
+	 */
+	public static String render(XMPDateTime dateTime)
+	{
+		StringBuffer buffer = new StringBuffer();
+
+		// year is rendered in any case, even 0000
+		DecimalFormat df = new DecimalFormat("0000", new DecimalFormatSymbols(Locale.ENGLISH));
+		buffer.append(df.format(dateTime.getYear()));
+		if (dateTime.getMonth() == 0)
+		{
+			return buffer.toString();
+		}
+
+		// month
+		df.applyPattern("'-'00");
+		buffer.append(df.format(dateTime.getMonth()));
+		if (dateTime.getDay() == 0)
+		{
+			return buffer.toString();
+		}
+
+		// day
+		buffer.append(df.format(dateTime.getDay()));
+		
+		// time, rendered if any time field is not zero
+		if (dateTime.getHour() != 0  ||
+			dateTime.getMinute() != 0  ||
+			dateTime.getSecond() != 0  ||
+			dateTime.getNanoSecond() != 0  ||
+			(dateTime.getTimeZone() != null  &&  dateTime.getTimeZone().getRawOffset() != 0))
+		{
+			// hours and minutes
+			buffer.append('T');
+			df.applyPattern("00");
+			buffer.append(df.format(dateTime.getHour()));
+			buffer.append(':');
+			buffer.append(df.format(dateTime.getMinute()));
+			
+			// seconds and nanoseconds
+			if (dateTime.getSecond() != 0 || dateTime.getNanoSecond() != 0)
+			{
+				double seconds = dateTime.getSecond() + dateTime.getNanoSecond() / 1e9d;
+
+				df.applyPattern(":00.#########");
+				buffer.append(df.format(seconds));
+			}
+			
+			// time zone
+			if (dateTime.getTimeZone() != null)
+			{
+				// used to calculate the time zone offset incl. Daylight Savings
+				long timeInMillis = dateTime.getCalendar().getTimeInMillis();
+				int offset = dateTime.getTimeZone().getOffset(timeInMillis);				
+				if (offset == 0)
+				{
+					// UTC
+					buffer.append('Z');
+				}
+				else
+				{
+					int thours = offset / 3600000;
+					int tminutes = Math.abs(offset % 3600000 / 60000);
+					df.applyPattern("+00;-00");
+					buffer.append(df.format(thours));
+					df.applyPattern(":00");
+					buffer.append(df.format(tminutes));
+				}	
+			}
+		}	
+		return buffer.toString();
+	}
+	
+	
+}
+
+
+/**
+ * @since   22.08.2006
+ */
+class ParseState
+{
+	/** */
+	private String str;
+	/** */
+	private int pos = 0;
+
+	
+	/**
+	 * @param str initializes the parser container
+	 */
+	public ParseState(String str)
+	{
+		this.str = str;
+	}
+	
+	
+	/**
+	 * @return Returns the length of the input.
+	 */
+	public int length()
+	{
+		return str.length();
+	}
+
+
+	/**
+	 * @return Returns whether there are more chars to come.
+	 */
+	public boolean hasNext()
+	{
+		return pos < str.length();
+	}
+
+	
+	/**
+	 * @param index index of char
+	 * @return Returns char at a certain index.
+	 */
+	public char ch(int index)
+	{
+		return index < str.length() ? 
+			str.charAt(index) :
+			0x0000;
+	}
+
+	
+	/**
+	 * @return Returns the current char or 0x0000 if there are no more chars.
+	 */
+	public char ch()
+	{
+		return pos < str.length() ? 
+			str.charAt(pos) :
+			0x0000;
+	}
+	
+	
+	/**
+	 * Skips the next char.
+	 */
+	public void skip()
+	{
+		pos++;
+	}
+
+	
+	/**
+	 * @return Returns the current position.
+	 */
+	public int pos()
+	{
+		return pos;
+	}
+	
+	
+	/**
+	 * Parses a integer from the source and sets the pointer after it.
+	 * @param errorMsg Error message to put in the exception if no number can be found
+	 * @param maxValue the max value of the number to return 
+	 * @return Returns the parsed integer.
+	 * @throws XMPException Thrown if no integer can be found.
+	 */
+	public int gatherInt(String errorMsg, int maxValue) throws XMPException
+	{
+		int value = 0;
+		boolean success = false;
+		char ch = ch(pos);
+		while ('0' <= ch  &&  ch <= '9')
+		{
+			value = (value * 10) + (ch - '0');
+			success = true;
+			pos++;
+			ch = ch(pos);
+		}
+		
+		if (success)
+		{
+			if (value > maxValue)
+			{
+				return maxValue;
+			}
+			else if (value < 0)
+			{
+				return 0;
+			}
+			else
+			{	
+				return value;
+			}	
+		}
+		else
+		{
+			throw new XMPException(errorMsg, XMPError.BADVALUE);
+		}
+	}
+}	
+
+
diff --git a/XMPCore/src/com/adobe/xmp/impl/Latin1Converter.java b/XMPCore/src/com/adobe/xmp/impl/Latin1Converter.java
new file mode 100644
index 0000000..118d77d
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/Latin1Converter.java
@@ -0,0 +1,197 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+
+
+package com.adobe.xmp.impl;
+
+import java.io.UnsupportedEncodingException;
+
+
+/**
+ * @since   12.10.2006
+ */
+public class Latin1Converter
+{
+	/** */
+	private static final int STATE_START = 0;
+	/** */
+	private static final int STATE_UTF8CHAR = 11;
+
+	
+	/**
+	 * Private constructor
+	 */
+	private Latin1Converter()
+	{
+		// EMPTY
+	}
+	
+	
+	/**
+	 * A converter that processes a byte buffer containing a mix of UTF8 and Latin-1/Cp1252 chars.
+	 * The result is a buffer where those chars have been converted to UTF-8; 
+	 * that means it contains only valid UTF-8 chars.
+	 * <p>
+	 * <em>Explanation of the processing:</em> First the encoding of the buffer is detected looking 
+	 * at the first four bytes (that works only if the buffer starts with an ASCII-char, 
+	 * like xmls &apos;&lt;&apos;). UTF-16/32 flavours do not require further proccessing.
+	 * <p> 
+	 * In the case, UTF-8 is detected, it assumes wrong UTF8 chars to be a sequence of 
+	 * Latin-1/Cp1252 encoded bytes and converts the chars to their corresponding UTF-8 byte 
+	 * sequence.
+	 * <p> 
+	 * The 0x80..0x9F range is undefined in Latin-1, but is defined in Windows code
+	 * page 1252. The bytes 0x81, 0x8D, 0x8F, 0x90, and 0x9D are formally undefined
+	 * by Windows 1252. These are in XML's RestrictedChar set, so we map them to a
+	 * space. 
+	 * <p>
+	 * The official Latin-1 characters in the range 0xA0..0xFF are converted into
+	 * the Unicode Latin Supplement range U+00A0 - U+00FF.
+	 * <p>
+	 * <em>Example:</em> If an Euro-symbol (€) appears in the byte buffer (0xE2, 0x82, 0xAC), 
+	 * it will be left as is. But if only the first two bytes are appearing, 
+	 * followed by an ASCII char a (0xE2 - 0x82 - 0x41), it will be converted to 
+	 * 0xC3, 0xA2 (â) - 0xE2, 0x80, 0x9A (‚) - 0x41 (a).
+	 *  
+	 * @param buffer a byte buffer contain
+	 * @return Returns a new buffer containing valid UTF-8
+	 */
+	public static ByteBuffer convert(ByteBuffer buffer)
+	{
+		if ("UTF-8".equals(buffer.getEncoding()))
+		{
+			// the buffer containing one UTF-8 char (up to 8 bytes) 
+			byte[] readAheadBuffer = new byte[8];
+			// the number of bytes read ahead.
+			int readAhead  = 0;
+			// expected UTF8 bytesto come
+			int expectedBytes = 0;
+			// output buffer with estimated length
+			ByteBuffer out = new ByteBuffer(buffer.length() * 4 / 3);
+			
+			int state = STATE_START;
+			for (int i = 0; i < buffer.length(); i++)
+			{
+				int b = buffer.charAt(i);
+			
+				switch (state)
+				{
+					default:
+					case STATE_START:
+						if (b < 0x7F)
+						{
+							out.append((byte) b);
+						}
+						else if (b >= 0xC0)
+						{
+							// start of UTF8 sequence
+							expectedBytes = -1;
+							int test = b;
+							for (; expectedBytes < 8  &&  (test & 0x80) == 0x80; test = test << 1)
+							{
+								expectedBytes++;
+							}
+							readAheadBuffer[readAhead++] = (byte) b;
+							state = STATE_UTF8CHAR;
+						}
+						else //  implicitly:  b >= 0x80  &&  b < 0xC0
+						{
+							// invalid UTF8 start char, assume to be Latin-1
+							byte[] utf8 = convertToUTF8((byte) b);
+							out.append(utf8);
+						}
+						break;
+						
+					case STATE_UTF8CHAR:
+						if (expectedBytes > 0  &&  (b & 0xC0) == 0x80)
+						{
+							// valid UTF8 char, add to readAheadBuffer
+							readAheadBuffer[readAhead++] = (byte) b;
+							expectedBytes--;
+							
+							if (expectedBytes == 0)
+							{
+								out.append(readAheadBuffer, 0, readAhead);
+								readAhead = 0;
+								
+								state = STATE_START;
+							}
+						}
+						else
+						{
+							// invalid UTF8 char: 
+							// 1. convert first of seq to UTF8 
+							byte[] utf8 = convertToUTF8(readAheadBuffer[0]);
+							out.append(utf8);
+
+							// 2. continue processing at second byte of sequence
+							i = i - readAhead;
+							readAhead = 0;
+							
+							state = STATE_START;
+						}
+						break;
+				}		
+			}
+			
+			// loop ends with "half" Utf8 char --> assume that the bytes are Latin-1
+			if (state == STATE_UTF8CHAR)
+			{
+				for (int j = 0; j < readAhead; j++)
+				{
+					byte b = readAheadBuffer[j];
+					byte[] utf8 = convertToUTF8(b);
+					out.append(utf8);
+				}
+			}
+			
+			return out;
+		}
+		else
+		{
+			// Latin-1 fixing applies only to UTF-8
+			return buffer;
+		}	
+	}
+		
+		
+	/**
+	 * Converts a Cp1252 char (contains all Latin-1 chars above 0x80) into a
+	 * UTF-8 byte sequence. The bytes 0x81, 0x8D, 0x8F, 0x90, and 0x9D are
+	 * formally undefined by Windows 1252 and therefore replaced by a space
+	 * (0x20).
+	 * 
+	 * @param ch
+	 *            an Cp1252 / Latin-1 byte
+	 * @return Returns a byte array containing a UTF-8 byte sequence.
+	 */
+	private static byte[] convertToUTF8(byte ch)
+	{
+		int c = ch & 0xFF; 
+		try
+		{
+			if (c >= 0x80)
+			{
+				if (c == 0x81  ||  c == 0x8D  ||  c == 0x8F  ||  c == 0x90  ||  c == 0x9D)
+				{
+					return new byte[] { 0x20 }; // space for undefined 
+				}
+				
+				// interpret byte as Windows Cp1252 char
+				return new String(new byte[] { ch }, "cp1252").getBytes("UTF-8");
+			}
+		}	
+		catch (UnsupportedEncodingException e)
+		{
+			// EMPTY
+		}
+		return new byte[] { ch };
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/ParameterAsserts.java b/XMPCore/src/com/adobe/xmp/impl/ParameterAsserts.java
new file mode 100644
index 0000000..78ae5d6
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/ParameterAsserts.java
@@ -0,0 +1,153 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+
+
+/**
+ * @since   11.08.2006
+ */
+class ParameterAsserts implements XMPConst
+{
+	/**
+	 * private constructor
+	 */
+	private ParameterAsserts()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Asserts that an array name is set.
+	 * @param arrayName an array name
+	 * @throws XMPException Array name is null or empty
+	 */
+	public static void assertArrayName(String arrayName) throws XMPException
+	{
+		if (arrayName == null  ||  arrayName.length() == 0)
+		{
+			throw new XMPException("Empty array name", XMPError.BADPARAM);
+		}
+	}
+
+	
+	/**
+	 * Asserts that a property name is set.
+	 * @param propName a property name or path
+	 * @throws XMPException Property name is null or empty
+	 */
+	public static void assertPropName(String propName) throws XMPException
+	{
+		if (propName == null  ||  propName.length() == 0)
+		{
+			throw new XMPException("Empty property name", XMPError.BADPARAM);
+		}
+	}
+
+	
+	/**
+	 * Asserts that a schema namespace is set.
+	 * @param schemaNS a schema namespace
+	 * @throws XMPException Schema is null or empty
+	 */
+	public static void assertSchemaNS(String schemaNS) throws XMPException
+	{
+		if (schemaNS == null  ||  schemaNS.length() == 0)
+		{
+			throw new XMPException("Empty schema namespace URI", XMPError.BADPARAM);
+		}
+	}
+
+	
+	/**
+	 * Asserts that a prefix is set.
+	 * @param prefix a prefix
+	 * @throws XMPException Prefix is null or empty
+	 */
+	public static void assertPrefix(String prefix) throws XMPException
+	{
+		if (prefix == null  ||  prefix.length() == 0)
+		{
+			throw new XMPException("Empty prefix", XMPError.BADPARAM);
+		}
+	}
+	
+	
+	/**
+	 * Asserts that a specific language is set.
+	 * @param specificLang a specific lang
+	 * @throws XMPException Specific language is null or empty
+	 */
+	public static void assertSpecificLang(String specificLang) throws XMPException
+	{
+		if (specificLang == null  ||  specificLang.length() == 0)
+		{
+			throw new XMPException("Empty specific language", XMPError.BADPARAM);
+		}
+	}
+
+	
+	/**
+	 * Asserts that a struct name is set.
+	 * @param structName a struct name
+	 * @throws XMPException Struct name is null or empty
+	 */
+	public static void assertStructName(String structName) throws XMPException
+	{
+		if (structName == null  ||  structName.length() == 0)
+		{
+			throw new XMPException("Empty array name", XMPError.BADPARAM);
+		}
+	}
+
+
+	/**
+	 * Asserts that any string parameter is set.
+	 * @param param any string parameter
+	 * @throws XMPException Thrown if the parameter is null or has length 0.
+	 */
+	public static void assertNotNull(Object param) throws XMPException
+	{
+		if (param == null)
+		{
+			throw new XMPException("Parameter must not be null", XMPError.BADPARAM);
+		}
+		else if ((param instanceof String)  &&  ((String) param).length() == 0)
+		{
+			throw new XMPException("Parameter must not be null or empty", XMPError.BADPARAM);
+		}
+	}
+
+
+	/**
+	 * Asserts that the xmp object is of this implemention
+	 * ({@link XMPMetaImpl}). 
+	 * @param xmp the XMP object
+	 * @throws XMPException A wrong implentaion is used.
+	 */
+	public static void assertImplementation(XMPMeta xmp) throws XMPException
+	{
+		if (xmp == null)
+		{
+			throw new XMPException("Parameter must not be null",
+					XMPError.BADPARAM);
+		}
+		else if (!(xmp instanceof XMPMetaImpl))
+		{
+			throw new XMPException("The XMPMeta-object is not compatible with this implementation",
+					XMPError.BADPARAM);
+		}
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/ParseRDF.java b/XMPCore/src/com/adobe/xmp/impl/ParseRDF.java
new file mode 100644
index 0000000..2b96550
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/ParseRDF.java
@@ -0,0 +1,1323 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.XMPSchemaRegistry;
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * Parser for "normal" XML serialisation of RDF.  
+ * 
+ * @since   14.07.2006
+ */
+public class ParseRDF implements XMPError, XMPConst
+{
+	/** */
+	public static final int RDFTERM_OTHER = 0;
+	/** Start of coreSyntaxTerms. */
+	public static final int RDFTERM_RDF = 1;
+	/** */
+	public static final int RDFTERM_ID = 2;
+	/** */
+	public static final int RDFTERM_ABOUT = 3;
+	/** */
+	public static final int RDFTERM_PARSE_TYPE = 4;
+	/** */
+	public static final int RDFTERM_RESOURCE = 5;
+	/** */
+	public static final int RDFTERM_NODE_ID = 6;
+	/** End of coreSyntaxTerms */
+	public static final int RDFTERM_DATATYPE = 7;
+	/** Start of additions for syntax Terms. */
+	public static final int RDFTERM_DESCRIPTION = 8; 
+	/** End of of additions for syntaxTerms. */
+	public static final int RDFTERM_LI = 9;
+	/** Start of oldTerms. */
+	public static final int RDFTERM_ABOUT_EACH = 10; 
+	/** */
+	public static final int RDFTERM_ABOUT_EACH_PREFIX = 11;
+	/** End of oldTerms. */
+	public static final int RDFTERM_BAG_ID = 12;
+	/** */
+	public static final int RDFTERM_FIRST_CORE = RDFTERM_RDF;
+	/** */
+	public static final int RDFTERM_LAST_CORE = RDFTERM_DATATYPE;
+	/** ! Yes, the syntax terms include the core terms. */
+	public static final int RDFTERM_FIRST_SYNTAX = RDFTERM_FIRST_CORE;
+	/** */
+	public static final int RDFTERM_LAST_SYNTAX = RDFTERM_LI;
+	/** */
+	public static final int RDFTERM_FIRST_OLD = RDFTERM_ABOUT_EACH;
+	/** */
+	public static final int RDFTERM_LAST_OLD = RDFTERM_BAG_ID;
+
+	/** this prefix is used for default namespaces */
+	public static final String DEFAULT_PREFIX = "_dflt";
+	
+	
+	
+	/**
+	 * The main parsing method. The XML tree is walked through from the root node and and XMP tree
+	 * is created. This is a raw parse, the normalisation of the XMP tree happens outside.
+	 * 
+	 * @param xmlRoot the XML root node
+	 * @return Returns an XMP metadata object (not normalized)
+	 * @throws XMPException Occurs if the parsing fails for any reason.
+	 */
+	static XMPMetaImpl parse(Node xmlRoot) throws XMPException
+	{
+		XMPMetaImpl xmp = new XMPMetaImpl();
+		rdf_RDF(xmp, xmlRoot);
+		return xmp;
+	}
+	
+	
+	/**
+	 * Each of these parsing methods is responsible for recognizing an RDF
+	 * syntax production and adding the appropriate structure to the XMP tree.
+	 * They simply return for success, failures will throw an exception.
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param rdfRdfNode the top-level xml node
+	 * @throws XMPException thown on parsing errors
+	 */
+	static void rdf_RDF(XMPMetaImpl xmp, Node rdfRdfNode) throws XMPException
+	{
+		if (rdfRdfNode.hasAttributes())
+		{
+			rdf_NodeElementList (xmp, xmp.getRoot(), rdfRdfNode);
+		}	
+		else
+		{	
+			throw new XMPException("Invalid attributes of rdf:RDF element", BADRDF);
+		}
+	}
+	
+	
+	/**
+	 * 7.2.10 nodeElementList<br>
+	 * ws* ( nodeElement ws* )*
+	 * 
+	 * Note: this method is only called from the rdf:RDF-node (top level)
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param rdfRdfNode the top-level xml node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_NodeElementList(XMPMetaImpl xmp, XMPNode xmpParent, Node rdfRdfNode) 
+		throws XMPException
+	{
+		for (int i = 0; i < rdfRdfNode.getChildNodes().getLength(); i++)
+		{
+			Node child = rdfRdfNode.getChildNodes().item(i);
+			// filter whitespaces (and all text nodes)
+			if (!isWhitespaceNode(child))
+			{	
+				rdf_NodeElement  (xmp, xmpParent, child, true);
+			}	
+		} 
+	}
+
+
+	/**
+ 	 * 7.2.5 nodeElementURIs
+	 * 		anyURI - ( coreSyntaxTerms | rdf:li | oldTerms )
+	 *
+ 	 * 7.2.11 nodeElement
+	 * 		start-element ( URI == nodeElementURIs,
+	 * 		attributes == set ( ( idAttr | nodeIdAttr | aboutAttr )?, propertyAttr* ) )
+	 * 		propertyEltList
+	 * 		end-element()
+	 * 
+	 * A node element URI is rdf:Description or anything else that is not an RDF
+	 * term.
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_NodeElement(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode,
+			boolean isTopLevel) throws XMPException
+	{
+		int nodeTerm = getRDFTermKind (xmlNode);
+		if (nodeTerm != RDFTERM_DESCRIPTION  &&  nodeTerm != RDFTERM_OTHER)
+		{
+			throw new XMPException("Node element must be rdf:Description or typed node",
+				BADRDF);
+		}
+		else if (isTopLevel  &&  nodeTerm == RDFTERM_OTHER)
+		{
+			throw new XMPException("Top level typed node not allowed", BADXMP);
+		}
+		else
+		{
+			rdf_NodeElementAttrs (xmp, xmpParent, xmlNode, isTopLevel);
+			rdf_PropertyElementList (xmp, xmpParent, xmlNode, isTopLevel);
+		}
+		
+	}
+
+
+	/**
+	 * 
+	 * 7.2.7 propertyAttributeURIs
+	 * 		anyURI - ( coreSyntaxTerms | rdf:Description | rdf:li | oldTerms )
+	 *
+	 * 7.2.11 nodeElement
+	 * start-element ( URI == nodeElementURIs,
+	 * 					attributes == set ( ( idAttr | nodeIdAttr | aboutAttr )?, propertyAttr* ) )
+	 * 					propertyEltList
+	 * 					end-element()
+	 * 
+	 * Process the attribute list for an RDF node element. A property attribute URI is 
+	 * anything other than an RDF term. The rdf:ID and rdf:nodeID attributes are simply ignored, 
+	 * as are rdf:about attributes on inner nodes.
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_NodeElementAttrs(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode,
+			boolean isTopLevel) throws XMPException
+	{
+		// Used to detect attributes that are mutually exclusive.
+		int exclusiveAttrs = 0;	
+	
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			
+			// quick hack, ns declarations do not appear in C++
+			// ignore "ID" without namespace
+			if ("xmlns".equals(attribute.getPrefix())  ||
+				(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;
+			}
+			
+			int attrTerm = getRDFTermKind(attribute);
+
+			switch (attrTerm)
+			{
+				case RDFTERM_ID:
+				case RDFTERM_NODE_ID:
+				case RDFTERM_ABOUT:
+					if (exclusiveAttrs > 0)
+					{
+						throw new XMPException("Mutally exclusive about, ID, nodeID attributes",
+								BADRDF);
+					}
+					
+					exclusiveAttrs++;
+	
+					if (isTopLevel && (attrTerm == RDFTERM_ABOUT))
+					{
+						// This is the rdf:about attribute on a top level node. Set
+						// the XMP tree name if
+						// it doesn't have a name yet. Make sure this name matches
+						// the XMP tree name.
+						if (xmpParent.getName() != null && xmpParent.getName().length() > 0)
+						{
+							if (!xmpParent.getName().equals(attribute.getNodeValue()))
+							{
+								throw new XMPException("Mismatched top level rdf:about values",
+										BADXMP);
+							}
+						}
+						else
+						{
+							xmpParent.setName(attribute.getNodeValue());
+						}
+					}
+					break;
+	
+				case RDFTERM_OTHER:
+					addChildNode(xmp, xmpParent, attribute, attribute.getNodeValue(), isTopLevel);
+					break;
+	
+				default:
+					throw new XMPException("Invalid nodeElement attribute", BADRDF);
+			}
+
+		}		
+	}
+
+
+	/**
+	 * 7.2.13 propertyEltList
+	 * ws* ( propertyElt ws* )*
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlParent the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_PropertyElementList(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlParent,
+			boolean isTopLevel) throws XMPException
+	{
+		for (int i = 0; i < xmlParent.getChildNodes().getLength(); i++)
+		{
+			Node currChild = xmlParent.getChildNodes().item(i);
+			if (isWhitespaceNode(currChild))
+			{
+				continue;
+			}	
+			else if (currChild.getNodeType() != Node.ELEMENT_NODE)
+			{
+				throw new XMPException("Expected property element node not found", BADRDF);
+			}
+			else
+			{	
+				rdf_PropertyElement(xmp, xmpParent, currChild, isTopLevel);
+			}	
+		}
+	}
+
+
+	/**
+	 * 7.2.14 propertyElt
+	 * 
+	 *		resourcePropertyElt | literalPropertyElt | parseTypeLiteralPropertyElt |
+	 *		parseTypeResourcePropertyElt | parseTypeCollectionPropertyElt | 
+	 *		parseTypeOtherPropertyElt | emptyPropertyElt
+	 *
+	 * 7.2.15 resourcePropertyElt
+	 *		start-element ( URI == propertyElementURIs, attributes == set ( idAttr? ) )
+	 *		ws* nodeElement ws*
+	 *		end-element()
+	 *
+	 * 7.2.16 literalPropertyElt
+	 *		start-element (
+	 *			URI == propertyElementURIs, attributes == set ( idAttr?, datatypeAttr?) )
+	 *		text()
+	 *		end-element()
+	 *
+	 * 7.2.17 parseTypeLiteralPropertyElt
+	 *		start-element (
+	 *			URI == propertyElementURIs, attributes == set ( idAttr?, parseLiteral ) )
+	 *		literal
+	 *		end-element()
+	 *
+	 * 7.2.18 parseTypeResourcePropertyElt
+	 *		start-element (
+	 *			 URI == propertyElementURIs, attributes == set ( idAttr?, parseResource ) )
+	 *		propertyEltList
+	 *		end-element()
+	 *
+	 * 7.2.19 parseTypeCollectionPropertyElt
+	 *		start-element (
+	 *			URI == propertyElementURIs, attributes == set ( idAttr?, parseCollection ) )
+	 *		nodeElementList
+	 *		end-element()
+	 *
+	 * 7.2.20 parseTypeOtherPropertyElt
+	 *		start-element ( URI == propertyElementURIs, attributes == set ( idAttr?, parseOther ) )
+	 *		propertyEltList
+	 *		end-element()
+	 *
+	 * 7.2.21 emptyPropertyElt
+	 *		start-element ( URI == propertyElementURIs,
+	 *			attributes == set ( idAttr?, ( resourceAttr | nodeIdAttr )?, propertyAttr* ) )
+	 *		end-element()
+	 *
+	 * The various property element forms are not distinguished by the XML element name, 
+	 * but by their attributes for the most part. The exceptions are resourcePropertyElt and 
+	 * literalPropertyElt. They are distinguished by their XML element content.
+	 *
+	 * NOTE: The RDF syntax does not explicitly include the xml:lang attribute although it can 
+	 * appear in many of these. We have to allow for it in the attibute counts below.	 
+	 *  
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_PropertyElement(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode,
+			boolean isTopLevel) throws XMPException
+	{
+		int nodeTerm = getRDFTermKind (xmlNode);
+		if (!isPropertyElementName(nodeTerm)) 
+		{
+			throw new XMPException("Invalid property element name", BADRDF);
+		}
+		
+		// remove the namespace-definitions from the list
+		NamedNodeMap attributes = xmlNode.getAttributes();
+		List nsAttrs = null;
+		for (int i = 0; i < attributes.getLength(); i++)
+		{
+			Node attribute = attributes.item(i);
+			if ("xmlns".equals(attribute.getPrefix())  ||
+				(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				if (nsAttrs == null)
+				{
+					nsAttrs = new ArrayList();
+				}
+				nsAttrs.add(attribute.getNodeName());
+			}
+		}
+		if (nsAttrs != null)
+		{
+			for (Iterator it = nsAttrs.iterator(); it.hasNext();)
+			{
+				String ns = (String) it.next();
+				attributes.removeNamedItem(ns);
+			}
+		}
+		
+		
+		if (attributes.getLength() > 3)
+		{
+			// Only an emptyPropertyElt can have more than 3 attributes.
+			rdf_EmptyPropertyElement(xmp, xmpParent, xmlNode, isTopLevel);
+		} 
+		else 
+		{
+			// Look through the attributes for one that isn't rdf:ID or xml:lang, 
+			// it will usually tell what we should be dealing with. 
+			// The called routines must verify their specific syntax!
+	
+			for (int i = 0; i < attributes.getLength(); i++)
+			{
+				Node attribute = attributes.item(i);
+				String attrLocal = attribute.getLocalName();
+				String attrNS = attribute.getNamespaceURI();
+				String attrValue = attribute.getNodeValue();
+				if (!(XML_LANG.equals(attribute.getNodeName())  &&
+					!("ID".equals(attrLocal)  &&  NS_RDF.equals(attrNS))))  
+				{
+					if ("datatype".equals(attrLocal)  &&  NS_RDF.equals(attrNS))
+					{
+						rdf_LiteralPropertyElement (xmp, xmpParent, xmlNode, isTopLevel);
+					}
+					else if (!("parseType".equals(attrLocal)  &&  NS_RDF.equals(attrNS)))
+					{
+						rdf_EmptyPropertyElement (xmp, xmpParent, xmlNode, isTopLevel);
+					}
+					else if ("Literal".equals(attrValue))
+					{
+						rdf_ParseTypeLiteralPropertyElement();
+					}
+					else if ("Resource".equals(attrValue))
+					{
+						rdf_ParseTypeResourcePropertyElement(xmp, xmpParent, xmlNode, isTopLevel);
+					}
+					else if ("Collection".equals(attrValue))
+					{
+						rdf_ParseTypeCollectionPropertyElement();
+					}
+					else
+					{
+						rdf_ParseTypeOtherPropertyElement();
+					}
+		
+					return;
+				}
+			}
+			
+			// Only rdf:ID and xml:lang, could be a resourcePropertyElt, a literalPropertyElt, 
+			// or an emptyPropertyElt. Look at the child XML nodes to decide which.
+
+			if (xmlNode.hasChildNodes())
+			{
+				for (int i = 0; i < xmlNode.getChildNodes().getLength(); i++)
+				{
+					Node currChild = xmlNode.getChildNodes().item(i);
+					if (currChild.getNodeType() != Node.TEXT_NODE)
+					{
+						rdf_ResourcePropertyElement (xmp, xmpParent, xmlNode, isTopLevel);
+						return;
+					}
+				}
+				
+				rdf_LiteralPropertyElement (xmp, xmpParent, xmlNode, isTopLevel);
+			}
+			else
+			{
+				rdf_EmptyPropertyElement (xmp, xmpParent, xmlNode, isTopLevel);
+			}
+		}		
+	}
+
+	
+	/**
+	 * 7.2.15 resourcePropertyElt
+	 *		start-element ( URI == propertyElementURIs, attributes == set ( idAttr? ) )
+	 *		ws* nodeElement ws*
+	 *		end-element()
+	 *
+	 * This handles structs using an rdf:Description node, 
+	 * arrays using rdf:Bag/Seq/Alt, and typedNodes. It also catches and cleans up qualified 
+	 * properties written with rdf:Description and rdf:value.
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_ResourcePropertyElement(XMPMetaImpl xmp, XMPNode xmpParent,
+			Node xmlNode, boolean isTopLevel) throws XMPException
+	{
+		if (isTopLevel  &&  "iX:changes".equals(xmlNode.getNodeName()))
+		{
+			// Strip old "punchcard" chaff which has on the prefix "iX:".
+			return;	
+		}
+		
+		XMPNode newCompound = addChildNode(xmp, xmpParent, xmlNode, "", isTopLevel);
+		
+		// walk through the attributes
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			if ("xmlns".equals(attribute.getPrefix())  ||
+					(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;
+			}
+			
+			String attrLocal = attribute.getLocalName();
+			String attrNS = attribute.getNamespaceURI();
+			if (XML_LANG.equals(attribute.getNodeName()))
+			{
+				addQualifierNode (newCompound, XML_LANG, attribute.getNodeValue());
+			} 
+			else if ("ID".equals(attrLocal)  &&  NS_RDF.equals(attrNS))
+			{
+				continue;	// Ignore all rdf:ID attributes.
+			}
+			else
+			{
+				throw new XMPException(
+					"Invalid attribute for resource property element", BADRDF);
+			}
+		}
+
+		// walk through the children
+		
+		Node currChild = null;
+		boolean found = false;
+		int i;
+		for (i = 0; i < xmlNode.getChildNodes().getLength(); i++)
+		{
+			currChild = xmlNode.getChildNodes().item(i);
+			if (!isWhitespaceNode(currChild))
+			{
+				if (currChild.getNodeType() == Node.ELEMENT_NODE  &&  !found)
+				{
+					boolean isRDF = NS_RDF.equals(currChild.getNamespaceURI());
+					String childLocal = currChild.getLocalName();
+					
+					if (isRDF  &&  "Bag".equals(childLocal))
+					{
+						newCompound.getOptions().setArray(true);
+					}
+					else if (isRDF  &&  "Seq".equals(childLocal))
+					{
+						newCompound.getOptions().setArray(true).setArrayOrdered(true);
+					}
+					else if (isRDF  &&  "Alt".equals(childLocal))
+					{
+						newCompound.getOptions().setArray(true).setArrayOrdered(true)
+								.setArrayAlternate(true);
+					}
+					else
+					{
+						newCompound.getOptions().setStruct(true);
+						if (!isRDF  &&  !"Description".equals(childLocal))
+						{
+							String typeName = currChild.getNamespaceURI();
+							if (typeName == null)
+							{
+								throw new XMPException(
+										"All XML elements must be in a namespace", BADXMP);
+							}
+							typeName += ':' + childLocal;
+							addQualifierNode (newCompound, "rdf:type", typeName);
+						}
+					}
+	
+					rdf_NodeElement (xmp, newCompound, currChild, false);
+					
+					if (newCompound.getHasValueChild())
+					{
+						fixupQualifiedNode (newCompound);
+					} 
+					else if (newCompound.getOptions().isArrayAlternate())
+					{
+						XMPNodeUtils.detectAltText(newCompound);
+					}				
+					
+					found = true;
+				}
+				else if (found)
+				{
+					// found second child element
+					throw new XMPException(
+						"Invalid child of resource property element", BADRDF);
+				}
+				else
+				{
+					throw new XMPException(
+						"Children of resource property element must be XML elements", BADRDF);
+				}
+			}
+		}
+		
+		if (!found)
+		{
+			// didn't found any child elements
+			throw new XMPException("Missing child of resource property element", BADRDF);
+		}
+	}	
+
+	
+	/**
+	 * 7.2.16 literalPropertyElt
+	 *		start-element ( URI == propertyElementURIs, 
+	 *				attributes == set ( idAttr?, datatypeAttr?) )
+	 *		text()
+	 *		end-element()
+	 *
+	 * Add a leaf node with the text value and qualifiers for the attributes.
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */	
+	private static void rdf_LiteralPropertyElement(XMPMetaImpl xmp, XMPNode xmpParent,
+			Node xmlNode, boolean isTopLevel) throws XMPException
+	{
+		XMPNode newChild = addChildNode (xmp, xmpParent, xmlNode, null, isTopLevel);
+		
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			if ("xmlns".equals(attribute.getPrefix())  ||
+					(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;
+			}
+			
+			String attrNS = attribute.getNamespaceURI();
+			String attrLocal = attribute.getLocalName();
+			if (XML_LANG.equals(attribute.getNodeName()))
+			{
+				addQualifierNode(newChild, XML_LANG, attribute.getNodeValue());
+			} 
+			else if (NS_RDF.equals(attrNS)  &&
+					 ("ID".equals(attrLocal)  ||  "datatype".equals(attrLocal)))
+			{
+				continue;	// Ignore all rdf:ID and rdf:datatype attributes.
+			}
+			else
+			{
+				throw new XMPException(
+					"Invalid attribute for literal property element", BADRDF);
+			}
+		}
+		String textValue = "";
+		for (int i = 0; i < xmlNode.getChildNodes().getLength(); i++)
+		{
+			Node child = xmlNode.getChildNodes().item(i);
+			if (child.getNodeType() == Node.TEXT_NODE)
+			{
+				textValue += child.getNodeValue();
+			}
+			else
+			{
+				throw new XMPException("Invalid child of literal property element", BADRDF);
+			}
+		}
+		newChild.setValue(textValue);
+	}
+	
+	
+	/**
+	 * 7.2.17 parseTypeLiteralPropertyElt
+	 *		start-element ( URI == propertyElementURIs,
+	 *			attributes == set ( idAttr?, parseLiteral ) )
+	 *		literal
+	 *		end-element()
+	 * 
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_ParseTypeLiteralPropertyElement() throws XMPException
+	{
+		throw new XMPException("ParseTypeLiteral property element not allowed", BADXMP);
+	}
+
+	
+	/**
+	 * 7.2.18 parseTypeResourcePropertyElt
+	 *		start-element ( URI == propertyElementURIs, 
+	 *			attributes == set ( idAttr?, parseResource ) )
+	 *		propertyEltList
+	 *		end-element()
+	 *
+	 * Add a new struct node with a qualifier for the possible rdf:ID attribute. 
+	 * Then process the XML child nodes to get the struct fields.
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_ParseTypeResourcePropertyElement(XMPMetaImpl xmp, XMPNode xmpParent,
+			Node xmlNode, boolean isTopLevel) throws XMPException
+	{
+		XMPNode newStruct = addChildNode (xmp, xmpParent, xmlNode, "", isTopLevel);
+		
+		newStruct.getOptions().setStruct(true);
+
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			if ("xmlns".equals(attribute.getPrefix())  ||
+					(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;
+			}
+			
+			String attrLocal = attribute.getLocalName();
+			String attrNS = attribute.getNamespaceURI();
+			if (XML_LANG.equals(attribute.getNodeName()))
+			{
+				addQualifierNode (newStruct, XML_LANG, attribute.getNodeValue());
+			}
+			else if (NS_RDF.equals(attrNS)  &&
+					 ("ID".equals(attrLocal)  ||  "parseType".equals(attrLocal)))
+			{
+				continue;	// The caller ensured the value is "Resource".
+							// Ignore all rdf:ID attributes.
+			} 
+			else
+			{
+				throw new XMPException("Invalid attribute for ParseTypeResource property element",
+						BADRDF);
+			}
+		}
+
+		rdf_PropertyElementList (xmp, newStruct, xmlNode, false);
+
+		if (newStruct.getHasValueChild())
+		{
+			fixupQualifiedNode (newStruct);
+		}
+	}
+
+	
+	/**
+	 * 7.2.19 parseTypeCollectionPropertyElt
+	 *		start-element ( URI == propertyElementURIs, 
+	 *			attributes == set ( idAttr?, parseCollection ) )
+	 *		nodeElementList
+	 *		end-element()
+	 *
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_ParseTypeCollectionPropertyElement() throws XMPException
+	{
+		throw new XMPException("ParseTypeCollection property element not allowed", BADXMP);
+	}
+
+
+	/**
+	 * 7.2.20 parseTypeOtherPropertyElt
+	 *		start-element ( URI == propertyElementURIs, attributes == set ( idAttr?, parseOther ) )
+	 *		propertyEltList
+	 *		end-element()
+	 * 
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_ParseTypeOtherPropertyElement() throws XMPException
+	{
+		throw new XMPException("ParseTypeOther property element not allowed", BADXMP);
+	}
+
+
+	/**
+	 * 7.2.21 emptyPropertyElt
+	 *		start-element ( URI == propertyElementURIs,
+	 *						attributes == set (
+	 *							idAttr?, ( resourceAttr | nodeIdAttr )?, propertyAttr* ) )
+	 *		end-element()
+	 *
+	 *	<ns:Prop1/>  <!-- a simple property with an empty value --> 
+	 *	<ns:Prop2 rdf:resource="http: *www.adobe.com/"/> <!-- a URI value --> 
+	 *	<ns:Prop3 rdf:value="..." ns:Qual="..."/> <!-- a simple qualified property --> 
+	 *	<ns:Prop4 ns:Field1="..." ns:Field2="..."/> <!-- a struct with simple fields -->
+	 *
+	 * An emptyPropertyElt is an element with no contained content, just a possibly empty set of
+	 * attributes. An emptyPropertyElt can represent three special cases of simple XMP properties: a
+	 * simple property with an empty value (ns:Prop1), a simple property whose value is a URI
+	 * (ns:Prop2), or a simple property with simple qualifiers (ns:Prop3). 
+	 * An emptyPropertyElt can also represent an XMP struct whose fields are all simple and 
+	 * unqualified (ns:Prop4).
+	 *
+	 * It is an error to use both rdf:value and rdf:resource - that can lead to invalid  RDF in the
+	 * verbose form written using a literalPropertyElt.
+	 *
+	 * The XMP mapping for an emptyPropertyElt is a bit different from generic RDF, partly for 
+	 * design reasons and partly for historical reasons. The XMP mapping rules are:
+	 * <ol> 
+	 *		<li> If there is an rdf:value attribute then this is a simple property
+	 *				 with a text value.
+	 *		All other attributes are qualifiers.
+	 *		<li> If there is an rdf:resource attribute then this is a simple property 
+	 *			with a URI value. 
+	 *		All other attributes are qualifiers.
+	 *		<li> If there are no attributes other than xml:lang, rdf:ID, or rdf:nodeID
+	 *				then this is a simple 
+	 *		property with an empty value. 
+	 *		<li> Otherwise this is a struct, the attributes other than xml:lang, rdf:ID, 
+	 *				or rdf:nodeID are fields. 
+	 * </ol>
+	 * 
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void rdf_EmptyPropertyElement(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode,
+			boolean isTopLevel) throws XMPException
+	{
+		boolean hasPropertyAttrs = false;
+		boolean hasResourceAttr = false;
+		boolean hasNodeIDAttr = false;
+		boolean hasValueAttr = false;
+		
+		Node valueNode = null;	// ! Can come from rdf:value or rdf:resource.
+		
+		if (xmlNode.hasChildNodes())
+		{
+			throw new XMPException(
+					"Nested content not allowed with rdf:resource or property attributes",
+					BADRDF);
+		}
+		
+		// First figure out what XMP this maps to and remember the XML node for a simple value.
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			if ("xmlns".equals(attribute.getPrefix())  ||
+					(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;
+			}
+			
+			int attrTerm = getRDFTermKind (attribute);
+
+			switch (attrTerm)
+			{
+				case RDFTERM_ID :
+					// Nothing to do.
+					break;
+
+				case RDFTERM_RESOURCE :
+					if (hasNodeIDAttr)
+					{
+						throw new XMPException(
+							"Empty property element can't have both rdf:resource and rdf:nodeID",
+							BADRDF);
+					}
+					else if (hasValueAttr)
+					{
+						throw new XMPException(
+								"Empty property element can't have both rdf:value and rdf:resource",
+								BADXMP);
+					}
+
+					hasResourceAttr = true;
+					if (!hasValueAttr) 
+					{
+						valueNode = attribute;
+					}	
+					break;
+
+				case RDFTERM_NODE_ID:
+				if (hasResourceAttr)
+				{
+					throw new XMPException(
+							"Empty property element can't have both rdf:resource and rdf:nodeID",
+							BADRDF);
+				}
+				hasNodeIDAttr = true;
+				break;
+
+			case RDFTERM_OTHER:
+				if ("value".equals(attribute.getLocalName())
+						&& NS_RDF.equals(attribute.getNamespaceURI()))
+				{
+					if (hasResourceAttr)
+					{
+						throw new XMPException(
+								"Empty property element can't have both rdf:value and rdf:resource",
+								BADXMP);
+					}
+					hasValueAttr = true;
+					valueNode = attribute;
+				}
+				else if (!XML_LANG.equals(attribute.getNodeName()))
+				{
+					hasPropertyAttrs = true;
+				}
+				break;
+
+			default:
+				throw new XMPException("Unrecognized attribute of empty property element",
+						BADRDF);
+			}
+		}
+		
+		// Create the right kind of child node and visit the attributes again 
+		// to add the fields or qualifiers.
+		// ! Because of implementation vagaries, 
+		//   the xmpParent is the tree root for top level properties.
+		// ! The schema is found, created if necessary, by addChildNode.
+		
+		XMPNode childNode = addChildNode(xmp, xmpParent, xmlNode, "", isTopLevel);
+		boolean childIsStruct = false;
+		
+		if (hasValueAttr || hasResourceAttr)
+		{
+			childNode.setValue(valueNode != null ? valueNode.getNodeValue() : "");
+			if (!hasValueAttr)
+			{
+				// ! Might have both rdf:value and rdf:resource.
+				childNode.getOptions().setURI(true);	
+			}
+		}
+		else if (hasPropertyAttrs)
+		{
+			childNode.getOptions().setStruct(true);
+			childIsStruct = true;
+		}
+		
+		for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
+		{
+			Node attribute = xmlNode.getAttributes().item(i);
+			if (attribute == valueNode  ||
+				"xmlns".equals(attribute.getPrefix())  ||
+				(attribute.getPrefix() == null  &&  "xmlns".equals(attribute.getNodeName())))
+			{
+				continue;	// Skip the rdf:value or rdf:resource attribute holding the value.
+			}
+			
+			int attrTerm = getRDFTermKind (attribute);
+
+			switch (attrTerm)
+			{
+				case RDFTERM_ID :
+				case RDFTERM_NODE_ID :
+					break;	// Ignore all rdf:ID and rdf:nodeID attributes.
+					
+				case RDFTERM_RESOURCE :
+					addQualifierNode(childNode, "rdf:resource", attribute.getNodeValue());
+					break;
+
+				case RDFTERM_OTHER :
+					if (!childIsStruct)
+					{
+						addQualifierNode(
+							childNode, attribute.getNodeName(), attribute.getNodeValue());
+					}
+					else if (XML_LANG.equals(attribute.getNodeName()))
+					{
+						addQualifierNode (childNode, XML_LANG, attribute.getNodeValue());
+					}
+					else
+					{
+						addChildNode (xmp, childNode, attribute, attribute.getNodeValue(), false);
+					}
+					break;
+
+				default :
+					throw new XMPException("Unrecognized attribute of empty property element",
+						BADRDF);
+			}
+
+		}		
+	}
+
+
+	/**
+	 * Adds a child node.
+	 *  
+	 * @param xmp the xmp metadata object that is generated
+	 * @param xmpParent the parent xmp node
+	 * @param xmlNode the currently processed XML node
+	 * @param value Node value	
+	 * @param isTopLevel Flag if the node is a top-level node
+	 * @return Returns the newly created child node.
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static XMPNode addChildNode(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode,
+			String value, boolean isTopLevel) throws XMPException
+	{
+		XMPSchemaRegistry registry = XMPMetaFactory.getSchemaRegistry();
+		String namespace = xmlNode.getNamespaceURI();
+		String childName;
+		if (namespace != null)
+		{
+			if (NS_DC_DEPRECATED.equals(namespace))
+			{
+				// Fix a legacy DC namespace
+				namespace = NS_DC;
+			}
+			
+			String prefix = registry.getNamespacePrefix(namespace);
+			if (prefix == null)
+			{
+				prefix = xmlNode.getPrefix() != null ? xmlNode.getPrefix() : DEFAULT_PREFIX;
+				prefix = registry.registerNamespace(namespace, prefix);
+			}
+			childName = prefix + xmlNode.getLocalName();
+		}
+		else
+		{
+			throw new XMPException(
+				"XML namespace required for all elements and attributes", BADRDF);
+		}
+
+		
+		// create schema node if not already there
+		PropertyOptions childOptions = new PropertyOptions();
+		boolean isAlias = false;
+		if (isTopLevel)
+		{
+			// Lookup the schema node, adjust the XMP parent pointer.
+			// Incoming parent must be the tree root.
+			XMPNode schemaNode = XMPNodeUtils.findSchemaNode(xmp.getRoot(), namespace,
+				DEFAULT_PREFIX, true);
+			schemaNode.setImplicit(false);	// Clear the implicit node bit.
+			// need runtime check for proper 32 bit code.
+			xmpParent = schemaNode;
+			
+			// If this is an alias set the alias flag in the node 
+			// and the hasAliases flag in the tree.
+			if (registry.findAlias(childName) != null)
+			{
+				isAlias = true;
+				xmp.getRoot().setHasAliases(true);
+				schemaNode.setHasAliases(true);
+			}
+		}
+
+		
+		// Make sure that this is not a duplicate of a named node.
+		boolean isArrayItem  = "rdf:li".equals(childName);
+		boolean isValueNode  = "rdf:value".equals(childName);
+
+		// Create XMP node and so some checks
+		XMPNode newChild = new XMPNode(
+			childName, value, childOptions);
+		newChild.setAlias(isAlias);
+		
+		// Add the new child to the XMP parent node, a value node first.
+		if (!isValueNode)
+		{
+			xmpParent.addChild(newChild);
+		}
+		else
+		{
+			xmpParent.addChild(1, newChild);
+		}
+		
+		
+		if (isValueNode)
+		{
+			if (isTopLevel  ||  !xmpParent.getOptions().isStruct())
+			{
+				throw new XMPException("Misplaced rdf:value element", BADRDF);
+			}	
+			xmpParent.setHasValueChild(true);
+		}
+		
+		if (isArrayItem)
+		{
+			if (!xmpParent.getOptions().isArray()) 
+			{
+				throw new XMPException("Misplaced rdf:li element", BADRDF);
+			}	
+			newChild.setName(ARRAY_ITEM_NAME);
+		}
+		
+		return newChild;
+	}
+
+	
+	/**
+	 * Adds a qualifier node.
+	 * 
+	 * @param xmpParent the parent xmp node
+	 * @param name the name of the qualifier which has to be 
+	 * 		QName including the <b>default prefix</b>
+	 * @param value the value of the qualifier
+	 * @return Returns the newly created child node.
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static XMPNode addQualifierNode(XMPNode xmpParent, String name, String value)
+			throws XMPException
+	{
+		boolean isLang = XML_LANG.equals(name);
+	
+		XMPNode newQual = null;
+
+		// normalize value of language qualifiers
+		newQual = new XMPNode(name, isLang ? Utils.normalizeLangValue(value) : value, null);
+		xmpParent.addQualifier(newQual);
+		
+		return newQual;
+	}
+	
+
+	/**
+	 * The parent is an RDF pseudo-struct containing an rdf:value field. Fix the
+	 * XMP data model. The rdf:value node must be the first child, the other
+	 * children are qualifiers. The form, value, and children of the rdf:value
+	 * node are the real ones. The rdf:value node's qualifiers must be added to
+	 * the others.
+	 * 
+	 * @param xmpParent the parent xmp node
+	 * @throws XMPException thown on parsing errors
+	 */
+	private static void fixupQualifiedNode(XMPNode xmpParent) throws XMPException
+	{
+		assert xmpParent.getOptions().isStruct()  &&  xmpParent.hasChildren();
+
+		XMPNode valueNode = xmpParent.getChild(1);
+		assert "rdf:value".equals(valueNode.getName());
+
+		// Move the qualifiers on the value node to the parent. 
+		// Make sure an xml:lang qualifier stays at the front.
+		// Check for duplicate names between the value node's qualifiers and the parent's children. 
+		// The parent's children are about to become qualifiers. Check here, between the groups. 
+		// Intra-group duplicates are caught by XMPNode#addChild(...).
+		if (valueNode.getOptions().getHasLanguage())
+		{
+			if (xmpParent.getOptions().getHasLanguage())
+			{
+				throw new XMPException("Redundant xml:lang for rdf:value element", 
+					BADXMP);
+			}
+			XMPNode langQual = valueNode.getQualifier(1);
+			valueNode.removeQualifier(langQual);
+			xmpParent.addQualifier(langQual);
+		}
+		
+		// Start the remaining copy after the xml:lang qualifier.		
+		for (int i = 1; i <= valueNode.getQualifierLength(); i++)
+		{
+			XMPNode qualifier = valueNode.getQualifier(i);
+			xmpParent.addQualifier(qualifier);
+		}
+		
+		
+		// Change the parent's other children into qualifiers. 
+		// This loop starts at 1, child 0 is the rdf:value node.
+		for (int i = 2; i <= xmpParent.getChildrenLength(); i++)
+		{
+			XMPNode qualifier = xmpParent.getChild(i);
+			xmpParent.addQualifier(qualifier);
+		}
+		
+		// Move the options and value last, other checks need the parent's original options. 
+		// Move the value node's children to be the parent's children.
+		assert xmpParent.getOptions().isStruct()  ||  xmpParent.getHasValueChild();
+		
+		xmpParent.setHasValueChild(false);
+		xmpParent.getOptions().setStruct(false);
+		xmpParent.getOptions().mergeWith(valueNode.getOptions());
+		xmpParent.setValue(valueNode.getValue());
+		
+		xmpParent.removeChildren();
+		for (Iterator it = valueNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode child = (XMPNode) it.next();
+			xmpParent.addChild(child);
+		}
+	}		
+
+	
+	/**
+	 * Checks if the node is a white space.
+	 * @param node an XML-node
+	 * @return Returns whether the node is a whitespace node, 
+	 * 		i.e. a text node that contains only whitespaces.
+	 */
+	private static boolean isWhitespaceNode(Node node)
+	{
+		if (node.getNodeType() != Node.TEXT_NODE)
+		{
+			return false;
+		}
+		
+		String value = node.getNodeValue();
+		for (int i = 0; i < value.length(); i++)
+		{
+			if (!Character.isWhitespace(value.charAt(i)))
+			{
+				return false;
+			}
+		}
+		
+		return true;
+	}
+	
+	
+	/**
+	 * 7.2.6 propertyElementURIs
+	 *			anyURI - ( coreSyntaxTerms | rdf:Description | oldTerms )
+	 * 
+	 * @param term the term id
+	 * @return Return true if the term is a property element name.
+	 */
+	private static boolean isPropertyElementName(int term)
+	{
+		if (term == RDFTERM_DESCRIPTION  ||  isOldTerm(term))
+		{
+			return false;
+		}
+		else
+		{	
+			return (!isCoreSyntaxTerm(term));
+		}	
+	}
+
+	
+	/**
+	 * 7.2.4 oldTerms<br>
+	 * rdf:aboutEach | rdf:aboutEachPrefix | rdf:bagID
+	 * 
+	 * @param term the term id
+	 * @return Returns true if the term is an old term.
+	 */
+	private static boolean isOldTerm(int term)
+	{
+		return  RDFTERM_FIRST_OLD <= term  &&  term <= RDFTERM_LAST_OLD;
+	}
+
+
+	/**
+	 * 7.2.2 coreSyntaxTerms<br>
+	 * rdf:RDF | rdf:ID | rdf:about | rdf:parseType | rdf:resource | rdf:nodeID |
+	 * rdf:datatype
+	 * 
+	 * @param term the term id
+	 * @return Return true if the term is a core syntax term
+	 */
+	private static boolean isCoreSyntaxTerm(int term)
+	{
+		return  RDFTERM_FIRST_CORE <= term  &&  term <= RDFTERM_LAST_CORE;
+	}
+
+
+	/**
+	 * Determines the ID for a certain RDF Term.
+	 * Arranged to hopefully minimize the parse time for large XMP.
+	 * 
+	 * @param node an XML node 
+	 * @return Returns the term ID.
+	 */
+	private static int getRDFTermKind(Node node)
+	{
+		String localName = node.getLocalName();
+		String namespace = node.getNamespaceURI();
+		
+		if (
+				namespace == null  && 
+				("about".equals(localName) || "ID".equals(localName))  &&
+				(node instanceof Attr)  &&
+				NS_RDF.equals(((Attr) node).getOwnerElement().getNamespaceURI())
+		   )
+		{
+			namespace = NS_RDF; 
+		}
+		
+		if (NS_RDF.equals(namespace))
+		{
+			if ("li".equals(localName))
+			{
+				return RDFTERM_LI;
+			}
+			else if ("parseType".equals(localName))
+			{
+				return RDFTERM_PARSE_TYPE;
+			}
+			else if ("Description".equals(localName))
+			{
+				return RDFTERM_DESCRIPTION;
+			}
+			else if ("about".equals(localName))
+			{
+				return RDFTERM_ABOUT;
+			}
+			else if ("resource".equals(localName))
+			{
+				return RDFTERM_RESOURCE;
+			}
+			else if ("RDF".equals(localName))
+			{
+				return RDFTERM_RDF;
+			}
+			else if ("ID".equals(localName))
+			{
+				return RDFTERM_ID;
+			}
+			else if ("nodeID".equals(localName))
+			{
+				return RDFTERM_NODE_ID;
+			}
+			else if ("datatype".equals(localName))
+			{
+				return RDFTERM_DATATYPE;
+			}
+			else if ("aboutEach".equals(localName))
+			{
+				return RDFTERM_ABOUT_EACH;
+			}
+			else if ("aboutEachPrefix".equals(localName))
+			{
+				return RDFTERM_ABOUT_EACH_PREFIX;
+			}
+			else if ("bagID".equals(localName))
+			{
+				return RDFTERM_BAG_ID;
+			}
+		}
+		
+		return RDFTERM_OTHER;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/QName.java b/XMPCore/src/com/adobe/xmp/impl/QName.java
new file mode 100644
index 0000000..783f792
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/QName.java
@@ -0,0 +1,80 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+/**
+ * @since   09.11.2006
+ */
+public class QName
+{
+	/** XML namespace prefix */
+	private String prefix;
+	/** XML localname */
+	private String localName;
+
+	
+	/**
+	 * Splits a qname into prefix and localname.
+	 * @param qname a QName
+	 */
+	public QName(String qname)
+	{
+		int colon = qname.indexOf(':');
+		
+		if (colon >= 0)
+		{
+			prefix = qname.substring(0, colon);
+			localName = qname.substring(colon + 1);
+		}
+		else
+		{
+			prefix = "";
+			localName = qname;
+		}
+	}
+	
+	
+	/** Constructor that initializes the fields
+	 * @param prefix the prefix  
+	 * @param localName the name
+	 */
+	public QName(String prefix, String localName)
+	{
+		this.prefix = prefix;
+		this.localName = localName;
+	}
+
+	
+	/**
+	 * @return Returns whether the QName has a prefix.
+	 */
+	public boolean hasPrefix()
+	{
+		return prefix != null  &&  prefix.length() > 0;
+	}
+	
+
+	/**
+	 * @return the localName
+	 */
+	public String getLocalName()
+	{
+		return localName;
+	}
+
+
+	/**
+	 * @return the prefix
+	 */
+	public String getPrefix()
+	{
+		return prefix;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/Utils.java b/XMPCore/src/com/adobe/xmp/impl/Utils.java
new file mode 100644
index 0000000..7ca3b27
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/Utils.java
@@ -0,0 +1,511 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+
+import com.adobe.xmp.XMPConst;
+
+
+/**
+ * Utility functions for the XMPToolkit implementation.
+ * 
+ * @since 06.06.2006
+ */
+public class Utils implements XMPConst
+{
+	/** segments of a UUID */
+	public static final int UUID_SEGMENT_COUNT = 4;
+	/** length of a UUID */
+	public static final int UUID_LENGTH = 32 + UUID_SEGMENT_COUNT;
+	/** table of XML name start chars (<= 0xFF) */
+	private  static boolean[] xmlNameStartChars;
+	/** table of XML name chars (<= 0xFF) */
+	private static boolean[] xmlNameChars;
+	/** init char tables */
+	static
+	{
+		initCharTables();
+	}
+	
+	
+	/**
+	 * Private constructor
+	 */
+	private Utils()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Normalize an xml:lang value so that comparisons are effectively case
+	 * insensitive as required by RFC 3066 (which superceeds RFC 1766). The
+	 * normalization rules:
+	 * <ul>
+	 * <li> The primary subtag is lower case, the suggested practice of ISO 639.
+	 * <li> All 2 letter secondary subtags are upper case, the suggested
+	 * practice of ISO 3166.
+	 * <li> All other subtags are lower case.
+	 * </ul>
+	 * 
+	 * @param value
+	 *            raw value
+	 * @return Returns the normalized value.
+	 */
+	public static String normalizeLangValue(String value)
+	{
+		// don't normalize x-default
+		if (XMPConst.X_DEFAULT.equals(value))
+		{
+			return value;
+		}	
+		
+		int subTag = 1;
+		StringBuffer buffer = new StringBuffer();
+
+		for (int i = 0; i < value.length(); i++)
+		{
+			switch (value.charAt(i))
+			{
+			case '-':
+			case '_':
+				// move to next subtag and convert underscore to hyphen
+				buffer.append('-');
+				subTag++;
+				break;
+			case ' ':
+				// remove spaces
+				break;
+			default:
+				// convert second subtag to uppercase, all other to lowercase
+				if (subTag != 2)
+				{
+					buffer.append(Character.toLowerCase(value.charAt(i)));
+				}
+				else
+				{
+					buffer.append(Character.toUpperCase(value.charAt(i)));
+				}
+			}
+
+		}
+		return buffer.toString();
+	}
+
+
+	/**
+	 * Split the name and value parts for field and qualifier selectors:
+	 * <ul>
+	 * <li>[qualName="value"] - An element in an array of structs, chosen by a
+	 * field value.
+	 * <li>[?qualName="value"] - An element in an array, chosen by a qualifier
+	 * value.
+	 * </ul>
+	 * The value portion is a string quoted by ''' or '"'. The value may contain
+	 * any character including a doubled quoting character. The value may be
+	 * empty. <em>Note:</em> It is assumed that the expression is formal
+	 * correct
+	 * 
+	 * @param selector
+	 *            the selector
+	 * @return Returns an array where the first entry contains the name and the
+	 *         second the value.
+	 */
+	static String[] splitNameAndValue(String selector)
+	{
+		// get the name
+		int eq = selector.indexOf('=');
+		int pos = 1;
+		if (selector.charAt(pos) == '?')
+		{
+			pos++;
+		}
+		String name = selector.substring(pos, eq);
+
+		// get the value
+		pos = eq + 1;
+		char quote = selector.charAt(pos);
+		pos++;
+		int end = selector.length() - 2; // quote and ]
+		StringBuffer value = new StringBuffer(end - eq);
+		while (pos < end)
+		{
+			value.append(selector.charAt(pos));
+			pos++;
+			if (selector.charAt(pos) == quote)
+			{
+				// skip one quote in value
+				pos++;
+			}
+		}
+		return new String[] { name, value.toString() };
+	}
+	
+
+	/**
+	 * 
+	 * @param schema
+	 *            a schema namespace
+	 * @param prop
+	 *            an XMP Property
+	 * @return Returns true if the property is defined as &quot;Internal
+	 *         Property&quot;, see XMP Specification.
+	 */
+	static boolean isInternalProperty(String schema, String prop)
+	{
+		boolean isInternal = false;
+
+		if (NS_DC.equals(schema))
+		{
+			if ("dc:format".equals(prop) || "dc:language".equals(prop))
+			{
+				isInternal = true;
+			}
+		}
+		else if (NS_XMP.equals(schema))
+		{
+			if ("xmp:BaseURL".equals(prop) || "xmp:CreatorTool".equals(prop)
+					|| "xmp:Format".equals(prop) || "xmp:Locale".equals(prop)
+					|| "xmp:MetadataDate".equals(prop) || "xmp:ModifyDate".equals(prop))
+			{
+				isInternal = true;
+			}
+		}
+		else if (NS_PDF.equals(schema))
+		{
+			if ("pdf:BaseURL".equals(prop) || "pdf:Creator".equals(prop)
+					|| "pdf:ModDate".equals(prop) || "pdf:PDFVersion".equals(prop)
+					|| "pdf:Producer".equals(prop))
+			{
+				isInternal = true;
+			}
+		}
+		else if (NS_TIFF.equals(schema))
+		{
+			isInternal = true;
+			if ("tiff:ImageDescription".equals(prop) || "tiff:Artist".equals(prop)
+					|| "tiff:Copyright".equals(prop))
+			{
+				isInternal = false;
+			}
+		}
+		else if (NS_EXIF.equals(schema))
+		{
+			isInternal = true;
+			if ("exif:UserComment".equals(prop))
+			{
+				isInternal = false;
+			}
+		}
+		else if (NS_EXIF_AUX.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (NS_PHOTOSHOP.equals(schema))
+		{
+			if ("photoshop:ICCProfile".equals(prop))
+			{
+				isInternal = true;
+			}
+		}
+		else if (NS_CAMERARAW.equals(schema))
+		{
+			if ("crs:Version".equals(prop) || "crs:RawFileName".equals(prop)
+					|| "crs:ToneCurveName".equals(prop))
+			{
+				isInternal = true;
+			}
+		}
+		else if (NS_ADOBESTOCKPHOTO.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (NS_XMP_MM.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (TYPE_TEXT.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (TYPE_PAGEDFILE.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (TYPE_GRAPHICS.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (TYPE_IMAGE.equals(schema))
+		{
+			isInternal = true;
+		}
+		else if (TYPE_FONT.equals(schema))
+		{
+			isInternal = true;
+		}
+
+		return isInternal;
+	}
+
+
+	/**
+	 * Check some requirements for an UUID:
+	 * <ul>
+	 * <li>Length of the UUID is 32</li>
+	 * <li>The Delimiter count is 4 and all the 4 delimiter are on their right
+	 * position (8,13,18,23)</li>
+	 * </ul>
+	 * 
+	 * 
+	 * @param uuid uuid to test
+	 * @return true - this is a well formed UUID, false - UUID has not the expected format
+	 */
+
+	static boolean checkUUIDFormat(String uuid)
+	{
+		boolean result = true;
+		int delimCnt = 0;
+		int delimPos = 0;
+
+		if (uuid == null)
+		{
+			return false;
+		}
+		
+		for (delimPos = 0; delimPos < uuid.length(); delimPos++)
+		{
+			if (uuid.charAt(delimPos) == '-')
+			{
+				delimCnt++;
+				result = result  &&  
+					(delimPos == 8 || delimPos == 13 || delimPos == 18 || delimPos == 23);
+			}
+		}
+
+		return result && UUID_SEGMENT_COUNT == delimCnt && UUID_LENGTH == delimPos;
+	}
+
+	
+	/**
+	 * Simple check for valid XMLNames. Within ASCII range<br>
+	 * ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6]<br>
+	 * are accepted, above all characters (which is not entirely 
+	 * correct according to the XML Spec.
+	 *  
+	 * @param name an XML Name
+	 * @return Return <code>true</code> if the name is correct.
+	 */
+	public static boolean isXMLName(String name)
+	{
+		if (name.length() > 0  &&  !isNameStartChar(name.charAt(0)))
+		{
+			return false;
+		}
+		for (int i = 1; i < name.length(); i++)
+		{
+			if (!isNameChar(name.charAt(i)))
+			{	
+				return false;
+			}
+		}
+		return true;
+	}
+
+	
+	/**
+	 * Checks if the value is a legal "unqualified" XML name, as
+	 * defined in the XML Namespaces proposed recommendation.
+	 * These are XML names, except that they must not contain a colon. 
+	 * @param name the value to check
+	 * @return Returns true if the name is a valid "unqualified" XML name.
+	 */
+	public static boolean isXMLNameNS(String name)
+	{
+		if (name.length() > 0  &&  (!isNameStartChar(name.charAt(0))  ||  name.charAt(0) == ':'))
+		{
+			return false;
+		}
+		for (int i = 1; i < name.length(); i++)
+		{
+			if (!isNameChar(name.charAt(i))  ||  name.charAt(i) == ':')
+			{	
+				return false;
+			}
+		}
+		return true;
+	}
+	
+
+	/**
+	 * @param c  a char
+	 * @return Returns true if the char is an ASCII control char.
+	 */
+	static boolean isControlChar(char c)
+	{
+		return (c <= 0x1F  ||  c == 0x7F)  &&
+				c != 0x09  &&  c != 0x0A  &&  c != 0x0D;
+	}
+
+	
+	/**
+	 * Serializes the node value in XML encoding. Its used for tag bodies and
+	 * attributes.<br>
+	 * <em>Note:</em> The attribute is always limited by quotes,
+	 * thats why <code>&amp;apos;</code> is never serialized.<br> 
+	 * <em>Note:</em> Control chars are written unescaped, but if the user uses others than tab, LF
+	 * and CR the resulting XML will become invalid.
+	 * @param value a string
+	 * @param forAttribute flag if string is attribute value (need to additional escape quotes)
+	 * @param escapeWhitespaces Decides if LF, CR and TAB are escaped.
+	 * @return Returns the value ready for XML output.
+	 */
+	public static String escapeXML(String value, boolean forAttribute, boolean escapeWhitespaces)
+	{
+		// quick check if character are contained that need special treatment
+		boolean needsEscaping = false;
+		for (int i = 0; i < value.length (); i++)
+        {
+            char c = value.charAt (i);
+			if (
+				 c == '<'  ||  c == '>'  ||  c == '&'  ||							    // XML chars
+				(escapeWhitespaces  &&  (c == '\t'  ||  c == '\n'  ||  c == '\r'))  || 
+				(forAttribute  &&  c == '"'))
+			{
+				needsEscaping = true;
+				break;
+			}
+        }
+		
+		if (!needsEscaping)
+		{
+			// fast path
+			return value;
+		}
+		else
+		{
+			// slow path with escaping
+			StringBuffer buffer = new StringBuffer(value.length() * 4 / 3);
+	        for (int i = 0; i < value.length (); i++)
+	        {
+	            char c = value.charAt (i);
+	            if (!(escapeWhitespaces  &&  (c == '\t'  ||  c == '\n'  ||  c == '\r')))
+	            {
+	            	switch (c)
+		            {	
+	            		// we do what "Canonical XML" expects
+	            		// AUDIT: &apos; not serialized as only outer qoutes are used
+		              	case '<':	buffer.append("&lt;"); continue;
+		              	case '>':	buffer.append("&gt;"); continue;
+		              	case '&':	buffer.append("&amp;"); continue;
+		              	case '"': 	buffer.append(forAttribute ? "&quot;" : "\""); continue;
+		              	default:	buffer.append(c); continue;
+		            }
+		        }
+	            else
+	            {
+	            	// write control chars escaped,
+	            	// if there are others than tab, LF and CR the xml will become invalid.
+	            	buffer.append("&#x");
+	            	buffer.append(Integer.toHexString(c).toUpperCase());
+	            	buffer.append(';');
+	            }
+	        }
+	        return buffer.toString();
+		}
+	}	
+	
+	
+	/**
+	 * Replaces the ASCII control chars with a space.
+	 * 
+	 * @param value
+	 *            a node value
+	 * @return Returns the cleaned up value
+	 */
+	static String removeControlChars(String value)
+	{
+		StringBuffer buffer = new StringBuffer(value);
+		for (int i = 0; i < buffer.length(); i++)
+		{
+			if (isControlChar(buffer.charAt(i)))
+			{
+				buffer.setCharAt(i, ' ');
+			}
+		}
+		return buffer.toString();
+	}
+
+	
+	/** 
+	 * Simple check if a character is a valid XML start name char.
+	 * Within ASCII range<br>
+	 * ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6]<br>
+	 * are accepted, above all characters (which is not entirely 
+	 * correct according to the XML Spec)
+	 *  
+	 * @param ch a character
+	 * @return Returns true if the character is a valid first char of an XML name.
+	 */
+	private static boolean isNameStartChar(char ch)
+	{
+		return ch > 0xFF  ||  xmlNameStartChars[ch];
+	}
+
+	
+	/** 
+	 * Simple check if a character is a valid XML name char
+	 * (every char except the first one).
+	 * Within ASCII range<br>
+	 * ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6]<br>
+	 * are accepted, above all characters (which is not entirely 
+	 * correct according to the XML Spec)
+	 * 
+	 * @param ch a character
+	 * @return Returns true if the character is a valid char of an XML name.
+	 */
+	private static boolean isNameChar(char ch)
+	{
+		return ch > 0xFF  ||  xmlNameChars[ch];
+	}
+
+	
+	/**
+	 * Initializes the char tables for later use.
+	 */
+	private static void initCharTables()
+	{
+		xmlNameChars = new boolean[0x0100];
+		xmlNameStartChars = new boolean[0x0100];
+		
+		for (char ch = 0; ch < xmlNameChars.length; ch++)
+		{
+			xmlNameStartChars[ch] = 
+				('a' <= ch  &&  ch <= 'z')  ||
+				('A' <= ch  &&  ch <= 'Z')  ||
+				ch == ':'  ||
+				ch == '_'  ||
+				(0xC0 <= ch  &&  ch <= 0xD6)  ||
+				(0xD8 <= ch  &&  ch <= 0xF6);
+			
+			xmlNameChars[ch] =
+				('a' <= ch  &&  ch <= 'z')  ||
+				('A' <= ch  &&  ch <= 'Z')  ||
+				('0' <= ch  &&  ch <= '9')  ||
+				ch == ':'  ||
+				ch == '_'  ||
+				ch == '-'  ||
+				ch == '.'  ||
+				ch == 0xB7  ||
+				(0xC0 <= ch  &&  ch <= 0xD6)  ||
+				(0xD8 <= ch  &&  ch <= 0xF6);
+		}
+	}	
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPDateTimeImpl.java b/XMPCore/src/com/adobe/xmp/impl/XMPDateTimeImpl.java
new file mode 100644
index 0000000..f3a17e7
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPDateTimeImpl.java
@@ -0,0 +1,346 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import com.adobe.xmp.XMPDateTime;
+import com.adobe.xmp.XMPException;
+
+
+/**
+ * The implementation of <code>XMPDateTime</code>. Internally a <code>calendar</code> is used
+ * plus an additional nano seconds field, because <code>Calendar</code> supports only milli
+ * seconds. The <code>nanoSeconds</code> convers only the resolution beyond a milli second.
+ * 
+ * @since 16.02.2006
+ */
+public class XMPDateTimeImpl implements XMPDateTime 
+{
+	/** */
+	private int year = 0;
+	/** */
+	private int month = 0;
+	/** */
+	private int day = 0;
+	/** */
+	private int hour = 0;
+	/** */
+	private int minute = 0;
+	/** */
+	private int second = 0;
+	/** Use the unversal time as default */
+	private TimeZone timeZone = TimeZone.getTimeZone("UTC");
+	/**
+	 * The nano seconds take micro and nano seconds, while the milli seconds are in the calendar.
+	 */
+	private int nanoSeconds;
+
+
+	/**
+	 * Creates an <code>XMPDateTime</code>-instance with the current time in the default time
+	 * zone.
+	 */
+	public XMPDateTimeImpl()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Creates an <code>XMPDateTime</code>-instance from a calendar.
+	 * 
+	 * @param calendar a <code>Calendar</code>
+	 */
+	public XMPDateTimeImpl(Calendar calendar)
+	{
+		// extract the date and timezone from the calendar provided
+        Date date = calendar.getTime();
+        TimeZone zone = calendar.getTimeZone();
+
+        // put that date into a calendar the pretty much represents ISO8601
+        // I use US because it is close to the "locale" for the ISO8601 spec
+        GregorianCalendar intCalendar = 
+        	(GregorianCalendar) Calendar.getInstance(Locale.US);
+        intCalendar.setGregorianChange(new Date(Long.MIN_VALUE));       
+        intCalendar.setTimeZone(zone);           
+        intCalendar.setTime(date); 		
+		
+		this.year = intCalendar.get(Calendar.YEAR);
+		this.month = intCalendar.get(Calendar.MONTH) + 1; // cal is from 0..12
+		this.day = intCalendar.get(Calendar.DAY_OF_MONTH);
+		this.hour = intCalendar.get(Calendar.HOUR_OF_DAY);
+		this.minute = intCalendar.get(Calendar.MINUTE);
+		this.second = intCalendar.get(Calendar.SECOND);
+		this.nanoSeconds = intCalendar.get(Calendar.MILLISECOND) * 1000000;
+		this.timeZone = intCalendar.getTimeZone();
+	}
+
+	
+	/**
+	 * Creates an <code>XMPDateTime</code>-instance from 
+	 * a <code>Date</code> and a <code>TimeZone</code>.
+	 * 
+	 * @param date a date describing an absolute point in time
+	 * @param timeZone a TimeZone how to interpret the date
+	 */
+	public XMPDateTimeImpl(Date date, TimeZone timeZone)
+	{
+		GregorianCalendar calendar = new GregorianCalendar(timeZone);
+		calendar.setTime(date);
+		this.year = calendar.get(Calendar.YEAR);
+		this.month = calendar.get(Calendar.MONTH) + 1; // cal is from 0..12
+		this.day = calendar.get(Calendar.DAY_OF_MONTH);
+		this.hour = calendar.get(Calendar.HOUR_OF_DAY);
+		this.minute = calendar.get(Calendar.MINUTE);
+		this.second = calendar.get(Calendar.SECOND);
+		this.nanoSeconds = calendar.get(Calendar.MILLISECOND) * 1000000;
+		this.timeZone = timeZone;
+	}
+
+	
+	/**
+	 * Creates an <code>XMPDateTime</code>-instance from an ISO 8601 string.
+	 * 
+	 * @param strValue an ISO 8601 string
+	 * @throws XMPException If the string is a non-conform ISO 8601 string, an exception is thrown
+	 */
+	public XMPDateTimeImpl(String strValue) throws XMPException
+	{
+		ISO8601Converter.parse(strValue, this);
+	}
+
+
+	/**
+	 * @see XMPDateTime#getYear()
+	 */
+	public int getYear()
+	{
+		return year;
+	}
+
+	
+	/**
+	 * @see XMPDateTime#setYear(int)
+	 */
+	public void setYear(int year)
+	{
+		this.year = Math.min(Math.abs(year), 9999);
+	}	
+	
+
+	/**
+	 * @see XMPDateTime#getMonth()
+	 */
+	public int getMonth()
+	{
+		return month;
+	}
+
+
+	/**
+	 * @see XMPDateTime#setMonth(int)
+	 */
+	public void setMonth(int month)
+	{
+		if (month < 1)
+		{	
+			this.month = 1;
+		}
+		else if (month > 12)
+		{
+			this.month = 12;
+		}
+		else
+		{
+			this.month = month;
+		}
+	}
+
+	
+	/**
+	 * @see XMPDateTime#getDay()
+	 */
+	public int getDay()
+	{
+		return day;
+	}
+
+
+	/**
+	 * @see XMPDateTime#setDay(int)
+	 */
+	public void setDay(int day)
+	{
+		if (day < 1)
+		{	
+			this.day = 1;
+		}
+		else if (day > 31)
+		{
+			this.day = 31;
+		}
+		else
+		{
+			this.day = day;
+		}
+	}
+	
+	
+	/**
+	 * @see XMPDateTime#getHour()
+	 */
+	public int getHour()
+	{
+		return hour;
+	}
+
+	
+	/**
+	 * @see XMPDateTime#setHour(int)
+	 */
+	public void setHour(int hour)
+	{
+		this.hour = Math.min(Math.abs(hour), 23);
+	}
+
+
+	/**
+	 * @see XMPDateTime#getMinute()
+	 */
+	public int getMinute()
+	{
+		return minute;
+	}
+
+	
+	/**
+	 * @see XMPDateTime#setMinute(int)
+	 */
+	public void setMinute(int minute)
+	{
+		this.minute = Math.min(Math.abs(minute), 59);
+	}
+
+	
+	/**
+	 * @see XMPDateTime#getSecond()
+	 */
+	public int getSecond()
+	{
+		return second;
+	}
+
+	
+	/**
+	 * @see XMPDateTime#setSecond(int)
+	 */
+	public void setSecond(int second)
+	{
+		this.second = Math.min(Math.abs(second), 59);
+	}
+
+
+	/**
+	 * @see XMPDateTime#getNanoSecond()
+	 */
+	public int getNanoSecond()
+	{
+		return nanoSeconds;
+	}
+
+	
+	/**
+	 * @see XMPDateTime#setNanoSecond(int)
+	 */
+	public void setNanoSecond(int nanoSecond)
+	{
+		this.nanoSeconds = nanoSecond;
+	}
+	
+
+	/**
+	 * @see Comparable#compareTo(Object)
+	 */
+	public int compareTo(Object dt)
+	{
+		long d = getCalendar().getTimeInMillis()
+				- ((XMPDateTime) dt).getCalendar().getTimeInMillis();
+		if (d != 0)
+		{
+			return (int) (d % 2);
+		}
+		else
+		{
+			// if millis are equal, compare nanoseconds
+			d = nanoSeconds - ((XMPDateTime) dt).getNanoSecond();
+			return (int) (d % 2);
+		}
+	}
+
+
+	/**
+	 * @see XMPDateTime#getTimeZone()
+	 */
+	public TimeZone getTimeZone()
+	{
+		return timeZone;
+	}
+
+
+	/**
+	 * @see XMPDateTime#setTimeZone(TimeZone)
+	 */
+	public void setTimeZone(TimeZone timeZone)
+	{
+		this.timeZone = timeZone;
+	}
+
+
+	/**
+	 * @see XMPDateTime#getCalendar()
+	 */
+	public Calendar getCalendar()
+	{
+		GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance(Locale.US);
+		calendar.setGregorianChange(new Date(Long.MIN_VALUE));
+		calendar.setTimeZone(timeZone);
+		calendar.set(Calendar.YEAR, year);
+		calendar.set(Calendar.MONTH, month - 1);
+		calendar.set(Calendar.DAY_OF_MONTH, day);
+		calendar.set(Calendar.HOUR_OF_DAY, hour);
+		calendar.set(Calendar.MINUTE, minute);
+		calendar.set(Calendar.SECOND, second);
+		calendar.set(Calendar.MILLISECOND, nanoSeconds / 1000000);
+		return calendar;
+	}
+
+
+	/**
+	 * @see XMPDateTime#getISO8601String()
+	 */
+	public String getISO8601String()
+	{
+		return ISO8601Converter.render(this);
+	}
+
+	
+	/**
+	 * @return Returns the ISO string representation.
+	 */
+	public String toString()
+	{
+		return getISO8601String();
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPIteratorImpl.java b/XMPCore/src/com/adobe/xmp/impl/XMPIteratorImpl.java
new file mode 100644
index 0000000..22ddebb
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPIteratorImpl.java
@@ -0,0 +1,598 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPIterator;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathParser;
+import com.adobe.xmp.options.IteratorOptions;
+import com.adobe.xmp.options.PropertyOptions;
+import com.adobe.xmp.properties.XMPPropertyInfo;
+
+
+/**
+ * The <code>XMPIterator</code> implementation.
+ * Iterates the XMP Tree according to a set of options.
+ * During the iteration the XMPMeta-object must not be changed.
+ * Calls to <code>skipSubtree()</code> / <code>skipSiblings()</code> will affect the iteration.
+ *  
+ * @since   29.06.2006
+ */
+public class XMPIteratorImpl implements XMPIterator
+{
+	/** stores the iterator options */
+	private IteratorOptions options;
+	/** the base namespace of the property path, will be changed during the iteration */ 
+	private String baseNS = null;
+	/** flag to indicate that skipSiblings() has been called. */
+	protected boolean skipSiblings = false;
+	/** flag to indicate that skipSiblings() has been called. */
+	protected boolean skipSubtree = false;
+	/** the node iterator doing the work */
+	private Iterator nodeIterator = null;
+	
+	
+	/**
+	 * Constructor with optionsl initial values. If <code>propName</code> is provided, 
+	 * <code>schemaNS</code> has also be provided.
+	 * @param xmp the iterated metadata object.
+	 * @param schemaNS the iteration is reduced to this schema (optional) 
+	 * @param propPath the iteration is redurce to this property within the <code>schemaNS</code>
+	 * @param options advanced iteration options, see {@link IteratorOptions}
+	 * @throws XMPException If the node defined by the paramters is not existing. 
+	 */
+	public XMPIteratorImpl(XMPMetaImpl xmp, String schemaNS, String propPath,
+			IteratorOptions options) throws XMPException
+	{
+		// make sure that options is defined at least with defaults
+		this.options = options != null ? options : new IteratorOptions();
+		
+		// the start node of the iteration depending on the schema and property filter
+		XMPNode startNode = null;
+		String initialPath = null;
+		boolean baseSchema = schemaNS != null  &&  schemaNS.length() > 0; 
+		boolean baseProperty = propPath != null  &&  propPath.length() > 0; 
+		
+		if (!baseSchema  &&  !baseProperty)
+		{
+			// complete tree will be iterated
+			startNode = xmp.getRoot();
+		}
+		else if (baseSchema  &&  baseProperty)
+		{
+			// Schema and property node provided
+			XMPPath path = XMPPathParser.expandXPath(schemaNS, propPath);
+			
+			// base path is the prop path without the property leaf
+			XMPPath basePath = new XMPPath();
+			for (int i = 0; i < path.size() - 1; i++)
+			{
+				basePath.add(path.getSegment(i));
+			}
+			
+			startNode = XMPNodeUtils.findNode(xmp.getRoot(), path, false, null);
+			baseNS = schemaNS;
+			initialPath = basePath.toString();
+		}
+		else if (baseSchema  &&  !baseProperty)
+		{
+			// Only Schema provided
+			startNode = XMPNodeUtils.findSchemaNode(xmp.getRoot(), schemaNS, false);
+		}
+		else // !baseSchema  &&  baseProperty
+		{
+			// No schema but property provided -> error
+			throw new XMPException("Schema namespace URI is required", XMPError.BADSCHEMA);
+		}			
+
+		
+		// create iterator
+		if (startNode != null)
+		{
+			if (!this.options.isJustChildren())
+			{	
+				nodeIterator = new NodeIterator(startNode, initialPath, 1);
+			}
+			else
+			{
+				nodeIterator = new NodeIteratorChildren(startNode, initialPath);
+			}
+		}
+		else
+		{
+			// create null iterator
+			nodeIterator = Collections.EMPTY_LIST.iterator();
+		}
+	}
+
+
+	/**
+	 * @see XMPIterator#skipSubtree()
+	 */
+	public void skipSubtree()
+	{
+		this.skipSubtree = true;
+	}
+
+	
+	/**
+	 * @see XMPIterator#skipSiblings()
+	 */
+	public void skipSiblings()
+	{
+		skipSubtree();
+		this.skipSiblings = true;
+	}
+	
+
+	/**
+	 * @see java.util.Iterator#hasNext()
+	 */
+	public boolean hasNext()
+	{
+		return nodeIterator.hasNext();
+	}
+
+	
+	/**
+	 * @see java.util.Iterator#next()
+	 */
+	public Object next()
+	{
+		return nodeIterator.next();
+	}
+
+	
+	/**
+	 * @see java.util.Iterator#remove()
+	 */
+	public void remove()
+	{
+		throw new UnsupportedOperationException("The XMPIterator does not support remove().");
+	}
+	
+	
+	/**
+	 * @return Exposes the options for inner class.
+	 */
+	protected IteratorOptions getOptions()
+	{
+		return options;
+	}
+
+	
+	/**
+	 * @return Exposes the options for inner class.
+	 */
+	protected String getBaseNS()
+	{
+		return baseNS;
+	}
+
+	
+	/**
+	 * @param baseNS sets the baseNS from the inner class.
+	 */
+	protected void setBaseNS(String baseNS)
+	{
+		this.baseNS = baseNS;
+	}
+	
+	
+	
+	
+	
+	
+	/**
+	 * The <code>XMPIterator</code> implementation.
+	 * It first returns the node itself, then recursivly the children and qualifier of the node.
+	 * 
+	 * @since   29.06.2006
+	 */
+	private class NodeIterator implements Iterator
+	{
+		/** iteration state */
+		protected static final int ITERATE_NODE = 0;
+		/** iteration state */
+		protected static final int ITERATE_CHILDREN = 1;
+		/** iteration state */
+		protected static final int ITERATE_QUALIFIER = 2;
+		
+		/** the state of the iteration */
+		private int state = ITERATE_NODE; 
+		/** the currently visited node */
+		private XMPNode visitedNode;
+		/** the recursively accumulated path */
+		private String path;
+		/** the iterator that goes through the children and qualifier list */
+		private Iterator childrenIterator = null;
+		/** index of node with parent, only interesting for arrays */
+		private int index = 0;
+		/** the iterator for each child */
+		private Iterator subIterator = Collections.EMPTY_LIST.iterator();
+		/** the cached <code>PropertyInfo</code> to return */
+		private XMPPropertyInfo returnProperty = null;
+
+		
+		/**
+		 * Default constructor
+		 */
+		public NodeIterator()
+		{
+			// EMPTY
+		}
+		
+		
+		/**
+		 * Constructor for the node iterator.
+		 * @param visitedNode the currently visited node
+		 * @param parentPath the accumulated path of the node
+		 * @param index the index within the parent node (only for arrays)
+		 */
+		public NodeIterator(XMPNode visitedNode, String parentPath, int index)
+		{
+			this.visitedNode = visitedNode;
+			this.state = NodeIterator.ITERATE_NODE;
+			if (visitedNode.getOptions().isSchemaNode())
+			{	
+				setBaseNS(visitedNode.getName());
+			}
+
+			// for all but the root node and schema nodes
+			path = accumulatePath(visitedNode, parentPath, index);
+		}
+
+		
+		/**
+		 * Prepares the next node to return if not already done. 
+		 * 
+		 * @see Iterator#hasNext()
+		 */
+		public boolean hasNext()
+		{
+			if (returnProperty != null)
+			{
+				// hasNext has been called before
+				return true;
+			}
+			
+			// find next node
+			if (state == ITERATE_NODE)
+			{
+				return reportNode();
+			}
+			else if (state == ITERATE_CHILDREN)
+			{
+				if (childrenIterator == null)
+				{
+					childrenIterator = visitedNode.iterateChildren();
+				}
+				
+				boolean hasNext = iterateChildren(childrenIterator);
+				
+				if (!hasNext  &&  visitedNode.hasQualifier()  &&  !getOptions().isOmitQualifiers()) 
+				{
+					state = ITERATE_QUALIFIER;
+					childrenIterator = null;
+					hasNext = hasNext();
+				}
+				return hasNext;
+			}
+			else
+			{
+				if (childrenIterator == null)
+				{
+					childrenIterator = visitedNode.iterateQualifier();
+				}
+				
+				return iterateChildren(childrenIterator);
+			}
+		}
+
+
+		/**
+		 * Sets the returnProperty as next item or recurses into <code>hasNext()</code>.
+		 * @return Returns if there is a next item to return. 
+		 */
+		protected boolean reportNode()
+		{
+			state = ITERATE_CHILDREN;
+			if (visitedNode.getParent() != null  &&
+				(!getOptions().isJustLeafnodes()  ||  !visitedNode.hasChildren()))
+			{	
+				returnProperty = createPropertyInfo(visitedNode, getBaseNS(), path);
+				return true;
+			}
+			else
+			{
+				return hasNext();
+			}
+		}
+
+
+		/**
+		 * Handles the iteration of the children or qualfier
+		 * @param iterator an iterator
+		 * @return Returns if there are more elements available.
+		 */
+		private boolean iterateChildren(Iterator iterator)
+		{
+			if (skipSiblings)
+			{
+				// setSkipSiblings(false);
+				skipSiblings = false;
+				subIterator = Collections.EMPTY_LIST.iterator();
+			}
+			
+			// create sub iterator for every child,
+			// if its the first child visited or the former child is finished 
+			if ((!subIterator.hasNext())  &&  iterator.hasNext())
+			{
+				XMPNode child = (XMPNode) iterator.next();
+				index++;
+				subIterator = new NodeIterator(child, path, index);
+			}
+			
+			if (subIterator.hasNext())
+			{
+				returnProperty = (XMPPropertyInfo) subIterator.next();
+				return true;
+			}
+			else
+			{
+				return false;
+			}
+		}
+	
+		
+		/**
+		 * Calls hasNext() and returnes the prepared node. Afterwards its set to null.
+		 * The existance of returnProperty indicates if there is a next node, otherwise
+		 * an exceptio is thrown.
+		 * 
+		 * @see Iterator#next()
+		 */
+		public Object next()
+		{
+			if (hasNext())
+			{
+				XMPPropertyInfo result = returnProperty; 
+				returnProperty = null;
+				return result;
+			}
+			else
+			{
+				throw new NoSuchElementException("There are no more nodes to return");
+			}
+		}
+	
+		
+		/**
+		 * Not supported.
+		 * @see Iterator#remove()
+		 */
+		public void remove()
+		{
+			throw new UnsupportedOperationException();
+		}
+		
+		
+		/**
+		 * @param currNode the node that will be added to the path.
+		 * @param parentPath the path up to this node.
+		 * @param currentIndex the current array index if an arrey is traversed
+		 * @return Returns the updated path.
+		 */
+		protected String accumulatePath(XMPNode currNode, String parentPath, int currentIndex)
+		{
+			String separator;
+			String segmentName;
+			if (currNode.getParent() == null  ||  currNode.getOptions().isSchemaNode())
+			{
+				return null;
+			}
+			else if (currNode.getParent().getOptions().isArray())
+			{
+				separator = "";
+				segmentName = "[" + String.valueOf(currentIndex) + "]";
+			}
+			else
+			{	
+				separator = "/";
+				segmentName = currNode.getName();
+			}
+			
+			
+			if (parentPath == null  ||  parentPath.length() == 0)
+			{
+				return segmentName;
+			}
+			else if (getOptions().isJustLeafname())
+			{
+				return !segmentName.startsWith("?") ? 
+					segmentName :
+					segmentName.substring(1); // qualifier
+			}
+			else 
+			{
+				return parentPath + separator + segmentName;
+			}
+		}
+			
+		
+		/**
+		 * Creates a property info object from an <code>XMPNode</code>.
+		 * @param node an <code>XMPNode</code>
+		 * @param baseNS the base namespace to report
+		 * @param path the full property path
+		 * @return Returns a <code>XMPProperty</code>-object that serves representation of the node.
+		 */
+		protected XMPPropertyInfo createPropertyInfo(final XMPNode node, final String baseNS,
+				final String path)
+		{
+			final Object value = node.getOptions().isSchemaNode() ? null : node.getValue();
+			
+			return new XMPPropertyInfo()
+			{
+				public String getNamespace()
+				{
+					return baseNS;
+				}
+	
+				public String getPath()
+				{
+					return path;
+				}
+				
+				public Object getValue()
+				{
+					return value;
+				}
+	
+				public PropertyOptions getOptions()
+				{
+					return node.getOptions();
+				}
+
+				public String getLanguage()
+				{
+					// the language is not reported
+					return null;
+				}
+			};
+		}
+
+
+		/**
+		 * @return the childrenIterator
+		 */
+		protected  Iterator getChildrenIterator()
+		{
+			return childrenIterator;
+		}
+
+
+		/**
+		 * @param childrenIterator the childrenIterator to set
+		 */
+		protected void setChildrenIterator(Iterator childrenIterator)
+		{
+			this.childrenIterator = childrenIterator;
+		}
+
+		
+		/**
+		 * @return Returns the returnProperty.
+		 */
+		protected XMPPropertyInfo getReturnProperty()
+		{
+			return returnProperty;
+		}
+		
+
+		/**
+		 * @param returnProperty the returnProperty to set
+		 */
+		protected  void setReturnProperty(XMPPropertyInfo returnProperty)
+		{
+			this.returnProperty = returnProperty;
+		}
+	}
+	
+	
+	/**
+	 * This iterator is derived from the default <code>NodeIterator</code>,
+	 * and is only used for the option {@link IteratorOptions#JUST_CHILDREN}.
+	 * 
+	 * @since 02.10.2006
+	 */
+	private class NodeIteratorChildren extends NodeIterator
+	{
+		/** */
+		private String parentPath;
+		/** */
+		private Iterator childrenIterator;
+		/** */
+		private int index = 0;
+		
+		
+		/**
+		 * Constructor 
+		 * @param parentNode the node which children shall be iterated. 
+		 * @param parentPath the full path of the former node without the leaf node.
+		 */
+		public NodeIteratorChildren(XMPNode parentNode, String parentPath)
+		{
+			if (parentNode.getOptions().isSchemaNode())
+			{	
+				setBaseNS(parentNode.getName());
+			}
+			this.parentPath = accumulatePath(parentNode, parentPath, 1);
+
+			childrenIterator = parentNode.iterateChildren();
+		}
+		
+		
+		/**
+		 * Prepares the next node to return if not already done. 
+		 * 
+		 * @see Iterator#hasNext()
+		 */
+		public boolean hasNext()
+		{
+			if (getReturnProperty() != null)
+			{
+				// hasNext has been called before
+				return true;
+			}
+			else if (skipSiblings)
+			{
+				return false;
+			}
+			else if (childrenIterator.hasNext())
+			{
+				XMPNode child = (XMPNode) childrenIterator.next();
+				index++;
+				
+				String path = null;
+				if (child.getOptions().isSchemaNode())
+				{	
+					setBaseNS(child.getName());
+				}
+				else if (child.getParent() != null)
+				{
+					// for all but the root node and schema nodes
+					path = accumulatePath(child, parentPath, index);
+				}
+
+				// report next property, skip not-leaf nodes in case options is set
+				if (!getOptions().isJustLeafnodes()  ||  !child.hasChildren())
+				{	
+					setReturnProperty(createPropertyInfo(child, getBaseNS(), path));
+					return true;
+				}
+				else
+				{
+					return hasNext();
+				}
+			}
+			else
+			{
+				return false;
+			}
+		}		
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPMetaImpl.java b/XMPCore/src/com/adobe/xmp/impl/XMPMetaImpl.java
new file mode 100644
index 0000000..a97de99
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPMetaImpl.java
@@ -0,0 +1,1424 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.Calendar;
+import java.util.Iterator;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPDateTime;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPIterator;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPPathFactory;
+import com.adobe.xmp.XMPUtils;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathParser;
+import com.adobe.xmp.options.IteratorOptions;
+import com.adobe.xmp.options.ParseOptions;
+import com.adobe.xmp.options.PropertyOptions;
+import com.adobe.xmp.properties.XMPProperty;
+
+
+/**
+ * Implementation for {@link XMPMeta}.
+ * 
+ * @since 17.02.2006
+ */
+public class XMPMetaImpl implements XMPMeta, XMPConst
+{
+	/** Property values are Strings by default */
+	private static final int VALUE_STRING = 0;
+	/** */
+	private static final int VALUE_BOOLEAN = 1;
+	/** */
+	private static final int VALUE_INTEGER = 2;
+	/** */
+	private static final int VALUE_LONG = 3;
+	/** */
+	private static final int VALUE_DOUBLE = 4;
+	/** */
+	private static final int VALUE_DATE = 5;
+	/** */
+	private static final int VALUE_CALENDAR = 6;
+	/** */
+	private static final int VALUE_BASE64 = 7;
+
+	/** root of the metadata tree */
+	private XMPNode tree;
+	/** the xpacket processing instructions content */ 
+	private String packetHeader = null;
+	
+
+	/**
+	 * Constructor for an empty metadata object.
+	 */
+	public XMPMetaImpl()
+	{
+		// create root node
+		tree = new XMPNode(null, null, null);
+	}
+
+
+	/**
+	 * Constructor for a cloned metadata tree.
+	 * 
+	 * @param tree
+	 *            an prefilled metadata tree which fulfills all
+	 *            <code>XMPNode</code> contracts.
+	 */
+	public XMPMetaImpl(XMPNode tree)
+	{
+		this.tree = tree;
+	}
+
+
+	/**
+	 * @see XMPMeta#appendArrayItem(String, String, PropertyOptions, String,
+	 *      PropertyOptions)
+	 */
+	public void appendArrayItem(String schemaNS, String arrayName, PropertyOptions arrayOptions,
+			String itemValue, PropertyOptions itemOptions) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+
+		if (arrayOptions == null)
+		{
+			arrayOptions = new PropertyOptions();
+		}
+		if (!arrayOptions.isOnlyArrayOptions())
+		{
+			throw new XMPException("Only array form flags allowed for arrayOptions",
+					XMPError.BADOPTIONS);
+		}
+
+		// Check if array options are set correctly.
+		arrayOptions = XMPNodeUtils.verifySetOptions(arrayOptions, null);
+
+
+		// Locate or create the array. If it already exists, make sure the array
+		// form from the options
+		// parameter is compatible with the current state.
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+
+
+		// Just lookup, don't try to create.
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, false, null);
+
+		if (arrayNode != null)
+		{
+			// The array exists, make sure the form is compatible. Zero
+			// arrayForm means take what exists.
+			if (!arrayNode.getOptions().isArray())
+			{
+				throw new XMPException("The named property is not an array", XMPError.BADXPATH);
+			}
+			// if (arrayOptions != null && !arrayOptions.equalArrayTypes(arrayNode.getOptions()))
+			// {
+			// throw new XMPException("Mismatch of existing and specified array form", BADOPTIONS);
+			// }
+		}
+		else
+		{
+			// The array does not exist, try to create it.
+			if (arrayOptions.isArray())
+			{
+				arrayNode = XMPNodeUtils.findNode(tree, arrayPath, true, arrayOptions);
+				if (arrayNode == null)
+				{
+					throw new XMPException("Failure creating array node", XMPError.BADXPATH);
+				}
+			}
+			else
+			{
+				// array options missing
+				throw new XMPException("Explicit arrayOptions required to create new array",
+						XMPError.BADOPTIONS);
+			}
+		}
+
+		doSetArrayItem(arrayNode, ARRAY_LAST_ITEM, itemValue, itemOptions, true);
+	}
+
+	
+	/**
+	 * @see XMPMeta#appendArrayItem(String, String, String)
+	 */
+	public void appendArrayItem(String schemaNS, String arrayName, String itemValue)
+			throws XMPException
+	{
+		appendArrayItem(schemaNS, arrayName, null, itemValue, null);
+	}
+
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#countArrayItems(String, String)
+	 */
+	public int countArrayItems(String schemaNS, String arrayName) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, false, null);
+
+		if (arrayNode == null)
+		{
+			return 0;
+		}
+
+		if (arrayNode.getOptions().isArray())
+		{
+			return arrayNode.getChildrenLength();
+		}
+		else
+		{
+			throw new XMPException("The named property is not an array", XMPError.BADXPATH);
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#deleteArrayItem(String, String, int)
+	 */
+	public void deleteArrayItem(String schemaNS, String arrayName, int itemIndex)
+	{
+		try
+		{
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertArrayName(arrayName);
+
+			String itemPath = XMPPathFactory.composeArrayItemPath(arrayName, itemIndex);
+			deleteProperty(schemaNS, itemPath);
+		}
+		catch (XMPException e)
+		{
+			// EMPTY, exceptions are ignored within delete
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#deleteProperty(String, String)
+	 */
+	public void deleteProperty(String schemaNS, String propName)
+	{
+		try
+		{
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertPropName(propName);
+
+			XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+
+			XMPNode propNode = XMPNodeUtils.findNode(tree, expPath, false, null);
+			if (propNode != null)
+			{
+				XMPNodeUtils.deleteNode(propNode);
+			}
+		}
+		catch (XMPException e)
+		{
+			// EMPTY, exceptions are ignored within delete
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#deleteQualifier(String, String, String, String)
+	 */
+	public void deleteQualifier(String schemaNS, String propName, String qualNS, String qualName)
+	{
+		try
+		{
+			// Note: qualNS and qualName are checked inside composeQualfierPath
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertPropName(propName);
+
+			String qualPath = propName + XMPPathFactory.composeQualifierPath(qualNS, qualName);
+			deleteProperty(schemaNS, qualPath);
+		}
+		catch (XMPException e)
+		{
+			// EMPTY, exceptions within delete are ignored
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#deleteStructField(String, String, String, String)
+	 */
+	public void deleteStructField(String schemaNS, String structName, String fieldNS,
+			String fieldName)
+	{
+		try
+		{
+			// fieldNS and fieldName are checked inside composeStructFieldPath
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertStructName(structName);
+
+			String fieldPath = structName
+					+ XMPPathFactory.composeStructFieldPath(fieldNS, fieldName);
+			deleteProperty(schemaNS, fieldPath);
+		}
+		catch (XMPException e)
+		{
+			// EMPTY, exceptions within delete are ignored
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#doesPropertyExist(String, String)
+	 */
+	public boolean doesPropertyExist(String schemaNS, String propName)
+	{
+		try
+		{
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertPropName(propName);
+
+			XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+			final XMPNode propNode = XMPNodeUtils.findNode(tree, expPath, false, null);
+			return propNode != null;
+		}
+		catch (XMPException e)
+		{
+			return false;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#doesArrayItemExist(String, String, int)
+	 */
+	public boolean doesArrayItemExist(String schemaNS, String arrayName, int itemIndex)
+	{
+		try
+		{
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertArrayName(arrayName);
+
+			String path = XMPPathFactory.composeArrayItemPath(arrayName, itemIndex);
+			return doesPropertyExist(schemaNS, path);
+		}
+		catch (XMPException e)
+		{
+			return false;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#doesStructFieldExist(String, String, String, String)
+	 */
+	public boolean doesStructFieldExist(String schemaNS, String structName, String fieldNS,
+			String fieldName)
+	{
+		try
+		{
+			// fieldNS and fieldName are checked inside composeStructFieldPath()
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertStructName(structName);
+
+			String path = XMPPathFactory.composeStructFieldPath(fieldNS, fieldName);
+			return doesPropertyExist(schemaNS, structName + path);
+		}
+		catch (XMPException e)
+		{
+			return false;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#doesQualifierExist(String, String, String, String)
+	 */
+	public boolean doesQualifierExist(String schemaNS, String propName, String qualNS,
+			String qualName)
+	{
+		try
+		{
+			// qualNS and qualName are checked inside composeQualifierPath()
+			ParameterAsserts.assertSchemaNS(schemaNS);
+			ParameterAsserts.assertPropName(propName);
+
+			String path = XMPPathFactory.composeQualifierPath(qualNS, qualName);
+			return doesPropertyExist(schemaNS, propName + path);
+		}
+		catch (XMPException e)
+		{
+			return false;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#getArrayItem(String, String, int)
+	 */
+	public XMPProperty getArrayItem(String schemaNS, String arrayName, int itemIndex)
+			throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+
+		String itemPath = XMPPathFactory.composeArrayItemPath(arrayName, itemIndex);
+		return getProperty(schemaNS, itemPath);
+	}
+
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#getLocalizedText(String, String, String, String)
+	 */
+	public XMPProperty getLocalizedText(String schemaNS, String altTextName, String genericLang,
+			String specificLang) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(altTextName);
+		ParameterAsserts.assertSpecificLang(specificLang);
+
+		genericLang = genericLang != null ? Utils.normalizeLangValue(genericLang) : null;
+		specificLang = Utils.normalizeLangValue(specificLang);
+
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, altTextName);
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, false, null);
+		if (arrayNode == null)
+		{
+			return null;
+		}
+
+		Object[] result = XMPNodeUtils.chooseLocalizedText(arrayNode, genericLang, specificLang);
+		int match = ((Integer) result[0]).intValue();
+		final XMPNode itemNode = (XMPNode) result[1];
+
+		if (match != XMPNodeUtils.CLT_NO_VALUES)
+		{
+			return new XMPProperty()
+			{
+				public Object getValue()
+				{
+					return itemNode.getValue();
+				}
+
+
+				public PropertyOptions getOptions()
+				{
+					return itemNode.getOptions();
+				}
+
+
+				public String getLanguage()
+				{
+					return itemNode.getQualifier(1).getValue();
+				}
+
+
+				public String toString()
+				{
+					return itemNode.getValue().toString();
+				}
+			};
+		}
+		else
+		{
+			return null;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#setLocalizedText(String, String, String, String, String,
+	 *      PropertyOptions)
+	 */
+	public void setLocalizedText(String schemaNS, String altTextName, String genericLang,
+			String specificLang, String itemValue, PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(altTextName);
+		ParameterAsserts.assertSpecificLang(specificLang);
+
+		genericLang = genericLang != null ? Utils.normalizeLangValue(genericLang) : null;
+		specificLang = Utils.normalizeLangValue(specificLang);
+
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, altTextName);
+
+		// Find the array node and set the options if it was just created.
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, true, new PropertyOptions(
+				PropertyOptions.ARRAY | PropertyOptions.ARRAY_ORDERED
+						| PropertyOptions.ARRAY_ALTERNATE | PropertyOptions.ARRAY_ALT_TEXT));
+
+		if (arrayNode == null)
+		{
+			throw new XMPException("Failed to find or create array node", XMPError.BADXPATH);
+		}
+		else if (!arrayNode.getOptions().isArrayAltText())
+		{
+			if (!arrayNode.hasChildren() && arrayNode.getOptions().isArrayAlternate())
+			{
+				arrayNode.getOptions().setArrayAltText(true);
+			}
+			else
+			{
+				throw new XMPException(
+					"Specified property is no alt-text array", XMPError.BADXPATH);
+			}
+		}
+
+		// Make sure the x-default item, if any, is first.
+		boolean haveXDefault = false;
+		XMPNode xdItem = null;
+
+		for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode currItem = (XMPNode) it.next();
+			if (!currItem.hasQualifier()
+					|| !XMPConst.XML_LANG.equals(currItem.getQualifier(1).getName()))
+			{
+				throw new XMPException("Language qualifier must be first", XMPError.BADXPATH);
+			}
+			else if (XMPConst.X_DEFAULT.equals(currItem.getQualifier(1).getValue()))
+			{
+				xdItem = currItem;
+				haveXDefault = true;
+				break;
+			}
+		}
+
+		// Moves x-default to the beginning of the array
+		if (xdItem != null  &&  arrayNode.getChildrenLength() > 1)
+		{
+			arrayNode.removeChild(xdItem);
+			arrayNode.addChild(1, xdItem);
+		}
+
+		// Find the appropriate item.
+		// chooseLocalizedText will make sure the array is a language
+		// alternative.
+		Object[] result = XMPNodeUtils.chooseLocalizedText(arrayNode, genericLang, specificLang);
+		int match = ((Integer) result[0]).intValue();
+		XMPNode itemNode = (XMPNode) result[1];
+
+		boolean specificXDefault = XMPConst.X_DEFAULT.equals(specificLang);
+
+		switch (match)
+		{
+		case XMPNodeUtils.CLT_NO_VALUES:
+
+			// Create the array items for the specificLang and x-default, with
+			// x-default first.
+			XMPNodeUtils.appendLangItem(arrayNode, XMPConst.X_DEFAULT, itemValue);
+			haveXDefault = true;
+			if (!specificXDefault)
+			{
+				XMPNodeUtils.appendLangItem(arrayNode, specificLang, itemValue);
+			}
+			break;
+
+		case XMPNodeUtils.CLT_SPECIFIC_MATCH:
+
+			if (!specificXDefault)
+			{
+				// Update the specific item, update x-default if it matches the
+				// old value.
+				if (haveXDefault && xdItem != itemNode && xdItem != null
+						&& xdItem.getValue().equals(itemNode.getValue()))
+				{
+					xdItem.setValue(itemValue);
+				}
+				// ! Do this after the x-default check!
+				itemNode.setValue(itemValue);
+			}
+			else
+			{
+				// Update all items whose values match the old x-default value.
+				assert  haveXDefault  &&  xdItem == itemNode;
+				for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+				{
+					XMPNode currItem = (XMPNode) it.next();
+					if (currItem == xdItem
+							|| !currItem.getValue().equals(
+									xdItem != null ? xdItem.getValue() : null))
+					{
+						continue;
+					}
+					currItem.setValue(itemValue);
+				}
+				// And finally do the x-default item.
+				if (xdItem != null)
+				{	
+					xdItem.setValue(itemValue);
+				}	
+			}
+			break;
+
+		case XMPNodeUtils.CLT_SINGLE_GENERIC:
+
+			// Update the generic item, update x-default if it matches the old
+			// value.
+			if (haveXDefault && xdItem != itemNode && xdItem != null
+					&& xdItem.getValue().equals(itemNode.getValue()))
+			{
+				xdItem.setValue(itemValue);
+			}
+			itemNode.setValue(itemValue); // ! Do this after
+			// the x-default
+			// check!
+			break;
+
+		case XMPNodeUtils.CLT_MULTIPLE_GENERIC:
+
+			// Create the specific language, ignore x-default.
+			XMPNodeUtils.appendLangItem(arrayNode, specificLang, itemValue);
+			if (specificXDefault)
+			{
+				haveXDefault = true;
+			}
+			break;
+
+		case XMPNodeUtils.CLT_XDEFAULT:
+
+			// Create the specific language, update x-default if it was the only
+			// item.
+			if (xdItem != null  &&  arrayNode.getChildrenLength() == 1)
+			{
+				xdItem.setValue(itemValue);
+			}
+			XMPNodeUtils.appendLangItem(arrayNode, specificLang, itemValue);
+			break;
+
+		case XMPNodeUtils.CLT_FIRST_ITEM:
+
+			// Create the specific language, don't add an x-default item.
+			XMPNodeUtils.appendLangItem(arrayNode, specificLang, itemValue);
+			if (specificXDefault)
+			{
+				haveXDefault = true;
+			}
+			break;
+
+		default:
+			// does not happen under normal circumstances
+			throw new XMPException("Unexpected result from ChooseLocalizedText",
+					XMPError.INTERNALFAILURE);
+
+		}
+
+		// Add an x-default at the front if needed.
+		if (!haveXDefault && arrayNode.getChildrenLength() == 1)
+		{
+			XMPNodeUtils.appendLangItem(arrayNode, XMPConst.X_DEFAULT, itemValue);
+		}
+	}
+
+	
+	/**
+	 * @see XMPMeta#setLocalizedText(String, String, String, String, String)
+	 */
+	public void setLocalizedText(String schemaNS, String altTextName, String genericLang,
+			String specificLang, String itemValue) throws XMPException
+	{
+		setLocalizedText(schemaNS, altTextName, genericLang, specificLang, itemValue, null);
+	}
+	
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#getProperty(String, String)
+	 */
+	public XMPProperty getProperty(String schemaNS, String propName) throws XMPException
+	{
+		return getProperty(schemaNS, propName, VALUE_STRING);
+	}
+
+
+	/**
+	 * Returns a property, but the result value can be requested. It can be one
+	 * of {@link XMPMetaImpl#VALUE_STRING}, {@link XMPMetaImpl#VALUE_BOOLEAN},
+	 * {@link XMPMetaImpl#VALUE_INTEGER}, {@link XMPMetaImpl#VALUE_LONG},
+	 * {@link XMPMetaImpl#VALUE_DOUBLE}, {@link XMPMetaImpl#VALUE_DATE},
+	 * {@link XMPMetaImpl#VALUE_CALENDAR}, {@link XMPMetaImpl#VALUE_BASE64}.
+	 * 
+	 * @see XMPMeta#getProperty(String, String)
+	 * @param schemaNS
+	 *            a schema namespace
+	 * @param propName
+	 *            a property name or path
+	 * @param valueType
+	 *            the type of the value, see VALUE_...
+	 * @return Returns an <code>XMPProperty</code>
+	 * @throws XMPException
+	 *             Collects any exception that occurs.
+	 */
+	protected XMPProperty getProperty(String schemaNS, String propName, int valueType)
+			throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertPropName(propName);
+
+		final XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+		final XMPNode propNode = XMPNodeUtils.findNode(tree, expPath, false, null);
+
+		if (propNode != null)
+		{
+			if (valueType != VALUE_STRING && propNode.getOptions().isCompositeProperty())
+			{
+				throw new XMPException("Property must be simple when a value type is requested",
+						XMPError.BADXPATH);
+			}
+
+			final Object value = evaluateNodeValue(valueType, propNode);
+
+			return new XMPProperty()
+			{
+				public Object getValue()
+				{
+					return value;
+				}
+
+
+				public PropertyOptions getOptions()
+				{
+					return propNode.getOptions();
+				}
+
+
+				public String getLanguage()
+				{
+					return null;
+				}
+
+
+				public String toString()
+				{
+					return value.toString();
+				}
+			};
+		}
+		else
+		{
+			return null;
+		}
+	}
+
+
+	/**
+	 * Returns a property, but the result value can be requested.
+	 * 
+	 * @see XMPMeta#getProperty(String, String)
+	 * @param schemaNS
+	 *            a schema namespace
+	 * @param propName
+	 *            a property name or path
+	 * @param valueType
+	 *            the type of the value, see VALUE_...
+	 * @return Returns the node value as an object according to the
+	 *         <code>valueType</code>.
+	 * @throws XMPException
+	 *             Collects any exception that occurs.
+	 */
+	protected Object getPropertyObject(String schemaNS, String propName, int valueType)
+			throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertPropName(propName);
+
+		final XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+		final XMPNode propNode = XMPNodeUtils.findNode(tree, expPath, false, null);
+
+		if (propNode != null)
+		{
+			if (valueType != VALUE_STRING && propNode.getOptions().isCompositeProperty())
+			{
+				throw new XMPException("Property must be simple when a value type is requested",
+						XMPError.BADXPATH);
+			}
+
+			return evaluateNodeValue(valueType, propNode);
+		}
+		else
+		{
+			return null;
+		}
+	}
+
+
+	/**
+	 * @see XMPMeta#getPropertyBoolean(String, String)
+	 */
+	public Boolean getPropertyBoolean(String schemaNS, String propName) throws XMPException
+	{
+		return (Boolean) getPropertyObject(schemaNS, propName, VALUE_BOOLEAN);
+	}
+
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#setPropertyBoolean(String, String, boolean, PropertyOptions)
+	 */
+	public void setPropertyBoolean(String schemaNS, String propName, boolean propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue ? TRUESTR : FALSESTR, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyBoolean(String, String, boolean)
+	 */
+	public void setPropertyBoolean(String schemaNS, String propName, boolean propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue ? TRUESTR : FALSESTR, null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyInteger(String, String)
+	 */
+	public Integer getPropertyInteger(String schemaNS, String propName) throws XMPException
+	{
+		return (Integer) getPropertyObject(schemaNS, propName, VALUE_INTEGER);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyInteger(String, String, int, PropertyOptions)
+	 */
+	public void setPropertyInteger(String schemaNS, String propName, int propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, new Integer(propValue), options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyInteger(String, String, int)
+	 */
+	public void setPropertyInteger(String schemaNS, String propName, int propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, new Integer(propValue), null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyLong(String, String)
+	 */
+	public Long getPropertyLong(String schemaNS, String propName) throws XMPException
+	{
+		return (Long) getPropertyObject(schemaNS, propName, VALUE_LONG);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyLong(String, String, long, PropertyOptions)
+	 */
+	public void setPropertyLong(String schemaNS, String propName, long propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, new Long(propValue), options);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyLong(String, String, long)
+	 */
+	public void setPropertyLong(String schemaNS, String propName, long propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, new Long(propValue), null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyDouble(String, String)
+	 */
+	public Double getPropertyDouble(String schemaNS, String propName) throws XMPException
+	{
+		return (Double) getPropertyObject(schemaNS, propName, VALUE_DOUBLE);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyDouble(String, String, double, PropertyOptions)
+	 */
+	public void setPropertyDouble(String schemaNS, String propName, double propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, new Double(propValue), options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyDouble(String, String, double)
+	 */
+	public void setPropertyDouble(String schemaNS, String propName, double propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, new Double(propValue), null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyDate(String, String)
+	 */
+	public XMPDateTime getPropertyDate(String schemaNS, String propName) throws XMPException
+	{
+		return (XMPDateTime) getPropertyObject(schemaNS, propName, VALUE_DATE);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyDate(String, String, XMPDateTime,
+	 *      PropertyOptions)
+	 */
+	public void setPropertyDate(String schemaNS, String propName, XMPDateTime propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyDate(String, String, XMPDateTime)
+	 */
+	public void setPropertyDate(String schemaNS, String propName, XMPDateTime propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyCalendar(String, String)
+	 */
+	public Calendar getPropertyCalendar(String schemaNS, String propName) throws XMPException
+	{
+		return (Calendar) getPropertyObject(schemaNS, propName, VALUE_CALENDAR);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyCalendar(String, String, Calendar,
+	 *      PropertyOptions)
+	 */
+	public void setPropertyCalendar(String schemaNS, String propName, Calendar propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyCalendar(String, String, Calendar)
+	 */
+	public void setPropertyCalendar(String schemaNS, String propName, Calendar propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getPropertyBase64(String, String)
+	 */
+	public byte[] getPropertyBase64(String schemaNS, String propName) throws XMPException
+	{
+		return (byte[]) getPropertyObject(schemaNS, propName, VALUE_BASE64);
+	}
+
+
+	/**
+	 * @see XMPMeta#getPropertyString(String, String)
+	 */
+	public String getPropertyString(String schemaNS, String propName) throws XMPException
+	{
+		return (String) getPropertyObject(schemaNS, propName, VALUE_STRING);
+	}
+
+
+	/**
+	 * @see XMPMeta#setPropertyBase64(String, String, byte[], PropertyOptions)
+	 */
+	public void setPropertyBase64(String schemaNS, String propName, byte[] propValue,
+			PropertyOptions options) throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setPropertyBase64(String, String, byte[])
+	 */
+	public void setPropertyBase64(String schemaNS, String propName, byte[] propValue)
+			throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, null);
+	}
+	
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#getQualifier(String, String, String, String)
+	 */
+	public XMPProperty getQualifier(String schemaNS, String propName, String qualNS, 
+		String qualName) throws XMPException
+	{
+		// qualNS and qualName are checked inside composeQualfierPath
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertPropName(propName);
+
+		String qualPath = propName + XMPPathFactory.composeQualifierPath(qualNS, qualName);
+		return getProperty(schemaNS, qualPath);
+	}
+
+
+	/**
+	 * @see XMPMeta#getStructField(String, String, String, String)
+	 */
+	public XMPProperty getStructField(String schemaNS, String structName, String fieldNS,
+			String fieldName) throws XMPException
+	{
+		// fieldNS and fieldName are checked inside composeStructFieldPath
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertStructName(structName);
+
+		String fieldPath = structName + XMPPathFactory.composeStructFieldPath(fieldNS, fieldName);
+		return getProperty(schemaNS, fieldPath);
+	}
+
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#iterator()
+	 */
+	public XMPIterator iterator() throws XMPException
+	{
+		return iterator(null, null, null);
+	}
+
+
+	/**
+	 * @see XMPMeta#iterator(IteratorOptions)
+	 */
+	public XMPIterator iterator(IteratorOptions options) throws XMPException
+	{
+		return iterator(null, null, options);
+	}
+
+
+	/**
+	 * @see XMPMeta#iterator(String, String, IteratorOptions)
+	 */
+	public XMPIterator iterator(String schemaNS, String propName, IteratorOptions options)
+			throws XMPException
+	{
+		return new XMPIteratorImpl(this, schemaNS, propName, options);
+	}
+
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#setArrayItem(String, String, int, String, PropertyOptions)
+	 */
+	public void setArrayItem(String schemaNS, String arrayName, int itemIndex, String itemValue,
+			PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+
+		// Just lookup, don't try to create.
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, false, null);
+
+		if (arrayNode != null)
+		{
+			doSetArrayItem(arrayNode, itemIndex, itemValue, options, false);
+		}
+		else
+		{
+			throw new XMPException("Specified array does not exist", XMPError.BADXPATH);
+		}
+	}
+
+	
+	/**
+	 * @see XMPMeta#setArrayItem(String, String, int, String)
+	 */
+	public void setArrayItem(String schemaNS, String arrayName, int itemIndex, String itemValue)
+			throws XMPException
+	{
+		setArrayItem(schemaNS, arrayName, itemIndex, itemValue, null);
+	}
+	
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#insertArrayItem(String, String, int, String,
+	 *      PropertyOptions)
+	 */
+	public void insertArrayItem(String schemaNS, String arrayName, int itemIndex, String itemValue,
+			PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+
+		// Just lookup, don't try to create.
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+		XMPNode arrayNode = XMPNodeUtils.findNode(tree, arrayPath, false, null);
+
+		if (arrayNode != null)
+		{
+			doSetArrayItem(arrayNode, itemIndex, itemValue, options, true);
+		}
+		else
+		{
+			throw new XMPException("Specified array does not exist", XMPError.BADXPATH);
+		}
+	}
+
+	
+	/**
+	 * @see XMPMeta#insertArrayItem(String, String, int, String)
+	 */
+	public void insertArrayItem(String schemaNS, String arrayName, int itemIndex, String itemValue)
+			throws XMPException
+	{
+		insertArrayItem(schemaNS, arrayName, itemIndex, itemValue, null);
+	}
+	
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#setProperty(String, String, Object, PropertyOptions)
+	 */
+	public void setProperty(String schemaNS, String propName, Object propValue,
+			PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertPropName(propName);
+
+		options = XMPNodeUtils.verifySetOptions(options, propValue);
+
+		XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+
+		XMPNode propNode = XMPNodeUtils.findNode(tree, expPath, true, options);
+		if (propNode != null)
+		{
+			setNode(propNode, propValue, options, false);
+		}
+		else
+		{
+			throw new XMPException("Specified property does not exist", XMPError.BADXPATH);
+		}
+	}
+
+	
+	/**
+	 * @see XMPMeta#setProperty(String, String, Object)
+	 */
+	public void setProperty(String schemaNS, String propName, Object propValue) throws XMPException
+	{
+		setProperty(schemaNS, propName, propValue, null);
+	}
+	
+
+	/**
+	 * @throws XMPException
+	 * @see XMPMeta#setQualifier(String, String, String, String, String,
+	 *      PropertyOptions)
+	 */
+	public void setQualifier(String schemaNS, String propName, String qualNS, String qualName,
+			String qualValue, PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertPropName(propName);
+
+		if (!doesPropertyExist(schemaNS, propName))
+		{
+			throw new XMPException("Specified property does not exist!", XMPError.BADXPATH);
+		}
+
+		String qualPath = propName + XMPPathFactory.composeQualifierPath(qualNS, qualName);
+		setProperty(schemaNS, qualPath, qualValue, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setQualifier(String, String, String, String, String)
+	 */
+	public void setQualifier(String schemaNS, String propName, String qualNS, String qualName,
+			String qualValue) throws XMPException
+	{
+		setQualifier(schemaNS, propName, qualNS, qualName, qualValue, null);
+		
+	}
+	
+
+	/**
+	 * @see XMPMeta#setStructField(String, String, String, String, String,
+	 *      PropertyOptions)
+	 */
+	public void setStructField(String schemaNS, String structName, String fieldNS,
+			String fieldName, String fieldValue, PropertyOptions options) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertStructName(structName);
+
+		String fieldPath = structName + XMPPathFactory.composeStructFieldPath(fieldNS, fieldName);
+		setProperty(schemaNS, fieldPath, fieldValue, options);
+	}
+
+	
+	/**
+	 * @see XMPMeta#setStructField(String, String, String, String, String)
+	 */
+	public void setStructField(String schemaNS, String structName, String fieldNS,
+			String fieldName, String fieldValue) throws XMPException
+	{
+		setStructField(schemaNS, structName, fieldNS, fieldName, fieldValue, null);
+	}
+	
+
+	/**
+	 * @see XMPMeta#getObjectName()
+	 */
+	public String getObjectName()
+	{
+		return tree.getName() != null ? tree.getName() : "";
+	}
+
+	
+	/**
+	 * @see XMPMeta#setObjectName(String)
+	 */
+	public void setObjectName(String name)
+	{
+		tree.setName(name);
+	}
+
+	
+	/**
+	 * @see XMPMeta#getPacketHeader()
+	 */
+	public String getPacketHeader()
+	{
+		return packetHeader;
+	}
+
+	
+	/**
+	 * Sets the packetHeader attributes, only used by the parser.
+	 * @param packetHeader the processing instruction content
+	 */
+	public void setPacketHeader(String packetHeader)
+	{
+		this.packetHeader = packetHeader;
+	}
+	
+	
+	/**
+	 * Performs a deep clone of the XMPMeta-object
+	 * 
+	 * @see java.lang.Object#clone()
+	 */
+	public Object clone()
+	{
+		XMPNode clonedTree = (XMPNode) tree.clone();
+		return new XMPMetaImpl(clonedTree);
+	}
+
+
+	/**
+	 * @see XMPMeta#dumpObject()
+	 */
+	public String dumpObject()
+	{
+		// renders tree recursively
+		return getRoot().dumpNode(true);
+	}
+
+	
+	/**
+	 * @see XMPMeta#sort()
+	 */
+	public void sort()
+	{
+		this.tree.sort();
+	}
+
+
+	/**
+	 * @see XMPMeta#normalize(ParseOptions)
+	 */
+	public void normalize(ParseOptions options) throws XMPException
+	{
+		if (options == null)
+		{
+			options = new ParseOptions();
+		}
+		XMPNormalizer.process(this, options);		
+	}
+
+	
+	/**
+	 * @return Returns the root node of the XMP tree.
+	 */
+	public XMPNode getRoot()
+	{
+		return tree;
+	}
+
+
+
+	// -------------------------------------------------------------------------------------
+	// private
+
+
+	/**
+	 * Locate or create the item node and set the value. Note the index
+	 * parameter is one-based! The index can be in the range [1..size + 1] or
+	 * "last()", normalize it and check the insert flags. The order of the
+	 * normalization checks is important. If the array is empty we end up with
+	 * an index and location to set item size + 1.
+	 * 
+	 * @param arrayNode an array node
+	 * @param itemIndex the index where to insert the item
+	 * @param itemValue the item value
+	 * @param itemOptions the options for the new item
+	 * @param insert insert oder overwrite at index position?
+	 * @throws XMPException
+	 */
+	private void doSetArrayItem(XMPNode arrayNode, int itemIndex, String itemValue,
+			PropertyOptions itemOptions, boolean insert) throws XMPException
+	{
+		XMPNode itemNode = new XMPNode(ARRAY_ITEM_NAME, null);
+		itemOptions = XMPNodeUtils.verifySetOptions(itemOptions, itemValue);
+
+		// in insert mode the index after the last is allowed,
+		// even ARRAY_LAST_ITEM points to the index *after* the last.
+		int maxIndex = insert ? arrayNode.getChildrenLength() + 1 : arrayNode.getChildrenLength();
+		if (itemIndex == ARRAY_LAST_ITEM)
+		{
+			itemIndex = maxIndex;
+		}
+
+		if (1 <= itemIndex && itemIndex <= maxIndex)
+		{
+			if (!insert)
+			{
+				arrayNode.removeChild(itemIndex);
+			}
+			arrayNode.addChild(itemIndex, itemNode);
+			setNode(itemNode, itemValue, itemOptions, false);
+		}
+		else
+		{
+			throw new XMPException("Array index out of bounds", XMPError.BADINDEX);
+		}
+	}
+
+
+	/**
+	 * The internals for setProperty() and related calls, used after the node is
+	 * found or created.
+	 * 
+	 * @param node
+	 *            the newly created node
+	 * @param value
+	 *            the node value, can be <code>null</code>
+	 * @param newOptions
+	 *            options for the new node, must not be <code>null</code>.
+	 * @param deleteExisting flag if the existing value is to be overwritten 
+	 * @throws XMPException thrown if options and value do not correspond
+	 */
+	void setNode(XMPNode node, Object value, PropertyOptions newOptions, boolean deleteExisting)
+			throws XMPException
+	{
+		if (deleteExisting)
+		{
+			node.clear();
+		}
+
+		// its checked by setOptions(), if the merged result is a valid options set
+		node.getOptions().mergeWith(newOptions);
+
+		if (!node.getOptions().isCompositeProperty())
+		{
+			// This is setting the value of a leaf node.
+			XMPNodeUtils.setNodeValue(node, value);
+		}
+		else
+		{
+			if (value != null && value.toString().length() > 0)
+			{
+				throw new XMPException("Composite nodes can't have values", XMPError.BADXPATH);
+			}
+
+			node.removeChildren();
+		}
+
+	}
+
+
+	/**
+	 * Evaluates a raw node value to the given value type, apply special
+	 * conversions for defined types in XMP.
+	 * 
+	 * @param valueType
+	 *            an int indicating the value type
+	 * @param propNode
+	 *            the node containing the value
+	 * @return Returns a literal value for the node.
+	 * @throws XMPException
+	 */
+	private Object evaluateNodeValue(int valueType, final XMPNode propNode) throws XMPException
+	{
+		final Object value;
+		String rawValue = propNode.getValue();
+		switch (valueType)
+		{
+		case VALUE_BOOLEAN:
+			value = new Boolean(XMPUtils.convertToBoolean(rawValue));
+			break;
+		case VALUE_INTEGER:
+			value = new Integer(XMPUtils.convertToInteger(rawValue));
+			break;
+		case VALUE_LONG:
+			value = new Long(XMPUtils.convertToLong(rawValue));
+			break;
+		case VALUE_DOUBLE:
+			value = new Double(XMPUtils.convertToDouble(rawValue));
+			break;
+		case VALUE_DATE:
+			value = XMPUtils.convertToDate(rawValue);
+			break;
+		case VALUE_CALENDAR:
+			XMPDateTime dt = XMPUtils.convertToDate(rawValue);
+			value = dt.getCalendar();
+			break;
+		case VALUE_BASE64:
+			value = XMPUtils.decodeBase64(rawValue);
+			break;
+		case VALUE_STRING:
+		default:
+			// leaf values return empty string instead of null
+			// for the other cases the converter methods provides a "null"
+			// value.
+			// a default value can only occur if this method is made public.
+			value = rawValue != null || propNode.getOptions().isCompositeProperty() ? rawValue : "";
+			break;
+		}
+		return value;
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPMetaParser.java b/XMPCore/src/com/adobe/xmp/impl/XMPMetaParser.java
new file mode 100644
index 0000000..40c0ce2
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPMetaParser.java
@@ -0,0 +1,411 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.options.ParseOptions;
+
+
+/**
+ * This class replaces the <code>ExpatAdapter.cpp</code> and does the
+ * XML-parsing and fixes the prefix. After the parsing several normalisations
+ * are applied to the XMPTree.
+ * 
+ * @since 01.02.2006
+ */
+public class XMPMetaParser
+{
+	/**  */
+	private static final Object XMP_RDF = new Object();
+	/** the DOM Parser Factory, options are set */ 
+	private static DocumentBuilderFactory factory = createDocumentBuilderFactory();
+
+	/**
+	 * Hidden constructor, initialises the SAX parser handler.
+	 */
+	private XMPMetaParser()
+	{
+		// EMPTY
+	}
+
+	
+
+	/**
+	 * Parses the input source into an XMP metadata object, including
+	 * de-aliasing and normalisation.
+	 * 
+	 * @param input the input can be an <code>InputStream</code>, a <code>String</code> or 
+	 * 			a byte buffer containing the XMP packet.
+	 * @param options the parse options
+	 * @return Returns the resulting XMP metadata object
+	 * @throws XMPException Thrown if parsing or normalisation fails.
+	 */
+	public static XMPMeta parse(Object input, ParseOptions options) throws XMPException
+	{
+		ParameterAsserts.assertNotNull(input);
+		options = options != null ? options : new ParseOptions();
+
+		Document document = parseXml(input, options);
+
+		boolean xmpmetaRequired = options.getRequireXMPMeta();
+		Object[] result = new Object[3];
+		result = findRootNode(document, xmpmetaRequired, result);
+		
+		if (result != null  &&  result[1] == XMP_RDF)
+		{
+			XMPMetaImpl xmp = ParseRDF.parse((Node) result[0]);
+			xmp.setPacketHeader((String) result[2]);
+			
+			// Check if the XMP object shall be normalized
+			if (!options.getOmitNormalization())
+			{
+				return XMPNormalizer.process(xmp, options);
+			}
+			else
+			{
+				return xmp;
+			}
+		}
+		else
+		{
+			// no appropriate root node found, return empty metadata object
+			return new XMPMetaImpl();
+		}
+	}
+
+	
+	/**
+	 * Parses the raw XML metadata packet considering the parsing options.
+	 * Latin-1/ISO-8859-1 can be accepted when the input is a byte stream 
+	 * (some old toolkits versions such packets). The stream is 
+	 * then wrapped in another stream that converts Latin-1 to UTF-8.
+	 * <p>
+	 * If control characters shall be fixed, a reader is used that fixes the chars to spaces
+	 * (if the input is a byte stream is has to be read as character stream).
+	 * <p>   
+	 * Both options reduce the performance of the parser.
+	 *  
+	 * @param input the input can be an <code>InputStream</code>, a <code>String</code> or 
+	 * 			a byte buffer containing the XMP packet.
+	 * @param options the parsing options
+	 * @return Returns the parsed XML document or an exception.
+	 * @throws XMPException Thrown if the parsing fails for different reasons
+	 */
+	private static Document parseXml(Object input, ParseOptions options)
+			throws XMPException
+	{
+		if (input instanceof InputStream)
+		{
+			return parseXmlFromInputStream((InputStream) input, options);
+		}
+		else if (input instanceof byte[])
+		{
+			return parseXmlFromBytebuffer(new ByteBuffer((byte[]) input), options);
+		} 
+		else
+		{
+			return parseXmlFromString((String) input, options);
+		}
+	}
+	
+
+	/**
+	 * Parses XML from an {@link InputStream},
+	 * fixing the encoding (Latin-1 to UTF-8) and illegal control character optionally.
+	 *  
+	 * @param stream an <code>InputStream</code>
+	 * @param options the parsing options
+	 * @return Returns an XML DOM-Document.
+	 * @throws XMPException Thrown when the parsing fails.
+	 */
+	private static Document parseXmlFromInputStream(InputStream stream, ParseOptions options)
+			throws XMPException
+	{
+		if (!options.getAcceptLatin1()  &&  !options.getFixControlChars())
+		{
+			return parseInputSource(new InputSource(stream));
+		}
+		else
+		{
+			// load stream into bytebuffer
+			try
+			{
+				ByteBuffer buffer = new ByteBuffer(stream);
+				return parseXmlFromBytebuffer(buffer, options);
+			}
+			catch (IOException e)
+			{
+				throw new XMPException("Error reading the XML-file",
+						XMPError.BADSTREAM, e);
+			}
+		}
+	}
+
+	
+	/**
+	 * Parses XML from a byte buffer, 
+	 * fixing the encoding (Latin-1 to UTF-8) and illegal control character optionally.
+	 * 
+	 * @param buffer a byte buffer containing the XMP packet
+	 * @param options the parsing options
+	 * @return Returns an XML DOM-Document.
+	 * @throws XMPException Thrown when the parsing fails.
+	 */
+	private static Document parseXmlFromBytebuffer(ByteBuffer buffer, ParseOptions options)
+		throws XMPException
+	{
+		InputSource source = new InputSource(buffer.getByteStream());
+		try
+		{
+			return parseInputSource(source);
+		}
+		catch (XMPException e)
+		{
+			if (e.getErrorCode() == XMPError.BADXML  ||
+				e.getErrorCode() == XMPError.BADSTREAM)
+			{
+				if (options.getAcceptLatin1())
+				{
+					buffer = Latin1Converter.convert(buffer);
+				}
+				
+				if (options.getFixControlChars())
+				{
+					try
+					{
+						String encoding = buffer.getEncoding();
+						Reader fixReader = new FixASCIIControlsReader(
+							new InputStreamReader(
+								buffer.getByteStream(), encoding));
+						return parseInputSource(new InputSource(fixReader));
+					}
+					catch (UnsupportedEncodingException e1)
+					{
+						// can normally not happen as the encoding is provided by a util function
+						throw new XMPException("Unsupported Encoding",
+								XMPError.INTERNALFAILURE, e);
+					}
+				}
+				source = new InputSource(buffer.getByteStream());
+				return parseInputSource(source);
+			}
+			else
+			{
+				throw e;
+			}	
+		}
+	}
+
+
+	/**
+	 * Parses XML from a {@link String}, 
+	 * fixing the illegal control character optionally.
+	 *  
+	 * @param input a <code>String</code> containing the XMP packet
+	 * @param options the parsing options
+	 * @return Returns an XML DOM-Document.
+	 * @throws XMPException Thrown when the parsing fails.
+	 */
+	private static Document parseXmlFromString(String input, ParseOptions options)
+			throws XMPException
+	{
+		InputSource source = new InputSource(new StringReader(input));
+		try
+		{
+			return parseInputSource(source);
+		}
+		catch (XMPException e)
+		{
+			if (e.getErrorCode() == XMPError.BADXML  &&  options.getFixControlChars())
+			{
+				source = new InputSource(new FixASCIIControlsReader(new StringReader(input)));
+				return parseInputSource(source);
+			}
+			else
+			{
+				throw e;
+			}	
+		}
+	}
+
+	
+	/**
+	 * Runs the XML-Parser. 
+	 * @param source an <code>InputSource</code>
+	 * @return Returns an XML DOM-Document.
+	 * @throws XMPException Wraps parsing and I/O-exceptions into an XMPException.
+	 */
+	private static Document parseInputSource(InputSource source) throws XMPException
+	{
+		try
+		{
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			builder.setErrorHandler(null);
+			return builder.parse(source);
+		}
+		catch (SAXException e)
+		{
+			throw new XMPException("XML parsing failure", XMPError.BADXML, e);
+		}
+		catch (ParserConfigurationException e)
+		{
+			throw new XMPException("XML Parser not correctly configured",
+					XMPError.UNKNOWN, e);
+		}
+		catch (IOException e)
+		{
+			throw new XMPException("Error reading the XML-file", XMPError.BADSTREAM, e);
+		}
+	}
+	
+
+	/**
+	 * Find the XML node that is the root of the XMP data tree. Generally this
+	 * will be an outer node, but it could be anywhere if a general XML document
+	 * is parsed (e.g. SVG). The XML parser counted all rdf:RDF and
+	 * pxmp:XMP_Packet nodes, and kept a pointer to the last one. If there is
+	 * more than one possible root use PickBestRoot to choose among them.
+	 * <p>
+	 * If there is a root node, try to extract the version of the previous XMP
+	 * toolkit.
+	 * <p>
+	 * Pick the first x:xmpmeta among multiple root candidates. If there aren't
+	 * any, pick the first bare rdf:RDF if that is allowed. The returned root is
+	 * the rdf:RDF child if an x:xmpmeta element was chosen. The search is
+	 * breadth first, so a higher level candiate is chosen over a lower level
+	 * one that was textually earlier in the serialized XML.
+	 * 
+	 * @param root the root of the xml document
+	 * @param xmpmetaRequired flag if the xmpmeta-tag is still required, might be set 
+	 * 		initially to <code>true</code>, if the parse option "REQUIRE_XMP_META" is set
+	 * @param result The result array that is filled during the recursive process.
+	 * @return Returns an array that contains the result or <code>null</code>. 
+	 * 		   The array contains:
+	 * <ol>
+	 * 		<li>the rdf:RDF-node
+	 * 		<li>an object that is either XMP_RDF or XMP_PLAIN
+	 * 		<li>a flag that is true if a <?xpacket..> processing instruction has been found
+	 * 		<li>the body text of the xpacket-instruction.
+	 * </ol>
+	 * 
+	 */
+	private static Object[] findRootNode(Node root, boolean xmpmetaRequired, Object[] result)
+	{
+		// Look among this parent's content for x:xapmeta or x:xmpmeta.
+		// The recursion for x:xmpmeta is broader than the strictly defined choice, 
+		// but gives us smaller code.
+		NodeList children = root.getChildNodes();
+		for (int i = 0; i < children.getLength(); i++)
+		{
+			root = children.item(i);
+			if (Node.PROCESSING_INSTRUCTION_NODE == root.getNodeType()  &&
+				((ProcessingInstruction) root).getTarget() == XMPConst.XMP_PI)
+			{
+				// Store the processing instructions content
+				if (result != null)
+				{	
+					result[2] = ((ProcessingInstruction) root).getData();
+				}	
+			}
+			else if (Node.TEXT_NODE != root.getNodeType()  &&  
+				Node.PROCESSING_INSTRUCTION_NODE != root.getNodeType())
+			{	
+				String rootNS = root.getNamespaceURI();
+				String rootLocal = root.getLocalName();
+				if (
+						(
+							XMPConst.TAG_XMPMETA.equals(rootLocal)  ||  
+							XMPConst.TAG_XAPMETA.equals(rootLocal)
+						)  &&
+						XMPConst.NS_X.equals(rootNS)
+				   )
+				{
+					// by not passing the RequireXMPMeta-option, the rdf-Node will be valid
+					return findRootNode(root, false, result);
+				}
+				else if (!xmpmetaRequired  &&
+						"RDF".equals(rootLocal)  &&
+						 XMPConst.NS_RDF.equals(rootNS))
+				{	
+					if (result != null)
+					{	
+						result[0] = root;
+						result[1] = XMP_RDF;
+					}	
+					return result;
+				}
+				else
+				{
+					// continue searching
+					Object[] newResult = findRootNode(root, xmpmetaRequired, result);
+					if (newResult != null)
+					{
+						return newResult;
+					}
+					else
+					{
+						continue;
+					}	
+				}
+			}	
+		}
+
+		// no appropriate node has been found
+		return null;
+		//     is extracted here in the C++ Toolkit		
+	}
+
+	
+	/**
+	 * @return Creates, configures and returnes the document builder factory for
+	 *         the Metadata Parser.
+	 */
+	private static DocumentBuilderFactory createDocumentBuilderFactory()
+	{
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		factory.setNamespaceAware(true);
+		factory.setIgnoringComments(true);
+		
+		try
+		{
+			// honor System parsing limits, e.g.
+			// System.setProperty("entityExpansionLimit", "10");
+			factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+		}
+		catch (Exception e)
+		{
+			// Ignore IllegalArgumentException and ParserConfigurationException
+			// in case the configured XML-Parser does not implement the feature.
+		}		
+		return factory;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPNode.java b/XMPCore/src/com/adobe/xmp/impl/XMPNode.java
new file mode 100644
index 0000000..9170efe
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPNode.java
@@ -0,0 +1,921 @@
+//=================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * A node in the internally XMP tree, which can be a schema node, a property node, an array node,
+ * an array item, a struct node or a qualifier node (without '?').
+ * 
+ * Possible improvements:
+ * 
+ * 1. The kind Node of node might be better represented by a class-hierarchy of different nodes.
+ * 2. The array type should be an enum
+ * 3. isImplicitNode should be removed completely and replaced by return values of fi.
+ * 4. hasLanguage, hasType should be automatically maintained by XMPNode
+ * 
+ * @since 21.02.2006
+ */
+class XMPNode implements Comparable
+{
+	/** name of the node, contains different information depending of the node kind */
+	private String name;
+	/** value of the node, contains different information depending of the node kind */
+	private String value;
+	/** link to the parent node */
+	private XMPNode parent;
+	/** list of child nodes, lazy initialized */
+	private List children = null; 
+	/** list of qualifier of the node, lazy initialized */
+	private List qualifier = null;
+	/** options describing the kind of the node */
+	private PropertyOptions options = null;
+	
+	// internal processing options
+	
+	/** flag if the node is implicitly created */
+	private boolean implicit;
+	/** flag if the node has aliases */
+	private boolean hasAliases;
+	/** flag if the node is an alias */
+	private boolean alias;
+	/** flag if the node has an "rdf:value" child node. */
+	private boolean hasValueChild;
+	
+	
+	
+	/**
+	 * Creates an <code>XMPNode</code> with initial values.
+	 * 
+	 * @param name the name of the node
+	 * @param value the value of the node
+	 * @param options the options of the node
+	 */
+	public XMPNode(String name, String value, PropertyOptions options)
+	{
+		this.name = name;
+		this.value = value;
+		this.options = options;
+	}
+
+	
+	/**
+	 * Constructor for the node without value.
+	 * 
+	 * @param name the name of the node
+	 * @param options the options of the node
+	 */
+	public XMPNode(String name, PropertyOptions options)
+	{
+		this(name, null, options);
+	}
+	
+
+	/**
+	 * Resets the node.
+	 */
+	public void clear()
+	{
+		options = null;
+		name = null;
+		value = null;
+		children = null;
+		qualifier = null;
+	}
+
+	
+	/**
+	 * @return Returns the parent node.
+	 */
+	public XMPNode getParent()
+	{
+		return parent;
+	}
+
+	
+	/**
+	 * @param index an index [1..size]
+	 * @return Returns the child with the requested index.
+	 */
+	public XMPNode getChild(int index)
+	{
+		return (XMPNode) getChildren().get(index - 1);
+	}
+	
+	
+	/**
+	 * Adds a node as child to this node.
+	 * @param node an XMPNode
+	 * @throws XMPException 
+	 */
+	public void addChild(XMPNode node) throws XMPException
+	{
+		// check for duplicate properties
+		assertChildNotExisting(node.getName());
+		node.setParent(this);
+		getChildren().add(node);
+	}
+
+	
+	/**
+	 * Adds a node as child to this node.
+	 * @param index the index of the node <em>before</em> which the new one is inserted.
+	 * <em>Note:</em> The node children are indexed from [1..size]! 
+	 * An index of size + 1 appends a node.   
+	 * @param node an XMPNode
+	 * @throws XMPException 
+	 */
+	public void addChild(int index, XMPNode node) throws XMPException
+	{
+		assertChildNotExisting(node.getName());
+		node.setParent(this);
+		getChildren().add(index - 1, node);
+	}
+
+	
+	/**
+	 * Replaces a node with another one.
+	 * @param index the index of the node that will be replaced.
+	 * <em>Note:</em> The node children are indexed from [1..size]! 
+	 * @param node the replacement XMPNode
+	 */
+	public void replaceChild(int index, XMPNode node)
+	{
+		node.setParent(this);
+		getChildren().set(index - 1, node);
+	}
+	
+	
+	/**
+	 * Removes a child at the requested index.
+	 * @param itemIndex the index to remove [1..size] 
+	 */
+	public void removeChild(int itemIndex)
+	{
+		getChildren().remove(itemIndex - 1);
+		cleanupChildren();
+	}
+	
+	
+	/**
+	 * Removes a child node.
+	 * If its a schema node and doesn't have any children anymore, its deleted.
+	 * 
+	 * @param node the child node to delete.
+	 */
+	public void removeChild(XMPNode node)
+	{
+		getChildren().remove(node);
+		cleanupChildren();
+	}
+
+
+	/**
+	 * Removes the children list if this node has no children anymore;
+	 * checks if the provided node is a schema node and doesn't have any children anymore, 
+	 * its deleted.
+	 */
+	protected void cleanupChildren()
+	{
+		if (children.isEmpty())
+		{
+			children = null;
+		}
+	}
+
+	
+	/**
+	 * Removes all children from the node. 
+	 */ 
+	public void removeChildren()
+	{
+		children = null;
+	}
+
+	
+	/**
+	 * @return Returns the number of children without neccessarily creating a list.
+	 */
+	public int getChildrenLength()
+	{
+		return children != null ?
+			children.size() :	
+			0;
+	}
+
+	
+	/**
+	 * @param expr child node name to look for
+	 * @return Returns an <code>XMPNode</code> if node has been found, <code>null</code> otherwise. 
+	 */
+	public XMPNode findChildByName(String expr)
+	{
+		return find(getChildren(), expr);
+	}
+
+	
+	/**
+	 * @param index an index [1..size]
+	 * @return Returns the qualifier with the requested index.
+	 */
+	public XMPNode getQualifier(int index)
+	{
+		return (XMPNode) getQualifier().get(index - 1);
+	}
+	
+	
+	/**
+	 * @return Returns the number of qualifier without neccessarily creating a list.
+	 */
+	public int getQualifierLength()
+	{
+		return qualifier != null ?
+			qualifier.size() :	
+			0;
+	}
+	
+	
+	/**
+	 * Appends a qualifier to the qualifier list and sets respective options.
+	 * @param qualNode a qualifier node.
+	 * @throws XMPException 
+	 */
+	public void addQualifier(XMPNode qualNode) throws XMPException
+	{
+		assertQualifierNotExisting(qualNode.getName());
+		qualNode.setParent(this);
+		qualNode.getOptions().setQualifier(true);
+		getOptions().setHasQualifiers(true);
+		
+		// contraints
+		if (qualNode.isLanguageNode())
+		{
+			// "xml:lang" is always first and the option "hasLanguage" is set
+			options.setHasLanguage(true);
+			getQualifier().add(0, qualNode);
+		}
+		else if (qualNode.isTypeNode())
+		{
+			// "rdf:type" must be first or second after "xml:lang" and the option "hasType" is set
+			options.setHasType(true);
+			getQualifier().add(
+				!options.getHasLanguage() ? 0 : 1,	
+				qualNode);
+		}
+		else
+		{
+			// other qualifiers are appended
+			getQualifier().add(qualNode);
+		}	
+	}
+
+	
+	/**
+	 * Removes one qualifier node and fixes the options.
+	 * @param qualNode qualifier to remove
+	 */
+	public void removeQualifier(XMPNode qualNode)
+	{
+		PropertyOptions opts = getOptions();
+		if (qualNode.isLanguageNode())
+		{
+			// if "xml:lang" is removed, remove hasLanguage-flag too
+			opts.setHasLanguage(false);
+		}
+		else if (qualNode.isTypeNode())
+		{
+			// if "rdf:type" is removed, remove hasType-flag too
+			opts.setHasType(false);
+		}
+		
+		getQualifier().remove(qualNode);
+		if (qualifier.isEmpty())
+		{
+			opts.setHasQualifiers(false);
+			qualifier = null;
+		}
+		
+	}
+
+	
+	/**
+	 * Removes all qualifiers from the node and sets the options appropriate. 
+	 */ 
+	public void removeQualifiers()
+	{
+		PropertyOptions opts = getOptions();
+		// clear qualifier related options
+		opts.setHasQualifiers(false);
+		opts.setHasLanguage(false);
+		opts.setHasType(false);
+		qualifier = null;
+	}
+
+
+	/**
+	 * @param expr qualifier node name to look for
+	 * @return Returns a qualifier <code>XMPNode</code> if node has been found, 
+	 * <code>null</code> otherwise. 
+	 */
+	public XMPNode findQualifierByName(String expr)
+	{
+		return find(qualifier, expr);
+	}
+	
+
+	/**
+	 * @return Returns whether the node has children.
+	 */
+	public boolean hasChildren()
+	{
+		return children != null  &&  children.size() > 0;
+	}	
+	
+
+	/**
+	 * @return Returns an iterator for the children.
+	 * <em>Note:</em> take care to use it.remove(), as the flag are not adjusted in that case.
+	 */
+	public Iterator iterateChildren()
+	{
+		if (children != null)
+		{
+			return getChildren().iterator();
+		}
+		else
+		{
+			return Collections.EMPTY_LIST.listIterator();
+		}
+	}
+	
+	
+	/**
+	 * @return Returns whether the node has qualifier attached.
+	 */
+	public boolean hasQualifier()
+	{
+		return qualifier != null  &&  qualifier.size() > 0;
+	}
+	
+	
+	/**
+	 * @return Returns an iterator for the qualifier.
+	 * <em>Note:</em> take care to use it.remove(), as the flag are not adjusted in that case.
+	 */
+	public Iterator iterateQualifier()
+	{
+		if (qualifier != null)
+		{
+			final Iterator it = getQualifier().iterator();
+			
+			return new Iterator()
+			{
+				public boolean hasNext()
+				{
+					return it.hasNext();
+				}
+
+				public Object next()
+				{
+					return it.next();
+				}
+
+				public void remove()
+				{
+					throw new UnsupportedOperationException(
+							"remove() is not allowed due to the internal contraints");
+				}
+				
+			};
+		}
+		else
+		{
+			return Collections.EMPTY_LIST.iterator();
+		}
+	}
+	
+	
+	/**
+	 * Performs a <b>deep clone</b> of the node and the complete subtree.
+	 * 
+	 * @see java.lang.Object#clone()
+	 */
+	public Object clone()
+	{
+		PropertyOptions newOptions;
+		try
+		{
+			newOptions = new PropertyOptions(getOptions().getOptions());
+		}
+		catch (XMPException e)
+		{
+			// cannot happen
+			newOptions = new PropertyOptions();
+		}
+		
+		XMPNode newNode = new XMPNode(name, value, newOptions);
+		cloneSubtree(newNode);
+		
+		return newNode;
+	}
+	
+	
+	/**
+	 * Performs a <b>deep clone</b> of the complete subtree (children and
+	 * qualifier )into and add it to the destination node.
+	 * 
+	 * @param destination the node to add the cloned subtree
+	 */
+	public void cloneSubtree(XMPNode destination)
+	{
+		try
+		{
+			for (Iterator it = iterateChildren(); it.hasNext();)
+			{
+				XMPNode child = (XMPNode) it.next();
+				destination.addChild((XMPNode) child.clone());
+			}
+			
+			for (Iterator it = iterateQualifier(); it.hasNext();)
+			{
+				XMPNode qualifier = (XMPNode) it.next();
+				destination.addQualifier((XMPNode) qualifier.clone());
+			}
+		}
+		catch (XMPException e)
+		{
+			// cannot happen (duplicate childs/quals do not exist in this node)
+			assert false;
+		}
+		
+	}	
+	
+	
+	/** 
+	 * Renders this node and the tree unter this node in a human readable form.
+	 * @param recursive Flag is qualifier and child nodes shall be rendered too
+	 * @return Returns a multiline string containing the dump.
+	 */
+	public String dumpNode(boolean recursive)
+	{
+		StringBuffer result = new StringBuffer(512);
+		this.dumpNode(result, recursive, 0, 0);
+		return result.toString();
+	}
+	
+	
+	/**
+	 * @see Comparable#compareTo(Object) 
+	 */
+	public int compareTo(Object xmpNode)
+	{
+		if (getOptions().isSchemaNode())
+		{
+			return this.value.compareTo(((XMPNode) xmpNode).getValue());
+		}
+		else
+		{
+			return this.name.compareTo(((XMPNode) xmpNode).getName());
+		}	
+	}
+	
+	
+	/**
+	 * @return Returns the name.
+	 */
+	public String getName()
+	{
+		return name;
+	}
+
+
+	/**
+	 * @param name The name to set.
+	 */
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+
+	/**
+	 * @return Returns the value.
+	 */
+	public String getValue()
+	{
+		return value;
+	}
+
+
+	/**
+	 * @param value The value to set.
+	 */
+	public void setValue(String value)
+	{
+		this.value = value;
+	}	
+
+	
+	/**
+	 * @return Returns the options.
+	 */
+	public PropertyOptions getOptions()
+	{
+		if (options == null)
+		{
+			options = new PropertyOptions();
+		}
+		return options;
+	}
+
+	
+	/**
+	 * Updates the options of the node.
+	 * @param options the options to set.
+	 */
+	public void setOptions(PropertyOptions options)
+	{
+		this.options = options;
+	}
+
+	
+	/**
+	 * @return Returns the implicit flag
+	 */
+	public boolean isImplicit()
+	{
+		return implicit;
+	}
+
+
+	/**
+	 * @param implicit Sets the implicit node flag
+	 */
+	public void setImplicit(boolean implicit)
+	{
+		this.implicit = implicit;
+	}
+	
+	
+	/**
+	 * @return Returns if the node contains aliases (applies only to schema nodes)
+	 */
+	public boolean getHasAliases()
+	{
+		return hasAliases;
+	}
+
+
+	/**
+	 * @param hasAliases sets the flag that the node contains aliases
+	 */
+	public void setHasAliases(boolean hasAliases)
+	{
+		this.hasAliases = hasAliases;
+	}	
+	
+	
+	/**
+	 * @return Returns if the node contains aliases (applies only to schema nodes)
+	 */
+	public boolean isAlias()
+	{
+		return alias;
+	}
+
+
+	/**
+	 * @param alias sets the flag that the node is an alias
+	 */
+	public void setAlias(boolean alias)
+	{
+		this.alias = alias;
+	}	
+	
+	
+	/**
+	 * @return the hasValueChild
+	 */
+	public boolean getHasValueChild()
+	{
+		return hasValueChild;
+	}
+
+
+	/**
+	 * @param hasValueChild the hasValueChild to set
+	 */
+	public void setHasValueChild(boolean hasValueChild)
+	{
+		this.hasValueChild = hasValueChild;
+	}
+	
+	
+	
+	/**
+	 * Sorts the complete datamodel according to the following rules:
+	 * <ul>
+	 * 		<li>Nodes at one level are sorted by name, that is prefix + local name
+	 * 		<li>Starting at the root node the children and qualifier are sorted recursively, 
+	 * 			which the following exceptions.
+	 * 		<li>Sorting will not be used for arrays.
+	 * 		<li>Within qualifier "xml:lang" and/or "rdf:type" stay at the top in that order, 
+	 * 			all others are sorted.  
+	 * </ul>
+	 */
+	public void sort()
+	{
+		// sort qualifier
+		if (hasQualifier())
+		{
+			XMPNode[] quals = (XMPNode[]) getQualifier()
+				.toArray(new XMPNode[getQualifierLength()]);
+			int sortFrom = 0;
+			while (
+					quals.length > sortFrom  &&
+					(XMPConst.XML_LANG.equals(quals[sortFrom].getName())  ||
+					 "rdf:type".equals(quals[sortFrom].getName()))
+				  )		 
+			{
+				quals[sortFrom].sort();
+				sortFrom++;
+			}
+
+			Arrays.sort(quals, sortFrom, quals.length);
+			ListIterator it = qualifier.listIterator();
+			for (int j = 0; j < quals.length; j++)
+			{
+				it.next();
+				it.set(quals[j]);
+				quals[j].sort();
+			}
+		}
+		
+		// sort children
+		if (hasChildren())
+		{	
+			if (!getOptions().isArray())
+			{
+				Collections.sort(children);
+			}
+			for (Iterator it = iterateChildren(); it.hasNext();)
+			{
+				((XMPNode) it.next()).sort();
+				
+			}
+		}
+	}	
+	
+	
+	
+	//------------------------------------------------------------------------------ private methods
+
+	
+	/**
+	 * Dumps this node and its qualifier and children recursively.
+	 * <em>Note:</em> It creats empty options on every node.
+	 *  
+	 * @param result the buffer to append the dump.
+	 * @param recursive Flag is qualifier and child nodes shall be rendered too
+	 * @param indent the current indent level.
+	 * @param index the index within the parent node (important for arrays) 
+	 */
+	private void dumpNode(StringBuffer result, boolean recursive, int indent, int index)
+	{
+		// write indent
+		for (int i = 0; i < indent; i++)
+		{
+			result.append('\t');
+		}
+		
+		// render Node
+		if (parent != null)
+		{
+			if (getOptions().isQualifier())
+			{
+				result.append('?');
+				result.append(name);
+			}
+			else if (getParent().getOptions().isArray())
+			{
+				result.append('[');
+				result.append(index);
+				result.append(']');
+			}
+			else
+			{
+				result.append(name);
+			}
+		}
+		else
+		{
+			// applies only to the root node
+			result.append("ROOT NODE");
+			if (name != null  &&  name.length() > 0)
+			{
+				// the "about" attribute
+				result.append(" (");
+				result.append(name);
+				result.append(')');
+			}	
+		}
+		
+		if (value != null  &&  value.length() > 0)
+		{
+			result.append(" = \"");
+			result.append(value);
+			result.append('"');
+		}
+		
+		// render options if at least one is set
+		if (getOptions().containsOneOf(0xffffffff))
+		{
+			result.append("\t(");
+			result.append(getOptions().toString());
+			result.append(" : ");
+			result.append(getOptions().getOptionsString());
+			result.append(')');
+		}
+		
+		result.append('\n');
+		
+		// render qualifier
+		if (recursive  &&  hasQualifier())
+		{
+			XMPNode[] quals = (XMPNode[]) getQualifier()
+				.toArray(new XMPNode[getQualifierLength()]);
+			int i = 0;
+			while (quals.length > i  &&
+					(XMPConst.XML_LANG.equals(quals[i].getName())  ||
+					 "rdf:type".equals(quals[i].getName()))
+				  )		 
+			{
+				i++;
+			}
+			Arrays.sort(quals, i, quals.length);
+			for (i = 0; i < quals.length; i++)
+			{
+				XMPNode qualifier = quals[i];
+				qualifier.dumpNode(result, recursive, indent + 2, i + 1);
+			}
+		}
+		
+		// render children
+		if (recursive  &&  hasChildren())
+		{	
+			XMPNode[] children = (XMPNode[]) getChildren()
+				.toArray(new XMPNode[getChildrenLength()]);
+			if (!getOptions().isArray())
+			{	
+				Arrays.sort(children);
+			}
+			for (int i = 0; i < children.length; i++)
+			{
+				XMPNode child = children[i];
+				child.dumpNode(result, recursive, indent + 1, i + 1);
+			}
+		}
+	}
+	
+	
+	/**
+	 * @return Returns whether this node is a language qualifier. 
+	 */
+	private boolean isLanguageNode()
+	{
+		return XMPConst.XML_LANG.equals(name);
+	}
+
+	
+	/**
+	 * @return Returns whether this node is a type qualifier. 
+	 */
+	private boolean isTypeNode()
+	{
+		return "rdf:type".equals(name);
+	}
+	
+
+	/**
+	 * <em>Note:</em> This method should always be called when accessing 'children' to be sure
+	 * that its initialized.
+	 * @return Returns list of children that is lazy initialized.
+	 */
+	private List getChildren()
+	{
+		if (children == null)
+		{
+			children = new ArrayList(0);
+		}
+		return children;
+	}
+
+	
+	/**
+	 * @return Returns a read-only copy of child nodes list.
+	 */
+	public List getUnmodifiableChildren()
+	{
+		return Collections.unmodifiableList(new ArrayList(getChildren()));
+	}
+	
+	
+	/**
+	 * @return Returns list of qualifier that is lazy initialized.
+	 */
+	private List getQualifier()
+	{
+		if (qualifier == null)
+		{
+			qualifier = new ArrayList(0);
+		}
+		return qualifier;
+	}
+	
+	
+	/**
+	 * Sets the parent node, this is solely done by <code>addChild(...)</code>
+	 * and <code>addQualifier()</code>.
+	 * 
+	 * @param parent
+	 *            Sets the parent node.
+	 */
+	protected void setParent(XMPNode parent)
+	{
+		this.parent = parent;
+	}
+
+	
+	/**
+	 * Internal find.
+	 * @param list the list to search in
+	 * @param expr the search expression
+	 * @return Returns the found node or <code>nulls</code>.
+	 */
+	private XMPNode find(List list, String expr)
+	{
+		
+		if (list != null)
+		{	
+			for (Iterator it = list.iterator(); it.hasNext();)
+			{
+				XMPNode child = (XMPNode) it.next();
+				if (child.getName().equals(expr))
+				{
+					return child;
+				}
+			}
+		}	
+		return null;
+	}
+	
+	
+	/**
+	 * Checks that a node name is not existing on the same level, except for array items.
+	 * @param childName the node name to check
+	 * @throws XMPException Thrown if a node with the same name is existing.
+	 */
+	private void assertChildNotExisting(String childName) throws XMPException
+	{
+		if (!XMPConst.ARRAY_ITEM_NAME.equals(childName)  &&
+			findChildByName(childName) != null)
+		{
+			throw new XMPException("Duplicate property or field node '" + childName + "'",
+					XMPError.BADXMP);
+		}
+	}
+	
+	
+	/**
+	 * Checks that a qualifier name is not existing on the same level.
+	 * @param qualifierName the new qualifier name
+	 * @throws XMPException Thrown if a node with the same name is existing.
+	 */
+	private void assertQualifierNotExisting(String qualifierName) throws XMPException
+	{
+		if (!XMPConst.ARRAY_ITEM_NAME.equals(qualifierName)  &&
+			findQualifierByName(qualifierName) != null)
+		{
+			throw new XMPException("Duplicate '" + qualifierName + "' qualifier", XMPError.BADXMP);
+		}
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPNodeUtils.java b/XMPCore/src/com/adobe/xmp/impl/XMPNodeUtils.java
new file mode 100644
index 0000000..8537469
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPNodeUtils.java
@@ -0,0 +1,924 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPDateTime;
+import com.adobe.xmp.XMPDateTimeFactory;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.XMPUtils;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathSegment;
+import com.adobe.xmp.options.AliasOptions;
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * Utilities for <code>XMPNode</code>.
+ * 
+ * @since   Aug 28, 2006
+ */
+public class XMPNodeUtils implements XMPConst
+{
+	/** */
+	static final int CLT_NO_VALUES = 0;
+	/** */
+	static final int CLT_SPECIFIC_MATCH = 1;
+	/** */
+	static final int CLT_SINGLE_GENERIC = 2;
+	/** */
+	static final int CLT_MULTIPLE_GENERIC = 3;
+	/** */
+	static final int CLT_XDEFAULT = 4;
+	/** */
+	static final int CLT_FIRST_ITEM = 5;
+
+
+	/**
+	 * Private Constructor
+	 */
+	private XMPNodeUtils()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Find or create a schema node if <code>createNodes</code> is false and
+	 *  
+	 * @param tree the root of the xmp tree. 
+	 * @param namespaceURI a namespace
+	 * @param createNodes a flag indicating if the node shall be created if not found.
+	 * 		  <em>Note:</em> The namespace must be registered prior to this call.
+	 * 
+	 * @return Returns the schema node if found, <code>null</code> otherwise.
+	 * 		   Note: If <code>createNodes</code> is <code>true</code>, it is <b>always</b>
+	 * 		   returned a valid node. 
+	 * @throws XMPException An exception is only thrown if an error occurred, not if a
+	 *         		node was not found.
+	 */
+	static XMPNode findSchemaNode(XMPNode tree, String namespaceURI,
+			boolean createNodes)
+			throws XMPException
+	{
+		return findSchemaNode(tree, namespaceURI, null, createNodes);
+	}
+	
+	
+	/**
+	 * Find or create a schema node if <code>createNodes</code> is true.
+	 *  
+	 * @param tree the root of the xmp tree. 
+	 * @param namespaceURI a namespace
+	 * @param suggestedPrefix If a prefix is suggested, the namespace is allowed to be registered.
+	 * @param createNodes a flag indicating if the node shall be created if not found.
+	 * 		  <em>Note:</em> The namespace must be registered prior to this call.
+	 * 
+	 * @return Returns the schema node if found, <code>null</code> otherwise.
+	 * 		   Note: If <code>createNodes</code> is <code>true</code>, it is <b>always</b>
+	 * 		   returned a valid node. 
+	 * @throws XMPException An exception is only thrown if an error occurred, not if a
+	 *         		node was not found.
+	 */
+	static XMPNode findSchemaNode(XMPNode tree, String namespaceURI, String suggestedPrefix,
+			boolean createNodes)
+			throws XMPException
+	{
+		assert tree.getParent() == null; // make sure that its the root
+		XMPNode schemaNode = tree.findChildByName(namespaceURI);
+		
+		if (schemaNode == null  &&  createNodes)
+		{
+			schemaNode = new XMPNode(namespaceURI, 
+				new PropertyOptions()
+					.setSchemaNode(true));
+			schemaNode.setImplicit(true);
+			
+			// only previously registered schema namespaces are allowed in the XMP tree.
+			String prefix = XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(namespaceURI);
+			if (prefix == null)
+			{	
+				if (suggestedPrefix != null  &&  suggestedPrefix.length() != 0)
+				{
+					prefix = XMPMetaFactory.getSchemaRegistry().registerNamespace(namespaceURI,
+							suggestedPrefix);
+				}
+				else
+				{
+					throw new XMPException("Unregistered schema namespace URI",
+							XMPError.BADSCHEMA);
+				}	
+			}	
+				
+			schemaNode.setValue(prefix);
+	
+			tree.addChild(schemaNode);
+		}
+		
+		return schemaNode;
+	}
+
+	
+	/**
+	 * Find or create a child node under a given parent node. If the parent node is no 
+	 * Returns the found or created child node.
+	 * 
+	 * @param parent
+	 *            the parent node
+	 * @param childName
+	 *            the node name to find
+	 * @param createNodes
+	 *            flag, if new nodes shall be created.
+	 * @return Returns the found or created node or <code>null</code>.
+	 * @throws XMPException Thrown if 
+	 */
+	static XMPNode findChildNode(XMPNode parent, String childName, boolean createNodes)
+			throws XMPException
+	{
+		if (!parent.getOptions().isSchemaNode() && !parent.getOptions().isStruct())
+		{
+			if (!parent.isImplicit())
+			{
+				throw new XMPException("Named children only allowed for schemas and structs",
+						XMPError.BADXPATH);
+			}	
+			else if (parent.getOptions().isArray())
+			{
+				throw new XMPException("Named children not allowed for arrays",
+						XMPError.BADXPATH);
+			}
+			else if (createNodes)
+			{	
+				parent.getOptions().setStruct(true);
+			}	
+		}
+			
+		XMPNode childNode = parent.findChildByName(childName); 
+		
+		if (childNode == null  &&  createNodes)
+		{
+			PropertyOptions options = new PropertyOptions();
+			childNode = new XMPNode(childName, options);
+			childNode.setImplicit(true);
+			parent.addChild(childNode);
+		}
+		
+		assert childNode != null ||  !createNodes;
+	
+		return childNode;
+	}
+
+
+	/**
+	 * Follow an expanded path expression to find or create a node.
+	 * 
+	 * @param xmpTree the node to begin the search. 
+	 * @param xpath the complete xpath
+	 * @param createNodes flag if nodes shall be created 
+	 * 			(when called by <code>setProperty()</code>)
+	 * @param leafOptions the options for the created leaf nodes (only when
+	 *			<code>createNodes == true</code>).
+	 * @return Returns the node if found or created or <code>null</code>.
+	 * @throws XMPException An exception is only thrown if an error occurred, 
+	 * 			not if a node was not found.
+	 */
+	static XMPNode findNode(XMPNode xmpTree, XMPPath xpath, boolean createNodes,
+		PropertyOptions leafOptions) throws XMPException
+	{
+		// check if xpath is set.
+		if (xpath == null  ||  xpath.size() == 0)
+		{
+			throw new XMPException("Empty XMPPath", XMPError.BADXPATH);
+		}
+
+		// Root of implicitly created subtree to possible delete it later. 
+		// Valid only if leaf is new.
+		XMPNode rootImplicitNode = null; 
+		XMPNode currNode = null;
+		
+		// resolve schema step
+		currNode = findSchemaNode(xmpTree,
+			xpath.getSegment(XMPPath.STEP_SCHEMA).getName(), createNodes);
+		if (currNode == null) 
+		{
+			return null;
+		}
+		else if (currNode.isImplicit())
+		{
+			currNode.setImplicit(false);	// Clear the implicit node bit.
+			rootImplicitNode = currNode;	// Save the top most implicit node.
+		}
+
+
+		// Now follow the remaining steps of the original XMPPath.
+		try
+		{
+			for (int i = 1; i < xpath.size(); i++)
+			{
+				currNode = followXPathStep(currNode, xpath.getSegment(i), createNodes);
+				if (currNode == null) 
+				{
+					if (createNodes)
+					{	
+						// delete implicitly created nodes
+						deleteNode(rootImplicitNode);
+					}	
+					return null;
+				}
+				else if (currNode.isImplicit())
+				{
+					// clear the implicit node flag
+					currNode.setImplicit(false);
+
+					// if node is an ALIAS (can be only in root step, auto-create array 
+					// when the path has been resolved from a not simple alias type
+					if (i == 1  &&  
+						xpath.getSegment(i).isAlias()  &&
+						xpath.getSegment(i).getAliasForm() != 0)
+					{
+						currNode.getOptions().setOption(xpath.getSegment(i).getAliasForm(), true);
+					}
+					// "CheckImplicitStruct" in C++
+					else if (i < xpath.size() - 1  &&
+						xpath.getSegment(i).getKind() == XMPPath.STRUCT_FIELD_STEP  &&	
+						!currNode.getOptions().isCompositeProperty())
+					{
+						currNode.getOptions().setStruct(true);
+					}					
+					
+					if (rootImplicitNode == null)
+					{
+						rootImplicitNode = currNode;	// Save the top most implicit node.
+					}
+				}
+			}
+		}
+		catch (XMPException e)
+		{
+			// if new notes have been created prior to the error, delete them
+			if (rootImplicitNode != null)
+			{
+				deleteNode(rootImplicitNode);
+			}
+			throw e;
+		}
+		
+		
+		if (rootImplicitNode != null)
+		{
+			// set options only if a node has been successful created
+			currNode.getOptions().mergeWith(leafOptions);
+			currNode.setOptions(currNode.getOptions());
+		}
+		
+		return currNode;
+	}
+
+
+	/**
+	 * Deletes the the given node and its children from its parent.
+	 * Takes care about adjusting the flags.
+	 * @param node the top-most node to delete.
+	 */
+	static void deleteNode(XMPNode node)
+	{
+		XMPNode parent = node.getParent();
+		
+		if (node.getOptions().isQualifier())
+		{
+			// root is qualifier
+			parent.removeQualifier(node);
+		}
+		else
+		{
+			// root is NO qualifier
+			parent.removeChild(node);
+		}
+		
+		// delete empty Schema nodes
+		if (!parent.hasChildren()  &&  parent.getOptions().isSchemaNode())
+		{
+			parent.getParent().removeChild(parent);
+		}
+	}
+
+
+	/**
+	 * This is setting the value of a leaf node.
+	 * 
+	 * @param node an XMPNode
+	 * @param value a value
+	 */
+	static void setNodeValue(XMPNode node, Object value)
+	{
+		String strValue = serializeNodeValue(value);
+		if (!(node.getOptions().isQualifier()  &&  XML_LANG.equals(node.getName()))) 
+		{	
+			node.setValue(strValue);
+		}
+		else
+		{
+			node.setValue(Utils.normalizeLangValue(strValue));
+		}
+	}
+	
+	
+	/**
+	 * Verifies the PropertyOptions for consistancy and updates them as needed. 
+	 * If options are <code>null</code> they are created with default values.
+	 *  
+	 * @param options the <code>PropertyOptions</code>
+	 * @param itemValue the node value to set
+	 * @return Returns the updated options.
+	 * @throws XMPException If the options are not consistant. 
+	 */
+	static PropertyOptions verifySetOptions(PropertyOptions options, Object itemValue)
+			throws XMPException
+	{
+		// create empty and fix existing options
+		if (options == null)
+		{
+			// set default options
+			options = new PropertyOptions();
+		}
+		
+		if (options.isArrayAltText())
+		{
+			options.setArrayAlternate(true);
+		}
+	
+		if (options.isArrayAlternate())
+		{
+			options.setArrayOrdered(true);
+		}
+	
+		if (options.isArrayOrdered())
+		{
+			options.setArray(true);
+		}
+	
+		if (options.isCompositeProperty() && itemValue != null && itemValue.toString().length() > 0)
+		{
+			throw new XMPException("Structs and arrays can't have values",
+				XMPError.BADOPTIONS);
+		}
+	
+		options.assertConsistency(options.getOptions());
+		
+		return options;
+	}
+
+
+	/**
+	 * Converts the node value to String, apply special conversions for defined
+	 * types in XMP.
+	 * 
+	 * @param value
+	 *            the node value to set
+	 * @return Returns the String representation of the node value.
+	 */
+	static String serializeNodeValue(Object value)
+	{
+		String strValue;
+		if (value == null)
+		{
+			strValue = null;
+		}
+		else if (value instanceof Boolean)
+		{
+			strValue = XMPUtils.convertFromBoolean(((Boolean) value).booleanValue());
+		}
+		else if (value instanceof Integer)
+		{
+			strValue = XMPUtils.convertFromInteger(((Integer) value).intValue());
+		}
+		else if (value instanceof Long)
+		{
+			strValue = XMPUtils.convertFromLong(((Long) value).longValue());
+		}
+		else if (value instanceof Double)
+		{
+			strValue = XMPUtils.convertFromDouble(((Double) value).doubleValue());
+		}
+		else if (value instanceof XMPDateTime)
+		{
+			strValue = XMPUtils.convertFromDate((XMPDateTime) value);
+		}
+		else if (value instanceof GregorianCalendar)
+		{
+			XMPDateTime dt = XMPDateTimeFactory.createFromCalendar((GregorianCalendar) value);
+			strValue = XMPUtils.convertFromDate(dt);
+		}
+		else if (value instanceof byte[])
+		{
+			strValue = XMPUtils.encodeBase64((byte[]) value);
+		}
+		else
+		{
+			strValue = value.toString();
+		}
+	
+		return strValue != null ? Utils.removeControlChars(strValue) : null;
+	}
+	
+	
+	/** 
+	 * After processing by ExpandXPath, a step can be of these forms:
+	 * <ul>
+	 * 	<li>qualName - A top level property or struct field.
+	 * <li>[index] - An element of an array.
+	 * <li>[last()] - The last element of an array.
+	 * <li>[qualName="value"] - An element in an array of structs, chosen by a field value.
+	 * <li>[?qualName="value"] - An element in an array, chosen by a qualifier value.
+	 * <li>?qualName - A general qualifier.
+	 * </ul>
+	 * Find the appropriate child node, resolving aliases, and optionally creating nodes.
+	 * 
+	 * @param parentNode the node to start to start from 
+	 * @param nextStep the xpath segment 
+	 * @param createNodes 
+	 * @return returns the found or created XMPPath node 
+	 * @throws XMPException 
+	 */
+	private static XMPNode followXPathStep(
+				XMPNode parentNode, 
+				XMPPathSegment nextStep,
+				boolean createNodes) throws XMPException
+	{
+		XMPNode nextNode = null;
+		int index = 0;
+		int stepKind = nextStep.getKind();
+		
+		if (stepKind == XMPPath.STRUCT_FIELD_STEP)
+		{
+			nextNode = findChildNode(parentNode, nextStep.getName(), createNodes);
+		}
+		else if (stepKind == XMPPath.QUALIFIER_STEP)
+		{
+			nextNode = findQualifierNode(
+				parentNode, nextStep.getName().substring(1), createNodes);
+		}
+		else
+		{
+			// This is an array indexing step. First get the index, then get the node.
+
+			if (!parentNode.getOptions().isArray())
+			{
+				throw new XMPException("Indexing applied to non-array", XMPError.BADXPATH);
+			}
+
+			if (stepKind == XMPPath.ARRAY_INDEX_STEP)
+			{
+				index = findIndexedItem(parentNode, nextStep.getName(), createNodes);
+			}
+			else if (stepKind == XMPPath.ARRAY_LAST_STEP)
+			{
+				index = parentNode.getChildrenLength();
+			}
+			else if (stepKind == XMPPath.FIELD_SELECTOR_STEP)
+			{
+				String[] result = Utils.splitNameAndValue(nextStep.getName());
+				String fieldName = result[0];
+				String fieldValue = result[1];
+				index = lookupFieldSelector(parentNode, fieldName, fieldValue);
+			}
+			else if (stepKind == XMPPath.QUAL_SELECTOR_STEP)
+			{
+				String[] result = Utils.splitNameAndValue(nextStep.getName());
+				String qualName = result[0];
+				String qualValue = result[1];
+				index = lookupQualSelector(
+					parentNode, qualName, qualValue, nextStep.getAliasForm());
+			}
+			else
+			{
+				throw new XMPException("Unknown array indexing step in FollowXPathStep",
+						XMPError.INTERNALFAILURE);
+			}
+
+			if (1 <= index  &&  index <=  parentNode.getChildrenLength())
+			{
+				nextNode = parentNode.getChild(index);
+			}
+		}
+	
+		return nextNode;		
+	}
+
+
+	/**
+	 * Find or create a qualifier node under a given parent node. Returns a pointer to the 
+	 * qualifier node, and optionally an iterator for the node's position in 
+	 * the parent's vector of qualifiers. The iterator is unchanged if no qualifier node (null) 
+	 * is returned.
+	 * <em>Note:</em> On entry, the qualName parameter must not have the leading '?' from the 
+	 * XMPPath step.
+	 * 
+	 * @param parent the parent XMPNode 
+	 * @param qualName the qualifier name
+	 * @param createNodes flag if nodes shall be created
+	 * @return Returns the qualifier node if found or created, <code>null</code> otherwise.
+	 * @throws XMPException 
+	 */
+	private static XMPNode findQualifierNode(XMPNode parent, String qualName, boolean createNodes)
+			throws XMPException
+	{
+		assert !qualName.startsWith("?");
+		
+		XMPNode qualNode = parent.findQualifierByName(qualName);
+		
+		if (qualNode == null  &&  createNodes)
+		{
+			qualNode = new XMPNode(qualName, null);
+			qualNode.setImplicit(true);
+	
+			parent.addQualifier(qualNode);				
+		}
+		
+		return qualNode;
+	}
+	
+	
+	/**
+	 * @param arrayNode an array node
+	 * @param segment the segment containing the array index
+	 * @param createNodes flag if new nodes are allowed to be created.
+	 * @return Returns the index or index = -1 if not found
+	 * @throws XMPException Throws Exceptions
+	 */
+	private static int findIndexedItem(XMPNode arrayNode, String segment, boolean createNodes)
+			throws XMPException
+	{
+		int index = 0;
+	
+		try
+		{
+			segment = segment.substring(1, segment.length() - 1);
+			index = Integer.parseInt(segment);
+			if (index < 1)
+			{
+				throw new XMPException("Array index must be larger than zero",
+						XMPError.BADXPATH);
+			}
+		}
+		catch (NumberFormatException e)
+		{
+			throw new XMPException("Array index not digits.", XMPError.BADXPATH);
+		}
+	
+		if (createNodes  &&  index == arrayNode.getChildrenLength() + 1)
+		{
+			// Append a new last + 1 node.
+			XMPNode newItem = new XMPNode(ARRAY_ITEM_NAME, null);
+			newItem.setImplicit(true);
+			arrayNode.addChild(newItem);
+		}
+
+		return index;
+	}
+	
+	
+	/**
+	 * Searches for a field selector in a node:
+	 * [fieldName="value] - an element in an array of structs, chosen by a field value.
+	 * No implicit nodes are created by field selectors. 
+	 * 
+	 * @param arrayNode
+	 * @param fieldName
+	 * @param fieldValue
+	 * @return Returns the index of the field if found, otherwise -1.
+	 * @throws XMPException 
+	 */
+	private static int lookupFieldSelector(XMPNode arrayNode, String fieldName, String fieldValue)
+		throws XMPException
+	{
+		int result = -1;
+		
+		for (int index = 1; index <= arrayNode.getChildrenLength()  &&  result < 0; index++)
+		{
+			XMPNode currItem = arrayNode.getChild(index);
+	
+			if (!currItem.getOptions().isStruct())
+			{
+				throw new XMPException("Field selector must be used on array of struct",
+						XMPError.BADXPATH);
+			}
+	
+			for (int f = 1; f <= currItem.getChildrenLength(); f++)
+			{
+				XMPNode currField = currItem.getChild(f);
+				if (!fieldName.equals(currField.getName()))
+				{
+					continue;
+				}
+				if (fieldValue.equals(currField.getValue())) 
+				{
+					result = index;
+					break;
+				}
+			}
+		}
+		
+		return result;
+	}
+	
+	
+	/**
+	 * Searches for a qualifier selector in a node:
+	 * [?qualName="value"] - an element in an array, chosen by a qualifier value.
+	 * No implicit nodes are created for qualifier selectors, 
+	 * except for an alias to an x-default item.
+	 * 
+	 * @param arrayNode an array node 
+	 * @param qualName the qualifier name
+	 * @param qualValue the qualifier value
+	 * @param aliasForm in case the qual selector results from an alias,
+	 * 		  an x-default node is created if there has not been one. 
+	 * @return Returns the index of th
+	 * @throws XMPException 
+	 */
+	private static int lookupQualSelector(XMPNode arrayNode, String qualName, 
+		String qualValue, int aliasForm) throws XMPException
+	{
+		if (XML_LANG.equals(qualName))
+		{
+			qualValue = Utils.normalizeLangValue(qualValue);
+			int index = XMPNodeUtils.lookupLanguageItem(arrayNode, qualValue);
+			if (index < 0  &&  (aliasForm & AliasOptions.PROP_ARRAY_ALT_TEXT) > 0)
+			{	
+				XMPNode langNode = new XMPNode(ARRAY_ITEM_NAME, null);
+				XMPNode xdefault = new XMPNode(XML_LANG, X_DEFAULT, null);
+				langNode.addQualifier(xdefault);
+				arrayNode.addChild(1, langNode);
+				return 1;
+			}
+			else
+			{
+				return index;
+			}
+		}
+		else
+		{
+			for (int index = 1; index < arrayNode.getChildrenLength(); index++)
+			{
+				XMPNode currItem = arrayNode.getChild(index);
+		
+				for (Iterator it = currItem.iterateQualifier(); it.hasNext();)
+				{
+					XMPNode qualifier = (XMPNode) it.next();
+					if (qualName.equals(qualifier.getName())  &&
+						qualValue.equals(qualifier.getValue()))
+					{
+						return index;
+					}
+				}
+			}
+			return -1;
+		}	
+	}
+
+
+	/**
+	 * Make sure the x-default item is first. Touch up &quot;single value&quot;
+	 * arrays that have a default plus one real language. This case should have
+	 * the same value for both items. Older Adobe apps were hardwired to only
+	 * use the &quot;x-default&quot; item, so we copy that value to the other
+	 * item.
+	 * 
+	 * @param arrayNode
+	 *            an alt text array node
+	 */
+	static void normalizeLangArray(XMPNode arrayNode)
+	{
+		if (!arrayNode.getOptions().isArrayAltText())
+		{
+			return;
+		}
+	
+		// check if node with x-default qual is first place
+		for (int i = 2; i <= arrayNode.getChildrenLength(); i++)
+		{
+			XMPNode child = arrayNode.getChild(i);
+			if (child.hasQualifier() && X_DEFAULT.equals(child.getQualifier(1).getValue()))
+			{
+				// move node to first place
+				try
+				{
+					arrayNode.removeChild(i);
+					arrayNode.addChild(1, child);
+				}
+				catch (XMPException e)
+				{
+					// cannot occur, because same child is removed before
+					assert false;
+				}
+				
+				if (i == 2)
+				{
+					arrayNode.getChild(2).setValue(child.getValue());
+				}
+				break;
+			}
+		}
+	}
+
+
+	/**
+	 * See if an array is an alt-text array. If so, make sure the x-default item
+	 * is first.
+	 * 
+	 * @param arrayNode
+	 *            the array node to check if its an alt-text array
+	 */
+	static void detectAltText(XMPNode arrayNode)
+	{
+		if (arrayNode.getOptions().isArrayAlternate() && arrayNode.hasChildren())
+		{
+			boolean isAltText = false;
+			for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+			{
+				XMPNode child = (XMPNode) it.next();
+				if (child.getOptions().getHasLanguage())
+				{
+					isAltText = true;
+					break;
+				}
+			}
+	
+			if (isAltText)
+			{
+				arrayNode.getOptions().setArrayAltText(true);
+				normalizeLangArray(arrayNode);
+			}
+		}
+	}
+
+
+	/**
+	 * Appends a language item to an alt text array.
+	 * 
+	 * @param arrayNode the language array
+	 * @param itemLang the language of the item
+	 * @param itemValue the content of the item
+	 * @throws XMPException Thrown if a duplicate property is added
+	 */
+	static void appendLangItem(XMPNode arrayNode, String itemLang, String itemValue)
+			throws XMPException
+	{
+		XMPNode newItem = new XMPNode(ARRAY_ITEM_NAME, itemValue, null);
+		XMPNode langQual = new XMPNode(XML_LANG, itemLang, null);
+		newItem.addQualifier(langQual);
+	
+		if (!X_DEFAULT.equals(langQual.getValue()))
+		{
+			arrayNode.addChild(newItem);
+		}
+		else
+		{
+			arrayNode.addChild(1, newItem);
+		}
+	}
+
+
+	/**
+	 * <ol>
+	 * <li>Look for an exact match with the specific language.
+	 * <li>If a generic language is given, look for partial matches.
+	 * <li>Look for an "x-default"-item.
+	 * <li>Choose the first item.
+	 * </ol>
+	 * 
+	 * @param arrayNode
+	 *            the alt text array node
+	 * @param genericLang
+	 *            the generic language
+	 * @param specificLang
+	 *            the specific language
+	 * @return Returns the kind of match as an Integer and the found node in an
+	 *         array.
+	 * 
+	 * @throws XMPException
+	 */
+	static Object[] chooseLocalizedText(XMPNode arrayNode, String genericLang, String specificLang)
+			throws XMPException
+	{
+		// See if the array has the right form. Allow empty alt arrays,
+		// that is what parsing returns.
+		if (!arrayNode.getOptions().isArrayAltText())
+		{
+			throw new XMPException("Localized text array is not alt-text", XMPError.BADXPATH);
+		}
+		else if (!arrayNode.hasChildren())
+		{
+			return new Object[] { new Integer(XMPNodeUtils.CLT_NO_VALUES), null };
+		}
+	
+		int foundGenericMatches = 0;
+		XMPNode resultNode = null;
+		XMPNode xDefault = null;
+	
+		// Look for the first partial match with the generic language.
+		for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode currItem = (XMPNode) it.next();
+	
+			// perform some checks on the current item
+			if (currItem.getOptions().isCompositeProperty())
+			{
+				throw new XMPException("Alt-text array item is not simple", XMPError.BADXPATH);
+			}
+			else if (!currItem.hasQualifier()
+					|| !XML_LANG.equals(currItem.getQualifier(1).getName()))
+			{
+				throw new XMPException("Alt-text array item has no language qualifier",
+						XMPError.BADXPATH);
+			}
+	
+			String currLang = currItem.getQualifier(1).getValue();
+	
+			// Look for an exact match with the specific language.
+			if (specificLang.equals(currLang))
+			{
+				return new Object[] { new Integer(XMPNodeUtils.CLT_SPECIFIC_MATCH), currItem };
+			}
+			else if (genericLang != null && currLang.startsWith(genericLang))
+			{
+				if (resultNode == null)
+				{
+					resultNode = currItem;
+				}
+				// ! Don't return/break, need to look for other matches.
+				foundGenericMatches++;
+			}
+			else if (X_DEFAULT.equals(currLang))
+			{
+				xDefault = currItem;
+			}
+		}
+	
+		// evaluate loop
+		if (foundGenericMatches == 1)
+		{
+			return new Object[] { new Integer(XMPNodeUtils.CLT_SINGLE_GENERIC), resultNode };
+		}
+		else if (foundGenericMatches > 1)
+		{
+			return new Object[] { new Integer(XMPNodeUtils.CLT_MULTIPLE_GENERIC), resultNode };
+		}
+		else if (xDefault != null)
+		{
+			return new Object[] { new Integer(XMPNodeUtils.CLT_XDEFAULT), xDefault };
+		}
+		else
+		{
+			// Everything failed, choose the first item.
+			return new Object[] { new Integer(XMPNodeUtils.CLT_FIRST_ITEM), arrayNode.getChild(1) };
+		}
+	}
+
+
+	/**
+	 * Looks for the appropriate language item in a text alternative array.item
+	 * 
+	 * @param arrayNode
+	 *            an array node
+	 * @param language
+	 *            the requested language
+	 * @return Returns the index if the language has been found, -1 otherwise.
+	 * @throws XMPException
+	 */
+	static int lookupLanguageItem(XMPNode arrayNode, String language) throws XMPException
+	{
+		if (!arrayNode.getOptions().isArray())
+		{
+			throw new XMPException("Language item must be used on array", XMPError.BADXPATH);
+		}
+	
+		for (int index = 1; index <= arrayNode.getChildrenLength(); index++)
+		{
+			XMPNode child = arrayNode.getChild(index);
+			if (!child.hasQualifier() || !XML_LANG.equals(child.getQualifier(1).getName()))
+			{
+				continue;
+			}
+			else if (language.equals(child.getQualifier(1).getValue()))
+			{
+				return index;
+			}
+		}
+	
+		return -1;
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPNormalizer.java b/XMPCore/src/com/adobe/xmp/impl/XMPNormalizer.java
new file mode 100644
index 0000000..d51d7de
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPNormalizer.java
@@ -0,0 +1,695 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPDateTime;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.XMPUtils;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathParser;
+import com.adobe.xmp.options.ParseOptions;
+import com.adobe.xmp.options.PropertyOptions;
+import com.adobe.xmp.properties.XMPAliasInfo;
+
+/**
+ * @since   Aug 18, 2006
+ */
+public class XMPNormalizer
+{
+	/** caches the correct dc-property array forms */
+	private static Map dcArrayForms;
+	/** init char tables */
+	static
+	{
+		initDCArrays();
+	}
+	
+	
+	/**
+	 * Hidden constructor
+	 */
+	private XMPNormalizer()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * Normalizes a raw parsed XMPMeta-Object
+	 * @param xmp the raw metadata object
+	 * @param options the parsing options
+	 * @return Returns the normalized metadata object
+	 * @throws XMPException Collects all severe processing errors. 
+	 */
+	static XMPMeta process(XMPMetaImpl xmp, ParseOptions options) throws XMPException 
+	{
+		XMPNode tree = xmp.getRoot();
+
+		touchUpDataModel(xmp);
+		moveExplicitAliases(tree, options);
+		
+		tweakOldXMP(tree);
+		
+		deleteEmptySchemas(tree);
+		
+		return xmp;
+	}
+	
+	
+	/**
+	 * Tweak old XMP: Move an instance ID from rdf:about to the
+	 * <em>xmpMM:InstanceID</em> property. An old instance ID usually looks
+	 * like &quot;uuid:bac965c4-9d87-11d9-9a30-000d936b79c4&quot;, plus InDesign
+	 * 3.0 wrote them like &quot;bac965c4-9d87-11d9-9a30-000d936b79c4&quot;. If
+	 * the name looks like a UUID simply move it to <em>xmpMM:InstanceID</em>,
+	 * don't worry about any existing <em>xmpMM:InstanceID</em>. Both will
+	 * only be present when a newer file with the <em>xmpMM:InstanceID</em>
+	 * property is updated by an old app that uses <em>rdf:about</em>.
+	 * 
+	 * @param tree the root of the metadata tree
+	 * @throws XMPException Thrown if tweaking fails. 
+	 */
+	private static void tweakOldXMP(XMPNode tree) throws XMPException
+	{
+		if (tree.getName() != null  &&  tree.getName().length() >= Utils.UUID_LENGTH)
+		{
+			String nameStr = tree.getName().toLowerCase();
+			if (nameStr.startsWith("uuid:"))
+			{
+				nameStr = nameStr.substring(5);
+			}
+			
+			if (Utils.checkUUIDFormat(nameStr))
+			{	
+				// move UUID to xmpMM:InstanceID and remove it from the root node
+				XMPPath path = XMPPathParser.expandXPath(XMPConst.NS_XMP_MM, "InstanceID");
+				XMPNode idNode = XMPNodeUtils.findNode (tree, path, true, null);
+				if (idNode != null)
+				{
+					idNode.setOptions(null);	// Clobber any existing xmpMM:InstanceID.
+					idNode.setValue("uuid:" + nameStr);
+					idNode.removeChildren();
+					idNode.removeQualifiers();		
+					tree.setName(null);
+				}
+				else
+				{	
+					throw new XMPException("Failure creating xmpMM:InstanceID",
+							XMPError.INTERNALFAILURE);
+				}	
+			}
+		}		
+	}
+
+	
+	/**
+	 * Visit all schemas to do general fixes and handle special cases.
+	 * 
+	 * @param xmp the metadata object implementation
+	 * @throws XMPException Thrown if the normalisation fails.
+	 */
+	private static void touchUpDataModel(XMPMetaImpl xmp) throws XMPException
+	{
+		// make sure the DC schema is existing, because it might be needed within the normalization
+		// if not touched it will be removed by removeEmptySchemas
+		XMPNodeUtils.findSchemaNode(xmp.getRoot(), XMPConst.NS_DC, true);
+		
+		// Do the special case fixes within each schema.
+		for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext();)
+		{
+			XMPNode currSchema = (XMPNode) it.next();
+			if (XMPConst.NS_DC.equals(currSchema.getName()))
+			{
+				normalizeDCArrays(currSchema);
+			}
+			else if (XMPConst.NS_EXIF.equals(currSchema.getName()))
+			{
+				// Do a special case fix for exif:GPSTimeStamp.
+				fixGPSTimeStamp(currSchema);
+				XMPNode arrayNode = XMPNodeUtils.findChildNode(currSchema, "exif:UserComment",
+						false);
+				if (arrayNode != null)
+				{
+					repairAltText(arrayNode);
+				}
+			}
+			else if (XMPConst.NS_DM.equals(currSchema.getName()))
+			{
+				// Do a special case migration of xmpDM:copyright to
+				// dc:rights['x-default'].
+				XMPNode dmCopyright = XMPNodeUtils.findChildNode(currSchema, "xmpDM:copyright",
+						false);
+				if (dmCopyright != null)
+				{
+					migrateAudioCopyright(xmp, dmCopyright);
+				}
+			}
+			else if (XMPConst.NS_XMP_RIGHTS.equals(currSchema.getName()))
+			{
+				XMPNode arrayNode = XMPNodeUtils.findChildNode(currSchema, "xmpRights:UsageTerms",
+						false);			
+				if (arrayNode != null)
+				{	
+					repairAltText(arrayNode);
+				}	
+			}
+		}
+	}
+	
+
+	/**
+	 * Undo the denormalization performed by the XMP used in Acrobat 5.<br> 
+	 * If a Dublin Core array had only one item, it was serialized as a simple
+	 * property. <br>
+	 * The <code>xml:lang</code> attribute was dropped from an
+	 * <code>alt-text</code> item if the language was <code>x-default</code>.
+	 * 
+	 * @param dcSchema the DC schema node
+	 * @throws XMPException Thrown if normalization fails
+	 */
+	private static void normalizeDCArrays(XMPNode dcSchema) throws XMPException
+	{
+		for (int i = 1; i <= dcSchema.getChildrenLength(); i++)
+		{
+			XMPNode currProp = dcSchema.getChild(i);
+			
+			PropertyOptions arrayForm = (PropertyOptions) dcArrayForms.get(currProp.getName());
+			if (arrayForm == null)
+			{
+				continue;
+			}
+			else if (currProp.getOptions().isSimple())
+			{	
+				// create a new array and add the current property as child, 
+				// if it was formerly simple 
+				XMPNode newArray = new XMPNode(currProp.getName(), arrayForm);
+				currProp.setName(XMPConst.ARRAY_ITEM_NAME);
+				newArray.addChild(currProp);
+				dcSchema.replaceChild(i, newArray);
+	
+				// fix language alternatives
+				if (arrayForm.isArrayAltText()  &&  !currProp.getOptions().getHasLanguage())
+				{
+					XMPNode newLang = new XMPNode(XMPConst.XML_LANG, XMPConst.X_DEFAULT, null);
+					currProp.addQualifier(newLang);
+				}
+			}
+			else
+			{
+				// clear array options and add corrected array form if it has been an array before
+				currProp.getOptions().setOption(
+					PropertyOptions.ARRAY  |
+					PropertyOptions.ARRAY_ORDERED  |
+					PropertyOptions.ARRAY_ALTERNATE  |
+					PropertyOptions.ARRAY_ALT_TEXT,  
+					false);
+				currProp.getOptions().mergeWith(arrayForm);
+				
+				if (arrayForm.isArrayAltText())
+				{
+					// applying for "dc:description", "dc:rights", "dc:title"
+					repairAltText(currProp);
+				}
+			}
+		
+		}
+	}
+
+	
+	/**
+	 * Make sure that the array is well-formed AltText. Each item must be simple
+	 * and have an "xml:lang" qualifier. If repairs are needed, keep simple
+	 * non-empty items by adding the "xml:lang" with value "x-repair".
+	 * @param arrayNode the property node of the array to repair.
+	 * @throws XMPException Forwards unexpected exceptions.
+	 */
+	private static void repairAltText(XMPNode arrayNode) throws XMPException
+	{
+		if (arrayNode == null  ||  
+			!arrayNode.getOptions().isArray())
+		{
+			// Already OK or not even an array.
+			return;	
+		}
+
+		// fix options
+		arrayNode.getOptions().setArrayOrdered(true).setArrayAlternate(true).setArrayAltText(true);
+		
+		for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode currChild = (XMPNode) it.next();
+			if (currChild.getOptions().isCompositeProperty())
+			{
+				// Delete non-simple children.
+				it.remove();
+			} 
+			else if (!currChild.getOptions().getHasLanguage())
+			{
+				String childValue = currChild.getValue();
+				if (childValue == null  ||  childValue.length() == 0)
+				{
+					// Delete empty valued children that have no xml:lang.
+					it.remove();
+				}
+				else
+				{
+					// Add an xml:lang qualifier with the value "x-repair".
+					XMPNode repairLang = new XMPNode(XMPConst.XML_LANG, "x-repair", null);
+					currChild.addQualifier(repairLang);
+				}
+			}
+		}		
+	}
+	
+
+	/**
+	 * Visit all of the top level nodes looking for aliases. If there is
+	 * no base, transplant the alias subtree. If there is a base and strict
+	 * aliasing is on, make sure the alias and base subtrees match.
+	 * 
+	 * @param tree the root of the metadata tree
+	 * @param options th parsing options
+	 * @throws XMPException Forwards XMP errors
+	 */
+	private static void moveExplicitAliases(XMPNode tree, ParseOptions options)
+			throws XMPException
+	{
+		if (!tree.getHasAliases())
+		{
+			return;
+		}
+		tree.setHasAliases(false);
+		
+		boolean strictAliasing = options.getStrictAliasing();
+
+		for (Iterator schemaIt = tree.getUnmodifiableChildren().iterator(); schemaIt.hasNext();)
+		{
+			XMPNode currSchema = (XMPNode) schemaIt.next();
+			if (!currSchema.getHasAliases())
+			{
+				continue;
+			}
+			
+			for (Iterator propertyIt = currSchema.iterateChildren(); propertyIt.hasNext();)
+			{
+				XMPNode currProp = (XMPNode) propertyIt.next();
+				
+				if (!currProp.isAlias())
+				{
+					continue;
+				}
+				
+				currProp.setAlias(false);
+	
+				// Find the base path, look for the base schema and root node.
+				XMPAliasInfo info = XMPMetaFactory.getSchemaRegistry()
+						.findAlias(currProp.getName());
+				if (info != null)
+				{	
+					// find or create schema
+					XMPNode baseSchema = XMPNodeUtils.findSchemaNode(tree, info
+							.getNamespace(), null, true);
+					baseSchema.setImplicit(false);
+					
+					XMPNode baseNode = XMPNodeUtils
+							.findChildNode(baseSchema, 
+								info.getPrefix() + info.getPropName(), false);
+					if (baseNode == null)
+					{
+						if (info.getAliasForm().isSimple())
+						{
+							// A top-to-top alias, transplant the property.
+							// change the alias property name to the base name
+							String qname = info.getPrefix() + info.getPropName();
+							currProp.setName(qname);
+							baseSchema.addChild(currProp);
+							// remove the alias property
+							propertyIt.remove();
+						}
+						else
+						{
+							// An alias to an array item, 
+							// create the array and transplant the property.
+							baseNode = new XMPNode(info.getPrefix() + info.getPropName(), info
+									.getAliasForm().toPropertyOptions());
+							baseSchema.addChild(baseNode);
+							transplantArrayItemAlias (propertyIt, currProp, baseNode);
+						}
+					
+					} 
+					else if (info.getAliasForm().isSimple())
+					{
+						// The base node does exist and this is a top-to-top alias.
+						// Check for conflicts if strict aliasing is on. 
+						// Remove and delete the alias subtree.
+						if (strictAliasing)
+						{
+							compareAliasedSubtrees (currProp, baseNode, true);
+						}
+						
+						propertyIt.remove();
+					}
+					else
+					{
+						// This is an alias to an array item and the array exists.
+						// Look for the aliased item.
+						// Then transplant or check & delete as appropriate.
+						
+						XMPNode  itemNode = null;
+						if (info.getAliasForm().isArrayAltText())
+						{
+							int xdIndex = XMPNodeUtils.lookupLanguageItem(baseNode,
+									XMPConst.X_DEFAULT); 
+							if (xdIndex != -1)
+							{
+								itemNode = baseNode.getChild(xdIndex);
+							}
+						}
+						else if (baseNode.hasChildren())
+						{
+							itemNode = baseNode.getChild(1);
+						}
+						
+						if (itemNode == null)
+						{
+							transplantArrayItemAlias (propertyIt, currProp, baseNode);
+						}
+						else
+						{
+							if (strictAliasing)
+							{
+								compareAliasedSubtrees (currProp, itemNode, true);
+							}
+							
+							propertyIt.remove();
+						}
+					}
+				}
+			}
+			currSchema.setHasAliases(false);
+		}
+	}
+
+	
+	/**
+	 * Moves an alias node of array form to another schema into an array
+	 * @param propertyIt the property iterator of the old schema (used to delete the property)
+	 * @param childNode the node to be moved
+	 * @param baseArray the base array for the array item 
+	 * @throws XMPException Forwards XMP errors
+	 */
+	private static void transplantArrayItemAlias(Iterator propertyIt, XMPNode childNode,
+			XMPNode baseArray) throws XMPException
+	{
+		if (baseArray.getOptions().isArrayAltText())
+		{
+			if (childNode.getOptions().getHasLanguage())
+			{
+				throw new XMPException("Alias to x-default already has a language qualifier",
+						XMPError.BADXMP);
+			}
+			
+			XMPNode langQual = new XMPNode(XMPConst.XML_LANG, XMPConst.X_DEFAULT, null);
+			childNode.addQualifier(langQual);
+		}
+	
+		propertyIt.remove();
+		childNode.setName(XMPConst.ARRAY_ITEM_NAME);
+		baseArray.addChild(childNode);
+	}
+	
+	
+	/**
+	 * Fixes the GPS Timestamp in EXIF.
+	 * @param exifSchema the EXIF schema node
+	 * @throws XMPException Thrown if the date conversion fails.
+	 */
+	private static void fixGPSTimeStamp(XMPNode exifSchema)
+			throws XMPException
+	{
+		// Note: if dates are not found the convert-methods throws an exceptions,
+		// 		 and this methods returns.
+		XMPNode gpsDateTime = XMPNodeUtils.findChildNode(exifSchema, "exif:GPSTimeStamp", false);
+		if (gpsDateTime == null)
+		{
+			return;
+		}
+		
+		try
+		{
+			XMPDateTime binGPSStamp;
+			XMPDateTime binOtherDate;
+			
+			binGPSStamp = XMPUtils.convertToDate(gpsDateTime.getValue());
+			if (binGPSStamp.getYear() != 0  || 
+				binGPSStamp.getMonth() != 0  ||
+				binGPSStamp.getDay() != 0)
+			{
+				return;
+			}
+			
+			XMPNode otherDate = XMPNodeUtils.findChildNode(exifSchema, "exif:DateTimeOriginal",
+					false);
+			if (otherDate == null)
+			{
+				otherDate = XMPNodeUtils.findChildNode(exifSchema, "exif:DateTimeDigitized", false);
+			}
+	
+			binOtherDate = XMPUtils.convertToDate(otherDate.getValue());
+			Calendar cal = binGPSStamp.getCalendar();
+			cal.set(Calendar.YEAR, binOtherDate.getYear());
+			cal.set(Calendar.MONTH, binOtherDate.getMonth());
+			cal.set(Calendar.DAY_OF_MONTH, binOtherDate.getDay());
+			binGPSStamp = new XMPDateTimeImpl(cal);
+			gpsDateTime.setValue(XMPUtils.convertFromDate (binGPSStamp));
+		}
+		catch (XMPException e)
+		{
+			// Don't let a missing or bad date stop other things.
+			return;
+		}
+	}
+
+
+
+	/**
+	 * Remove all empty schemas from the metadata tree that were generated during the rdf parsing.
+	 * @param tree the root of the metadata tree
+	 */
+	private static void deleteEmptySchemas(XMPNode tree)
+	{
+		// Delete empty schema nodes. Do this last, other cleanup can make empty
+		// schema.
+	
+		for (Iterator it = tree.iterateChildren(); it.hasNext();)
+		{
+			XMPNode schema = (XMPNode) it.next();
+			if (!schema.hasChildren())
+			{
+				it.remove();
+			}
+		}
+	}
+
+	
+	/**
+	 * The outermost call is special. The names almost certainly differ. The
+	 * qualifiers (and hence options) will differ for an alias to the x-default
+	 * item of a langAlt array.
+	 * 
+	 * @param aliasNode the alias node
+	 * @param baseNode the base node of the alias
+	 * @param outerCall marks the outer call of the recursion
+	 * @throws XMPException Forwards XMP errors 
+	 */
+	private static void compareAliasedSubtrees(XMPNode aliasNode, XMPNode baseNode,
+			boolean outerCall) throws XMPException 
+	{
+		if (!aliasNode.getValue().equals(baseNode.getValue())  || 
+			aliasNode.getChildrenLength() != baseNode.getChildrenLength())
+		{
+			throw new XMPException("Mismatch between alias and base nodes", XMPError.BADXMP);
+		}
+		
+		if (
+				!outerCall  &&
+				(!aliasNode.getName().equals(baseNode.getName())  ||
+				 !aliasNode.getOptions().equals(baseNode.getOptions())  ||
+				 aliasNode.getQualifierLength() != baseNode.getQualifierLength())
+		   ) 
+	    {
+			throw new XMPException("Mismatch between alias and base nodes", 
+				XMPError.BADXMP);
+		}
+		
+		for (Iterator an = aliasNode.iterateChildren(), 
+					  bn = baseNode.iterateChildren();
+			 an.hasNext() && bn.hasNext();)
+		{
+			XMPNode aliasChild = (XMPNode) an.next();
+			XMPNode baseChild =  (XMPNode) bn.next();
+			compareAliasedSubtrees (aliasChild, baseChild, false);
+		}
+	
+		
+		for (Iterator an = aliasNode.iterateQualifier(), 
+					  bn = baseNode.iterateQualifier();
+			 an.hasNext() && bn.hasNext();)
+		{
+			XMPNode aliasQual = (XMPNode) an.next();
+			XMPNode baseQual =  (XMPNode) bn.next();
+			compareAliasedSubtrees (aliasQual, baseQual, false);
+		}
+	}
+
+	
+	/**
+	 * The initial support for WAV files mapped a legacy ID3 audio copyright
+	 * into a new xmpDM:copyright property. This is special case code to migrate
+	 * that into dc:rights['x-default']. The rules:
+	 * 
+	 * <pre>
+	 * 1. If there is no dc:rights array, or an empty array -
+	 *    Create one with dc:rights['x-default'] set from double linefeed and xmpDM:copyright.
+	 * 
+	 * 2. If there is a dc:rights array but it has no x-default item -
+	 *    Create an x-default item as a copy of the first item then apply rule #3.
+	 * 
+	 * 3. If there is a dc:rights array with an x-default item, 
+	 *    Look for a double linefeed in the value.
+	 *     A. If no double linefeed, compare the x-default value to the xmpDM:copyright value.
+	 *         A1. If they match then leave the x-default value alone.
+	 *         A2. Otherwise, append a double linefeed and 
+	 *             the xmpDM:copyright value to the x-default value.
+	 *     B. If there is a double linefeed, compare the trailing text to the xmpDM:copyright value.
+	 *         B1. If they match then leave the x-default value alone.
+	 *         B2. Otherwise, replace the trailing x-default text with the xmpDM:copyright value.
+	 * 
+	 * 4. In all cases, delete the xmpDM:copyright property.
+	 * </pre>
+	 * 
+	 * @param xmp the metadata object 
+	 * @param dmCopyright the "dm:copyright"-property
+	 */
+	private static void	migrateAudioCopyright (XMPMeta xmp, XMPNode dmCopyright)
+	{
+		try 
+		{
+			XMPNode dcSchema = XMPNodeUtils.findSchemaNode(
+				((XMPMetaImpl) xmp).getRoot(), XMPConst.NS_DC, true);
+			
+			String dmValue = dmCopyright.getValue();
+			String doubleLF = "\n\n";
+			
+			XMPNode dcRightsArray = XMPNodeUtils.findChildNode (dcSchema, "dc:rights", false);
+			
+			if (dcRightsArray == null  ||  !dcRightsArray.hasChildren()) 
+			{
+				// 1. No dc:rights array, create from double linefeed and xmpDM:copyright.
+				dmValue = doubleLF + dmValue;
+				xmp.setLocalizedText(XMPConst.NS_DC, "rights", "", XMPConst.X_DEFAULT, dmValue,
+						null);
+			}
+			else
+			{
+				int xdIndex = XMPNodeUtils.lookupLanguageItem(dcRightsArray, XMPConst.X_DEFAULT);
+				
+				if (xdIndex < 0)
+				{
+					// 2. No x-default item, create from the first item.
+					String firstValue = dcRightsArray.getChild(1).getValue();
+					xmp.setLocalizedText (XMPConst.NS_DC, "rights", "", XMPConst.X_DEFAULT, 
+						firstValue, null);
+					xdIndex = XMPNodeUtils.lookupLanguageItem(dcRightsArray, XMPConst.X_DEFAULT);
+				}
+							
+				// 3. Look for a double linefeed in the x-default value.
+				XMPNode defaultNode = dcRightsArray.getChild(xdIndex);
+				String defaultValue = defaultNode.getValue();
+				int lfPos = defaultValue.indexOf(doubleLF);
+				
+				if (lfPos < 0)
+				{
+					// 3A. No double LF, compare whole values.
+					if (!dmValue.equals(defaultValue))
+					{
+						// 3A2. Append the xmpDM:copyright to the x-default
+						// item.
+						defaultNode.setValue(defaultValue + doubleLF + dmValue);
+					}
+				}
+				else
+				{
+					// 3B. Has double LF, compare the tail.
+					if (!defaultValue.substring(lfPos + 2).equals(dmValue))
+					{
+						// 3B2. Replace the x-default tail.
+						defaultNode.setValue(defaultValue.substring(0, lfPos + 2) + dmValue);
+					}
+				}
+
+			}
+			
+			// 4. Get rid of the xmpDM:copyright.
+			dmCopyright.getParent().removeChild(dmCopyright);
+		}
+		catch (XMPException e)
+		{
+			// Don't let failures (like a bad dc:rights form) stop other
+			// cleanup.
+		}
+	}
+	
+	
+	/**
+	 * Initializes the map that contains the known arrays, that are fixed by 
+	 * {@link XMPNormalizer#normalizeDCArrays(XMPNode)}. 
+	 */
+	private static void initDCArrays()
+	{
+		dcArrayForms = new HashMap(); 
+		
+		// Properties supposed to be a "Bag".
+		PropertyOptions bagForm = new PropertyOptions();
+		bagForm.setArray(true);
+		dcArrayForms.put("dc:contributor", bagForm);
+		dcArrayForms.put("dc:language", bagForm);
+		dcArrayForms.put("dc:publisher", bagForm);
+		dcArrayForms.put("dc:relation", bagForm);
+		dcArrayForms.put("dc:subject", bagForm);
+		dcArrayForms.put("dc:type", bagForm);
+
+		// Properties supposed to be a "Seq".
+		PropertyOptions seqForm = new PropertyOptions();
+		seqForm.setArray(true);
+		seqForm.setArrayOrdered(true);
+		dcArrayForms.put("dc:creator", seqForm);
+		dcArrayForms.put("dc:date", seqForm);
+		
+		// Properties supposed to be an "Alt" in alternative-text form.
+		PropertyOptions altTextForm = new PropertyOptions();
+		altTextForm.setArray(true);
+		altTextForm.setArrayOrdered(true);
+		altTextForm.setArrayAlternate(true);
+		altTextForm.setArrayAltText(true);
+		dcArrayForms.put("dc:description", altTextForm);
+		dcArrayForms.put("dc:rights", altTextForm);
+		dcArrayForms.put("dc:title", altTextForm);
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPSchemaRegistryImpl.java b/XMPCore/src/com/adobe/xmp/impl/XMPSchemaRegistryImpl.java
new file mode 100644
index 0000000..1b8430d
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPSchemaRegistryImpl.java
@@ -0,0 +1,490 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPSchemaRegistry;
+import com.adobe.xmp.options.AliasOptions;
+import com.adobe.xmp.properties.XMPAliasInfo;
+
+
+/**
+ * The schema registry handles the namespaces, aliases and global options for the XMP Toolkit. There
+ * is only one single instance used by the toolkit.
+ * 
+ * @since 27.01.2006
+ */
+public final class XMPSchemaRegistryImpl implements XMPSchemaRegistry, XMPConst
+{
+	/** a map from a namespace URI to its registered prefix */
+	private Map namespaceToPrefixMap = new HashMap();
+
+	/** a map from a prefix to the associated namespace URI */
+	private Map prefixToNamespaceMap = new HashMap();
+
+	/** a map of all registered aliases. 
+	 *  The map is a relationship from a qname to an <code>XMPAliasInfo</code>-object. */
+	private Map aliasMap = new HashMap();
+	/** The pattern that must not be contained in simple properties */
+	private Pattern p = Pattern.compile("[/*?\\[\\]]");
+
+	
+	/**
+	 * Performs the initialisation of the registry with the default namespaces, aliases and global
+	 * options.
+	 */
+	public XMPSchemaRegistryImpl()
+	{
+		try
+		{
+			registerStandardNamespaces();
+			registerStandardAliases();
+		}
+		catch (XMPException e)
+		{
+			throw new RuntimeException("The XMPSchemaRegistry cannot be initialized!");
+		}
+	}
+
+	
+	// ---------------------------------------------------------------------------------------------
+	// Namespace Functions
+	
+
+	/**
+	 * @see XMPSchemaRegistry#registerNamespace(String, String)
+	 */
+	public synchronized String registerNamespace(String namespaceURI, String suggestedPrefix)
+			throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(namespaceURI);
+		ParameterAsserts.assertPrefix(suggestedPrefix);
+		
+		if (suggestedPrefix.charAt(suggestedPrefix.length() - 1) != ':')
+		{
+			suggestedPrefix += ':';
+		}
+		
+		if (!Utils.isXMLNameNS(suggestedPrefix.substring(0,
+				suggestedPrefix.length() - 1)))
+		{
+			throw new XMPException("The prefix is a bad XML name", XMPError.BADXML);
+		}
+		
+		String registeredPrefix = (String) namespaceToPrefixMap.get(namespaceURI);
+		String registeredNS = (String) prefixToNamespaceMap.get(suggestedPrefix);
+		if (registeredPrefix != null)
+		{
+			// Return the actual prefix
+			return registeredPrefix;
+		}
+		else
+		{
+			if (registeredNS != null) 
+			{
+				// the namespace is new, but the prefix is already engaged,
+				// we generate a new prefix out of the suggested
+				String generatedPrefix = suggestedPrefix;
+				for (int i = 1; prefixToNamespaceMap.containsKey(generatedPrefix); i++)
+				{
+					generatedPrefix = suggestedPrefix
+							.substring(0, suggestedPrefix.length() - 1)
+							+ "_" + i + "_:";
+				}
+				suggestedPrefix = generatedPrefix;
+			}			
+			prefixToNamespaceMap.put(suggestedPrefix, namespaceURI);
+			namespaceToPrefixMap.put(namespaceURI, suggestedPrefix);
+			
+			// Return the suggested prefix
+			return suggestedPrefix;
+		}
+	}
+
+
+	/**
+	 * @see XMPSchemaRegistry#deleteNamespace(String)
+	 */
+	public synchronized void deleteNamespace(String namespaceURI)
+	{
+		String prefixToDelete = getNamespacePrefix(namespaceURI);
+		if (prefixToDelete != null)
+		{	
+			namespaceToPrefixMap.remove(namespaceURI);
+			prefixToNamespaceMap.remove(prefixToDelete);
+		}	
+	}
+
+
+	/**
+	 * @see XMPSchemaRegistry#getNamespacePrefix(String)
+	 */
+	public synchronized String getNamespacePrefix(String namespaceURI)
+	{
+		return (String) namespaceToPrefixMap.get(namespaceURI);
+	}
+
+
+	/**
+	 * @see XMPSchemaRegistry#getNamespaceURI(String)
+	 */
+	public synchronized String getNamespaceURI(String namespacePrefix)
+	{
+		if (namespacePrefix != null  &&  !namespacePrefix.endsWith(":"))
+		{
+			namespacePrefix += ":";
+		}
+		return (String) prefixToNamespaceMap.get(namespacePrefix);
+	}
+
+
+	/**
+	 * @see XMPSchemaRegistry#getNamespaces()
+	 */
+	public synchronized Map getNamespaces()
+	{
+		return Collections.unmodifiableMap(new TreeMap(namespaceToPrefixMap));
+	}
+	
+	
+	/**
+	 * @see XMPSchemaRegistry#getPrefixes()
+	 */
+	public synchronized Map getPrefixes()
+	{
+		return Collections.unmodifiableMap(new TreeMap(prefixToNamespaceMap));
+	}
+	
+	
+	/**
+	 * Register the standard namespaces of schemas and types that are included in the XMP
+	 * Specification and some other Adobe private namespaces.
+	 * Note: This method is not lock because only called by the constructor.
+	 * 
+	 * @throws XMPException Forwards processing exceptions
+	 */
+	private void registerStandardNamespaces() throws XMPException
+	{
+		// register standard namespaces
+		registerNamespace(NS_XML, "xml");
+		registerNamespace(NS_RDF, "rdf");
+		registerNamespace(NS_DC, "dc");
+		registerNamespace(NS_IPTCCORE, "Iptc4xmpCore");
+
+		// register Adobe standard namespaces
+		registerNamespace(NS_X, "x");
+		registerNamespace(NS_IX, "iX");
+
+		registerNamespace(NS_XMP, "xmp");
+		registerNamespace(NS_XMP_RIGHTS, "xmpRights");
+		registerNamespace(NS_XMP_MM, "xmpMM");
+		registerNamespace(NS_XMP_BJ, "xmpBJ");
+		registerNamespace(NS_XMP_NOTE, "xmpNote");
+		
+		registerNamespace(NS_PDF, "pdf");
+		registerNamespace(NS_PDFX, "pdfx");
+		registerNamespace(NS_PDFX_ID, "pdfxid");
+		registerNamespace(NS_PDFA_SCHEMA, "pdfaSchema");
+		registerNamespace(NS_PDFA_PROPERTY, "pdfaProperty");
+		registerNamespace(NS_PDFA_TYPE, "pdfaType");
+		registerNamespace(NS_PDFA_FIELD, "pdfaField");
+		registerNamespace(NS_PDFA_ID, "pdfaid");
+		registerNamespace(NS_PDFA_EXTENSION, "pdfaExtension");
+		registerNamespace(NS_PHOTOSHOP, "photoshop");
+		registerNamespace(NS_PSALBUM, "album");
+		registerNamespace(NS_EXIF, "exif");
+		registerNamespace(NS_EXIF_AUX, "aux");
+		registerNamespace(NS_TIFF, "tiff");
+		registerNamespace(NS_PNG, "png");
+		registerNamespace(NS_JPEG, "jpeg");
+		registerNamespace(NS_JP2K, "jp2k");
+		registerNamespace(NS_CAMERARAW, "crs");
+		registerNamespace(NS_ADOBESTOCKPHOTO, "bmsp");
+		registerNamespace(NS_CREATOR_ATOM, "creatorAtom");
+		registerNamespace(NS_ASF, "asf");
+		registerNamespace(NS_WAV, "wav");
+		
+		// register Adobe private namespaces
+		registerNamespace(NS_DM, "xmpDM");
+		registerNamespace(NS_TRANSIENT, "xmpx");
+		
+		// register Adobe standard type namespaces
+		registerNamespace(TYPE_TEXT, "xmpT");
+		registerNamespace(TYPE_PAGEDFILE, "xmpTPg");
+		registerNamespace(TYPE_GRAPHICS, "xmpG");
+		registerNamespace(TYPE_IMAGE, "xmpGImg");
+		registerNamespace(TYPE_FONT, "stFNT");
+		registerNamespace(TYPE_DIMENSIONS, "stDim");
+		registerNamespace(TYPE_RESOURCEEVENT, "stEvt");
+		registerNamespace(TYPE_RESOURCEREF, "stRef");
+		registerNamespace(TYPE_ST_VERSION, "stVer");
+		registerNamespace(TYPE_ST_JOB, "stJob");
+		registerNamespace(TYPE_MANIFESTITEM, "stMfs");
+		registerNamespace(TYPE_IDENTIFIERQUAL, "xmpidq");
+	}
+	
+
+	
+	// ---------------------------------------------------------------------------------------------
+	// Alias Functions
+
+	
+	/**
+	 * @see XMPSchemaRegistry#resolveAlias(String, String)
+	 */
+	public synchronized XMPAliasInfo resolveAlias(String aliasNS, String aliasProp)
+	{
+		String aliasPrefix = getNamespacePrefix(aliasNS);
+		if (aliasPrefix == null)
+		{	
+			return null;
+		}
+		
+		return (XMPAliasInfo) aliasMap.get(aliasPrefix + aliasProp);
+	}
+
+
+	/**
+	 * @see XMPSchemaRegistry#findAlias(java.lang.String)
+	 */
+	public synchronized XMPAliasInfo findAlias(String qname)
+	{
+		return (XMPAliasInfo) aliasMap.get(qname);
+	}
+
+	
+	/**
+	 * @see XMPSchemaRegistry#findAliases(String)
+	 */
+	public synchronized XMPAliasInfo[] findAliases(String aliasNS)
+	{
+		String prefix = getNamespacePrefix(aliasNS);
+		List result = new ArrayList(); 
+		if (prefix != null)
+		{
+			for (Iterator it = aliasMap.keySet().iterator(); it.hasNext();)
+			{
+				String qname = (String) it.next();
+				if (qname.startsWith(prefix))
+				{
+					result.add(findAlias(qname));
+				}
+			}
+			
+		}
+		return (XMPAliasInfo[]) result.toArray(new XMPAliasInfo[result.size()]);
+	}	
+	
+	
+	/**
+	 * Associates an alias name with an actual name.
+	 * <p>
+	 * Define a alias mapping from one namespace/property to another. Both
+	 * property names must be simple names. An alias can be a direct mapping,
+	 * where the alias and actual have the same data type. It is also possible
+	 * to map a simple alias to an item in an array. This can either be to the
+	 * first item in the array, or to the 'x-default' item in an alt-text array.
+	 * Multiple alias names may map to the same actual, as long as the forms
+	 * match. It is a no-op to reregister an alias in an identical fashion.
+	 * Note: This method is not locking because only called by registerStandardAliases 
+	 * which is only called by the constructor.
+	 * Note2: The method is only package-private so that it can be tested with unittests 
+	 * 
+	 * @param aliasNS
+	 *            The namespace URI for the alias. Must not be null or the empty
+	 *            string.
+	 * @param aliasProp
+	 *            The name of the alias. Must be a simple name, not null or the
+	 *            empty string and not a general path expression.
+	 * @param actualNS
+	 *            The namespace URI for the actual. Must not be null or the
+	 *            empty string.
+	 * @param actualProp
+	 *            The name of the actual. Must be a simple name, not null or the
+	 *            empty string and not a general path expression.
+	 * @param aliasForm
+	 *            Provides options for aliases for simple aliases to array
+	 *            items. This is needed to know what kind of array to create if
+	 *            set for the first time via the simple alias. Pass
+	 *            <code>XMP_NoOptions</code>, the default value, for all
+	 *            direct aliases regardless of whether the actual data type is
+	 *            an array or not (see {@link AliasOptions}).
+	 * @throws XMPException
+	 *             for inconsistant aliases.
+	 */
+	synchronized void registerAlias(String aliasNS, String aliasProp, final String actualNS,
+			final String actualProp, final AliasOptions aliasForm) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(aliasNS);
+		ParameterAsserts.assertPropName(aliasProp);
+		ParameterAsserts.assertSchemaNS(actualNS);
+		ParameterAsserts.assertPropName(actualProp);
+		
+		// Fix the alias options
+		final AliasOptions aliasOpts = aliasForm != null ?
+			new AliasOptions(XMPNodeUtils.verifySetOptions(
+				aliasForm.toPropertyOptions(), null).getOptions()) :
+			new AliasOptions();
+	
+		if (p.matcher(aliasProp).find()  ||  p.matcher(actualProp).find())
+		{
+			throw new XMPException("Alias and actual property names must be simple",
+					XMPError.BADXPATH);
+		}
+		
+		// check if both namespaces are registered
+		final String aliasPrefix = getNamespacePrefix(aliasNS);
+		final String actualPrefix = getNamespacePrefix(actualNS);
+		if (aliasPrefix == null)
+		{
+			throw new XMPException("Alias namespace is not registered", XMPError.BADSCHEMA);
+		}
+		else if (actualPrefix == null)
+		{
+			throw new XMPException("Actual namespace is not registered", 
+				XMPError.BADSCHEMA);
+		}
+		
+		String key = aliasPrefix + aliasProp;
+		
+		// check if alias is already existing
+		if (aliasMap.containsKey(key))
+		{
+			throw new XMPException("Alias is already existing", XMPError.BADPARAM);
+		}
+		else if (aliasMap.containsKey(actualPrefix + actualProp))
+		{	
+			throw new XMPException(
+					"Actual property is already an alias, use the base property",
+					XMPError.BADPARAM);
+		}
+		
+		XMPAliasInfo aliasInfo = new XMPAliasInfo()
+		{
+			/**
+			 * @see XMPAliasInfo#getNamespace()
+			 */
+			public String getNamespace()
+			{
+				return actualNS;
+			}
+
+			/**
+			 * @see XMPAliasInfo#getPrefix()
+			 */
+			public String getPrefix()
+			{
+				return actualPrefix;
+			}
+
+			/**
+			 * @see XMPAliasInfo#getPropName()
+			 */
+			public String getPropName()
+			{
+				return actualProp;
+			}
+			
+			/**
+			 * @see XMPAliasInfo#getAliasForm()
+			 */
+			public AliasOptions getAliasForm()
+			{
+				return aliasOpts;
+			}
+			
+			public String toString()
+			{
+				return actualPrefix + actualProp + " NS(" + actualNS + "), FORM ("
+						+ getAliasForm() + ")"; 
+			}
+		};
+		
+		aliasMap.put(key, aliasInfo);
+	}
+
+		
+	/**
+	 * @see XMPSchemaRegistry#getAliases()
+	 */
+	public synchronized Map getAliases()
+	{
+		return Collections.unmodifiableMap(new TreeMap(aliasMap));
+	}
+	
+	
+	/**
+	 * Register the standard aliases.
+	 * Note: This method is not lock because only called by the constructor.
+	 * 
+	 * @throws XMPException If the registrations of at least one alias fails.
+	 */
+	private void registerStandardAliases() throws XMPException
+	{
+		AliasOptions aliasToArrayOrdered = new AliasOptions().setArrayOrdered(true);
+		AliasOptions aliasToArrayAltText = new AliasOptions().setArrayAltText(true);
+		
+		
+		// Aliases from XMP to DC.
+		registerAlias(NS_XMP, "Author", NS_DC, "creator", aliasToArrayOrdered);
+		registerAlias(NS_XMP, "Authors", NS_DC, "creator", null);
+		registerAlias(NS_XMP, "Description", NS_DC, "description", null);
+		registerAlias(NS_XMP, "Format", NS_DC, "format", null);
+		registerAlias(NS_XMP, "Keywords", NS_DC, "subject", null);
+		registerAlias(NS_XMP, "Locale", NS_DC, "language", null);
+		registerAlias(NS_XMP, "Title", NS_DC, "title", null);
+		registerAlias(NS_XMP_RIGHTS, "Copyright", NS_DC, "rights", null);
+
+		// Aliases from PDF to DC and XMP.
+		registerAlias(NS_PDF, "Author", NS_DC, "creator", aliasToArrayOrdered);
+		registerAlias(NS_PDF, "BaseURL", NS_XMP, "BaseURL", null);
+		registerAlias(NS_PDF, "CreationDate", NS_XMP, "CreateDate", null);
+		registerAlias(NS_PDF, "Creator", NS_XMP, "CreatorTool", null);
+		registerAlias(NS_PDF, "ModDate", NS_XMP, "ModifyDate", null);
+		registerAlias(NS_PDF, "Subject", NS_DC, "description", aliasToArrayAltText);
+		registerAlias(NS_PDF, "Title", NS_DC, "title", aliasToArrayAltText);
+
+		// Aliases from PHOTOSHOP to DC and XMP.
+		registerAlias(NS_PHOTOSHOP, "Author", NS_DC, "creator", aliasToArrayOrdered);
+		registerAlias(NS_PHOTOSHOP, "Caption", NS_DC, "description", aliasToArrayAltText);
+		registerAlias(NS_PHOTOSHOP, "Copyright", NS_DC, "rights", aliasToArrayAltText);
+		registerAlias(NS_PHOTOSHOP, "Keywords", NS_DC, "subject", null);
+		registerAlias(NS_PHOTOSHOP, "Marked", NS_XMP_RIGHTS, "Marked", null);
+		registerAlias(NS_PHOTOSHOP, "Title", NS_DC, "title", aliasToArrayAltText);
+		registerAlias(NS_PHOTOSHOP, "WebStatement", NS_XMP_RIGHTS, "WebStatement", null);
+
+		// Aliases from TIFF and EXIF to DC and XMP.
+		registerAlias(NS_TIFF, "Artist", NS_DC, "creator", aliasToArrayOrdered);
+		registerAlias(NS_TIFF, "Copyright", NS_DC, "rights", null);
+		registerAlias(NS_TIFF, "DateTime", NS_XMP, "ModifyDate", null);
+		registerAlias(NS_TIFF, "ImageDescription", NS_DC, "description", null);
+		registerAlias(NS_TIFF, "Software", NS_XMP, "CreatorTool", null);
+
+		// Aliases from PNG (Acrobat ImageCapture) to DC and XMP.
+		registerAlias(NS_PNG, "Author", NS_DC, "creator", aliasToArrayOrdered);
+		registerAlias(NS_PNG, "Copyright", NS_DC, "rights", aliasToArrayAltText);
+		registerAlias(NS_PNG, "CreationTime", NS_XMP, "CreateDate", null);
+		registerAlias(NS_PNG, "Description", NS_DC, "description", aliasToArrayAltText);
+		registerAlias(NS_PNG, "ModificationTime", NS_XMP, "ModifyDate", null);
+		registerAlias(NS_PNG, "Software", NS_XMP, "CreatorTool", null);
+		registerAlias(NS_PNG, "Title", NS_DC, "title", aliasToArrayAltText);
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPSerializerHelper.java b/XMPCore/src/com/adobe/xmp/impl/XMPSerializerHelper.java
new file mode 100644
index 0000000..ba43f01
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPSerializerHelper.java
@@ -0,0 +1,102 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.options.SerializeOptions;
+
+
+/**
+ * Serializes the <code>XMPMeta</code>-object to an <code>OutputStream</code> according to the
+ * <code>SerializeOptions</code>. 
+ * 
+ * @since   11.07.2006
+ */
+public class XMPSerializerHelper
+{
+	/**
+	 * Static method to serialize the metadata object. For each serialisation, a new XMPSerializer
+	 * instance is created, either XMPSerializerRDF or XMPSerializerPlain so thats its possible to 
+	 * serialialize the same XMPMeta objects in two threads.
+	 * 
+	 * @param xmp a metadata implementation object
+	 * @param out the output stream to serialize to
+	 * @param options serialization options, can be <code>null</code> for default.
+	 * @throws XMPException
+	 */
+	public static void serialize(XMPMetaImpl xmp, OutputStream out, 
+		SerializeOptions options)
+		throws XMPException
+	{
+		options = options != null ? options : new SerializeOptions();		
+		
+		// sort the internal data model on demand
+		if (options.getSort())
+		{
+			xmp.sort();
+		}
+		new XMPSerializerRDF().serialize(xmp, out, options);
+	}		
+	
+
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into a string.
+	 * <em>Note:</em> Encoding is forced to UTF-16 when serializing to a
+	 * string to ensure the correctness of &quot;exact packet size&quot;.
+	 * 
+	 * @param xmp a metadata implementation object
+	 * @param options Options to control the serialization (see
+	 *            {@link SerializeOptions}).
+	 * @return Returns a string containing the serialized RDF.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static String serializeToString(XMPMetaImpl xmp, SerializeOptions options)
+		throws XMPException
+	{
+		// forces the encoding to be UTF-16 to get the correct string length
+		options = options != null ? options : new SerializeOptions();		
+		options.setEncodeUTF16BE(true);
+
+		ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
+		serialize(xmp, out, options);
+
+		try
+		{
+			return out.toString(options.getEncoding());
+		}
+		catch (UnsupportedEncodingException e)
+		{
+			// cannot happen as UTF-8/16LE/BE is required to be implemented in
+			// Java
+			return out.toString();
+		}
+	}
+	
+	
+	/**
+	 * Serializes an <code>XMPMeta</code>-object as RDF into a byte buffer.
+	 * 
+	 * @param xmp a metadata implementation object
+	 * @param options Options to control the serialization (see {@link SerializeOptions}).
+	 * @return Returns a byte buffer containing the serialized RDF.
+	 * @throws XMPException on serializsation errors.
+	 */
+	public static byte[] serializeToBuffer(XMPMetaImpl xmp, SerializeOptions options)
+			throws XMPException
+	{
+		ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
+		serialize(xmp, out, options);
+		return out.toByteArray();
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPSerializerRDF.java b/XMPCore/src/com/adobe/xmp/impl/XMPSerializerRDF.java
new file mode 100644
index 0000000..b00877f
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPSerializerRDF.java
@@ -0,0 +1,1276 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.options.SerializeOptions;
+
+
+/**
+ * Serializes the <code>XMPMeta</code>-object using the standard RDF serialization format. 
+ * The output is written to an <code>OutputStream</code> 
+ * according to the <code>SerializeOptions</code>. 
+ * 
+ * @since   11.07.2006
+ */
+public class XMPSerializerRDF
+{
+	/** default padding */
+	private static final int DEFAULT_PAD = 2048;	
+	/** */
+	private static final String PACKET_HEADER  =
+		"<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>";
+	/** The w/r is missing inbetween */
+	private static final String PACKET_TRAILER = "<?xpacket end=\"";
+	/** */
+	private static final String PACKET_TRAILER2 = "\"?>"; 
+	/** */
+	private static final String RDF_XMPMETA_START = 
+		"<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"";
+	/** */
+	private static final String RDF_XMPMETA_END   = "</x:xmpmeta>";
+	/** */
+	private static final String RDF_RDF_START = 
+		"<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">";
+	/** */
+	private static final String RDF_RDF_END       = "</rdf:RDF>";
+	
+	/** */
+	private static final String RDF_SCHEMA_START  = "<rdf:Description rdf:about=";
+	/** */
+	private static final String RDF_SCHEMA_END    = "</rdf:Description>";
+	/** */
+	private static final String RDF_STRUCT_START  = "<rdf:Description";
+	/** */
+	private static final String RDF_STRUCT_END    = "</rdf:Description>";
+	/** a set of all rdf attribute qualifier */
+	static final Set RDF_ATTR_QUALIFIER = new HashSet(Arrays.asList(new String[] {
+			XMPConst.XML_LANG, "rdf:resource", "rdf:ID", "rdf:bagID", "rdf:nodeID" }));
+	
+	/** the metadata object to be serialized. */ 
+	private XMPMetaImpl xmp; 
+	/** the output stream to serialize to */ 
+	private CountOutputStream outputStream;
+	/** this writer is used to do the actual serialisation */
+	private OutputStreamWriter writer;
+	/** the stored serialisation options */
+	private SerializeOptions options;
+	/** the size of one unicode char, for UTF-8 set to 1 
+	 *  (Note: only valid for ASCII chars lower than 0x80),
+	 *  set to 2 in case of UTF-16 */
+	private int unicodeSize = 1; // UTF-8
+	/** the padding in the XMP Packet, or the length of the complete packet in
+	 *  case of option <em>exactPacketLength</em>. */ 
+	private int padding;
+
+	
+	/**
+	 * The actual serialisation.
+	 * 
+	 * @param xmp the metadata object to be serialized
+	 * @param out outputStream the output stream to serialize to
+	 * @param options the serialization options
+	 * 
+	 * @throws XMPException If case of wrong options or any other serialisaton error.
+	 */
+	public void serialize(XMPMeta xmp, OutputStream out, 
+			SerializeOptions options) throws XMPException
+	{
+		try
+		{
+			outputStream = new CountOutputStream(out); 
+			writer = new OutputStreamWriter(outputStream, options.getEncoding());
+			
+			this.xmp = (XMPMetaImpl) xmp;
+			this.options = options;
+			this.padding = options.getPadding();
+
+			writer = new OutputStreamWriter(outputStream, options.getEncoding());
+			
+			checkOptionsConsistence();
+			
+			// serializes the whole packet, but don't write the tail yet 
+			// and flush to make sure that the written bytes are calculated correctly
+			String tailStr = serializeAsRDF();
+			writer.flush();
+			
+			// adds padding
+			addPadding(tailStr.length());
+
+			// writes the tail
+			write(tailStr);
+			writer.flush();
+			
+			outputStream.close();
+		}
+		catch (IOException e)
+		{
+			throw new XMPException("Error writing to the OutputStream", XMPError.UNKNOWN);
+		}
+	}
+
+
+	/**
+	 * Calulates the padding according to the options and write it to the stream.
+	 * @param tailLength the length of the tail string 
+	 * @throws XMPException thrown if packet size is to small to fit the padding
+	 * @throws IOException forwards writer errors
+	 */
+	private void addPadding(int tailLength) throws XMPException, IOException
+	{
+		if (options.getExactPacketLength())
+		{
+			// the string length is equal to the length of the UTF-8 encoding
+			int minSize = outputStream.getBytesWritten() + tailLength * unicodeSize;
+			if (minSize > padding)
+			{
+				throw new XMPException("Can't fit into specified packet size",
+					XMPError.BADSERIALIZE);
+			}
+			padding -= minSize;	// Now the actual amount of padding to add.
+		}
+
+		// fix rest of the padding according to Unicode unit size.
+		padding /= unicodeSize;
+		
+		int newlineLen = options.getNewline().length();
+		if (padding >= newlineLen)
+		{
+			padding -= newlineLen;	// Write this newline last.
+			while (padding >= (100 + newlineLen))
+			{
+				writeChars(100, ' ');
+				writeNewline();
+				padding -= (100 + newlineLen);
+			}
+			writeChars(padding, ' ');
+			writeNewline();
+		}
+		else
+		{
+			writeChars(padding, ' ');				
+		}
+	}
+
+
+	/**
+	 * Checks if the supplied options are consistent.
+	 * @throws XMPException Thrown if options are conflicting
+	 */
+	protected void checkOptionsConsistence() throws XMPException
+	{
+		if (options.getEncodeUTF16BE() | options.getEncodeUTF16LE())
+		{
+			unicodeSize = 2;
+		}
+
+		if (options.getExactPacketLength())
+		{
+			if (options.getOmitPacketWrapper() | options.getIncludeThumbnailPad())
+			{
+				throw new XMPException("Inconsistent options for exact size serialize",
+						XMPError.BADOPTIONS);
+			}
+			if ((options.getPadding() & (unicodeSize - 1)) != 0)
+			{
+				throw new XMPException("Exact size must be a multiple of the Unicode element",
+						XMPError.BADOPTIONS);
+			}
+		}
+		else if (options.getReadOnlyPacket())
+		{
+			if (options.getOmitPacketWrapper() | options.getIncludeThumbnailPad())
+			{
+				throw new XMPException("Inconsistent options for read-only packet",
+						XMPError.BADOPTIONS);
+			}
+			padding = 0;
+		}
+		else if (options.getOmitPacketWrapper())
+		{
+			if (options.getIncludeThumbnailPad())
+			{
+				throw new XMPException("Inconsistent options for non-packet serialize",
+						XMPError.BADOPTIONS);
+			}
+			padding = 0;
+		}
+		else
+		{
+			if (padding == 0)
+			{
+				padding = DEFAULT_PAD * unicodeSize;
+			}
+			
+			if (options.getIncludeThumbnailPad())
+			{
+				if (!xmp.doesPropertyExist(XMPConst.NS_XMP, "Thumbnails"))
+				{
+					padding += 10000 * unicodeSize;
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * Writes the (optional) packet header and the outer rdf-tags. 
+	 * @return Returns the packet end processing instraction to be written after the padding. 
+	 * @throws IOException Forwarded writer exceptions.
+	 * @throws XMPException 
+	 */
+	private String serializeAsRDF() throws IOException, XMPException
+	{
+		// Write the packet header PI.
+		if (!options.getOmitPacketWrapper())
+		{
+			writeIndent(0);
+			write(PACKET_HEADER);
+			writeNewline();
+		}
+	
+		// Write the xmpmeta element's start tag.
+		writeIndent(0);
+		write(RDF_XMPMETA_START);
+		// Note: this flag can only be set by unit tests
+		if (!options.getOmitVersionAttribute())
+		{	
+			write(XMPMetaFactory.getVersionInfo().getMessage());
+		}	
+		write("\">");
+		writeNewline();
+	
+		// Write the rdf:RDF start tag.
+		writeIndent(1);
+		write(RDF_RDF_START);
+		writeNewline();
+		
+		// Write all of the properties.
+		if (options.getUseCompactFormat())
+		{
+			serializeCompactRDFSchemas();
+		} 
+		else
+		{
+			serializePrettyRDFSchemas();
+		}
+	
+		// Write the rdf:RDF end tag.
+		writeIndent(1);
+		write(RDF_RDF_END);
+		writeNewline();
+	
+		// Write the xmpmeta end tag.
+		writeIndent(0);		
+		write(RDF_XMPMETA_END);
+		writeNewline();
+		
+		// Write the packet trailer PI into the tail string as UTF-8.
+		String tailStr = "";
+		if (!options.getOmitPacketWrapper())
+		{
+			for (int level = options.getBaseIndent(); level > 0; level--)
+			{
+				tailStr += options.getIndent();
+			}
+
+			tailStr += PACKET_TRAILER;
+			tailStr += options.getReadOnlyPacket() ? 'r' : 'w';
+			tailStr += PACKET_TRAILER2;
+		}
+		
+		return tailStr;
+	}
+
+	
+	/**
+	 * Serializes the metadata in pretty-printed manner.
+	 * @throws IOException Forwarded writer exceptions
+	 * @throws XMPException 
+	 */
+	private void serializePrettyRDFSchemas() throws IOException, XMPException
+	{
+		if (xmp.getRoot().getChildrenLength() > 0)
+		{
+			for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext(); )
+			{
+				XMPNode currSchema = (XMPNode) it.next();
+				serializePrettyRDFSchema(currSchema);
+			}
+		}
+		else
+		{
+			writeIndent(2);
+			write(RDF_SCHEMA_START); // Special case an empty XMP object.
+			writeTreeName();
+			write("/>");
+			writeNewline();
+		}		
+	}
+
+
+	/**
+	 * @throws IOException
+	 */
+	private void writeTreeName() throws IOException
+	{
+		write('"');
+		String name = xmp.getRoot().getName();
+		if (name != null)
+		{	
+			appendNodeValue(name, true);
+		}	
+		write('"');
+	}
+	
+	
+	/**
+	 * Serializes the metadata in compact manner.
+	 * @throws IOException Forwarded writer exceptions
+	 * @throws XMPException 
+	 */
+	private void serializeCompactRDFSchemas() throws IOException, XMPException
+	{
+		// Begin the rdf:Description start tag.
+		writeIndent(2);
+		write(RDF_SCHEMA_START);
+		writeTreeName();
+		
+		// Write all necessary xmlns attributes.
+		Set usedPrefixes = new HashSet();
+		usedPrefixes.add("xml");
+		usedPrefixes.add("rdf");
+
+		for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext();)
+		{
+			XMPNode schema = (XMPNode) it.next();
+			declareUsedNamespaces(schema, usedPrefixes, 4);
+		}
+	
+		// Write the top level "attrProps" and close the rdf:Description start tag.
+		boolean allAreAttrs = true;
+		for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext();)
+		{
+			XMPNode schema = (XMPNode) it.next();
+			allAreAttrs &= serializeCompactRDFAttrProps (schema, 3);
+		}
+
+		if (!allAreAttrs)
+		{
+			write('>');
+			writeNewline();
+		}
+		else
+		{
+			write("/>");
+			writeNewline();
+			return;	// ! Done if all properties in all schema are written as attributes.
+		}
+	
+		// Write the remaining properties for each schema.
+		for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext();)
+		{
+			XMPNode schema = (XMPNode) it.next();
+			serializeCompactRDFElementProps (schema, 3);
+		}
+
+		// Write the rdf:Description end tag.
+		writeIndent(2);
+		write(RDF_SCHEMA_END);
+		writeNewline();
+	}
+
+
+	
+	/**
+	 * Write each of the parent's simple unqualified properties as an attribute. Returns true if all
+	 * of the properties are written as attributes.
+	 * 
+	 * @param parentNode the parent property node
+	 * @param indent the current indent level
+	 * @return Returns true if all properties can be rendered as RDF attribute.
+	 * @throws IOException
+	 */
+	private boolean serializeCompactRDFAttrProps(XMPNode parentNode, int indent) throws IOException
+	{
+		boolean allAreAttrs = true;
+	
+		for (Iterator it = parentNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode prop = (XMPNode) it.next();
+		
+			if (canBeRDFAttrProp(prop))
+			{
+				writeNewline();
+				writeIndent(indent);
+				write(prop.getName());
+				write("=\"");
+				appendNodeValue(prop.getValue(), true);
+				write('"');
+			}
+			else
+			{
+				allAreAttrs = false;
+			}
+		}
+		return allAreAttrs;
+	}
+
+	
+	/**
+	 * Recursively handles the "value" for a node that must be written as an RDF
+	 * property element. It does not matter if it is a top level property, a
+	 * field of a struct, or an item of an array. The indent is that for the
+	 * property element. The patterns bwlow ignore attribute qualifiers such as
+	 * xml:lang, they don't affect the output form.
+	 * 
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 *  	&lt;ns:UnqualifiedStructProperty-1
+	 *  		... The fields as attributes, if all are simple and unqualified
+	 *  	/&gt;
+	 *  
+	 *  	&lt;ns:UnqualifiedStructProperty-2 rdf:parseType=&quot;Resource&quot;&gt;
+	 *  		... The fields as elements, if none are simple and unqualified
+	 *  	&lt;/ns:UnqualifiedStructProperty-2&gt;
+	 *  
+	 *  	&lt;ns:UnqualifiedStructProperty-3&gt;
+	 *  		&lt;rdf:Description
+	 *  			... The simple and unqualified fields as attributes
+	 *  		&gt;
+	 *  			... The compound or qualified fields as elements
+	 *  		&lt;/rdf:Description&gt;
+	 *  	&lt;/ns:UnqualifiedStructProperty-3&gt;
+	 *  
+	 *  	&lt;ns:UnqualifiedArrayProperty&gt;
+	 *  		&lt;rdf:Bag&gt; or Seq or Alt
+	 *  			... Array items as rdf:li elements, same forms as top level properties
+	 *  		&lt;/rdf:Bag&gt;
+	 *  	&lt;/ns:UnqualifiedArrayProperty&gt;
+	 *  
+	 *  	&lt;ns:QualifiedProperty rdf:parseType=&quot;Resource&quot;&gt;
+	 *  		&lt;rdf:value&gt; ... Property &quot;value&quot; 
+	 *  			following the unqualified forms ... &lt;/rdf:value&gt;
+	 *  		... Qualifiers looking like named struct fields
+	 *  	&lt;/ns:QualifiedProperty&gt;
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * *** Consider numbered array items, but has compatibility problems. ***
+	 * Consider qualified form with rdf:Description and attributes.
+	 * 
+	 * @param parentNode the parent node
+	 * @param indent the current indent level
+	 * @throws IOException Forwards writer exceptions
+	 * @throws XMPException If qualifier and element fields are mixed.
+	 */
+	private void serializeCompactRDFElementProps(XMPNode parentNode, int indent)
+			throws IOException, XMPException
+	{
+		for (Iterator it = parentNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode node = (XMPNode) it.next();
+			if (canBeRDFAttrProp (node))
+			{	
+				continue;
+			}
+	
+			boolean emitEndTag = true;
+			boolean indentEndTag = true;
+	
+			// Determine the XML element name, write the name part of the start tag. Look over the
+			// qualifiers to decide on "normal" versus "rdf:value" form. Emit the attribute
+			// qualifiers at the same time.
+			String elemName = node.getName();
+			if (XMPConst.ARRAY_ITEM_NAME.equals(elemName))
+			{
+				elemName = "rdf:li";
+			}
+	
+			writeIndent(indent);
+			write('<');
+			write(elemName);
+	
+			boolean hasGeneralQualifiers = false;
+			boolean hasRDFResourceQual   = false;
+	
+			for (Iterator iq = 	node.iterateQualifier(); iq.hasNext();)
+			{
+				XMPNode qualifier = (XMPNode) iq.next();
+				if (!RDF_ATTR_QUALIFIER.contains(qualifier.getName()))
+				{
+					hasGeneralQualifiers = true;
+				}
+				else
+				{
+					hasRDFResourceQual = "rdf:resource".equals(qualifier.getName());
+					write(' ');
+					write(qualifier.getName());
+					write("=\"");
+					appendNodeValue(qualifier.getValue(), true);
+					write('"');
+				}
+			}
+			
+			
+			// Process the property according to the standard patterns.
+			if (hasGeneralQualifiers)
+			{
+				serializeCompactRDFGeneralQualifier(indent, node);
+			}
+			else
+			{
+				// This node has only attribute qualifiers. Emit as a property element.
+				if (!node.getOptions().isCompositeProperty())
+				{
+					Object[] result = serializeCompactRDFSimpleProp(node);
+					emitEndTag = ((Boolean) result[0]).booleanValue();
+					indentEndTag = ((Boolean) result[1]).booleanValue();
+				}
+				else if (node.getOptions().isArray())
+				{
+					serializeCompactRDFArrayProp(node, indent);
+				}
+				else
+				{
+					emitEndTag = serializeCompactRDFStructProp(
+						node, indent, hasRDFResourceQual);
+				}
+	
+			}
+
+			// Emit the property element end tag.
+			if (emitEndTag)
+			{
+				if (indentEndTag)
+				{
+					writeIndent(indent);
+				}
+				write("</");
+				write(elemName);
+				write('>');
+				writeNewline();
+			}
+	
+		}
+	}
+
+
+	/**
+	 * Serializes a simple property.
+	 * 
+	 * @param node an XMPNode 
+	 * @return Returns an array containing the flags emitEndTag and indentEndTag.
+	 * @throws IOException Forwards the writer exceptions.
+	 */
+	private Object[] serializeCompactRDFSimpleProp(XMPNode node) throws IOException
+	{
+		// This is a simple property.
+		Boolean emitEndTag = Boolean.TRUE;
+		Boolean indentEndTag = Boolean.TRUE;		
+
+		if (node.getOptions().isURI())
+		{
+			write(" rdf:resource=\"");
+			appendNodeValue(node.getValue(), true);
+			write("\"/>");
+			writeNewline();
+			emitEndTag = Boolean.FALSE;
+		}
+		else if (node.getValue() == null  ||  node.getValue().length() == 0)
+		{
+			write("/>");
+			writeNewline();
+			emitEndTag = Boolean.FALSE;
+		}
+		else
+		{
+			write('>');
+			appendNodeValue (node.getValue(), false);
+			indentEndTag = Boolean.FALSE;
+		}
+		
+		return new Object[] {emitEndTag, indentEndTag};
+	}
+
+
+	/**
+	 * Serializes an array property.
+	 * 
+	 * @param node an XMPNode 
+	 * @param indent the current indent level 
+	 * @throws IOException Forwards the writer exceptions.
+	 * @throws XMPException If qualifier and element fields are mixed.
+	 */
+	private void serializeCompactRDFArrayProp(XMPNode node, int indent) throws IOException,
+			XMPException
+	{
+		// This is an array.
+		write('>');
+		writeNewline();
+		emitRDFArrayTag (node, true, indent + 1);
+		
+		if (node.getOptions().isArrayAltText())
+		{
+			XMPNodeUtils.normalizeLangArray (node);
+		}
+		
+		serializeCompactRDFElementProps(node, indent + 2);
+		
+		emitRDFArrayTag(node, false, indent + 1);
+	}
+	
+	
+	/**
+	 * Serializes a struct property.
+	 * 
+	 * @param node an XMPNode 
+	 * @param indent the current indent level 
+	 * @param hasRDFResourceQual Flag if the element has resource qualifier
+	 * @return Returns true if an end flag shall be emitted.
+	 * @throws IOException Forwards the writer exceptions.
+	 * @throws XMPException If qualifier and element fields are mixed.
+	 */
+	private boolean serializeCompactRDFStructProp(XMPNode node, int indent,
+			boolean hasRDFResourceQual) throws XMPException, IOException
+	{
+		// This must be a struct.
+		boolean hasAttrFields = false;
+		boolean hasElemFields = false;
+		boolean emitEndTag = true;
+		
+		for (Iterator ic = node.iterateChildren(); ic.hasNext(); )
+		{
+			XMPNode field = (XMPNode) ic.next();
+			if (canBeRDFAttrProp(field))
+			{
+				hasAttrFields = true;
+			}
+			else
+			{
+				hasElemFields = true;
+			}
+
+			if (hasAttrFields  &&  hasElemFields)
+			{
+				break;	// No sense looking further.
+			}
+		}
+		
+		if (hasRDFResourceQual && hasElemFields)
+		{
+			throw new XMPException(
+					"Can't mix rdf:resource qualifier and element fields",
+					XMPError.BADRDF);
+		}
+
+		if (!node.hasChildren())
+		{
+			// Catch an empty struct as a special case. The case
+			// below would emit an empty
+			// XML element, which gets reparsed as a simple property
+			// with an empty value.
+			write(" rdf:parseType=\"Resource\"/>");
+			writeNewline();
+			emitEndTag = false;
+		
+		}
+		else if (!hasElemFields)
+		{
+			// All fields can be attributes, use the
+			// emptyPropertyElt form.
+			serializeCompactRDFAttrProps(node, indent + 1);
+			write("/>");
+			writeNewline();
+			emitEndTag = false;
+
+		}
+		else if (!hasAttrFields)
+		{
+			// All fields must be elements, use the
+			// parseTypeResourcePropertyElt form.
+			write(" rdf:parseType=\"Resource\">");
+			writeNewline();
+			serializeCompactRDFElementProps(node, indent + 1);
+		
+		}
+		else
+		{
+			// Have a mix of attributes and elements, use an inner rdf:Description.
+			write('>');
+			writeNewline();
+			writeIndent(indent + 1);
+			write(RDF_STRUCT_START);
+			serializeCompactRDFAttrProps(node, indent + 2);
+			write(">");
+			writeNewline();
+			serializeCompactRDFElementProps(node, indent + 1);
+			writeIndent(indent + 1);
+			write(RDF_STRUCT_END);
+			writeNewline();
+		}
+		return emitEndTag;
+	}
+
+
+	/**
+	 * Serializes the general qualifier.  
+	 * @param node the root node of the subtree
+	 * @param indent the current indent level
+	 * @throws IOException Forwards all writer exceptions.
+	 * @throws XMPException If qualifier and element fields are mixed.
+	 */
+	private void serializeCompactRDFGeneralQualifier(int indent, XMPNode node)
+			throws IOException, XMPException
+	{
+		// The node has general qualifiers, ones that can't be
+		// attributes on a property element.
+		// Emit using the qualified property pseudo-struct form. The
+		// value is output by a call
+		// to SerializePrettyRDFProperty with emitAsRDFValue set.
+		write(" rdf:parseType=\"Resource\">");
+		writeNewline();
+
+		serializePrettyRDFProperty(node, true, indent + 1);
+
+		for (Iterator iq = 	node.iterateQualifier(); iq.hasNext();)
+		{
+			XMPNode qualifier = (XMPNode) iq.next();
+			serializePrettyRDFProperty(qualifier, false, indent + 1);
+		}
+	}
+
+
+	/**
+	 * Serializes one schema with all contained properties in pretty-printed
+	 * manner.<br> 
+	 * Each schema's properties are written in a separate
+	 * rdf:Description element. All of the necessary namespaces are declared in
+	 * the rdf:Description element. The baseIndent is the base level for the
+	 * entire serialization, that of the x:xmpmeta element. An xml:lang
+	 * qualifier is written as an attribute of the property start tag, not by
+	 * itself forcing the qualified property form.
+	 * 
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 *  	 &lt;rdf:Description rdf:about=&quot;TreeName&quot; xmlns:ns=&quot;URI&quot; ... &gt;
+	 *  
+	 *  	 	... The actual properties of the schema, see SerializePrettyRDFProperty
+	 *  
+	 *  	 	&lt;!-- ns1:Alias is aliased to ns2:Actual --&gt;  ... If alias comments are wanted
+	 *  
+	 *  	 &lt;/rdf:Description&gt;
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * @param schemaNode a schema node
+	 * @throws IOException Forwarded writer exceptions
+	 * @throws XMPException 
+	 */
+	private void serializePrettyRDFSchema(XMPNode schemaNode) throws IOException, XMPException
+	{
+		writeIndent(2);
+		write(RDF_SCHEMA_START);
+		writeTreeName();
+		
+		Set usedPrefixes = new HashSet();
+		usedPrefixes.add("xml");
+		usedPrefixes.add("rdf");
+
+		declareUsedNamespaces(schemaNode, usedPrefixes, 4);
+	
+		write('>');
+		writeNewline();
+		
+		// Write each of the schema's actual properties.
+		for (Iterator it = schemaNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode propNode = (XMPNode) it.next();
+			serializePrettyRDFProperty(propNode, false, 3);
+		}
+		
+		// Write the rdf:Description end tag.
+		writeIndent(2);
+		write(RDF_SCHEMA_END);
+		writeNewline();
+	}
+
+
+	/** 
+	 * Writes all used namespaces of the subtree in node to the output. 
+	 * The subtree is recursivly traversed.
+	 * @param node the root node of the subtree
+	 * @param usedPrefixes a set containing currently used prefixes
+	 * @param indent the current indent level
+	 * @throws IOException Forwards all writer exceptions.
+	 */
+	private void declareUsedNamespaces(XMPNode node, Set usedPrefixes, int indent)
+			throws IOException
+	{
+		if (node.getOptions().isSchemaNode())
+		{
+			// The schema node name is the URI, the value is the prefix.
+			String prefix = node.getValue().substring(0, node.getValue().length() - 1);
+			declareNamespace(prefix, node.getName(), usedPrefixes, indent);
+		}
+		else if (node.getOptions().isStruct())
+		{
+			for (Iterator it = node.iterateChildren(); it.hasNext();)
+			{
+				XMPNode field = (XMPNode) it.next();
+				declareNamespace(field.getName(), null, usedPrefixes, indent);
+			}
+		}
+	
+		for (Iterator it = node.iterateChildren(); it.hasNext();)
+		{
+			XMPNode child = (XMPNode) it.next();
+			declareUsedNamespaces(child, usedPrefixes, indent);
+		}
+
+		for (Iterator it = node.iterateQualifier(); it.hasNext();)
+		{
+			XMPNode qualifier = (XMPNode) it.next();
+			declareNamespace(qualifier.getName(), null, usedPrefixes, indent);
+			declareUsedNamespaces(qualifier, usedPrefixes, indent);
+		}
+	}
+	
+	
+	/**
+	 * Writes one namespace declaration to the output.
+	 * @param prefix a namespace prefix (without colon) or a complete qname (when namespace == null)
+	 * @param namespace the a namespace
+	 * @param usedPrefixes a set containing currently used prefixes
+	 * @param indent the current indent level
+	 * @throws IOException Forwards all writer exceptions.
+	 */
+	private void declareNamespace(String prefix, String namespace, Set usedPrefixes, int indent)
+			throws IOException
+	{
+		if (namespace == null)
+		{
+			// prefix contains qname, extract prefix and lookup namespace with prefix
+			QName qname = new QName(prefix);
+			if (qname.hasPrefix())
+			{
+				prefix = qname.getPrefix();
+				// add colon for lookup
+				namespace = XMPMetaFactory.getSchemaRegistry().getNamespaceURI(prefix + ":");
+				// prefix w/o colon
+				declareNamespace(prefix, namespace, usedPrefixes, indent);
+			}
+			else
+			{
+				return;
+			}
+		}
+		
+		if (!usedPrefixes.contains(prefix))
+		{
+			writeNewline();
+			writeIndent(indent);
+			write("xmlns:");
+			write(prefix);
+			write("=\"");
+			write(namespace);
+			write('"');
+			usedPrefixes.add(prefix);
+		}
+	}
+
+
+	/**
+	 * Recursively handles the "value" for a node. It does not matter if it is a
+	 * top level property, a field of a struct, or an item of an array. The
+	 * indent is that for the property element. An xml:lang qualifier is written
+	 * as an attribute of the property start tag, not by itself forcing the
+	 * qualified property form. The patterns below mostly ignore attribute
+	 * qualifiers like xml:lang. Except for the one struct case, attribute
+	 * qualifiers don't affect the output form.
+	 * 
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * 	&lt;ns:UnqualifiedSimpleProperty&gt;value&lt;/ns:UnqualifiedSimpleProperty&gt;
+	 * 
+	 * 	&lt;ns:UnqualifiedStructProperty rdf:parseType=&quot;Resource&quot;&gt;	
+	 * 		(If no rdf:resource qualifier)
+	 * 		... Fields, same forms as top level properties
+	 * 	&lt;/ns:UnqualifiedStructProperty&gt;
+	 * 
+	 * 	&lt;ns:ResourceStructProperty rdf:resource=&quot;URI&quot;
+	 * 		... Fields as attributes
+	 * 	&gt;
+	 * 
+	 * 	&lt;ns:UnqualifiedArrayProperty&gt;
+	 * 		&lt;rdf:Bag&gt; or Seq or Alt
+	 * 			... Array items as rdf:li elements, same forms as top level properties
+	 * 		&lt;/rdf:Bag&gt;
+	 * 	&lt;/ns:UnqualifiedArrayProperty&gt;
+	 * 
+	 * 	&lt;ns:QualifiedProperty rdf:parseType=&quot;Resource&quot;&gt;
+	 * 		&lt;rdf:value&gt; ... Property &quot;value&quot; following the unqualified 
+	 * 			forms ... &lt;/rdf:value&gt;
+	 * 		... Qualifiers looking like named struct fields
+	 * 	&lt;/ns:QualifiedProperty&gt;
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * @param node the property node
+	 * @param emitAsRDFValue property shall be renderes as attribute rather than tag
+	 * @param indent the current indent level
+	 * @throws IOException Forwards all writer exceptions.
+	 * @throws XMPException If &quot;rdf:resource&quot; and general qualifiers are mixed.
+	 */
+	private void serializePrettyRDFProperty(XMPNode node, boolean emitAsRDFValue, int indent)
+			throws IOException, XMPException
+	{
+		boolean emitEndTag   = true;
+		boolean indentEndTag = true;
+	
+		// Determine the XML element name. Open the start tag with the name and
+		// attribute qualifiers.
+		
+		String elemName = node.getName();
+		if (emitAsRDFValue)
+		{
+			elemName = "rdf:value";
+		}
+		else if (XMPConst.ARRAY_ITEM_NAME.equals(elemName))
+		{
+			elemName = "rdf:li";
+		}
+	
+		writeIndent(indent);
+		write('<');
+		write(elemName);
+		
+		boolean hasGeneralQualifiers = false;
+		boolean hasRDFResourceQual   = false;
+		
+		for (Iterator it = node.iterateQualifier(); it.hasNext();)
+		{
+			XMPNode qualifier = (XMPNode) it.next();
+			if (!RDF_ATTR_QUALIFIER.contains(qualifier.getName()))
+			{
+				hasGeneralQualifiers = true;
+			}
+			else
+			{
+				hasRDFResourceQual = "rdf:resource".equals(qualifier.getName());
+				if (!emitAsRDFValue)
+				{
+					write(' ');
+					write(qualifier.getName());
+					write("=\"");
+					appendNodeValue(qualifier.getValue(), true);
+					write('"');
+				}
+			}
+		}
+		
+		// Process the property according to the standard patterns.
+		
+		if (hasGeneralQualifiers &&  !emitAsRDFValue)
+		{
+			// This node has general, non-attribute, qualifiers. Emit using the
+			// qualified property form.
+			// ! The value is output by a recursive call ON THE SAME NODE with
+			// emitAsRDFValue set.
+	
+			if (hasRDFResourceQual)
+			{
+				throw new XMPException("Can't mix rdf:resource and general qualifiers",
+						XMPError.BADRDF);
+			}
+			
+			write(" rdf:parseType=\"Resource\">");
+			writeNewline();
+	
+			serializePrettyRDFProperty(node, true, indent + 1);
+			
+			for (Iterator it = node.iterateQualifier(); it.hasNext();)
+			{
+				XMPNode qualifier = (XMPNode) it.next();
+				if (!RDF_ATTR_QUALIFIER.contains(qualifier.getName()))
+				{
+					serializePrettyRDFProperty(qualifier, false, indent + 1);
+				}
+			}
+		}
+		else
+		{
+			// This node has no general qualifiers. Emit using an unqualified form.
+			
+			if (!node.getOptions().isCompositeProperty())
+			{
+				// This is a simple property.
+				
+				if (node.getOptions().isURI())
+				{
+					write(" rdf:resource=\"");
+					appendNodeValue(node.getValue(), true);
+					write("\"/>");
+					writeNewline();
+					emitEndTag = false;
+				}
+				else if (node.getValue() == null ||  "".equals(node.getValue()))
+				{
+					write("/>");
+					writeNewline();
+					emitEndTag = false;
+				} 
+				else
+				{
+					write('>');
+					appendNodeValue(node.getValue(), false);
+					indentEndTag = false;
+				}
+			}
+			else if (node.getOptions().isArray())
+			{
+				// This is an array.
+				write('>');
+				writeNewline();
+				emitRDFArrayTag(node, true, indent + 1);
+				if (node.getOptions().isArrayAltText())
+				{
+					XMPNodeUtils.normalizeLangArray(node);
+				}
+				for (Iterator it = node.iterateChildren(); it.hasNext();)
+				{
+					XMPNode child = (XMPNode) it.next();
+					serializePrettyRDFProperty(child, false, indent + 2);
+				}
+				emitRDFArrayTag(node, false, indent + 1);
+			
+			
+			} 
+			else if (!hasRDFResourceQual)
+			{
+				// This is a "normal" struct, use the rdf:parseType="Resource" form.
+				if (!node.hasChildren())
+				{
+					write(" rdf:parseType=\"Resource\"/>");
+					writeNewline();
+					emitEndTag = false;
+				}
+				else
+				{
+					write(" rdf:parseType=\"Resource\">");
+					writeNewline();
+					for (Iterator it = node.iterateChildren(); it.hasNext();)
+					{
+						XMPNode child = (XMPNode) it.next();
+						serializePrettyRDFProperty(child, false, indent + 1);
+					}
+				}
+			}
+			else
+			{
+				// This is a struct with an rdf:resource attribute, use the
+				// "empty property element" form.
+				for (Iterator it = node.iterateChildren(); it.hasNext();)
+				{
+					XMPNode child = (XMPNode) it.next();
+					if (!canBeRDFAttrProp(child))
+					{
+						throw new XMPException("Can't mix rdf:resource and complex fields",
+								XMPError.BADRDF);
+					}
+					writeNewline();
+					writeIndent(indent + 1);
+					write(' ');
+					write(child.getName());
+					write("=\"");
+					appendNodeValue(child.getValue(), true);
+					write('"');
+				}
+				write("/>");
+				writeNewline();
+				emitEndTag = false;
+			}
+		}
+		
+		// Emit the property element end tag.
+		if (emitEndTag)
+		{
+			if (indentEndTag) 
+			{
+				writeIndent(indent);
+			}
+			write("</");
+			write(elemName);
+			write('>');
+			writeNewline();
+		}		
+	}
+
+	
+	/**
+	 * Writes the array start and end tags.
+	 *  
+	 * @param arrayNode an array node
+	 * @param isStartTag flag if its the start or end tag
+	 * @param indent the current indent level
+	 * @throws IOException forwards writer exceptions
+	 */
+	private void emitRDFArrayTag(XMPNode arrayNode, boolean isStartTag, int indent) 
+		throws IOException
+	{
+		if (isStartTag  ||  arrayNode.hasChildren())
+		{
+			writeIndent(indent);
+			write(isStartTag ? "<rdf:" : "</rdf:");
+		
+			if (arrayNode.getOptions().isArrayAlternate())
+			{
+				write("Alt");
+			} 
+			else if (arrayNode.getOptions().isArrayOrdered())
+			{
+				write("Seq");
+			}
+			else
+			{
+				write("Bag");
+			}
+		
+			if (isStartTag && !arrayNode.hasChildren())
+			{
+				write("/>");
+			}
+			else
+			{
+				write(">");
+			}
+			
+			writeNewline();
+		}	
+	}
+
+
+	/**
+	 * Serializes the node value in XML encoding. Its used for tag bodies and
+	 * attributes. <em>Note:</em> The attribute is always limited by quotes,
+	 * thats why <code>&amp;apos;</code> is never serialized. <em>Note:</em>
+	 * Control chars are written unescaped, but if the user uses others than tab, LF
+	 * and CR the resulting XML will become invalid.
+	 * 
+	 * @param value the value of the node
+	 * @param forAttribute flag if value is an attribute value
+	 * @throws IOException
+	 */
+	private void appendNodeValue(String value, boolean forAttribute) throws IOException
+	{
+		write (Utils.escapeXML(value, forAttribute, true));
+	}
+	
+	
+	/**
+	 * A node can be serialized as RDF-Attribute, if it meets the following conditions:
+	 * <ul>
+	 *  	<li>is not array item
+	 * 		<li>don't has qualifier
+	 * 		<li>is no URI
+	 * 		<li>is no composite property
+	 * </ul> 
+	 * 
+	 * @param node an XMPNode
+	 * @return Returns true if the node serialized as RDF-Attribute
+	 */
+	private boolean canBeRDFAttrProp(XMPNode node)
+	{
+		return
+			!node.hasQualifier()  &&
+			!node.getOptions().isURI()  &&
+			!node.getOptions().isCompositeProperty()  &&
+			!XMPConst.ARRAY_ITEM_NAME.equals(node.getName());
+	}
+
+
+	/**
+	 * Writes indents and automatically includes the baseindend from the options. 
+	 * @param times number of indents to write
+	 * @throws IOException forwards exception
+	 */
+	private void writeIndent(int times) throws IOException
+	{
+		for (int i = options.getBaseIndent() + times; i > 0; i--)
+		{
+			writer.write(options.getIndent());
+		}
+	}
+	
+	
+	/**
+	 * Writes a char to the output.
+	 * @param c a char
+	 * @throws IOException forwards writer exceptions
+	 */
+	private void write(int c) throws IOException
+	{
+		writer.write(c);
+	}
+	
+	
+	/**
+	 * Writes a String to the output.
+	 * @param str a String
+	 * @throws IOException forwards writer exceptions
+	 */
+	private void write(String str) throws IOException
+	{
+		writer.write(str);
+	}
+	
+	
+	/**
+	 * Writes an amount of chars, mostly spaces
+	 * @param number number of chars
+	 * @param c a char
+	 * @throws IOException
+	 */
+	private void writeChars(int number, char c) throws IOException
+	{
+		for (; number > 0; number--)
+		{
+			writer.write(c);
+		}
+	}
+	
+	
+	/**
+	 * Writes a newline according to the options.
+	 * @throws IOException Forwards exception
+	 */
+	private void writeNewline() throws IOException
+	{
+		writer.write(options.getNewline());
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/XMPUtilsImpl.java b/XMPCore/src/com/adobe/xmp/impl/XMPUtilsImpl.java
new file mode 100644
index 0000000..ab36996
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/XMPUtilsImpl.java
@@ -0,0 +1,1170 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+
+
+package com.adobe.xmp.impl;
+
+import java.util.Iterator;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.XMPUtils;
+import com.adobe.xmp.impl.xpath.XMPPath;
+import com.adobe.xmp.impl.xpath.XMPPathParser;
+import com.adobe.xmp.options.PropertyOptions;
+import com.adobe.xmp.properties.XMPAliasInfo;
+
+
+
+/**
+ * @since 11.08.2006
+ */
+public class XMPUtilsImpl implements XMPConst
+{
+	/** */
+	private static final int UCK_NORMAL = 0;
+	/** */
+	private static final int UCK_SPACE = 1;
+	/** */
+	private static final int UCK_COMMA = 2;
+	/** */
+	private static final int UCK_SEMICOLON = 3;
+	/** */
+	private static final int UCK_QUOTE = 4;
+	/** */
+	private static final int UCK_CONTROL = 5;
+
+
+	/**
+	 * Private constructor, as
+	 */
+	private XMPUtilsImpl()
+	{
+		// EMPTY
+	}
+
+
+	/**
+	 * @see XMPUtils#catenateArrayItems(XMPMeta, String, String, String, String,
+	 *      boolean)
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the array to be catenated.
+	 * @param schemaNS
+	 *            The schema namespace URI for the array. Must not be null or
+	 *            the empty string.
+	 * @param arrayName
+	 *            The name of the array. May be a general path expression, must
+	 *            not be null or the empty string. Each item in the array must
+	 *            be a simple string value.
+	 * @param separator
+	 *            The string to be used to separate the items in the catenated
+	 *            string. Defaults to &quot;; &quot;, ASCII semicolon and space
+	 *            (U+003B, U+0020).
+	 * @param quotes
+	 *            The characters to be used as quotes around array items that
+	 *            contain a separator. Defaults to &apos;&quot;&apos;
+	 * @param allowCommas
+	 *            Option flag to control the catenation.
+	 * @return Returns the string containing the catenated array items.
+	 * @throws XMPException
+	 *             Forwards the Exceptions from the metadata processing
+	 */
+	public static String catenateArrayItems(XMPMeta xmp, String schemaNS, String arrayName,
+			String separator, String quotes, boolean allowCommas) throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+		ParameterAsserts.assertImplementation(xmp);
+		if (separator == null  ||  separator.length() == 0)
+		{
+			separator = "; ";	
+		}
+		if (quotes == null  ||  quotes.length() == 0)
+		{	
+			quotes = "\"";
+		}
+		
+		XMPMetaImpl xmpImpl = (XMPMetaImpl) xmp;
+		XMPNode arrayNode = null;
+		XMPNode currItem = null;
+
+		// Return an empty result if the array does not exist, 
+		// hurl if it isn't the right form.
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+		arrayNode = XMPNodeUtils.findNode(xmpImpl.getRoot(), arrayPath, false, null);
+		if (arrayNode == null)
+		{
+			return "";
+		}
+		else if (!arrayNode.getOptions().isArray() || arrayNode.getOptions().isArrayAlternate())
+		{
+			throw new XMPException("Named property must be non-alternate array", XMPError.BADPARAM);
+		}
+
+		// Make sure the separator is OK.
+		checkSeparator(separator);
+		// Make sure the open and close quotes are a legitimate pair.
+		char openQuote = quotes.charAt(0);
+		char closeQuote = checkQuotes(quotes, openQuote);
+
+		// Build the result, quoting the array items, adding separators.
+		// Hurl if any item isn't simple.
+
+		StringBuffer catinatedString = new StringBuffer();
+
+		for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
+		{
+			currItem = (XMPNode) it.next();
+			if (currItem.getOptions().isCompositeProperty())
+			{
+				throw new XMPException("Array items must be simple", XMPError.BADPARAM);
+			}
+			String str = applyQuotes(currItem.getValue(), openQuote, closeQuote, allowCommas);
+
+			catinatedString.append(str);
+			if (it.hasNext())
+			{
+				catinatedString.append(separator);
+			}
+		}
+
+		return catinatedString.toString();
+	}
+
+
+	/**
+	 * see {@link XMPUtils#separateArrayItems(XMPMeta, String, String, String, 
+	 * PropertyOptions, boolean)}
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the array to be updated.
+	 * @param schemaNS
+	 *            The schema namespace URI for the array. Must not be null or
+	 *            the empty string.
+	 * @param arrayName
+	 *            The name of the array. May be a general path expression, must
+	 *            not be null or the empty string. Each item in the array must
+	 *            be a simple string value.
+	 * @param catedStr
+	 *            The string to be separated into the array items.
+	 * @param arrayOptions
+	 *            Option flags to control the separation.
+	 * @param preserveCommas
+	 *            Flag if commas shall be preserved
+	 * 
+	 * @throws XMPException
+	 *             Forwards the Exceptions from the metadata processing
+	 */
+	public static void separateArrayItems(XMPMeta xmp, String schemaNS, String arrayName,
+			String catedStr, PropertyOptions arrayOptions, boolean preserveCommas)
+			throws XMPException
+	{
+		ParameterAsserts.assertSchemaNS(schemaNS);
+		ParameterAsserts.assertArrayName(arrayName);
+		if (catedStr == null)
+		{
+			throw new XMPException("Parameter must not be null", XMPError.BADPARAM);
+		}
+		ParameterAsserts.assertImplementation(xmp);
+		XMPMetaImpl xmpImpl = (XMPMetaImpl) xmp;
+
+		// Keep a zero value, has special meaning below.
+		XMPNode arrayNode = separateFindCreateArray(schemaNS, arrayName, arrayOptions, xmpImpl);
+
+		// Extract the item values one at a time, until the whole input string is done.
+		String itemValue;
+		int itemStart, itemEnd;
+		int nextKind = UCK_NORMAL, charKind = UCK_NORMAL;
+		char ch = 0, nextChar = 0;
+		
+		itemEnd = 0;
+		int endPos = catedStr.length();
+		while (itemEnd < endPos)
+		{
+			// Skip any leading spaces and separation characters. Always skip commas here.
+			// They can be kept when within a value, but not when alone between values.
+			for (itemStart = itemEnd; itemStart < endPos; itemStart++)
+			{
+				ch = catedStr.charAt(itemStart);
+				charKind = classifyCharacter(ch);
+				if (charKind == UCK_NORMAL || charKind == UCK_QUOTE)
+				{
+					break;
+				}
+			}
+			if (itemStart >= endPos)
+			{
+				break;
+			}
+
+			if (charKind != UCK_QUOTE)
+			{
+				// This is not a quoted value. Scan for the end, create an array
+				// item from the substring.
+				for (itemEnd = itemStart; itemEnd < endPos; itemEnd++)
+				{
+					ch = catedStr.charAt(itemEnd);
+					charKind = classifyCharacter(ch);
+
+					if (charKind == UCK_NORMAL || charKind == UCK_QUOTE  ||
+						(charKind == UCK_COMMA && preserveCommas))
+					{
+						continue;
+					}
+					else if (charKind != UCK_SPACE)
+					{
+						break;
+					}
+					else if ((itemEnd + 1) < endPos)
+					{
+						ch = catedStr.charAt(itemEnd + 1);
+						nextKind = classifyCharacter(ch);
+						if (nextKind == UCK_NORMAL  ||  nextKind == UCK_QUOTE  ||
+							(nextKind == UCK_COMMA && preserveCommas))
+						{
+							continue;
+						}
+					}
+					
+					// Anything left?
+					break; // Have multiple spaces, or a space followed by a
+							// separator.
+				}
+				itemValue = catedStr.substring(itemStart, itemEnd);
+			}
+			else
+			{
+				// Accumulate quoted values into a local string, undoubling
+				// internal quotes that
+				// match the surrounding quotes. Do not undouble "unmatching"
+				// quotes.
+
+				char openQuote = ch;
+				char closeQuote = getClosingQuote(openQuote);
+
+				itemStart++; // Skip the opening quote;
+				itemValue = "";
+
+				for (itemEnd = itemStart; itemEnd < endPos; itemEnd++)
+				{
+					ch = catedStr.charAt(itemEnd);
+					charKind = classifyCharacter(ch);
+
+					if (charKind != UCK_QUOTE || !isSurroundingQuote(ch, openQuote, closeQuote))
+					{
+						// This is not a matching quote, just append it to the
+						// item value.
+						itemValue += ch;
+					}
+					else
+					{
+						// This is a "matching" quote. Is it doubled, or the
+						// final closing quote?
+						// Tolerate various edge cases like undoubled opening
+						// (non-closing) quotes,
+						// or end of input.
+
+						if ((itemEnd + 1) < endPos)
+						{
+							nextChar = catedStr.charAt(itemEnd + 1);
+							nextKind = classifyCharacter(nextChar);
+						}
+						else
+						{
+							nextKind = UCK_SEMICOLON;
+							nextChar = 0x3B;
+						}
+
+						if (ch == nextChar)
+						{
+							// This is doubled, copy it and skip the double.
+							itemValue += ch;
+							// Loop will add in charSize.
+							itemEnd++;
+						}
+						else if (!isClosingingQuote(ch, openQuote, closeQuote))
+						{
+							// This is an undoubled, non-closing quote, copy it.
+							itemValue += ch;
+						}
+						else
+						{
+							// This is an undoubled closing quote, skip it and
+							// exit the loop.
+							itemEnd++;
+							break;
+						}
+					}
+				}
+			}
+
+			// Add the separated item to the array. 
+			// Keep a matching old value in case it had separators.
+			int foundIndex = -1;
+			for (int oldChild = 1; oldChild <= arrayNode.getChildrenLength(); oldChild++)
+			{
+				if (itemValue.equals(arrayNode.getChild(oldChild).getValue()))
+				{
+					foundIndex = oldChild;
+					break;
+				}
+			}
+
+			XMPNode newItem = null;
+			if (foundIndex < 0)
+			{
+				newItem = new XMPNode(ARRAY_ITEM_NAME, itemValue, null);
+				arrayNode.addChild(newItem);
+			}			
+		}
+	}
+
+	
+	/**
+	 * Utility to find or create the array used by <code>separateArrayItems()</code>.
+	 * @param schemaNS a the namespace fo the array
+	 * @param arrayName the name of the array 
+	 * @param arrayOptions the options for the array if newly created
+	 * @param xmp the xmp object
+	 * @return Returns the array node.
+	 * @throws XMPException Forwards exceptions
+	 */
+	private static XMPNode separateFindCreateArray(String schemaNS, String arrayName,
+			PropertyOptions arrayOptions, XMPMetaImpl xmp) throws XMPException
+	{
+		arrayOptions = XMPNodeUtils.verifySetOptions(arrayOptions, null);
+		if (!arrayOptions.isOnlyArrayOptions())
+		{
+			throw new XMPException("Options can only provide array form", XMPError.BADOPTIONS);
+		}
+
+		// Find the array node, make sure it is OK. Move the current children
+		// aside, to be readded later if kept.
+		XMPPath arrayPath = XMPPathParser.expandXPath(schemaNS, arrayName);
+		XMPNode arrayNode = XMPNodeUtils.findNode(xmp.getRoot(), arrayPath, false, null);
+		if (arrayNode != null)
+		{
+			// The array exists, make sure the form is compatible. Zero
+			// arrayForm means take what exists.
+			PropertyOptions arrayForm = arrayNode.getOptions();
+			if (!arrayForm.isArray() || arrayForm.isArrayAlternate())
+			{
+				throw new XMPException("Named property must be non-alternate array", 
+					XMPError.BADXPATH);
+			}
+			if (arrayOptions.equalArrayTypes(arrayForm))
+			{
+				throw new XMPException("Mismatch of specified and existing array form",
+						XMPError.BADXPATH); // *** Right error?
+			}
+		}
+		else
+		{
+			// The array does not exist, try to create it.
+			// don't modify the options handed into the method
+			arrayNode = XMPNodeUtils.findNode(xmp.getRoot(), arrayPath, true, arrayOptions
+					.setArray(true));
+			if (arrayNode == null)
+			{
+				throw new XMPException("Failed to create named array", XMPError.BADXPATH);
+			}
+		}
+		return arrayNode;
+	}
+
+
+	/**
+	 * @see XMPUtils#removeProperties(XMPMeta, String, String, boolean, boolean)
+	 * 
+	 * @param xmp
+	 *            The XMP object containing the properties to be removed.
+	 * 
+	 * @param schemaNS
+	 *            Optional schema namespace URI for the properties to be
+	 *            removed.
+	 * 
+	 * @param propName
+	 *            Optional path expression for the property to be removed.
+	 * 
+	 * @param doAllProperties
+	 *            Option flag to control the deletion: do internal properties in
+	 *            addition to external properties.
+	 * @param includeAliases
+	 *            Option flag to control the deletion: Include aliases in the
+	 *            "named schema" case above.
+	 * @throws XMPException If metadata processing fails
+	 */
+	public static void removeProperties(XMPMeta xmp, String schemaNS, String propName,
+			boolean doAllProperties, boolean includeAliases) throws XMPException
+	{
+		ParameterAsserts.assertImplementation(xmp);
+		XMPMetaImpl xmpImpl = (XMPMetaImpl) xmp;
+
+		if (propName != null && propName.length() > 0)
+		{
+			// Remove just the one indicated property. This might be an alias,
+			// the named schema might not actually exist. So don't lookup the
+			// schema node.
+
+			if (schemaNS == null || schemaNS.length() == 0)
+			{
+				throw new XMPException("Property name requires schema namespace", 
+					XMPError.BADPARAM);
+			}
+
+			XMPPath expPath = XMPPathParser.expandXPath(schemaNS, propName);
+
+			XMPNode propNode = XMPNodeUtils.findNode(xmpImpl.getRoot(), expPath, false, null);
+			if (propNode != null)
+			{
+				if (doAllProperties
+						|| !Utils.isInternalProperty(expPath.getSegment(XMPPath.STEP_SCHEMA)
+								.getName(), expPath.getSegment(XMPPath.STEP_ROOT_PROP).getName()))
+				{
+					XMPNode parent = propNode.getParent();
+					parent.removeChild(propNode);
+					if (parent.getOptions().isSchemaNode()  &&  !parent.hasChildren())
+					{
+						// remove empty schema node
+						parent.getParent().removeChild(parent);
+					}
+						
+				}
+			}
+		}
+		else if (schemaNS != null && schemaNS.length() > 0)
+		{
+
+			// Remove all properties from the named schema. Optionally include
+			// aliases, in which case
+			// there might not be an actual schema node.
+
+			// XMP_NodePtrPos schemaPos;
+			XMPNode schemaNode = XMPNodeUtils.findSchemaNode(xmpImpl.getRoot(), schemaNS, false);
+			if (schemaNode != null)
+			{
+				if (removeSchemaChildren(schemaNode, doAllProperties))
+				{
+					xmpImpl.getRoot().removeChild(schemaNode);
+				}
+			}
+
+			if (includeAliases)
+			{
+				// We're removing the aliases also. Look them up by their
+				// namespace prefix.
+				// But that takes more code and the extra speed isn't worth it.
+				// Lookup the XMP node
+				// from the alias, to make sure the actual exists.
+
+				XMPAliasInfo[] aliases = XMPMetaFactory.getSchemaRegistry().findAliases(schemaNS);
+				for (int i = 0; i < aliases.length; i++)
+				{
+					XMPAliasInfo info = aliases[i];
+					XMPPath path = XMPPathParser.expandXPath(info.getNamespace(), info
+							.getPropName());
+					XMPNode actualProp = XMPNodeUtils
+							.findNode(xmpImpl.getRoot(), path, false, null);
+					if (actualProp != null)
+					{
+						XMPNode parent = actualProp.getParent();
+						parent.removeChild(actualProp);
+					}
+				}
+			}
+		}
+		else
+		{
+			// Remove all appropriate properties from all schema. In this case
+			// we don't have to be
+			// concerned with aliases, they are handled implicitly from the
+			// actual properties.
+			for (Iterator it = xmpImpl.getRoot().iterateChildren(); it.hasNext();)
+			{
+				XMPNode schema = (XMPNode) it.next();
+				if (removeSchemaChildren(schema, doAllProperties))
+				{
+					it.remove();
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * @see XMPUtils#appendProperties(XMPMeta, XMPMeta, boolean, boolean)
+	 * @param source The source XMP object.
+	 * @param destination The destination XMP object.
+	 * @param doAllProperties Do internal properties in addition to external properties.
+	 * @param replaceOldValues Replace the values of existing properties.
+	 * @param deleteEmptyValues Delete destination values if source property is empty. 
+	 * @throws XMPException Forwards the Exceptions from the metadata processing
+	 */
+	public static void appendProperties(XMPMeta source, XMPMeta destination,
+			boolean doAllProperties, boolean replaceOldValues, boolean deleteEmptyValues) 
+		throws XMPException
+	{
+		ParameterAsserts.assertImplementation(source);
+		ParameterAsserts.assertImplementation(destination);
+
+		XMPMetaImpl src = (XMPMetaImpl) source;
+		XMPMetaImpl dest = (XMPMetaImpl) destination;
+
+		for (Iterator it = src.getRoot().iterateChildren(); it.hasNext();)
+		{
+			XMPNode sourceSchema = (XMPNode) it.next();
+			
+			// Make sure we have a destination schema node
+			XMPNode destSchema = XMPNodeUtils.findSchemaNode(dest.getRoot(),
+					sourceSchema.getName(), false);
+			boolean createdSchema = false;
+			if (destSchema == null)
+			{
+				destSchema = new XMPNode(sourceSchema.getName(), sourceSchema.getValue(),
+						new PropertyOptions().setSchemaNode(true));
+				dest.getRoot().addChild(destSchema);
+				createdSchema = true;
+			}
+
+			// Process the source schema's children.			
+			for (Iterator ic = sourceSchema.iterateChildren(); ic.hasNext();)
+			{
+				XMPNode sourceProp = (XMPNode) ic.next();
+				if (doAllProperties
+						|| !Utils.isInternalProperty(sourceSchema.getName(), sourceProp.getName()))
+				{
+					appendSubtree(
+						dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues);
+				}
+			}
+
+			if (!destSchema.hasChildren()  &&  (createdSchema  ||  deleteEmptyValues))
+			{
+				// Don't create an empty schema / remove empty schema.
+				dest.getRoot().removeChild(destSchema);
+			}
+		}
+	}
+
+
+	/**
+	 * Remove all schema children according to the flag
+	 * <code>doAllProperties</code>. Empty schemas are automatically remove
+	 * by <code>XMPNode</code>
+	 * 
+	 * @param schemaNode
+	 *            a schema node
+	 * @param doAllProperties
+	 *            flag if all properties or only externals shall be removed.
+	 * @return Returns true if the schema is empty after the operation.
+	 */
+	private static boolean removeSchemaChildren(XMPNode schemaNode, boolean doAllProperties)
+	{
+		for (Iterator it = schemaNode.iterateChildren(); it.hasNext();)
+		{
+			XMPNode currProp = (XMPNode) it.next();
+			if (doAllProperties
+					|| !Utils.isInternalProperty(schemaNode.getName(), currProp.getName()))
+			{
+				it.remove();
+			}
+		}
+		
+		return !schemaNode.hasChildren();
+	}
+
+
+	/**
+	 * @see XMPUtilsImpl#appendProperties(XMPMeta, XMPMeta, boolean, boolean, boolean)
+	 * @param destXMP The destination XMP object.
+	 * @param sourceNode the source node
+	 * @param destParent the parent of the destination node
+	 * @param replaceOldValues Replace the values of existing properties.
+	 * @param deleteEmptyValues flag if properties with empty values should be deleted 
+	 * 		   in the destination object.
+	 * @throws XMPException
+	 */
+	private static void appendSubtree(XMPMetaImpl destXMP, XMPNode sourceNode, XMPNode destParent,
+			boolean replaceOldValues, boolean deleteEmptyValues) throws XMPException
+	{
+		XMPNode destNode = XMPNodeUtils.findChildNode(destParent, sourceNode.getName(), false);
+
+		boolean valueIsEmpty = false;
+		if (deleteEmptyValues)
+		{
+			valueIsEmpty = sourceNode.getOptions().isSimple() ?
+				sourceNode.getValue() == null  ||  sourceNode.getValue().length() == 0 :
+				!sourceNode.hasChildren();
+		}
+		
+		if (deleteEmptyValues  &&  valueIsEmpty)
+		{
+			if (destNode != null)
+			{
+				destParent.removeChild(destNode);
+			}
+		} 
+		else if (destNode == null)
+		{
+			// The one easy case, the destination does not exist.
+			destParent.addChild((XMPNode) sourceNode.clone());
+		}
+		else if (replaceOldValues)
+		{
+			// The destination exists and should be replaced.
+			destXMP.setNode(destNode, sourceNode.getValue(), sourceNode.getOptions(), true);
+			destParent.removeChild(destNode);
+			destNode = (XMPNode) sourceNode.clone();
+			destParent.addChild(destNode);
+		}
+		else
+		{
+			// The destination exists and is not totally replaced. Structs and
+			// arrays are merged.
+
+			PropertyOptions sourceForm = sourceNode.getOptions();
+			PropertyOptions destForm = destNode.getOptions();
+			if (sourceForm != destForm)
+			{
+				return;
+			}
+			if (sourceForm.isStruct())
+			{
+				// To merge a struct process the fields recursively. E.g. add simple missing fields.
+				// The recursive call to AppendSubtree will handle deletion for fields with empty 
+				// values.
+				for (Iterator it = sourceNode.iterateChildren(); it.hasNext();)
+				{
+					XMPNode sourceField = (XMPNode) it.next();
+					appendSubtree(destXMP, sourceField, destNode, 
+						replaceOldValues, deleteEmptyValues);
+					if (deleteEmptyValues  &&  !destNode.hasChildren())
+					{
+						destParent.removeChild(destNode);
+					}
+				}
+			}
+			else if (sourceForm.isArrayAltText())
+			{
+				// Merge AltText arrays by the "xml:lang" qualifiers. Make sure x-default is first. 
+				// Make a special check for deletion of empty values. Meaningful in AltText arrays 
+				// because the "xml:lang" qualifier provides unambiguous source/dest correspondence.
+				for (Iterator it = sourceNode.iterateChildren(); it.hasNext();)
+				{
+					XMPNode sourceItem = (XMPNode) it.next();
+					if (!sourceItem.hasQualifier()
+							|| !XMPConst.XML_LANG.equals(sourceItem.getQualifier(1).getName()))
+					{
+						continue;
+					}
+					
+					int destIndex = XMPNodeUtils.lookupLanguageItem(destNode, 
+							sourceItem.getQualifier(1).getValue());
+					if (deleteEmptyValues  &&  
+							(sourceItem.getValue() == null  ||
+							 sourceItem.getValue().length() == 0))
+					{
+						if (destIndex != -1)
+						{
+							destNode.removeChild(destIndex);
+							if (!destNode.hasChildren())
+							{
+								destParent.removeChild(destNode);
+							}
+						}	
+					}
+					else if (destIndex == -1)
+					{
+						// Not replacing, keep the existing item.						
+						if (!XMPConst.X_DEFAULT.equals(sourceItem.getQualifier(1).getValue())
+								|| !destNode.hasChildren())
+						{
+							sourceItem.cloneSubtree(destNode);
+						}
+						else
+						{
+							XMPNode destItem = new XMPNode(
+								sourceItem.getName(), 
+								sourceItem.getValue(), 
+								sourceItem.getOptions());
+							sourceItem.cloneSubtree(destItem);
+							destNode.addChild(1, destItem);
+						}	
+					}
+				}				
+			}
+			else if (sourceForm.isArray())
+			{
+				// Merge other arrays by item values. Don't worry about order or duplicates. Source 
+				// items with empty values do not cause deletion, that conflicts horribly with 
+				// merging.
+
+				for (Iterator is = sourceNode.iterateChildren(); is.hasNext();)
+				{
+					XMPNode sourceItem = (XMPNode) is.next();
+
+					boolean match = false;
+					for (Iterator id = destNode.iterateChildren(); id.hasNext();)
+					{
+						XMPNode destItem = (XMPNode) id.next();
+						if (itemValuesMatch(sourceItem, destItem))
+						{
+							match = true;
+						}
+					}
+					if (!match)
+					{
+						destNode = (XMPNode) sourceItem.clone();
+						destParent.addChild(destNode);
+					}
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * Compares two nodes including its children and qualifier.
+	 * @param leftNode an <code>XMPNode</code>
+	 * @param rightNode an <code>XMPNode</code>
+	 * @return Returns true if the nodes are equal, false otherwise.
+	 * @throws XMPException Forwards exceptions to the calling method.
+	 */
+	private static boolean itemValuesMatch(XMPNode leftNode, XMPNode rightNode) throws XMPException
+	{
+		PropertyOptions leftForm = leftNode.getOptions();
+		PropertyOptions rightForm = rightNode.getOptions();
+
+		if (leftForm.equals(rightForm))
+		{
+			return false;
+		}
+
+		if (leftForm.getOptions() == 0)
+		{
+			// Simple nodes, check the values and xml:lang qualifiers.
+			if (!leftNode.getValue().equals(rightNode.getValue()))
+			{
+				return false;
+			}
+			if (leftNode.getOptions().getHasLanguage() != rightNode.getOptions().getHasLanguage())
+			{
+				return false;
+			}
+			if (leftNode.getOptions().getHasLanguage()
+					&& !leftNode.getQualifier(1).getValue().equals(
+							rightNode.getQualifier(1).getValue()))
+			{
+				return false;
+			}
+		}
+		else if (leftForm.isStruct())
+		{
+			// Struct nodes, see if all fields match, ignoring order.
+
+			if (leftNode.getChildrenLength() != rightNode.getChildrenLength())
+			{
+				return false;
+			}
+
+			for (Iterator it = leftNode.iterateChildren(); it.hasNext();)
+			{
+				XMPNode leftField = (XMPNode) it.next();
+				XMPNode rightField = XMPNodeUtils.findChildNode(rightNode, leftField.getName(),
+						false);
+				if (rightField == null || !itemValuesMatch(leftField, rightField))
+				{
+					return false;
+				}
+			}
+		}
+		else
+		{
+			// Array nodes, see if the "leftNode" values are present in the
+			// "rightNode", ignoring order, duplicates,
+			// and extra values in the rightNode-> The rightNode is the
+			// destination for AppendProperties.
+
+			assert leftForm.isArray();
+
+			for (Iterator il = leftNode.iterateChildren(); il.hasNext();)
+			{
+				XMPNode leftItem = (XMPNode) il.next();
+
+				boolean match = false;
+				for (Iterator ir = rightNode.iterateChildren(); ir.hasNext();)
+				{
+					XMPNode rightItem = (XMPNode) ir.next();
+					if (itemValuesMatch(leftItem, rightItem))
+					{
+						match = true;
+						break;
+					}
+				}
+				if (!match)
+				{
+					return false;
+				}
+			}
+		}
+		return true; // All of the checks passed.
+	}
+
+
+	/**
+	 * Make sure the separator is OK. It must be one semicolon surrounded by
+	 * zero or more spaces. Any of the recognized semicolons or spaces are
+	 * allowed.
+	 * 
+	 * @param separator
+	 * @throws XMPException
+	 */
+	private static void checkSeparator(String separator) throws XMPException
+	{
+		boolean haveSemicolon = false;
+		for (int i = 0; i < separator.length(); i++)
+		{
+			int charKind = classifyCharacter(separator.charAt(i));
+			if (charKind == UCK_SEMICOLON)
+			{
+				if (haveSemicolon)
+				{
+					throw new XMPException("Separator can have only one semicolon", 
+						XMPError.BADPARAM);
+				}
+				haveSemicolon = true;
+			}
+			else if (charKind != UCK_SPACE)
+			{
+				throw new XMPException("Separator can have only spaces and one semicolon",
+						XMPError.BADPARAM);
+			}
+		}
+		if (!haveSemicolon)
+		{
+			throw new XMPException("Separator must have one semicolon", XMPError.BADPARAM);
+		}
+	}
+
+
+	/**
+	 * Make sure the open and close quotes are a legitimate pair and return the
+	 * correct closing quote or an exception.
+	 * 
+	 * @param quotes
+	 *            opened and closing quote in a string
+	 * @param openQuote
+	 *            the open quote
+	 * @return Returns a corresponding closing quote.
+	 * @throws XMPException
+	 */
+	private static char checkQuotes(String quotes, char openQuote) throws XMPException
+	{
+		char closeQuote;
+
+		int charKind = classifyCharacter(openQuote);
+		if (charKind != UCK_QUOTE)
+		{
+			throw new XMPException("Invalid quoting character", XMPError.BADPARAM);
+		}
+
+		if (quotes.length() == 1)
+		{
+			closeQuote = openQuote;
+		}
+		else
+		{
+			closeQuote = quotes.charAt(1);
+			charKind = classifyCharacter(closeQuote);
+			if (charKind != UCK_QUOTE)
+			{
+				throw new XMPException("Invalid quoting character", XMPError.BADPARAM);
+			}
+		}
+
+		if (closeQuote != getClosingQuote(openQuote))
+		{
+			throw new XMPException("Mismatched quote pair", XMPError.BADPARAM);
+		}
+		return closeQuote;
+	}
+
+
+	/**
+	 * Classifies the character into normal chars, spaces, semicola, quotes,
+	 * control chars.
+	 * 
+	 * @param ch
+	 *            a char
+	 * @return Return the character kind.
+	 */
+	private static int classifyCharacter(char ch)
+	{
+		if (SPACES.indexOf(ch) >= 0 || (0x2000 <= ch && ch <= 0x200B))
+		{
+			return UCK_SPACE;
+		}
+		else if (COMMAS.indexOf(ch) >= 0)
+		{
+			return UCK_COMMA;
+		}
+		else if (SEMICOLA.indexOf(ch) >= 0)
+		{
+			return UCK_SEMICOLON;
+		}
+		else if (QUOTES.indexOf(ch) >= 0 || (0x3008 <= ch && ch <= 0x300F)
+				|| (0x2018 <= ch && ch <= 0x201F))
+		{
+			return UCK_QUOTE;
+		}
+		else if (ch < 0x0020 || CONTROLS.indexOf(ch) >= 0)
+		{
+			return UCK_CONTROL;
+		}
+		else
+		{
+			// Assume typical case.
+			return UCK_NORMAL;
+		}
+	}
+
+
+	/**
+	 * @param openQuote
+	 *            the open quote char
+	 * @return Returns the matching closing quote for an open quote.
+	 */
+	private static char getClosingQuote(char openQuote)
+	{
+		switch (openQuote)
+		{
+		case 0x0022:
+			return 0x0022; // ! U+0022 is both opening and closing.
+		case 0x005B:
+			return 0x005D;
+		case 0x00AB:
+			return 0x00BB; // ! U+00AB and U+00BB are reversible.
+		case 0x00BB:
+			return 0x00AB;
+		case 0x2015:
+			return 0x2015; // ! U+2015 is both opening and closing.
+		case 0x2018:
+			return 0x2019;
+		case 0x201A:
+			return 0x201B;
+		case 0x201C:
+			return 0x201D;
+		case 0x201E:
+			return 0x201F;
+		case 0x2039:
+			return 0x203A; // ! U+2039 and U+203A are reversible.
+		case 0x203A:
+			return 0x2039;
+		case 0x3008:
+			return 0x3009;
+		case 0x300A:
+			return 0x300B;
+		case 0x300C:
+			return 0x300D;
+		case 0x300E:
+			return 0x300F;
+		case 0x301D:
+			return 0x301F; // ! U+301E also closes U+301D.
+		default:
+			return 0;
+		}
+	}
+
+
+	/**
+	 * Add quotes to the item.
+	 * 
+	 * @param item
+	 *            the array item
+	 * @param openQuote
+	 *            the open quote character
+	 * @param closeQuote
+	 *            the closing quote character
+	 * @param allowCommas
+	 *            flag if commas are allowed
+	 * @return Returns the value in quotes.
+	 */
+	private static String applyQuotes(String item, char openQuote, char closeQuote,
+			boolean allowCommas)
+	{
+		if (item == null)
+		{
+			item = "";
+		}
+		
+		boolean prevSpace = false;
+		int charOffset;
+		int charKind;
+
+		// See if there are any separators in the value. Stop at the first
+		// occurrance. This is a bit
+		// tricky in order to make typical typing work conveniently. The purpose
+		// of applying quotes
+		// is to preserve the values when splitting them back apart. That is
+		// CatenateContainerItems
+		// and SeparateContainerItems must round trip properly. For the most
+		// part we only look for
+		// separators here. Internal quotes, as in -- Irving "Bud" Jones --
+		// won't cause problems in
+		// the separation. An initial quote will though, it will make the value
+		// look quoted.
+
+		int i;
+		for (i = 0; i < item.length(); i++)
+		{
+			char ch = item.charAt(i);
+			charKind = classifyCharacter(ch);
+			if (i == 0 && charKind == UCK_QUOTE)
+			{
+				break;
+			}
+
+			if (charKind == UCK_SPACE)
+			{
+				// Multiple spaces are a separator.
+				if (prevSpace)
+				{
+					break;
+				}
+				prevSpace = true;
+			}
+			else
+			{
+				prevSpace = false;
+				if ((charKind == UCK_SEMICOLON || charKind == UCK_CONTROL)
+						|| (charKind == UCK_COMMA && !allowCommas))
+				{
+					break;
+				}
+			}
+		}
+
+
+		if (i < item.length())
+		{
+			// Create a quoted copy, doubling any internal quotes that match the
+			// outer ones. Internal quotes did not stop the "needs quoting"
+			// search, but they do need
+			// doubling. So we have to rescan the front of the string for
+			// quotes. Handle the special
+			// case of U+301D being closed by either U+301E or U+301F.
+
+			StringBuffer newItem = new StringBuffer(item.length() + 2);
+			int splitPoint;
+			for (splitPoint = 0; splitPoint <= i; splitPoint++)
+			{
+				if (classifyCharacter(item.charAt(i)) == UCK_QUOTE)
+				{
+					break;
+				}
+			}
+
+			// Copy the leading "normal" portion.
+			newItem.append(openQuote).append(item.substring(0, splitPoint));
+
+			for (charOffset = splitPoint; charOffset < item.length(); charOffset++)
+			{
+				newItem.append(item.charAt(charOffset));
+				if (classifyCharacter(item.charAt(charOffset)) == UCK_QUOTE
+						&& isSurroundingQuote(item.charAt(charOffset), openQuote, closeQuote))
+				{
+					newItem.append(item.charAt(charOffset));
+				}
+			}
+
+			newItem.append(closeQuote);
+
+			item = newItem.toString();
+		}
+
+		return item;
+	}
+
+
+	/**
+	 * @param ch a character
+	 * @param openQuote the opening quote char
+	 * @param closeQuote the closing quote char 
+	 * @return Return it the character is a surrounding quote.
+	 */
+	private static boolean isSurroundingQuote(char ch, char openQuote, char closeQuote)
+	{
+		return ch == openQuote || isClosingingQuote(ch, openQuote, closeQuote);
+	}
+
+
+	/**
+	 * @param ch a character
+	 * @param openQuote the opening quote char
+	 * @param closeQuote the closing quote char 
+	 * @return Returns true if the character is a closing quote.
+	 */
+	private static boolean isClosingingQuote(char ch, char openQuote, char closeQuote)
+	{
+		return ch == closeQuote || (openQuote == 0x301D && ch == 0x301E || ch == 0x301F);
+	}
+	
+	
+	
+	/**
+	 * U+0022 ASCII space<br>
+	 * U+3000, ideographic space<br>
+	 * U+303F, ideographic half fill space<br>
+	 * U+2000..U+200B, en quad through zero width space
+	 */
+	private static final String SPACES = "\u0020\u3000\u303F";
+	/**
+	 * U+002C, ASCII comma<br>
+	 * U+FF0C, full width comma<br>
+	 * U+FF64, half width ideographic comma<br>
+	 * U+FE50, small comma<br>
+	 * U+FE51, small ideographic comma<br>
+	 * U+3001, ideographic comma<br>
+	 * U+060C, Arabic comma<br>
+	 * U+055D, Armenian comma
+	 */
+	private static final String COMMAS = "\u002C\uFF0C\uFF64\uFE50\uFE51\u3001\u060C\u055D";
+	/**
+	 * U+003B, ASCII semicolon<br>
+	 * U+FF1B, full width semicolon<br>
+	 * U+FE54, small semicolon<br>
+	 * U+061B, Arabic semicolon<br>
+	 * U+037E, Greek "semicolon" (really a question mark)
+	 */
+	private static final String SEMICOLA = "\u003B\uFF1B\uFE54\u061B\u037E";
+	/**
+	 * U+0022 ASCII quote<br>
+	 * ASCII '[' (0x5B) and ']' (0x5D) are used as quotes in Chinese and
+	 * Korean.<br>
+	 * U+00AB and U+00BB, guillemet quotes<br>
+	 * U+3008..U+300F, various quotes.<br>
+	 * U+301D..U+301F, double prime quotes.<br>
+	 * U+2015, dash quote.<br>
+	 * U+2018..U+201F, various quotes.<br>
+	 * U+2039 and U+203A, guillemet quotes.
+	 */
+	private static final String QUOTES = 
+		"\"\u005B\u005D\u00AB\u00BB\u301D\u301E\u301F\u2015\u2039\u203A";
+	/**
+	 * U+0000..U+001F ASCII controls<br>
+	 * U+2028, line separator.<br>
+	 * U+2029, paragraph separator.
+	 */
+	private static final String CONTROLS = "\u2028\u2029";	
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/package.html b/XMPCore/src/com/adobe/xmp/impl/package.html
new file mode 100644
index 0000000..aea0dfa
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/package.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>Package overview</title>
+</head>
+
+<body>
+	<p>Package containing the xmpcore implementation.</p>
+</body>
+</html>
diff --git a/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPath.java b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPath.java
new file mode 100644
index 0000000..ff810dc
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPath.java
@@ -0,0 +1,106 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl.xpath;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Representates an XMP XMPPath with segment accessor methods.
+ *
+ * @since   28.02.2006
+ */
+public class XMPPath
+{
+	// Bits for XPathStepInfo options.
+	
+	/** Marks a struct field step , also for top level nodes (schema "fields"). */
+	public static final int STRUCT_FIELD_STEP = 0x01;
+	/** Marks a qualifier step. 
+	 *  Note: Order is significant to separate struct/qual from array kinds! */
+	public static final int QUALIFIER_STEP = 0x02; 		// 
+	/** Marks an array index step */
+	public static final int ARRAY_INDEX_STEP = 0x03;
+	/** */
+	public static final int ARRAY_LAST_STEP = 0x04;
+	/** */
+	public static final int QUAL_SELECTOR_STEP = 0x05;
+	/** */
+	public static final int FIELD_SELECTOR_STEP = 0x06;
+	/** */
+	public static final int SCHEMA_NODE = 0x80000000;	
+	/** */
+	public static final int STEP_SCHEMA = 0;
+	/** */
+	public static final int STEP_ROOT_PROP = 1;
+
+	
+	/** stores the segments of an XMPPath */
+	private List segments = new ArrayList(5);
+	
+	
+	/**
+	 * Append a path segment
+	 * 
+	 * @param segment the segment to add
+	 */
+	public void add(XMPPathSegment segment)
+	{	
+		segments.add(segment);
+	}
+
+	
+	/**
+	 * @param index the index of the segment to return
+	 * @return Returns a path segment.
+	 */
+	public XMPPathSegment getSegment(int index)
+	{
+		return (XMPPathSegment) segments.get(index);
+	}
+	
+	
+	/**
+	 * @return Returns the size of the xmp path. 
+	 */
+	public int size()
+	{
+		return segments.size();
+	}
+	
+	
+	/**
+	 * Serializes the normalized XMP-path.
+	 * @see Object#toString()
+	 */
+	public String toString()
+	{
+		StringBuffer result = new StringBuffer();
+		int index = 1;
+		while (index < size())
+		{
+			result.append(getSegment(index));
+			if (index < size() - 1)
+			{
+				int kind = getSegment(index + 1).getKind(); 
+				if (kind == STRUCT_FIELD_STEP  || 
+					kind == QUALIFIER_STEP)
+				{	
+					// all but last and array indices
+					result.append('/');
+				}	
+			}
+			index++;			
+		}
+		
+		return result.toString();
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathParser.java b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathParser.java
new file mode 100644
index 0000000..9936c06
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathParser.java
@@ -0,0 +1,537 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl.xpath;
+
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.impl.Utils;
+import com.adobe.xmp.properties.XMPAliasInfo;
+
+
+/**
+ * Parser for XMP XPaths.
+ *
+ * @since   01.03.2006
+ */
+public final class XMPPathParser
+{
+	/**
+	 * Private constructor
+	 */
+	private XMPPathParser()
+	{
+		// empty
+	}
+
+
+	/**
+	 * Split an XMPPath expression apart at the conceptual steps, adding the
+	 * root namespace prefix to the first property component. The schema URI is
+	 * put in the first (0th) slot in the expanded XMPPath. Check if the top
+	 * level component is an alias, but don't resolve it.
+	 * <p>
+	 * In the most verbose case steps are separated by '/', and each step can be
+	 * of these forms:
+	 * <dl>
+	 * <dt>prefix:name
+	 * <dd> A top level property or struct field.
+	 * <dt>[index]
+	 * <dd> An element of an array.
+	 * <dt>[last()]
+	 * <dd> The last element of an array.
+	 * <dt>[fieldName=&quot;value&quot;]
+	 * <dd> An element in an array of structs, chosen by a field value.
+	 * <dt>[@xml:lang=&quot;value&quot;]
+	 * <dd> An element in an alt-text array, chosen by the xml:lang qualifier.
+	 * <dt>[?qualName=&quot;value&quot;]
+	 * <dd> An element in an array, chosen by a qualifier value.
+	 * <dt>@xml:lang
+	 * <dd> An xml:lang qualifier.
+	 * <dt>?qualName
+	 * <dd> A general qualifier.
+	 * </dl>
+	 * <p>
+	 * The logic is complicated though by shorthand for arrays, the separating
+	 * '/' and leading '*' are optional. These are all equivalent: array/*[2]
+	 * array/[2] array*[2] array[2] All of these are broken into the 2 steps
+	 * "array" and "[2]".
+	 * <p>
+	 * The value portion in the array selector forms is a string quoted by '''
+	 * or '"'. The value may contain any character including a doubled quoting
+	 * character. The value may be empty.
+	 * <p>
+	 * The syntax isn't checked, but an XML name begins with a letter or '_',
+	 * and contains letters, digits, '.', '-', '_', and a bunch of special
+	 * non-ASCII Unicode characters. An XML qualified name is a pair of names
+	 * separated by a colon.
+	 * @param schemaNS
+	 *            schema namespace
+	 * @param path
+	 *            property name
+	 * @return Returns the expandet XMPPath.
+	 * @throws XMPException
+	 *             Thrown if the format is not correct somehow.
+	 * 
+	 */
+	public static XMPPath expandXPath(String schemaNS, String path) throws XMPException
+	{
+		if (schemaNS == null  ||  path == null)
+		{
+			throw new XMPException("Parameter must not be null", XMPError.BADPARAM);
+		}
+
+		XMPPath expandedXPath = new XMPPath();
+		PathPosition pos = new PathPosition();
+		pos.path = path;
+		
+		// Pull out the first component and do some special processing on it: add the schema
+		// namespace prefix and and see if it is an alias. The start must be a "qualName".
+		parseRootNode(schemaNS, pos, expandedXPath);
+
+		// Now continue to process the rest of the XMPPath string.
+		while (pos.stepEnd < path.length())
+		{
+			pos.stepBegin = pos.stepEnd;
+			
+			skipPathDelimiter(path, pos);
+
+			pos.stepEnd = pos.stepBegin;
+
+			
+			XMPPathSegment segment;
+			if (path.charAt(pos.stepBegin) != '[')
+			{
+				// A struct field or qualifier.
+				segment = parseStructSegment(pos);
+			}
+			else
+			{
+				// One of the array forms.
+				segment = parseIndexSegment(pos);
+			}
+			
+
+			if (segment.getKind() == XMPPath.STRUCT_FIELD_STEP)
+			{
+				if (segment.getName().charAt(0) == '@')
+				{
+					segment.setName("?" + segment.getName().substring(1));
+					if (!"?xml:lang".equals(segment.getName()))
+					{
+						throw new XMPException("Only xml:lang allowed with '@'",
+								XMPError.BADXPATH);
+					}
+				}
+				if (segment.getName().charAt(0) == '?')
+				{
+					pos.nameStart++;
+					segment.setKind(XMPPath.QUALIFIER_STEP);
+				}
+
+				verifyQualName(pos.path.substring(pos.nameStart, pos.nameEnd));
+			}
+			else if (segment.getKind() == XMPPath.FIELD_SELECTOR_STEP)
+			{
+				if (segment.getName().charAt(1) == '@')
+				{
+					segment.setName("[?" + segment.getName().substring(2));
+					if (!segment.getName().startsWith("[?xml:lang="))
+					{
+						throw new XMPException("Only xml:lang allowed with '@'",
+								XMPError.BADXPATH);
+					}
+				}
+
+				if (segment.getName().charAt(1) == '?')
+				{
+					pos.nameStart++;
+					segment.setKind(XMPPath.QUAL_SELECTOR_STEP);
+					verifyQualName(pos.path.substring(pos.nameStart, pos.nameEnd));
+				}
+			}			
+
+			expandedXPath.add(segment);
+		}
+		return expandedXPath;
+	}
+
+
+	/**
+	 * @param path
+	 * @param pos
+	 * @throws XMPException
+	 */
+	private static void skipPathDelimiter(String path, PathPosition pos) throws XMPException
+	{
+		if (path.charAt(pos.stepBegin) == '/')
+		{
+			// skip slash
+
+			pos.stepBegin++;
+
+			// added for Java
+			if (pos.stepBegin >= path.length())
+			{
+				throw new XMPException("Empty XMPPath segment", XMPError.BADXPATH);
+			}
+		}
+
+		if (path.charAt(pos.stepBegin) == '*')
+		{
+			// skip asterisk
+
+			pos.stepBegin++;
+			if (pos.stepBegin >= path.length() || path.charAt(pos.stepBegin) != '[')
+			{
+				throw new XMPException("Missing '[' after '*'", XMPError.BADXPATH);
+			}
+		}
+	}
+
+
+	/**
+	 * Parses a struct segment
+	 * @param pos the current position in the path
+	 * @return Retusn the segment or an errror
+	 * @throws XMPException If the sement is empty
+	 */
+	private static XMPPathSegment parseStructSegment(PathPosition pos) throws XMPException
+	{
+		pos.nameStart = pos.stepBegin;
+		while (pos.stepEnd < pos.path.length() && "/[*".indexOf(pos.path.charAt(pos.stepEnd)) < 0)
+		{
+			pos.stepEnd++;
+		}
+		pos.nameEnd = pos.stepEnd;
+
+		if (pos.stepEnd == pos.stepBegin)
+		{
+			throw new XMPException("Empty XMPPath segment", XMPError.BADXPATH);
+		}
+
+		// ! Touch up later, also changing '@' to '?'.
+		XMPPathSegment segment = new XMPPathSegment(pos.path.substring(pos.stepBegin, pos.stepEnd),
+				XMPPath.STRUCT_FIELD_STEP);
+		return segment;
+	}
+
+
+	/**
+	 * Parses an array index segment.
+	 * 
+	 * @param pos the xmp path 
+	 * @return Returns the segment or an error
+	 * @throws XMPException thrown on xmp path errors
+	 * 
+	 */
+	private static XMPPathSegment parseIndexSegment(PathPosition pos) throws XMPException
+	{
+		XMPPathSegment segment;
+		pos.stepEnd++; // Look at the character after the leading '['.
+
+		if ('0' <= pos.path.charAt(pos.stepEnd) && pos.path.charAt(pos.stepEnd) <= '9')
+		{
+			// A numeric (decimal integer) array index.
+			while (pos.stepEnd < pos.path.length() && '0' <= pos.path.charAt(pos.stepEnd)
+					&& pos.path.charAt(pos.stepEnd) <= '9')
+			{
+				pos.stepEnd++;
+			}
+
+			segment = new XMPPathSegment(null, XMPPath.ARRAY_INDEX_STEP);
+		}
+		else
+		{
+			// Could be "[last()]" or one of the selector forms. Find the ']' or '='.
+
+			while (pos.stepEnd < pos.path.length() && pos.path.charAt(pos.stepEnd) != ']'
+					&& pos.path.charAt(pos.stepEnd) != '=')
+			{
+				pos.stepEnd++;
+			}
+			
+			if (pos.stepEnd >= pos.path.length())
+			{
+				throw new XMPException("Missing ']' or '=' for array index", XMPError.BADXPATH);
+			}
+
+			if (pos.path.charAt(pos.stepEnd) == ']')
+			{
+				if (!"[last()".equals(pos.path.substring(pos.stepBegin, pos.stepEnd)))
+				{
+					throw new XMPException(
+						"Invalid non-numeric array index", XMPError.BADXPATH);
+				}
+				segment = new XMPPathSegment(null, XMPPath.ARRAY_LAST_STEP);
+			}
+			else
+			{
+				pos.nameStart = pos.stepBegin + 1;
+				pos.nameEnd = pos.stepEnd;
+				pos.stepEnd++; // Absorb the '=', remember the quote.
+				char quote = pos.path.charAt(pos.stepEnd);
+				if (quote != '\'' && quote != '"')
+				{
+					throw new XMPException(
+						"Invalid quote in array selector", XMPError.BADXPATH);
+				}
+
+				pos.stepEnd++; // Absorb the leading quote.
+				while (pos.stepEnd < pos.path.length())
+				{
+					if (pos.path.charAt(pos.stepEnd) == quote)
+					{
+						// check for escaped quote
+						if (pos.stepEnd + 1 >= pos.path.length()
+								|| pos.path.charAt(pos.stepEnd + 1) != quote)
+						{
+							break;
+						}
+						pos.stepEnd++;
+					}
+					pos.stepEnd++;
+				}
+
+				if (pos.stepEnd >= pos.path.length())
+				{
+					throw new XMPException("No terminating quote for array selector",
+							XMPError.BADXPATH);
+				}
+				pos.stepEnd++; // Absorb the trailing quote.
+
+				// ! Touch up later, also changing '@' to '?'.
+				segment = new XMPPathSegment(null, XMPPath.FIELD_SELECTOR_STEP);
+			}
+		}
+		
+
+		if (pos.stepEnd >= pos.path.length() || pos.path.charAt(pos.stepEnd) != ']')
+		{
+			throw new XMPException("Missing ']' for array index", XMPError.BADXPATH);
+		}
+		pos.stepEnd++;
+		segment.setName(pos.path.substring(pos.stepBegin, pos.stepEnd));
+		
+		return segment;
+	}
+
+
+	/**
+	 * Parses the root node of an XMP Path, checks if namespace and prefix fit together
+	 * and resolve the property to the base property if it is an alias. 
+	 * @param schemaNS the root namespace
+	 * @param pos the parsing position helper
+	 * @param expandedXPath  the path to contribute to
+	 * @throws XMPException If the path is not valid.
+	 */
+	private static void parseRootNode(String schemaNS, PathPosition pos, XMPPath expandedXPath)
+			throws XMPException
+	{
+		while (pos.stepEnd < pos.path.length() && "/[*".indexOf(pos.path.charAt(pos.stepEnd)) < 0)
+		{
+			pos.stepEnd++;
+		}
+
+		if (pos.stepEnd == pos.stepBegin)
+		{
+			throw new XMPException("Empty initial XMPPath step", XMPError.BADXPATH);
+		}
+		
+		String rootProp = verifyXPathRoot(schemaNS, pos.path.substring(pos.stepBegin, pos.stepEnd));
+		XMPAliasInfo aliasInfo = XMPMetaFactory.getSchemaRegistry().findAlias(rootProp);
+		if (aliasInfo == null)
+		{
+			// add schema xpath step
+			expandedXPath.add(new XMPPathSegment(schemaNS, XMPPath.SCHEMA_NODE));
+			XMPPathSegment rootStep = new XMPPathSegment(rootProp, XMPPath.STRUCT_FIELD_STEP);
+			expandedXPath.add(rootStep);
+		}
+		else
+		{
+			// add schema xpath step and base step of alias
+			expandedXPath.add(new XMPPathSegment(aliasInfo.getNamespace(), XMPPath.SCHEMA_NODE));
+			XMPPathSegment rootStep = new XMPPathSegment(verifyXPathRoot(aliasInfo.getNamespace(),
+					aliasInfo.getPropName()),
+					XMPPath.STRUCT_FIELD_STEP);
+			rootStep.setAlias(true);
+			rootStep.setAliasForm(aliasInfo.getAliasForm().getOptions());
+			expandedXPath.add(rootStep);
+			
+			if (aliasInfo.getAliasForm().isArrayAltText())
+			{
+				XMPPathSegment qualSelectorStep = new XMPPathSegment("[?xml:lang='x-default']",
+						XMPPath.QUAL_SELECTOR_STEP);
+				qualSelectorStep.setAlias(true);
+				qualSelectorStep.setAliasForm(aliasInfo.getAliasForm().getOptions());
+				expandedXPath.add(qualSelectorStep);
+			}
+			else if (aliasInfo.getAliasForm().isArray())
+			{
+				XMPPathSegment indexStep = new XMPPathSegment("[1]",
+					XMPPath.ARRAY_INDEX_STEP);
+				indexStep.setAlias(true);
+				indexStep.setAliasForm(aliasInfo.getAliasForm().getOptions());
+				expandedXPath.add(indexStep);
+			}
+		}
+	}
+
+
+	/**
+	 * Verifies whether the qualifier name is not XML conformant or the
+	 * namespace prefix has not been registered.
+	 * 
+	 * @param qualName
+	 *            a qualifier name
+	 * @throws XMPException
+	 *             If the name is not conformant
+	 */
+	private static void verifyQualName(String qualName) throws XMPException
+	{
+		int colonPos = qualName.indexOf(':');
+		if (colonPos > 0)
+		{	
+			String prefix = qualName.substring(0, colonPos);		
+			if (Utils.isXMLNameNS(prefix))
+			{	
+				String regURI = XMPMetaFactory.getSchemaRegistry().getNamespaceURI(
+						prefix);
+				if (regURI != null)
+				{
+					return;
+				}
+
+				throw new XMPException("Unknown namespace prefix for qualified name",
+						XMPError.BADXPATH);
+			}
+		}
+		
+		throw new XMPException("Ill-formed qualified name", XMPError.BADXPATH);
+	}
+
+
+	/**
+	 * Verify if an XML name is conformant.
+	 * 
+	 * @param name
+	 *            an XML name
+	 * @throws XMPException
+	 *             When the name is not XML conformant
+	 */
+	private static void verifySimpleXMLName(String name) throws XMPException
+	{
+		if (!Utils.isXMLName(name))
+		{
+			throw new XMPException("Bad XML name", XMPError.BADXPATH);
+		}
+	}
+
+
+	/**
+	 * Set up the first 2 components of the expanded XMPPath. Normalizes the various cases of using
+	 * the full schema URI and/or a qualified root property name. Returns true for normal
+	 * processing. If allowUnknownSchemaNS is true and the schema namespace is not registered, false
+	 * is returned. If allowUnknownSchemaNS is false and the schema namespace is not registered, an
+	 * exception is thrown
+	 * <P>
+	 * (Should someday check the full syntax:)
+	 * 
+	 * @param schemaNS schema namespace
+	 * @param rootProp the root xpath segment
+	 * @return Returns root QName.
+	 * @throws XMPException Thrown if the format is not correct somehow.
+	 */
+	private static String verifyXPathRoot(String schemaNS, String rootProp)
+		throws XMPException
+	{
+		// Do some basic checks on the URI and name. Try to lookup the URI. See if the name is
+		// qualified.
+
+		if (schemaNS == null || schemaNS.length() == 0)
+		{
+			throw new XMPException(
+				"Schema namespace URI is required", XMPError.BADSCHEMA);
+		}
+
+		if ((rootProp.charAt(0) == '?') || (rootProp.charAt(0) == '@'))
+		{
+			throw new XMPException("Top level name must not be a qualifier", XMPError.BADXPATH);
+		}
+
+		if (rootProp.indexOf('/') >= 0 || rootProp.indexOf('[') >= 0)
+		{
+			throw new XMPException("Top level name must be simple", XMPError.BADXPATH);
+		}
+
+		String prefix = XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(schemaNS);
+		if (prefix == null)
+		{
+			throw new XMPException("Unregistered schema namespace URI", XMPError.BADSCHEMA);
+		}
+
+		// Verify the various URI and prefix combinations. Initialize the
+		// expanded XMPPath.
+		int colonPos = rootProp.indexOf(':');
+		if (colonPos < 0)
+		{
+			// The propName is unqualified, use the schemaURI and associated
+			// prefix.
+			verifySimpleXMLName(rootProp); // Verify the part before any colon
+			return prefix + rootProp;
+		}
+		else
+		{
+			// The propName is qualified. Make sure the prefix is legit. Use the associated URI and
+			// qualified name.
+
+			// Verify the part before any colon
+			verifySimpleXMLName(rootProp.substring(0, colonPos));
+			verifySimpleXMLName(rootProp.substring(colonPos));
+			
+			prefix = rootProp.substring(0, colonPos + 1);
+
+			String regPrefix = XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(schemaNS);
+			if (regPrefix == null)
+			{
+				throw new XMPException("Unknown schema namespace prefix", XMPError.BADSCHEMA);
+			}
+			if (!prefix.equals(regPrefix))
+			{
+				throw new XMPException("Schema namespace URI and prefix mismatch",
+						XMPError.BADSCHEMA);
+			}
+
+			return rootProp;
+		}
+	}
+}
+
+
+
+
+
+/**
+ * This objects contains all needed char positions to parse.
+ */
+class PathPosition
+{
+	/** the complete path */
+	public String path = null;
+	/** the start of a segment name */
+	int nameStart = 0;
+	/** the end of a segment name */
+	int nameEnd = 0;
+	/** the begin of a step */
+	int stepBegin = 0;
+	/** the end of a step */
+	int stepEnd = 0;
+}
+
diff --git a/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathSegment.java b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathSegment.java
new file mode 100644
index 0000000..88b42a1
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/xpath/XMPPathSegment.java
@@ -0,0 +1,147 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.impl.xpath;
+
+
+/**
+ * A segment of a parsed <code>XMPPath</code>.
+ *  
+ * @since   23.06.2006
+ */
+public class XMPPathSegment
+{
+	/** name of the path segment */
+	private String name;
+	/** kind of the path segment */
+	private int kind;
+	/** flag if segment is an alias */
+	private boolean alias;
+	/** alias form if applicable */
+	private int aliasForm;
+
+
+	/**
+	 * Constructor with initial values.
+	 * 
+	 * @param name the name of the segment
+	 */
+	public XMPPathSegment(String name)
+	{
+		this.name = name;
+	}
+
+
+	/**
+	 * Constructor with initial values.
+	 * 
+	 * @param name the name of the segment
+	 * @param kind the kind of the segment
+	 */
+	public XMPPathSegment(String name, int kind)
+	{
+		this.name = name;
+		this.kind = kind;
+	}
+
+
+	/**
+	 * @return Returns the kind.
+	 */
+	public int getKind()
+	{
+		return kind;
+	}
+
+
+	/**
+	 * @param kind The kind to set.
+	 */
+	public void setKind(int kind)
+	{
+		this.kind = kind;
+	}
+
+
+	/**
+	 * @return Returns the name.
+	 */
+	public String getName()
+	{
+		return name;
+	}
+
+
+	/**
+	 * @param name The name to set.
+	 */
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+
+	/**
+	 * @param alias the flag to set
+	 */
+	public void setAlias(boolean alias)
+	{
+		this.alias = alias;
+	}
+
+
+	/**
+	 * @return Returns the alias.
+	 */
+	public boolean isAlias()
+	{
+		return alias;
+	}
+	
+	
+	/** 
+	 * @return Returns the aliasForm if this segment has been created by an alias.
+	 */ 
+	public int getAliasForm()
+	{
+		return aliasForm;
+	}
+
+	
+	/**
+	 * @param aliasForm the aliasForm to set
+	 */
+	public void setAliasForm(int aliasForm)
+	{
+		this.aliasForm = aliasForm;
+	}
+	
+	
+	/**
+	 * @see Object#toString()
+	 */
+	public String toString()
+	{
+		switch (kind)
+		{
+			case XMPPath.STRUCT_FIELD_STEP:
+			case XMPPath.ARRAY_INDEX_STEP: 
+			case XMPPath.QUALIFIER_STEP: 
+			case XMPPath.ARRAY_LAST_STEP: 
+				return name;
+			case XMPPath.QUAL_SELECTOR_STEP: 
+			case XMPPath.FIELD_SELECTOR_STEP: 
+			return name;
+
+		default:
+			// no defined step
+			return name;
+		}
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/impl/xpath/package.html b/XMPCore/src/com/adobe/xmp/impl/xpath/package.html
new file mode 100644
index 0000000..e444a87
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/impl/xpath/package.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>Package overview</title>
+</head>
+
+<body>
+	<p>Package containing the XMPPath handling.</p>
+	<p>An XMPPath a simplified form of an XPath, used only to create or retrieve properties in an XMPMeta object.<p>
+</body>
+</html>
diff --git a/XMPCore/src/com/adobe/xmp/options/AliasOptions.java b/XMPCore/src/com/adobe/xmp/options/AliasOptions.java
new file mode 100644
index 0000000..cf58273
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/AliasOptions.java
@@ -0,0 +1,184 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+import com.adobe.xmp.XMPException;
+
+
+/**
+ * Options for XMPSchemaRegistryImpl#registerAlias.
+ * 
+ * @since 20.02.2006
+ */
+public final class AliasOptions extends Options
+{
+	/** This is a direct mapping. The actual data type does not matter. */
+	public static final int PROP_DIRECT = 0;
+	/** The actual is an unordered array, the alias is to the first element of the array. */
+	public static final int PROP_ARRAY = PropertyOptions.ARRAY;
+	/** The actual is an ordered array, the alias is to the first element of the array. */
+	public static final int PROP_ARRAY_ORDERED = PropertyOptions.ARRAY_ORDERED;
+	/** The actual is an alternate array, the alias is to the first element of the array. */
+	public static final int PROP_ARRAY_ALTERNATE = PropertyOptions.ARRAY_ALTERNATE;
+	/**
+	 * The actual is an alternate text array, the alias is to the 'x-default' element of the array.
+	 */
+	public static final int PROP_ARRAY_ALT_TEXT = PropertyOptions.ARRAY_ALT_TEXT;
+
+	
+	/**
+	 * @see Options#Options()
+	 */
+	public AliasOptions()
+	{
+		// EMPTY
+	}
+
+	
+	/**
+	 * @param options the options to init with
+	 * @throws XMPException If options are not consistant
+	 */
+	public AliasOptions(int options) throws XMPException
+	{
+		super(options);
+	}
+
+
+	/**
+	 * @return Returns if the alias is of the simple form.
+	 */
+	public boolean isSimple()
+	{
+		return getOptions() == PROP_DIRECT;
+	}
+
+	
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean isArray()
+	{
+		return getOption(PROP_ARRAY);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public AliasOptions setArray(boolean value)
+	{
+		setOption(PROP_ARRAY, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean isArrayOrdered()
+	{
+		return getOption(PROP_ARRAY_ORDERED);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public AliasOptions setArrayOrdered(boolean value)
+	{
+		setOption(PROP_ARRAY | PROP_ARRAY_ORDERED, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean isArrayAlternate()
+	{
+		return getOption(PROP_ARRAY_ALTERNATE);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public AliasOptions setArrayAlternate(boolean value)
+	{
+		setOption(PROP_ARRAY | PROP_ARRAY_ORDERED | PROP_ARRAY_ALTERNATE, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean isArrayAltText()
+	{
+		return getOption(PROP_ARRAY_ALT_TEXT);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public AliasOptions setArrayAltText(boolean value)
+	{
+		setOption(PROP_ARRAY | PROP_ARRAY_ORDERED | 
+			PROP_ARRAY_ALTERNATE | PROP_ARRAY_ALT_TEXT, value);
+		return this;
+	}
+
+
+	/**
+	 * @return returns a {@link PropertyOptions}s object
+	 * @throws XMPException If the options are not consistant. 
+	 */
+	public PropertyOptions toPropertyOptions() throws XMPException
+	{
+		return new PropertyOptions(getOptions());
+	}
+
+
+	/**
+	 * @see Options#defineOptionName(int)
+	 */
+	protected String defineOptionName(int option)
+	{
+		switch (option)
+		{
+			case PROP_DIRECT : 			return "PROP_DIRECT";
+			case PROP_ARRAY :			return "ARRAY";
+			case PROP_ARRAY_ORDERED :	return "ARRAY_ORDERED";
+			case PROP_ARRAY_ALTERNATE :	return "ARRAY_ALTERNATE";
+			case PROP_ARRAY_ALT_TEXT :	return "ARRAY_ALT_TEXT";
+			default: 					return null;
+		}
+	}
+
+	
+	/**
+	 * @see Options#getValidOptions()
+	 */
+	protected int getValidOptions()
+	{
+		return 
+			PROP_DIRECT |
+			PROP_ARRAY |
+			PROP_ARRAY_ORDERED |
+			PROP_ARRAY_ALTERNATE |
+			PROP_ARRAY_ALT_TEXT;
+	}
+}	
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/options/IteratorOptions.java b/XMPCore/src/com/adobe/xmp/options/IteratorOptions.java
new file mode 100644
index 0000000..3dcb524
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/IteratorOptions.java
@@ -0,0 +1,148 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+
+/**
+ * Options for <code>XMPIterator</code> construction.
+ * 
+ * @since 24.01.2006
+ */
+public final class IteratorOptions extends Options
+{
+	/** Just do the immediate children of the root, default is subtree. */
+	public static final int JUST_CHILDREN = 0x0100;
+	/** Just do the leaf nodes, default is all nodes in the subtree. */
+	public static final int JUST_LEAFNODES = 0x0200;
+	/** Return just the leaf part of the path, default is the full path. */
+	public static final int JUST_LEAFNAME = 0x0400;
+	/** Include aliases, default is just actual properties. <em>Note:</em> Not supported. 
+	 *  @deprecated it is commonly preferred to work with the base properties */
+	public static final int INCLUDE_ALIASES = 0x0800;
+	/** Omit all qualifiers. */
+	public static final int OMIT_QUALIFIERS = 0x1000;
+
+
+	/**
+	 * @return Returns whether the option is set.
+	 */
+	public boolean isJustChildren()
+	{
+		return getOption(JUST_CHILDREN);
+	}
+
+
+	/**
+	 * @return Returns whether the option is set.
+	 */
+	public boolean isJustLeafname()
+	{
+		return getOption(JUST_LEAFNAME);
+	}
+
+
+	/**
+	 * @return Returns whether the option is set.
+	 */
+	public boolean isJustLeafnodes()
+	{
+		return getOption(JUST_LEAFNODES);
+	}
+
+
+	/**
+	 * @return Returns whether the option is set.
+	 */
+	public boolean isOmitQualifiers()
+	{
+		return getOption(OMIT_QUALIFIERS);
+	}
+
+
+	/**
+	 * Sets the option and returns the instance.
+	 * 
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public IteratorOptions setJustChildren(boolean value)
+	{
+		setOption(JUST_CHILDREN, value);
+		return this;
+	}
+
+
+	/**
+	 * Sets the option and returns the instance.
+	 * 
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public IteratorOptions setJustLeafname(boolean value)
+	{
+		setOption(JUST_LEAFNAME, value);
+		return this;
+	}
+
+
+	/**
+	 * Sets the option and returns the instance.
+	 * 
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public IteratorOptions setJustLeafnodes(boolean value)
+	{
+		setOption(JUST_LEAFNODES, value);
+		return this;
+	}
+
+
+	/**
+	 * Sets the option and returns the instance.
+	 * 
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public IteratorOptions setOmitQualifiers(boolean value)
+	{
+		setOption(OMIT_QUALIFIERS, value);
+		return this;
+	}
+
+
+	/**
+	 * @see Options#defineOptionName(int)
+	 */
+	protected String defineOptionName(int option)
+	{
+		switch (option)
+		{
+			case JUST_CHILDREN : 	return "JUST_CHILDREN";
+			case JUST_LEAFNODES :	return "JUST_LEAFNODES";
+			case JUST_LEAFNAME :	return "JUST_LEAFNAME";
+			case OMIT_QUALIFIERS :	return "OMIT_QUALIFIERS";
+			default: 				return null;
+		}
+	}
+
+
+	/**
+	 * @see Options#getValidOptions()
+	 */
+	protected int getValidOptions()
+	{
+		return 
+			JUST_CHILDREN |
+			JUST_LEAFNODES |
+			JUST_LEAFNAME |
+			OMIT_QUALIFIERS;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/options/Options.java b/XMPCore/src/com/adobe/xmp/options/Options.java
new file mode 100644
index 0000000..6d6bd98
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/Options.java
@@ -0,0 +1,290 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+
+/**
+ * The base class for a collection of 32 flag bits. Individual flags are defined as enum value bit
+ * masks. Inheriting classes add convenience accessor methods.
+ * 
+ * @since 24.01.2006
+ */
+public abstract class Options
+{
+	/** the internal int containing all options */
+	private int options = 0;
+	/** a map containing the bit names */
+	private Map optionNames = null;
+
+
+	/**
+	 * The default constructor.
+	 */
+	public Options()
+	{
+		// EMTPY
+	}
+
+
+	/**
+	 * Constructor with the options bit mask. 
+	 * 
+	 * @param options the options bit mask
+	 * @throws XMPException If the options are not correct
+	 */
+	public Options(int options) throws XMPException
+	{
+		assertOptionsValid(options);
+		setOptions(options);
+	}
+
+	
+	/**
+	 * Resets the options.
+	 */
+	public void clear()
+	{
+		options = 0;
+	}
+	
+	
+	/**
+	 * @param optionBits an option bitmask
+	 * @return Returns true, if this object is equal to the given options. 
+	 */
+	public boolean isExactly(int optionBits)
+	{
+		return getOptions() == optionBits;
+	}
+
+
+	/**
+	 * @param optionBits an option bitmask
+	 * @return Returns true, if this object contains all given options. 
+	 */
+	public boolean containsAllOptions(int optionBits)
+	{
+		return (getOptions() & optionBits) == optionBits;
+	}
+
+
+	/**
+	 * @param optionBits an option bitmask
+	 * @return Returns true, if this object contain at least one of the given options. 
+	 */
+	public boolean containsOneOf(int optionBits)
+	{
+		return ((getOptions()) & optionBits) != 0;
+	}	
+
+	
+	/**
+	 * @param optionBit the binary bit or bits that are requested
+	 * @return Returns if <emp>all</emp> of the requested bits are set or not.
+	 */
+	protected boolean getOption(int optionBit)
+	{
+		return (options & optionBit) != 0;
+	}
+
+
+	/**
+	 * @param optionBits the binary bit or bits that shall be set to the given value
+	 * @param value the boolean value to set
+	 */
+	public void setOption(int optionBits, boolean value)
+	{
+		options = value ? options | optionBits : options & ~optionBits;
+	}
+
+	
+	/**
+	 * Is friendly to access it during the tests.
+	 * @return Returns the options.
+	 */
+	public int getOptions()
+	{
+		return options;
+	}
+
+
+	/**
+	 * @param options The options to set.
+	 * @throws XMPException 
+	 */
+	public void setOptions(int options) throws XMPException
+	{
+		assertOptionsValid(options);
+		this.options = options;
+	}
+	
+	
+	/**
+	 * @see Object#equals(Object)
+	 */
+	public boolean equals(Object obj)
+	{
+		return getOptions() == ((Options) obj).getOptions();
+	}
+	
+	
+	/**
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode()
+	{
+		return getOptions();
+	}
+	
+	
+	/**
+	 * Creates a human readable string from the set options. <em>Note:</em> This method is quite
+	 * expensive and should only be used within tests or as
+	 * @return Returns a String listing all options that are set to <code>true</code> by their name,
+	 * like &quot;option1 | option4&quot;.
+	 */
+	public String getOptionsString()
+	{
+		if (options != 0)
+		{	
+			StringBuffer sb = new StringBuffer();
+			int theBits = options;
+			while (theBits != 0)
+			{
+				int oneLessBit = theBits & (theBits - 1); // clear rightmost one bit
+				int singleBit = theBits ^ oneLessBit;
+				String bitName = getOptionName(singleBit);
+				sb.append(bitName);
+				if (oneLessBit != 0)
+				{	
+					sb.append(" | ");
+				}	
+				theBits = oneLessBit;
+			}
+			return sb.toString();
+		}	
+		else
+		{
+			return "<none>";
+		}
+	}
+
+	
+	/**
+	 * @return Returns the options as hex bitmask. 
+	 */
+	public String toString()
+	{
+		return "0x" + Integer.toHexString(options);
+	}
+	
+	
+	/**
+	 * To be implemeted by inheritants.
+	 * @return Returns a bit mask where all valid option bits are set.
+	 */
+	protected abstract int getValidOptions();
+	
+	
+	/**
+	 * To be implemeted by inheritants.
+	 * @param option a single, valid option bit.
+	 * @return Returns a human readable name for an option bit.
+	 */
+	protected abstract String defineOptionName(int option);
+	
+	
+	/**
+	 * The inheriting option class can do additional checks on the options.
+	 * <em>Note:</em> For performance reasons this method is only called 
+	 * when setting bitmasks directly.
+	 * When get- and set-methods are used, this method must be called manually,
+	 * normally only when the Options-object has been created from a client
+	 * (it has to be made public therefore).
+	 * 
+	 * @param options the bitmask to check.
+	 * @throws XMPException Thrown if the options are not consistent.
+	 */
+	protected void assertConsistency(int options) throws XMPException
+	{
+		// empty, no checks
+	}
+	
+	
+	/**
+	 * Checks options before they are set.
+	 * First it is checked if only defined options are used,
+	 * second the additional {@link Options#assertConsistency(int)}-method is called.
+	 *  
+	 * @param options the options to check
+	 * @throws XMPException Thrown if the options are invalid.
+	 */
+	private void assertOptionsValid(int options) throws XMPException
+	{
+		int invalidOptions = options & ~getValidOptions();
+		if (invalidOptions == 0)
+		{
+			assertConsistency(options);
+		}
+		else
+		{
+			throw new XMPException("The option bit(s) 0x" + Integer.toHexString(invalidOptions)
+					+ " are invalid!", XMPError.BADOPTIONS);
+		}
+	}
+	
+	
+	
+	/**
+	 * Looks up or asks the inherited class for the name of an option bit.
+	 * Its save that there is only one valid option handed into the method.
+	 * @param option a single option bit
+	 * @return Returns the option name or undefined.
+	 */
+	private String getOptionName(int option)
+	{
+		Map optionsNames = procureOptionNames();
+		
+		Integer key = new Integer(option);
+		String result = (String) optionsNames.get(key);
+		if (result == null)
+		{
+			result = defineOptionName(option);
+			if (result != null)
+			{
+				optionsNames.put(key, result); 
+			}
+			else
+			{
+				result = "<option name not defined>";
+			}
+		}
+		
+		return result;
+	}
+
+
+	/**
+	 * @return Returns the optionNames map and creates it if required.
+	 */
+	private Map procureOptionNames()
+	{
+		if (optionNames == null)
+		{	
+			optionNames = new HashMap();
+		}
+		return optionNames;
+	}
+}
diff --git a/XMPCore/src/com/adobe/xmp/options/ParseOptions.java b/XMPCore/src/com/adobe/xmp/options/ParseOptions.java
new file mode 100644
index 0000000..c05f871
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/ParseOptions.java
@@ -0,0 +1,174 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+import java.io.InputStream;
+
+import com.adobe.xmp.XMPMetaFactory;
+
+
+/**
+ * Options for {@link XMPMetaFactory#parse(InputStream, ParseOptions)}.
+ * 
+ * @since 24.01.2006
+ */
+public final class ParseOptions extends Options
+{
+	/** Require a surrounding &quot;x:xmpmeta&quot; element in the xml-document. */
+	public static final int REQUIRE_XMP_META = 0x0001;
+	/** Do not reconcile alias differences, throw an exception instead. */
+	public static final int STRICT_ALIASING = 0x0004;
+	/** Convert ASCII control characters 0x01 - 0x1F (except tab, cr, and lf) to spaces. */
+	public static final int FIX_CONTROL_CHARS = 0x0008;
+	/** If the input is not unicode, try to parse it as ISO-8859-1. */
+	public static final int ACCEPT_LATIN_1 = 0x0010;
+	/** Do not carry run the XMPNormalizer on a packet, leave it as it is. */
+	public static final int OMIT_NORMALIZATION = 0x0020;
+
+	
+	/**
+	 * Sets the options to the default values.
+	 */
+	public ParseOptions()
+	{
+		setOption(FIX_CONTROL_CHARS | ACCEPT_LATIN_1, true);
+	}
+	
+	
+	/**
+	 * @return Returns the requireXMPMeta.
+	 */
+	public boolean getRequireXMPMeta()
+	{
+		return getOption(REQUIRE_XMP_META);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public ParseOptions setRequireXMPMeta(boolean value)
+	{
+		setOption(REQUIRE_XMP_META, value);
+		return this;
+	}
+
+	
+	/**
+	 * @return Returns the strictAliasing.
+	 */
+	public boolean getStrictAliasing()
+	{
+		return getOption(STRICT_ALIASING);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public ParseOptions setStrictAliasing(boolean value)
+	{
+		setOption(STRICT_ALIASING, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Returns the strictAliasing.
+	 */
+	public boolean getFixControlChars()
+	{
+		return getOption(FIX_CONTROL_CHARS);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public ParseOptions setFixControlChars(boolean value)
+	{
+		setOption(FIX_CONTROL_CHARS, value);
+		return this;
+	}
+	
+	
+	/**
+	 * @return Returns the strictAliasing.
+	 */
+	public boolean getAcceptLatin1()
+	{
+		return getOption(ACCEPT_LATIN_1);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public ParseOptions setOmitNormalization(boolean value)
+	{
+		setOption(OMIT_NORMALIZATION, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option "omit normalization".
+	 */
+	public boolean getOmitNormalization()
+	{
+		return getOption(OMIT_NORMALIZATION);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public ParseOptions setAcceptLatin1(boolean value)
+	{
+		setOption(ACCEPT_LATIN_1, value);
+		return this;
+	}
+
+	
+	/**
+	 * @see Options#defineOptionName(int)
+	 */
+	protected String defineOptionName(int option)
+	{
+		switch (option)
+		{
+			case REQUIRE_XMP_META :		return "REQUIRE_XMP_META";
+			case STRICT_ALIASING :		return "STRICT_ALIASING";
+			case FIX_CONTROL_CHARS:		return "FIX_CONTROL_CHARS";
+			case ACCEPT_LATIN_1:		return "ACCEPT_LATIN_1";
+			case OMIT_NORMALIZATION:	return "OMIT_NORMALIZATION";
+			default: 					return null;
+		}
+	}
+
+	
+	/**
+	 * @see Options#getValidOptions()
+	 */
+	protected int getValidOptions()
+	{
+		return 
+			REQUIRE_XMP_META |
+			STRICT_ALIASING |
+			FIX_CONTROL_CHARS |
+			ACCEPT_LATIN_1 |
+			OMIT_NORMALIZATION;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/options/PropertyOptions.java b/XMPCore/src/com/adobe/xmp/options/PropertyOptions.java
new file mode 100644
index 0000000..ae280fe
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/PropertyOptions.java
@@ -0,0 +1,429 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+import com.adobe.xmp.XMPError;
+import com.adobe.xmp.XMPException;
+
+
+/**
+ * The property flags are used when properties are fetched from the <code>XMPMeta</code>-object
+ * and provide more detailed information about the property.
+ * 
+ * @since   03.07.2006
+ */
+public final class PropertyOptions extends Options
+{
+	/** */
+	public static final int NO_OPTIONS = 0x00000000;
+	/** */
+	public static final int URI = 0x00000002;
+	/** */
+	public static final int HAS_QUALIFIERS = 0x00000010;
+	/** */
+	public static final int QUALIFIER = 0x00000020;
+	/** */
+	public static final int HAS_LANGUAGE = 0x00000040;
+	/** */
+	public static final int HAS_TYPE = 0x00000080;
+	/** */
+	public static final int STRUCT = 0x00000100;
+	/** */
+	public static final int ARRAY = 0x00000200;
+	/** */
+	public static final int ARRAY_ORDERED = 0x00000400;
+	/** */
+	public static final int ARRAY_ALTERNATE = 0x00000800;
+	/** */
+	public static final int ARRAY_ALT_TEXT = 0x00001000;
+	/** */
+	public static final int SCHEMA_NODE = 0x80000000;
+	/** may be used in the future */
+	public static final int DELETE_EXISTING = 0x20000000;
+	
+	
+	/**
+	 * Default constructor
+	 */
+	public PropertyOptions()
+	{
+		// reveal default constructor
+	}
+	
+	
+	/**
+	 * Intialization constructor
+	 * 
+	 * @param options the initialization options
+	 * @throws XMPException If the options are not valid 
+	 */
+	public PropertyOptions(int options) throws XMPException
+	{
+		super(options);
+	}
+
+	
+	/**
+	 * @return Return whether the property value is a URI. It is serialized to RDF using the
+	 *         <tt>rdf:resource</tt> attribute. Not mandatory for URIs, but considered RDF-savvy.
+	 */
+	public boolean isURI()
+	{
+		return getOption(URI);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setURI(boolean value)
+	{
+		setOption(URI, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Return whether the property has qualifiers. These could be an <tt>xml:lang</tt>
+	 *         attribute, an <tt>rdf:type</tt> property, or a general qualifier. See the
+	 *         introductory discussion of qualified properties for more information.
+	 */
+	public boolean getHasQualifiers()
+	{
+		return getOption(HAS_QUALIFIERS);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setHasQualifiers(boolean value)
+	{
+		setOption(HAS_QUALIFIERS, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Return whether this property is a qualifier for some other property. Note that if the
+	 *         qualifier itself has a structured value, this flag is only set for the top node of
+	 *         the qualifier's subtree. Qualifiers may have arbitrary structure, and may even have
+	 *         qualifiers.
+	 */
+	public boolean isQualifier()
+	{
+		return getOption(QUALIFIER);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setQualifier(boolean value)
+	{
+		setOption(QUALIFIER, value);
+		return this;
+	}
+	
+
+	/** @return Return whether this property has an <tt>xml:lang</tt> qualifier. */
+	public boolean getHasLanguage()
+	{
+		return getOption(HAS_LANGUAGE);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setHasLanguage(boolean value)
+	{
+		setOption(HAS_LANGUAGE, value);
+		return this;
+	}
+	
+
+	/** @return Return whether this property has an <tt>rdf:type</tt> qualifier. */
+	public boolean getHasType()
+	{
+		return getOption(HAS_TYPE);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setHasType(boolean value)
+	{
+		setOption(HAS_TYPE, value);
+		return this;
+	}
+	
+
+	/** @return Return whether this property contains nested fields. */
+	public boolean isStruct()
+	{
+		return getOption(STRUCT);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setStruct(boolean value)
+	{
+		setOption(STRUCT, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Return whether this property is an array. By itself this indicates a general
+	 *         unordered array. It is serialized using an <tt>rdf:Bag</tt> container.
+	 */
+	public boolean isArray()
+	{
+		return getOption(ARRAY);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setArray(boolean value)
+	{
+		setOption(ARRAY, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Return whether this property is an ordered array. Appears in conjunction with
+	 *         getPropValueIsArray(). It is serialized using an <tt>rdf:Seq</tt> container.
+	 */
+	public boolean isArrayOrdered()
+	{
+		return getOption(ARRAY_ORDERED);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setArrayOrdered(boolean value)
+	{
+		setOption(ARRAY_ORDERED, value);
+		return this;
+	}
+
+	
+	/**
+	 * @return Return whether this property is an alternative array. Appears in conjunction with
+	 *         getPropValueIsArray(). It is serialized using an <tt>rdf:Alt</tt> container.
+	 */
+	public boolean isArrayAlternate()
+	{
+		return getOption(ARRAY_ALTERNATE);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setArrayAlternate(boolean value)
+	{
+		setOption(ARRAY_ALTERNATE, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Return whether this property is an alt-text array. Appears in conjunction with
+	 *         getPropArrayIsAlternate(). It is serialized using an <tt>rdf:Alt</tt> container.
+	 *         Each array element is a simple property with an <tt>xml:lang</tt> attribute.
+	 */
+	public boolean isArrayAltText()
+	{
+		return getOption(ARRAY_ALT_TEXT);
+	}
+
+	
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setArrayAltText(boolean value)
+	{
+		setOption(ARRAY_ALT_TEXT, value);
+		return this;
+	}
+	
+
+	/**
+	 * @param value the value to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	
+	
+	/**
+	 * @return Returns whether the SCHEMA_NODE option is set.
+	 */
+	public boolean isSchemaNode()
+	{
+		return getOption(SCHEMA_NODE);
+	}
+
+
+	/**
+	 * @param value the option DELETE_EXISTING to set
+	 * @return Returns this to enable cascaded options.
+	 */
+	public PropertyOptions setSchemaNode(boolean value)
+	{
+		setOption(SCHEMA_NODE, value);
+		return this;
+	}
+	
+	
+	//-------------------------------------------------------------------------- convenience methods
+	
+	/**
+	 * @return Returns whether the property is of composite type - an array or a struct.
+	 */
+	public boolean isCompositeProperty()
+	{
+		return (getOptions() & (ARRAY | STRUCT)) > 0;
+	}
+
+	
+	/**
+	 * @return Returns whether the property is of composite type - an array or a struct.
+	 */
+	public boolean isSimple()
+	{
+		return (getOptions() & (ARRAY | STRUCT)) == 0;
+	}
+	
+	
+	/**
+	 * Compares two options set for array compatibility.
+	 * 
+	 * @param options other options
+	 * @return Returns true if the array options of the sets are equal.
+	 */
+	public boolean equalArrayTypes(PropertyOptions options)
+	{
+		return
+			isArray()			== options.isArray()  			&&
+			isArrayOrdered()	== options.isArrayOrdered()  	&&
+			isArrayAlternate()	== options.isArrayAlternate()	&&
+			isArrayAltText()	== options.isArrayAltText();
+	}
+	
+	
+	
+	/**
+	 * Merges the set options of a another options object with this.
+	 * If the other options set is null, this objects stays the same.
+	 * @param options other options
+	 * @throws XMPException If illegal options are provided 
+	 */
+	public void mergeWith(PropertyOptions options) throws XMPException
+	{
+		if (options != null)
+		{	
+			setOptions(getOptions() | options.getOptions());
+		}
+	}
+
+
+	/**
+	 * @return Returns true if only array options are set.
+	 */
+	public boolean isOnlyArrayOptions()
+	{
+		return (getOptions() & 
+			~(ARRAY | ARRAY_ORDERED | ARRAY_ALTERNATE | ARRAY_ALT_TEXT)) == 0;
+	}
+
+
+	/**
+	 * @see Options#getValidOptions()
+	 */
+	protected int getValidOptions()
+	{
+		return
+			URI |
+			HAS_QUALIFIERS |
+			QUALIFIER |
+			HAS_LANGUAGE |
+			HAS_TYPE |
+			STRUCT |
+			ARRAY |
+			ARRAY_ORDERED |
+			ARRAY_ALTERNATE |
+			ARRAY_ALT_TEXT |
+			SCHEMA_NODE;			
+	}
+
+	
+	/**
+	 * @see Options#defineOptionName(int)
+	 */
+	protected String defineOptionName(int option)
+	{
+		switch (option)
+		{
+			case URI : 				return "URI";
+			case HAS_QUALIFIERS :	return "HAS_QUALIFIER";
+			case QUALIFIER :		return "QUALIFIER";
+			case HAS_LANGUAGE :		return "HAS_LANGUAGE";
+			case HAS_TYPE:			return "HAS_TYPE";
+			case STRUCT :			return "STRUCT";
+			case ARRAY :			return "ARRAY";
+			case ARRAY_ORDERED :	return "ARRAY_ORDERED";
+			case ARRAY_ALTERNATE :	return "ARRAY_ALTERNATE";
+			case ARRAY_ALT_TEXT : 	return "ARRAY_ALT_TEXT";
+			case SCHEMA_NODE : 		return "SCHEMA_NODE";
+			default: 				return null;
+		}
+	}
+
+
+	/**
+	 * Checks that a node not a struct and array at the same time;
+	 * and URI cannot be a struct.
+	 * 
+	 * @param options the bitmask to check.
+	 * @throws XMPException Thrown if the options are not consistent.
+	 */
+	public void assertConsistency(int options) throws XMPException
+	{
+		if ((options & STRUCT) > 0  &&  (options & ARRAY) > 0)
+		{
+			throw new XMPException("IsStruct and IsArray options are mutually exclusive",
+					XMPError.BADOPTIONS);
+		}
+		else if ((options & URI) > 0  &&  (options & (ARRAY | STRUCT)) > 0)
+		{	
+			throw new XMPException("Structs and arrays can't have \"value\" options",
+				XMPError.BADOPTIONS);
+		}
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/options/SerializeOptions.java b/XMPCore/src/com/adobe/xmp/options/SerializeOptions.java
new file mode 100644
index 0000000..37ed7bd
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/SerializeOptions.java
@@ -0,0 +1,436 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.options;
+
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPMetaFactory;
+
+
+/**
+ * Options for {@link XMPMetaFactory#serializeToBuffer(XMPMeta, SerializeOptions)}.
+ * 
+ * @since 24.01.2006
+ */
+public final class SerializeOptions extends Options
+{
+	/** Omit the XML packet wrapper. */
+	public static final int OMIT_PACKET_WRAPPER = 0x0010;
+	/** Mark packet as read-only. Default is a writeable packet. */
+	public static final int READONLY_PACKET = 0x0020;
+	/** Use a compact form of RDF. */
+	public static final int USE_COMPACT_FORMAT = 0x0040;
+	/**
+	 * Include a padding allowance for a thumbnail image. If no <tt>xmp:Thumbnails</tt> property
+	 * is present, the typical space for a JPEG thumbnail is used.
+	 */
+	public static final int INCLUDE_THUMBNAIL_PAD = 0x0100;
+	/**
+	 * The padding parameter provides the overall packet length. The actual amount of padding is
+	 * computed. An exception is thrown if the packet exceeds this length with no padding.
+	 */
+	public static final int EXACT_PACKET_LENGTH = 0x0200;
+	/** Sort the struct properties and qualifier before serializing */
+	public static final int SORT = 0x1000;
+
+	// ---------------------------------------------------------------------------------------------
+	// encoding bit constants
+
+	/** Bit indicating little endian encoding, unset is big endian */
+	private static final int LITTLEENDIAN_BIT = 0x0001;
+	/** Bit indication UTF16 encoding. */
+	private static final int UTF16_BIT = 0x0002;
+	/** UTF8 encoding; this is the default */
+	public static final int ENCODE_UTF8 = 0;
+	/** UTF16BE encoding */
+	public static final int ENCODE_UTF16BE = UTF16_BIT;
+	/** UTF16LE encoding */
+	public static final int ENCODE_UTF16LE = UTF16_BIT | LITTLEENDIAN_BIT;
+	/** */
+	private static final int ENCODING_MASK = UTF16_BIT | LITTLEENDIAN_BIT;			
+
+	/**
+	 * The amount of padding to be added if a writeable XML packet is created. If zero is passed
+	 * (the default) an appropriate amount of padding is computed.
+	 */
+	private int padding = 2048;
+	/**
+	 * The string to be used as a line terminator. If empty it defaults to; linefeed, U+000A, the
+	 * standard XML newline.
+	 */
+	private String newline = "\n";
+	/**
+	 * The string to be used for each level of indentation in the serialized
+	 * RDF. If empty it defaults to two ASCII spaces, U+0020.
+	 */
+	private String indent = "  ";
+	/**
+	 * The number of levels of indentation to be used for the outermost XML element in the
+	 * serialized RDF. This is convenient when embedding the RDF in other text, defaults to 0.
+	 */
+	private int baseIndent = 0;
+	/** Omits the Toolkit version attribute, not published, only used for Unit tests. */
+	private boolean omitVersionAttribute = false;
+	
+	
+	/**
+	 * Default constructor.
+	 */
+	public SerializeOptions()
+	{
+		// reveal default constructor
+	}
+
+	
+	/**
+	 * Constructor using inital options
+	 * @param options the inital options
+	 * @throws XMPException Thrown if options are not consistant.
+	 */
+	public SerializeOptions(int options) throws XMPException
+	{
+		super(options);
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getOmitPacketWrapper()
+	{
+		return getOption(OMIT_PACKET_WRAPPER);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setOmitPacketWrapper(boolean value)
+	{
+		setOption(OMIT_PACKET_WRAPPER, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getReadOnlyPacket()
+	{
+		return getOption(READONLY_PACKET);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setReadOnlyPacket(boolean value)
+	{
+		setOption(READONLY_PACKET, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getUseCompactFormat()
+	{
+		return getOption(USE_COMPACT_FORMAT);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setUseCompactFormat(boolean value)
+	{
+		setOption(USE_COMPACT_FORMAT, value);
+		return this;
+	}
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getIncludeThumbnailPad()
+	{
+		return getOption(INCLUDE_THUMBNAIL_PAD);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setIncludeThumbnailPad(boolean value)
+	{
+		setOption(INCLUDE_THUMBNAIL_PAD, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getExactPacketLength()
+	{
+		return getOption(EXACT_PACKET_LENGTH);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setExactPacketLength(boolean value)
+	{
+		setOption(EXACT_PACKET_LENGTH, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getSort()
+	{
+		return getOption(SORT);
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setSort(boolean value)
+	{
+		setOption(SORT, value);
+		return this;
+	}
+	
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getEncodeUTF16BE()
+	{
+		return (getOptions() & ENCODING_MASK) == ENCODE_UTF16BE;
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setEncodeUTF16BE(boolean value)
+	{
+		// clear unicode bits
+		setOption(UTF16_BIT | LITTLEENDIAN_BIT, false);
+		setOption(ENCODE_UTF16BE, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the option.
+	 */
+	public boolean getEncodeUTF16LE()
+	{
+		return (getOptions() & ENCODING_MASK) == ENCODE_UTF16LE;
+	}
+
+
+	/**
+	 * @param value the value to set
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setEncodeUTF16LE(boolean value)
+	{
+		// clear unicode bits
+		setOption(UTF16_BIT | LITTLEENDIAN_BIT, false);
+		setOption(ENCODE_UTF16LE, value);
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the baseIndent.
+	 */
+	public int getBaseIndent()
+	{
+		return baseIndent;
+	}
+
+
+	/**
+	 * @param baseIndent
+	 *            The baseIndent to set.
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setBaseIndent(int baseIndent)
+	{
+		this.baseIndent = baseIndent;
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the indent.
+	 */
+	public String getIndent()
+	{
+		return indent;
+	}
+
+
+	/**
+	 * @param indent
+	 *            The indent to set.
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setIndent(String indent)
+	{
+		this.indent = indent;
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the newline.
+	 */
+	public String getNewline()
+	{
+		return newline;
+	}
+
+
+	/**
+	 * @param newline
+	 *            The newline to set.
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setNewline(String newline)
+	{
+		this.newline = newline;
+		return this;
+	}
+
+
+	/**
+	 * @return Returns the padding.
+	 */
+	public int getPadding()
+	{
+		return padding;
+	}
+
+
+	/**
+	 * @param padding
+	 *            The padding to set.
+	 * @return Returns the instance to call more set-methods.
+	 */
+	public SerializeOptions setPadding(int padding)
+	{
+		this.padding = padding;
+		return this;
+	}
+	
+	
+	/**
+	 * @return Returns whether the Toolkit version attribute shall be omitted.
+	 * <em>Note:</em> This options can only be set by unit tests.
+	 */
+	public boolean getOmitVersionAttribute()
+	{
+		return omitVersionAttribute;
+	}
+	
+	
+	/**
+	 * @return Returns the encoding as Java encoding String. 
+	 */
+	public String getEncoding()
+	{
+		if (getEncodeUTF16BE())
+		{
+			return "UTF-16BE";
+		}
+		else if (getEncodeUTF16LE())
+		{
+			return "UTF-16LE";
+		}
+		else
+		{
+			return "UTF-8";
+		}
+	}
+	
+	
+	/**
+	 * 
+	 * @return Returns clone of this SerializeOptions-object with the same options set. 
+	 * @throws CloneNotSupportedException Cannot happen in this place.  
+	 */
+	public Object clone() throws CloneNotSupportedException
+	{
+		SerializeOptions clone;
+		try
+		{
+			clone = new SerializeOptions(getOptions());
+			clone.setBaseIndent(baseIndent);
+			clone.setIndent(indent);
+			clone.setNewline(newline);
+			clone.setPadding(padding);
+			return clone;
+		}
+		catch (XMPException e)
+		{
+			// This cannot happen, the options are already checked in "this" object.
+			return null;
+		}
+	}
+
+
+	/**
+	 * @see Options#defineOptionName(int)
+	 */
+	protected String defineOptionName(int option)
+	{
+		switch (option)
+		{
+			case OMIT_PACKET_WRAPPER : 		return "OMIT_PACKET_WRAPPER";
+			case READONLY_PACKET :			return "READONLY_PACKET";
+			case USE_COMPACT_FORMAT :		return "USE_COMPACT_FORMAT";
+			case INCLUDE_THUMBNAIL_PAD :	return "INCLUDE_THUMBNAIL_PAD";
+			case EXACT_PACKET_LENGTH :		return "EXACT_PACKET_LENGTH";
+			case SORT :				return "NORMALIZED";
+			default: 						return null;
+		}
+	}
+
+	
+	/**
+	 * @see Options#getValidOptions()
+	 */
+	protected int getValidOptions()
+	{
+		return 
+		OMIT_PACKET_WRAPPER |
+		READONLY_PACKET |
+		USE_COMPACT_FORMAT |
+		INCLUDE_THUMBNAIL_PAD |
+		EXACT_PACKET_LENGTH |
+		SORT;
+	}
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/options/package.html b/XMPCore/src/com/adobe/xmp/options/package.html
new file mode 100644
index 0000000..d2e56d0
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/options/package.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>Package overview</title>
+</head>
+
+<body>
+	<p>Package containing the option classes.</p>
+	<p>These are used to configure diverse function calls of xmpcore:<p>
+	<ul>
+		<li>PropertyOptions - these are used to create properties and also to retrieve information about simple, array or struct properties, as well as qualifiers
+		<li>ParseOptions - used to configure the parsing of xmp metadata packets
+		<li>SerializationOptions - used to control the serialization of xmp metadata packets
+		<li>AliasOptions - used by XMPSchemaRegistry#registerAlias()
+		<li>IteratorOptions - used to set up an XMPIterator
+		<li>Options - the base class of all option classes
+	</ul>
+</body>
+</html>
diff --git a/XMPCore/src/com/adobe/xmp/package.html b/XMPCore/src/com/adobe/xmp/package.html
new file mode 100644
index 0000000..8afb896
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/package.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>Package overview</title>
+</head>
+
+<body>
+	<p>Package containing the xmpcore interface.</p>
+</body>
+</html>
diff --git a/XMPCore/src/com/adobe/xmp/properties/XMPAliasInfo.java b/XMPCore/src/com/adobe/xmp/properties/XMPAliasInfo.java
new file mode 100644
index 0000000..e9078d4
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/properties/XMPAliasInfo.java
@@ -0,0 +1,48 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.properties;
+
+import com.adobe.xmp.options.AliasOptions;
+
+
+/**
+ * This interface is used to return info about an alias.
+ * 
+ * @since   27.01.2006
+ */
+public interface XMPAliasInfo
+{
+	/**
+	 * @return Returns Returns the namespace URI for the base property.
+	 */
+	String getNamespace();
+
+
+	/**
+	 * @return Returns the default prefix for the given base property. 
+	 */
+	String getPrefix();
+
+	
+	/**
+	 * @return Returns the path of the base property.
+	 */
+	String getPropName();
+
+	
+	/**
+	 * @return Returns the kind of the alias. This can be a direct alias
+	 *         (ARRAY), a simple property to an ordered array
+	 *         (ARRAY_ORDERED), to an alternate array
+	 *         (ARRAY_ALTERNATE) or to an alternate text array
+	 *         (ARRAY_ALT_TEXT).
+	 */
+	AliasOptions getAliasForm();
+}
\ No newline at end of file
diff --git a/XMPCore/src/com/adobe/xmp/properties/XMPProperty.java b/XMPCore/src/com/adobe/xmp/properties/XMPProperty.java
new file mode 100644
index 0000000..767c94b
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/properties/XMPProperty.java
@@ -0,0 +1,40 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.properties;
+
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * This interface is used to return a text property together with its and options.
+ * 
+ * @since   23.01.2006
+ */
+public interface XMPProperty 
+{
+	/**
+	 * @return Returns the value of the property.
+	 */
+	Object getValue();
+	
+	
+	/**
+	 * @return Returns the options of the property.
+	 */
+	PropertyOptions getOptions();
+	
+	
+	/**
+	 * Only set by {@link XMPMeta#getLocalizedText(String, String, String, String)}. 
+	 * @return Returns the language of the alt-text item.
+	 */
+	String getLanguage();
+}
diff --git a/XMPCore/src/com/adobe/xmp/properties/XMPPropertyInfo.java b/XMPCore/src/com/adobe/xmp/properties/XMPPropertyInfo.java
new file mode 100644
index 0000000..8a9c519
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/properties/XMPPropertyInfo.java
@@ -0,0 +1,45 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2006 Adobe Systems Incorporated
+// All Rights Reserved
+//
+// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+package com.adobe.xmp.properties;
+
+import com.adobe.xmp.options.PropertyOptions;
+
+
+/**
+ * This interface is used to return a property together with its path and namespace.
+ * It is returned when properties are iterated with the <code>XMPIterator</code>.
+ * 
+ * @since   06.07.2006
+ */
+public interface XMPPropertyInfo extends XMPProperty
+{
+	/**
+	 * @return Returns the namespace of the property
+	 */
+	String getNamespace();
+
+	
+	/**
+	 * @return Returns the path of the property, but only if returned by the iterator.
+	 */
+	String getPath();
+
+	
+	/**
+	 * @return Returns the value of the property.
+	 */
+	Object getValue();
+	
+	
+	/**
+	 * @return Returns the options of the property.
+	 */
+	PropertyOptions getOptions();
+}
diff --git a/XMPCore/src/com/adobe/xmp/properties/package.html b/XMPCore/src/com/adobe/xmp/properties/package.html
new file mode 100644
index 0000000..19e7427
--- /dev/null
+++ b/XMPCore/src/com/adobe/xmp/properties/package.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<title>Package overview</title>
+</head>
+
+<body>
+	<p>Package containing the property information classes.</p>
+	<p>XMPProperty and XMPPropertyInfo are used to report properties when they are retrieved by get-methods or by the iterator. 
+	   XMPAliasInfo informs about a certain property-to-property alias.<p>
+</body>
+</html>
