diff --git a/ChangeLog b/ChangeLog
index c043a40..3950c73 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-06-28  Hubert Figuiere  <hub@figuiere.net>
+
+	* src/eog-exif-details.{c,h}, src/main.c, 
+	src/eog-properties-dialog.{c.h}, src/eog-metadata-reader.(c,h},
+	src/eog-image.{c,h}, src/eog-image-private.h, src/Makefile.am,
+	data/eog.glade, configure.ac: Optional XMP metadata support.
+	Fixes bug #451101 (Hubert Figuiere).
+
 2007-06-26  Lucas Rocha  <lucasr@geladinho>
 
 	* src/eog-window.c: use slideshow icon from gnome-icon-theme for
diff --git a/configure.ac b/configure.ac
index 16a0ba2..6e33961 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,6 +60,8 @@ LIBART_REQUIRED=2.3.16
 GNOME_DESKTOP_REQUIRED=2.10.0
 GTK_PRINT_REQUIRED=2.10.0
 GNOME_ICON_THEME_REQUIRED=2.17.1
+EXEMPI_REQUIRED=1.99.2
+
 
 EOG_MODULES="gtk+-2.0 >= $GTK_REQUIRED \
              glib-2.0 >= $GLIB_REQUIRED \
@@ -105,6 +107,23 @@ if test "x$have_lcms" = "xyes"; then
   EOG_MODULES="$EOG_MODULES lcms"
 fi
 
+
+# *********************
+# Exempi (optional)
+# *********************
+AC_ARG_WITH(xmp, AC_HELP_STRING([--without-xmp], [disable special XMP support]))
+have_exempi=no
+if test x$with_xmp != xno; then
+    PKG_CHECK_MODULES(EXEMPI, exempi-2.0 >= $EXEMPI_REQUIRED, have_exempi=yes, have_exempi=no)
+fi 
+if test "x$have_exempi" = "xyes"; then
+  AC_DEFINE(HAVE_EXEMPI,1, [XMP support.])
+  EOG_MODULES="$EOG_MODULES exempi-2.0 >= $EXEMPI_REQUIRED"
+fi
+
+AM_CONDITIONAL([HAVE_EXEMPI], [test "x$have_exempi" = "xyes"])
+ 
+
 # ********************
 # Jpeg (semi-optional)
 # ********************
@@ -253,6 +272,7 @@ Configure summary:
 	Extra Compiler Warnings ....:  ${WARN_CFLAGS}
 
 	EXIF support ...............:  ${have_exif}
+	XMP support ................:  ${have_exempi}
 	JPEG support ...............:  ${have_jpeg}
 	Colour management support ..:  ${have_lcms}
 	D-Bus activation............:  ${have_dbus}
diff --git a/data/eog.glade b/data/eog.glade
index 5b4dd62..a34f1fb 100644
--- a/data/eog.glade
+++ b/data/eog.glade
@@ -232,6 +232,8 @@
 		      <property name="width_request">100</property>
 		      <property name="height_request">100</property>
 		      <property name="visible">True</property>
+		      <property name="stock">gtk-missing-image</property>
+		      <property name="icon_size">4</property>
 		      <property name="xalign">0.5</property>
 		      <property name="yalign">0.5</property>
 		      <property name="xpad">0</property>
@@ -838,6 +840,156 @@
 			  <property name="fill">False</property>
 			</packing>
 		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label19">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Location:&lt;/b&gt;	</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label20">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Description:&lt;/b&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label21">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Keywords:&lt;/b&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label28">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Author:&lt;/b&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label29">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Copyright:&lt;/b&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label22">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">&lt;b&gt;Rating:&lt;/b&gt;</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">True</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
 		    </widget>
 		    <packing>
 		      <property name="padding">0</property>
@@ -1051,6 +1203,161 @@
 			  <property name="fill">False</property>
 			</packing>
 		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_location">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">True</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_description">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">True</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_keywords">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">True</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_creator">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">True</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_rights">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">True</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="xmp_rating">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">...</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
 		    </widget>
 		    <packing>
 		      <property name="padding">0</property>
@@ -1117,7 +1424,7 @@
 	  <child>
 	    <widget class="GtkLabel" id="label44">
 	      <property name="visible">True</property>
-	      <property name="label">EXIF</property>
+	      <property name="label">Metadata</property>
 	      <property name="use_underline">False</property>
 	      <property name="use_markup">False</property>
 	      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -1663,10 +1970,10 @@
 			  <property name="column_spacing">6</property>
 
 			  <child>
-			    <widget class="GtkRadioButton" id="left_radio">
+			    <widget class="GtkRadioButton" id="bottom_radio">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Left</property>
+			      <property name="label" translatable="yes">Bottom</property>
 			      <property name="use_underline">True</property>
 			      <property name="relief">GTK_RELIEF_NORMAL</property>
 			      <property name="focus_on_click">True</property>
@@ -1675,80 +1982,77 @@
 			      <property name="draw_indicator">True</property>
 			    </widget>
 			    <packing>
-			      <property name="left_attach">0</property>
-			      <property name="right_attach">1</property>
-			      <property name="top_attach">0</property>
-			      <property name="bottom_attach">1</property>
-			      <property name="x_options">fill</property>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options"></property>
 			      <property name="y_options"></property>
 			    </packing>
 			  </child>
 
 			  <child>
-			    <widget class="GtkRadioButton" id="right_radio">
+			    <widget class="GtkRadioButton" id="top_radio">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Right</property>
+			      <property name="label" translatable="yes">Top</property>
 			      <property name="use_underline">True</property>
 			      <property name="relief">GTK_RELIEF_NORMAL</property>
 			      <property name="focus_on_click">True</property>
 			      <property name="active">False</property>
 			      <property name="inconsistent">False</property>
 			      <property name="draw_indicator">True</property>
-			      <property name="group">left_radio</property>
 			    </widget>
 			    <packing>
-			      <property name="left_attach">1</property>
-			      <property name="right_attach">2</property>
-			      <property name="top_attach">0</property>
-			      <property name="bottom_attach">1</property>
-			      <property name="x_options">fill</property>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options"></property>
 			      <property name="y_options"></property>
 			    </packing>
 			  </child>
 
 			  <child>
-			    <widget class="GtkRadioButton" id="top_radio">
+			    <widget class="GtkRadioButton" id="right_radio">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Top</property>
+			      <property name="label" translatable="yes">Right</property>
 			      <property name="use_underline">True</property>
 			      <property name="relief">GTK_RELIEF_NORMAL</property>
 			      <property name="focus_on_click">True</property>
 			      <property name="active">False</property>
 			      <property name="inconsistent">False</property>
 			      <property name="draw_indicator">True</property>
-			      <property name="group">left_radio</property>
 			    </widget>
 			    <packing>
-			      <property name="left_attach">0</property>
-			      <property name="right_attach">1</property>
-			      <property name="top_attach">1</property>
-			      <property name="bottom_attach">2</property>
-			      <property name="x_options">fill</property>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options"></property>
 			      <property name="y_options"></property>
 			    </packing>
 			  </child>
 
 			  <child>
-			    <widget class="GtkRadioButton" id="bottom_radio">
+			    <widget class="GtkRadioButton" id="left_radio">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">Bottom</property>
+			      <property name="label" translatable="yes">Left</property>
 			      <property name="use_underline">True</property>
 			      <property name="relief">GTK_RELIEF_NORMAL</property>
 			      <property name="focus_on_click">True</property>
 			      <property name="active">False</property>
 			      <property name="inconsistent">False</property>
 			      <property name="draw_indicator">True</property>
-			      <property name="group">left_radio</property>
 			    </widget>
 			    <packing>
-			      <property name="left_attach">1</property>
-			      <property name="right_attach">2</property>
-			      <property name="top_attach">1</property>
-			      <property name="bottom_attach">2</property>
-			      <property name="x_options">fill</property>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options"></property>
 			      <property name="y_options"></property>
 			    </packing>
 			  </child>
@@ -2379,6 +2683,114 @@
 		      <property name="column_spacing">6</property>
 
 		      <child>
+			<widget class="GtkLabel" id="label10">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Destination folder:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkFileChooserButton" id="dir_chooser">
+			  <property name="visible">True</property>
+			  <property name="title" translatable="yes">Choose a folder</property>
+			  <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+			  <property name="local_only">False</property>
+			  <property name="show_hidden">False</property>
+			  <property name="do_overwrite_confirmation">False</property>
+			  <property name="width_chars">-1</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label11">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Filename format:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="token_entry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes">%f</property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</property>
+			  <signal name="changed" handler="on_token_entry_changed"/>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="format_combobox">
+			  <property name="visible">True</property>
+			  <property name="items" translatable="yes">
+</property>
+			  <property name="add_tearoffs">False</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">2</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			</packing>
+		      </child>
+
+		      <child>
 			<widget class="GtkVBox" id="vbox2">
 			  <property name="visible">True</property>
 			  <property name="homogeneous">False</property>
@@ -2441,114 +2853,6 @@
 			  <property name="bottom_attach">3</property>
 			</packing>
 		      </child>
-
-		      <child>
-			<widget class="GtkComboBox" id="format_combobox">
-			  <property name="visible">True</property>
-			  <property name="items" translatable="yes">
-</property>
-			  <property name="add_tearoffs">False</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">2</property>
-			  <property name="right_attach">3</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkEntry" id="token_entry">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-			  <property name="editable">True</property>
-			  <property name="visibility">True</property>
-			  <property name="max_length">0</property>
-			  <property name="text" translatable="yes">%f</property>
-			  <property name="has_frame">True</property>
-			  <property name="invisible_char">*</property>
-			  <property name="activates_default">False</property>
-			  <signal name="changed" handler="on_token_entry_changed" last_modification_time="Sun, 11 Jul 2004 14:33:47 GMT"/>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label11">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Filename format:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkFileChooserButton" id="dir_chooser">
-			  <property name="visible">True</property>
-			  <property name="title" translatable="yes">Choose a folder</property>
-			  <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
-			  <property name="local_only">False</property>
-			  <property name="show_hidden">False</property>
-			  <property name="do_overwrite_confirmation">False</property>
-			  <property name="width_chars">-1</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">3</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label10">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Destination folder:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			</packing>
-		      </child>
 		    </widget>
 		  </child>
 		</widget>
@@ -2652,7 +2956,7 @@
 			      <property name="snap_to_ticks">False</property>
 			      <property name="wrap">False</property>
 			      <property name="adjustment">1 0 10000000 1 10 10</property>
-			      <signal name="changed" handler="on_counter_spin_changed" last_modification_time="Wed, 30 Jun 2004 20:04:23 GMT"/>
+			      <signal name="changed" handler="on_counter_spin_changed"/>
 			    </widget>
 			    <packing>
 			      <property name="padding">0</property>
@@ -2750,9 +3054,9 @@
 		      <property name="column_spacing">6</property>
 
 		      <child>
-			<widget class="GtkLabel" id="preview_label">
+			<widget class="GtkLabel" id="label24">
 			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label</property>
+			  <property name="label" translatable="yes">Rename from:</property>
 			  <property name="use_underline">False</property>
 			  <property name="use_markup">False</property>
 			  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -2768,17 +3072,17 @@
 			  <property name="angle">0</property>
 			</widget>
 			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
 			</packing>
 		      </child>
 
 		      <child>
-			<widget class="GtkLabel" id="preview_label_from">
+			<widget class="GtkLabel" id="label35">
 			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label</property>
+			  <property name="label" translatable="yes">To:</property>
 			  <property name="use_underline">False</property>
 			  <property name="use_markup">False</property>
 			  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -2794,17 +3098,17 @@
 			  <property name="angle">0</property>
 			</widget>
 			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
 			</packing>
 		      </child>
 
 		      <child>
-			<widget class="GtkLabel" id="label35">
+			<widget class="GtkLabel" id="preview_label_from">
 			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">To:</property>
+			  <property name="label" translatable="yes">label</property>
 			  <property name="use_underline">False</property>
 			  <property name="use_markup">False</property>
 			  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -2820,17 +3124,17 @@
 			  <property name="angle">0</property>
 			</widget>
 			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
 			</packing>
 		      </child>
 
 		      <child>
-			<widget class="GtkLabel" id="label24">
+			<widget class="GtkLabel" id="preview_label">
 			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Rename from:</property>
+			  <property name="label" translatable="yes">label</property>
 			  <property name="use_underline">False</property>
 			  <property name="use_markup">False</property>
 			  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -2846,10 +3150,10 @@
 			  <property name="angle">0</property>
 			</widget>
 			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
 			</packing>
 		      </child>
 		    </widget>
diff --git a/src/Makefile.am b/src/Makefile.am
index d23f796..96dac23 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -108,11 +108,17 @@ libeog_la_SOURCES +=			\
 	eog-exif-details.c
 endif
 
+if HAVE_EXEMPI
+libeog_la_SOURCES +=			\
+	eog-exif-details.h		\
+	eog-exif-details.c
+endif
+
 libeog_la_CFLAGS =						\
 	$(EOG_CFLAGS)						\
 	$(WARN_CFLAGS)						\
 	-I$(top_srcdir)/jpegutils				\
- 	-I$(top_srcdir)/cut-n-paste/toolbar-editor		\
+	-I$(top_srcdir)/cut-n-paste/toolbar-editor		\
 	-DG_LOG_DOMAIN=\"EOG\"					\
 	-DEOG_PREFIX=\""${prefix}"\"				\
 	-DEOG_DATA_DIR=\""$(pkgdatadir)"\"			\
@@ -128,7 +134,7 @@ eog_DEPENDENCIES = 	\
 
 eog_CFLAGS = 							\
 	$(EOG_CFLAGS)						\
- 	-I$(top_srcdir)/cut-n-paste/toolbar-editor		\
+	-I$(top_srcdir)/cut-n-paste/toolbar-editor		\
 	-DEOG_DATADIR=\""$(pkgdatadir)"\"			\
 	-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
 
@@ -137,7 +143,7 @@ eog_LDADD = 				\
 	$(EOG_LIBS)			\
 	$(X_LIBS)			\
 	$(LIBJPEG)			\
- 	$(toolbar_LIB)			\
+	$(toolbar_LIB)			\
 	$(jpeg_LIB)
 
 BUILT_SOURCES = 			\
diff --git a/src/eog-exif-details.c b/src/eog-exif-details.c
index 9e5c083..22b278c 100644
--- a/src/eog-exif-details.c
+++ b/src/eog-exif-details.c
@@ -26,12 +26,20 @@
 #include "eog-exif-details.h"
 #include "eog-util.h"
 
+#if HAVE_EXIF
 #include <libexif/exif-entry.h>
 #include <libexif/exif-utils.h>
+#endif
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#include <exempi/xmpconsts.h>
+#endif
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#include <string.h>
+
 #define EOG_EXIF_DETAILS_GET_PRIVATE(object) \
 	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_EXIF_DETAILS, EogExifDetailsPrivate))
 
@@ -42,7 +50,11 @@ typedef enum {
 	EXIF_CATEGORY_IMAGE_DATA,
 	EXIF_CATEGORY_IMAGE_TAKING_CONDITIONS,
 	EXIF_CATEGORY_MAKER_NOTE,
-	EXIF_CATEGORY_OTHER
+	EXIF_CATEGORY_OTHER,
+	XMP_CATEGORY_EXIF,
+	XMP_CATEGORY_IPTC,
+	XMP_CATEGORY_RIGHTS,
+	XMP_CATEGORY_OTHER
 } ExifCategory;
 
 typedef struct {
@@ -56,6 +68,10 @@ static ExifCategoryInfo exif_categories[] = {
 	{ N_("Image Taking Conditions"), "2" },
 	{ N_("Maker Note"),              "3" },
 	{ N_("Other"),                   "4" },
+	{ N_("XMP Exif"),                "5" },
+	{ N_("XMP IPTC"),                "6" },
+	{ N_("XMP Rights Management"),   "7" },
+	{ N_("XMP Other"),               "8" },
 	{ NULL, NULL }
 };
 
@@ -441,3 +457,102 @@ eog_exif_details_update (EogExifDetails *exif_details, ExifData *data)
 		exif_data_foreach_content (data, exif_content_cb, exif_details);
 	}
 }
+
+
+#if HAVE_EXEMPI
+
+typedef struct {
+	const char *id;
+	ExifCategory category;
+} XmpNsCategory;
+
+static XmpNsCategory xmp_ns_category_map[] = {
+	{ NS_EXIF,                  XMP_CATEGORY_EXIF},
+	{ NS_TIFF,                  XMP_CATEGORY_EXIF},
+	{ NS_XAP,                   XMP_CATEGORY_EXIF},
+	{ NS_XAP_RIGHTS,            XMP_CATEGORY_RIGHTS},
+	{ NS_EXIF_AUX,              XMP_CATEGORY_EXIF},
+	{ NS_DC,                    XMP_CATEGORY_IPTC},
+	{ NS_IPTC4XMP,              XMP_CATEGORY_IPTC},
+	{ NS_CC,                    XMP_CATEGORY_RIGHTS},
+	{ NULL, -1}
+};
+
+static ExifCategory
+get_xmp_category (XmpStringPtr schema)
+{
+	ExifCategory cat = XMP_CATEGORY_OTHER;
+	int i;
+	const char *s = xmp_string_cstr(schema);
+	
+	for (i = 0; xmp_ns_category_map[i].id != NULL; i++) {
+		if (strcmp(xmp_ns_category_map[i].id, s) == 0) {
+			cat = xmp_ns_category_map[i].category;
+			break;
+		}
+	}
+	
+	return cat;
+}
+
+
+static void 
+xmp_entry_insert (EogExifDetails *view, XmpStringPtr xmp_schema, 
+									XmpStringPtr xmp_path, XmpStringPtr xmp_prop)
+{
+	GtkTreeStore *store;
+	EogExifDetailsPrivate *priv;
+	ExifCategory cat;
+	char *path;
+	gchar *key;
+	
+	priv = view->priv;
+	key = g_strdup_printf("%s:%s", xmp_string_cstr(xmp_schema), 
+												xmp_string_cstr(xmp_path));
+	
+	store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
+	
+	path = g_hash_table_lookup (priv->id_path_hash, key);
+	
+	if (path != NULL) {
+		set_row_data (store, path, NULL, xmp_string_cstr(xmp_path), 
+									xmp_string_cstr(xmp_prop));
+		g_free(key);
+	}
+	else {
+		cat = get_xmp_category(xmp_schema);
+		path = set_row_data (store, NULL, exif_categories[cat].path,
+												 xmp_string_cstr(xmp_path),  xmp_string_cstr(xmp_prop));
+		g_hash_table_insert (priv->id_path_hash, key, path);
+	}
+}
+
+void
+eog_exif_details_xmp_update  (EogExifDetails *view, XmpPtr data)
+{
+	EogExifDetailsPrivate *priv;
+	
+	g_return_if_fail (EOG_IS_EXIF_DETAILS (view));
+	
+	priv = view->priv;
+	
+	if (data) {
+		XmpIteratorPtr iter = xmp_iterator_new(data, NULL, NULL, 
+																					 XMP_ITER_JUSTLEAFNODES);
+		XmpStringPtr the_schema = xmp_string_new();
+		XmpStringPtr the_path = xmp_string_new();
+		XmpStringPtr the_prop = xmp_string_new();
+		while( xmp_iterator_next(iter, the_schema, the_path, the_prop, NULL) )
+		{
+			xmp_entry_insert(view, the_schema, the_path, the_prop);
+		}
+		xmp_string_free(the_prop);
+		xmp_string_free(the_path);
+		xmp_string_free(the_schema);
+		xmp_iterator_free(iter);
+	}
+}
+
+
+#endif
+
diff --git a/src/eog-exif-details.h b/src/eog-exif-details.h
index f2a8547..832e0cc 100644
--- a/src/eog-exif-details.h
+++ b/src/eog-exif-details.h
@@ -24,7 +24,12 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
+#if HAVE_EXIF
 #include <libexif/exif-data.h>
+#endif
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -53,8 +58,14 @@ GType               eog_exif_details_get_type    (void) G_GNUC_CONST;
 
 GtkWidget          *eog_exif_details_new         (void);
 
+#if HAVE_EXIF
 void                eog_exif_details_update      (EogExifDetails *view, 
 						  ExifData       *data);
+#endif
+#if HAVE_EXEMPI
+void                eog_exif_details_xmp_update  (EogExifDetails *view,
+							XmpPtr          xmp_data);
+#endif
 
 G_END_DECLS
 
diff --git a/src/eog-image-private.h b/src/eog-image-private.h
index ee7db87..e55698e 100644
--- a/src/eog-image-private.h
+++ b/src/eog-image-private.h
@@ -53,6 +53,9 @@ struct _EogImagePrivate {
 	gint              orientation;
 	ExifData         *exif;
 #endif
+#ifdef HAVE_EXEMPI
+ 	XmpPtr   xmp;
+#endif
 
 #ifdef HAVE_LCMS
 	cmsHPROFILE       profile;
diff --git a/src/eog-image.c b/src/eog-image.c
index 416974a..c8d0459 100644
--- a/src/eog-image.c
+++ b/src/eog-image.c
@@ -110,6 +110,13 @@ eog_image_free_mem_private (EogImage *image)
 
 		priv->exif_chunk_len = 0;
 
+#ifdef HAVE_EXEMPI
+		if(priv->xmp != NULL) {
+			xmp_free(priv->xmp);
+			priv->xmp = NULL;
+		}
+#endif
+
 #ifdef HAVE_LCMS
 		if (priv->profile != NULL) {
 			cmsCloseProfile (priv->profile);
@@ -239,7 +246,9 @@ eog_image_init (EogImage *img)
 	img->priv->autorotate = FALSE;
 	img->priv->exif = NULL;
 #endif
-
+#ifdef HAVE_EXEMPI
+	img->priv->xmp = NULL;
+#endif
 #ifdef HAVE_LCMS
 	img->priv->profile = NULL;
 #endif
@@ -510,6 +519,8 @@ eog_image_determine_file_bytes (EogImage *img, GError **error)
 	return bytes;
 }
 
+
+
 #ifdef HAVE_LCMS
 void
 eog_image_apply_display_profile (EogImage *img, cmsHPROFILE screen)
@@ -740,7 +751,7 @@ eog_image_real_autorotate (EogImage *img)
 		} else {
 			eog_transform_compose (priv->trans, trans);
 		}
-
+		
 		g_object_unref (trans);
 	}
 
@@ -759,6 +770,21 @@ eog_image_autorotate (EogImage *img)
 #endif
 
 static void
+eog_image_set_xmp_data (EogImage *img, EogMetadataReader *md_reader)
+{
+#ifdef HAVE_EXEMPI
+	EogImagePrivate *priv;
+
+	g_return_if_fail (EOG_IS_IMAGE (img));
+
+	priv = img->priv;
+
+	priv->xmp = eog_metadata_reader_get_xmp_data (md_reader);
+
+#endif
+}
+
+static void
 eog_image_set_exif_data (EogImage *img, EogMetadataReader *md_reader)
 {
 	EogImagePrivate *priv;
@@ -960,6 +986,9 @@ eog_image_real_load (EogImage *img,
 #ifdef HAVE_LCMS
 					eog_image_set_icc_data (img, md_reader);
 #endif
+#ifdef HAVE_EXEMPI
+					eog_image_set_xmp_data (img, md_reader);
+#endif
 					set_metadata = FALSE;
 				}
 
@@ -1071,6 +1100,13 @@ eog_image_has_data (EogImage *img, guint req_data)
 #endif
 	}
 
+	if ((req_data & EOG_IMAGE_DATA_XMP) > 0) {
+		req_data = (req_data & !EOG_IMAGE_DATA_XMP);
+#ifdef HAVE_EXEMPI
+		has_data = has_data && (priv->xmp != NULL);
+#endif
+	}
+
 	if (req_data != 0) {
 		g_warning ("Asking for unknown data, remaining: %i\n", req_data);
 		has_data = FALSE;
@@ -1792,6 +1828,27 @@ eog_image_get_exif_info (EogImage *img)
 	return data;
 }
 
+
+gpointer
+eog_image_get_xmp_info (EogImage *img)
+{
+	EogImagePrivate *priv;
+ 	gpointer data = NULL;
+ 	
+ 	g_return_val_if_fail (EOG_IS_IMAGE (img), NULL);
+ 	
+ 	priv = img->priv;
+	
+#ifdef HAVE_EXEMPI
+ 	g_mutex_lock (priv->status_mutex);
+ 	data =(gpointer)xmp_copy(priv->xmp);
+ 	g_mutex_unlock (priv->status_mutex);
+#endif
+	
+ 	return data;
+}
+
+
 GnomeVFSURI *
 eog_image_get_uri (EogImage *img)
 {
diff --git a/src/eog-image.h b/src/eog-image.h
index 71372f5..7d33311 100644
--- a/src/eog-image.h
+++ b/src/eog-image.h
@@ -40,6 +40,10 @@
 #include <lcms.h>
 #endif
 
+#ifdef HAVE_EXEMPI
+#include <exempi/xmp.h>
+#endif
+
 G_BEGIN_DECLS
 
 #ifndef __EOG_IMAGE_DECLR__
@@ -59,12 +63,13 @@ typedef struct _EogImagePrivate EogImagePrivate;
 typedef enum {
 	EOG_IMAGE_DATA_IMAGE     = 1 << 0,
 	EOG_IMAGE_DATA_DIMENSION = 1 << 1,
-	EOG_IMAGE_DATA_EXIF      = 1 << 2
+	EOG_IMAGE_DATA_EXIF      = 1 << 2,
+	EOG_IMAGE_DATA_XMP       = 1 << 3
 } EogImageData;
 
 #define EOG_IMAGE_DATA_ALL  (EOG_IMAGE_DATA_IMAGE |     \
 			     EOG_IMAGE_DATA_DIMENSION | \
-			     EOG_IMAGE_DATA_EXIF)
+			     EOG_IMAGE_DATA_EXIF | EOG_IMAGE_DATA_XMP)
 
 typedef enum {
 	EOG_IMAGE_ERROR_SAVE_NOT_LOCAL,
@@ -159,6 +164,7 @@ const gchar*      eog_image_get_caption              (EogImage   *img);
 const gchar      *eog_image_get_collate_key          (EogImage   *img);
 
 gpointer          eog_image_get_exif_info            (EogImage   *img);
+gpointer          eog_image_get_xmp_info             (EogImage   *img);
 
 GnomeVFSURI*      eog_image_get_uri                  (EogImage   *img);
 
diff --git a/src/eog-metadata-reader.c b/src/eog-metadata-reader.c
index 29cdd6b..d2b3057 100644
--- a/src/eog-metadata-reader.c
+++ b/src/eog-metadata-reader.c
@@ -13,12 +13,21 @@ typedef enum {
 	EMR_READ_SIZE_LOW_BYTE,
 	EMR_READ_MARKER,
 	EMR_SKIP_BYTES,
+	EMR_READ_APP1,
 	EMR_READ_EXIF,
+	EMR_READ_XMP,
 	EMR_READ_ICC,
 	EMR_READ_IPTC,
 	EMR_FINISHED
 } EogMetadataReaderState;
 
+typedef enum {
+	EJA_EXIF = 0,
+	EJA_XMP,
+	EJA_OTHER
+} EogJpegApp1Type;
+
+
 #define EOG_JPEG_MARKER_START   0xFF
 #define EOG_JPEG_MARKER_SOI     0xD8
 #define EOG_JPEG_MARKER_APP1	0xE1
@@ -27,6 +36,10 @@ typedef enum {
 
 #define NO_DEBUG
 
+#define IS_FINISHED(priv) (priv->exif_chunk != NULL && \
+ priv->icc_chunk != NULL && priv->iptc_chunk != NULL && \
+ priv->xmp_chunk != NULL)
+
 struct _EogMetadataReaderPrivate {
 	EogMetadataReaderState  state;
 
@@ -39,6 +52,9 @@ struct _EogMetadataReaderPrivate {
 	
 	gpointer icc_chunk;
 	guint icc_len;
+
+	gpointer xmp_chunk;
+	guint xmp_len;
 	
 	/* management fields */
 	int      size;
@@ -74,6 +90,11 @@ eog_metadata_reader_dispose (GObject *object)
 		emr->priv->iptc_chunk = NULL;
 	}
 
+	if (emr->priv->xmp_chunk != NULL) {
+		g_free (emr->priv->xmp_chunk);
+		emr->priv->xmp_chunk = NULL;
+	}
+
 	if (emr->priv->icc_chunk != NULL) {
 		g_free (emr->priv->icc_chunk);
 		emr->priv->icc_chunk = NULL;
@@ -126,11 +147,32 @@ eog_metadata_reader_finished (EogMetadataReader *emr)
 	return (emr->priv->state == EMR_FINISHED);
 }
 
+
+static EogJpegApp1Type
+eog_metadata_identify_app1(gchar *buf, guint len)
+{
+ 	if(len < 5) {
+ 		return EJA_OTHER;
+ 	}
+ 	if(len < 29) {
+ 		return (strncmp("Exif", buf, 5) == 0 ? EJA_EXIF : EJA_OTHER);
+ 	}
+ 	if( strncmp("Exif", buf, 5) == 0) {
+ 		return EJA_EXIF;
+ 	}
+ 	else 	if( strncmp("http://ns.adobe.com/xap/1.0/", buf, 29) == 0) {
+ 		return EJA_XMP;
+ 	}
+ 	return EJA_OTHER;
+}
+
+
 void
 eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 {
 	EogMetadataReaderPrivate *priv;
 	int i;
+ 	EogJpegApp1Type app1_type;
 
 	g_return_if_fail (EOG_IS_METADATA_READER (emr));
 
@@ -180,9 +222,9 @@ eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 				priv->state = EMR_READ;
 			}
 			else if (priv->last_marker == EOG_JPEG_MARKER_APP1 && 
-				 priv->exif_chunk == NULL) 
+				 ((priv->exif_chunk == NULL) || (priv->xmp_chunk == NULL))) 
 			{
-				priv->state = EMR_READ_EXIF;
+				priv->state = EMR_READ_APP1;
 			}
 			else if (priv->last_marker == EOG_JPEG_MARKER_APP2 && 
 				 priv->icc_chunk == NULL) 
@@ -217,22 +259,67 @@ eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 			}
 			break;
 			
-		case EMR_READ_EXIF:			
-			eog_debug_message (DEBUG_IMAGE_DATA, "Read EXIF data, Length: %i", priv->size);
-
-			if (priv->exif_chunk == NULL) { 
-				priv->exif_chunk = g_new0 (guchar, priv->size);
-				priv->exif_len = priv->size;
-				priv->bytes_read = 0;
-			}
-
-			if (i + priv->size < len) {
-                                /* read data in one block */
-				memcpy ((guchar*) (priv->exif_chunk) + priv->bytes_read, &buf[i], priv->size);
-				priv->state = EMR_READ;
-				i = i + priv->size - 1; /* the for-loop consumes the other byte */
+		case EMR_READ_APP1:			
+			eog_debug_message (DEBUG_IMAGE_DATA, "Read APP1 data, Length: %i", priv->size);
+			app1_type = eog_metadata_identify_app1((gchar*)&buf[i], priv->size);
+			
+			if (app1_type != EJA_OTHER) {
+				guchar *chunk = NULL;
+				int offset = 0;
+				EogMetadataReaderState next_state;
+				
+				switch(app1_type) {
+				case EJA_EXIF:
+					if (priv->exif_chunk == NULL) { 
+						priv->exif_chunk = g_new0 (guchar, priv->size);
+						priv->exif_len = priv->size;
+						priv->bytes_read = 0;
+						chunk = priv->exif_chunk;
+						next_state = EMR_READ_EXIF;
+					}
+					break;
+				case EJA_XMP:
+					if (priv->xmp_chunk == NULL) { 
+						offset = 29 + 54; /* skip the ID + packet */
+						if(priv->size > offset)  { /* ensure that we have enough bytes */
+							priv->xmp_chunk = g_new0 (guchar, priv->size);
+							priv->xmp_len = priv->size - offset;
+							priv->bytes_read = 0;
+							chunk = priv->xmp_chunk;
+							next_state = EMR_READ_XMP;
+						}
+					}
+				default:
+					break;
+				}
+				
+				if(chunk) {
+					if (i + priv->size < len) {
+						/* read data in one block */
+						memcpy ((guchar*) (chunk) + priv->bytes_read, &buf[i + offset], priv->size);
+						priv->state = EMR_READ;
+						i = i + priv->size - 1; /* the for-loop consumes the other byte */
+					}
+					else
+					{
+						int chunk_len = len - i;
+						memcpy ((guchar*) (priv->exif_chunk) + priv->bytes_read, &buf[i], chunk_len);
+						priv->bytes_read += chunk_len; /* bytes already read */
+						priv->size = (i + priv->size) - len; /* remaining data to read */
+						i = len - 1;
+						priv->state = next_state;
+					}
+				}
 			}
-			else {
+			if (IS_FINISHED(priv))
+				priv->state = EMR_FINISHED;
+			break;
+			
+		case EMR_READ_EXIF:                     
+#ifdef DEBUG
+			eog_debug_message (DEBUG_IMAGE_DATA, "Read continuation of EXIF data, length: %i", priv->size);
+#endif
+			{
 				int chunk_len = len - i;
 				memcpy ((guchar*) (priv->exif_chunk) + priv->bytes_read, &buf[i], chunk_len);
 				priv->bytes_read += chunk_len; /* bytes already read */
@@ -240,11 +327,26 @@ eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 				i = len - 1;
 				priv->state = EMR_READ_EXIF;
 			}
+			if (IS_FINISHED(priv))
+				priv->state = EMR_FINISHED;
+			break;
 			
-			if (priv->exif_chunk != NULL && priv->icc_chunk != NULL && priv->iptc_chunk != NULL)
+		case EMR_READ_XMP:
+#ifdef DEBUG
+			eog_debug_message (DEBUG_IMAGE_DATA, "Read continuation of XMP data, length: %i", priv->size);
+#endif
+			{
+				int chunk_len = len - i;
+				memcpy ((guchar*) (priv->xmp_chunk) + priv->bytes_read, &buf[i], chunk_len);
+				priv->bytes_read += chunk_len; /* bytes already read */
+				priv->size = (i + priv->size) - len; /* remaining data to read */
+				i = len - 1;
+				priv->state = EMR_READ_XMP;
+			}
+			if (IS_FINISHED(priv))
 				priv->state = EMR_FINISHED;
 			break;
-
+			
 		case EMR_READ_ICC:			
 			eog_debug_message (DEBUG_IMAGE_DATA, "Read ICC data, Length: %i\n", priv->size);
 
@@ -269,7 +371,7 @@ eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 				priv->state = EMR_READ_ICC;
 			}
 			
-			if (priv->exif_chunk != NULL && priv->icc_chunk != NULL && priv->iptc_chunk != NULL)
+			if (IS_FINISHED(priv))
 				priv->state = EMR_FINISHED;
 			break;
 			
@@ -294,7 +396,7 @@ eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
 				priv->state = EMR_READ_IPTC;
 			}
 			
-			if (priv->exif_chunk != NULL && priv->icc_chunk != NULL && priv->iptc_chunk != NULL)
+			if (IS_FINISHED(priv))
 				priv->state = EMR_FINISHED;
 			break;
 
@@ -322,7 +424,7 @@ eog_metadata_reader_get_exif_chunk (EogMetadataReader *emr, guchar **data, guint
 	priv->exif_len = 0;
 }
 
-#if HAVE_EXIF
+#ifdef HAVE_EXIF
 ExifData*
 eog_metadata_reader_get_exif_data (EogMetadataReader *emr)
 {
@@ -340,6 +442,26 @@ eog_metadata_reader_get_exif_data (EogMetadataReader *emr)
 }
 #endif
 
+
+#ifdef HAVE_EXEMPI
+XmpPtr 
+eog_metadata_reader_get_xmp_data (EogMetadataReader *emr )
+{
+	XmpPtr xmp = NULL;
+	EogMetadataReaderPrivate *priv;
+
+	g_return_val_if_fail (EOG_IS_METADATA_READER (emr), NULL);
+	priv = emr->priv;
+
+	if(priv->xmp_chunk != NULL) {
+		xmp = xmp_new(priv->xmp_chunk, priv->xmp_len);
+	}
+
+	return xmp;
+}
+#endif
+
+
 /*
  * TODO: very broken, assumes the profile fits in a single chunk.  Change to
  * parse the sections and construct a single memory chunk, or maybe even parse
diff --git a/src/eog-metadata-reader.h b/src/eog-metadata-reader.h
index 966e318..7ff64f6 100644
--- a/src/eog-metadata-reader.h
+++ b/src/eog-metadata-reader.h
@@ -5,6 +5,9 @@
 #if HAVE_EXIF
 #include <libexif/exif-data.h>
 #endif 
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -44,6 +47,10 @@ void                 eog_metadata_reader_get_exif_chunk (EogMetadataReader *emr,
 ExifData*            eog_metadata_reader_get_exif_data (EogMetadataReader *emr);
 #endif
 
+#if HAVE_EXEMPI
+XmpPtr               eog_metadata_reader_get_xmp_data (EogMetadataReader *emr);
+#endif
+
 #if 0
 gpointer             eog_metadata_reader_get_iptc_chunk (EogMetadataReader *emr);
 IptcData*            eog_metadata_reader_get_iptc_data (EogMetadataReader *emr);
diff --git a/src/eog-properties-dialog.c b/src/eog-properties-dialog.c
index 6c03087..b37d9ed 100644
--- a/src/eog-properties-dialog.c
+++ b/src/eog-properties-dialog.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2006 The Free Software Foundation
  *
  * Author: Lucas Rocha <lucasr@gnome.org>
+ *         Hubert Figuiere <hub@figuiere.net> (XMP support)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,6 +39,15 @@
 #include <libgnomevfs/gnome-vfs-mime-utils.h>
 #include <libgnomevfs/gnome-vfs-mime-handlers.h>
 
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#include <exempi/xmpconsts.h>
+#endif
+
+#if HAVE_EXIF || HAVE_EXEMPI
+#define HAVE_METADATA 1
+#endif
+
 #define EOG_PROPERTIES_DIALOG_GET_PRIVATE(object) \
 	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_PROPERTIES_DIALOG, EogPropertiesDialogPrivate))
 
@@ -69,7 +79,7 @@ struct _EogPropertiesDialogPrivate {
 	GtkWidget      *location_label;
 	GtkWidget      *created_label;
 	GtkWidget      *modified_label;
-#ifdef HAVE_EXIF
+#ifdef HAVE_METADATA
 	GtkWidget      *exif_box;
 	GtkWidget      *exif_aperture_label;
 	GtkWidget      *exif_exposure_label;
@@ -79,9 +89,18 @@ struct _EogPropertiesDialogPrivate {
 	GtkWidget      *exif_metering_label;
 	GtkWidget      *exif_model_label;
 	GtkWidget      *exif_date_label;
+	GtkWidget      *xmp_location;
+	GtkWidget      *xmp_description;
+	GtkWidget      *xmp_keywords;
+	GtkWidget      *xmp_creator;
+	GtkWidget      *xmp_rights;
+	GtkWidget      *xmp_rating;	
 	GtkWidget      *exif_details_expander;
 	GtkWidget      *exif_details;
 #endif
+#ifdef HAVE_EXEMPI
+	GtkWidget      *xmp_details;
+#endif
 };
 
 static void
@@ -129,18 +148,62 @@ pd_update_general_tab (EogPropertiesDialog *prop_dlg,
 	g_free (dir_str);
 }
 
-#ifdef HAVE_EXIF
+
+
+#if HAVE_EXEMPI
+static void
+eog_xmp_set_label(XmpPtr xmp, const char* ns, const char* propname, 
+									GtkWidget *w)
+{
+	uint32_t options;
+	XmpStringPtr  value = xmp_string_new();
+	if(xmp_get_property_and_bits(xmp, ns, propname, value, &options)) {
+		if(XMP_IS_PROP_SIMPLE(options)) {
+			gtk_label_set_text (GTK_LABEL (w), xmp_string_cstr(value));
+		}
+		else if(XMP_IS_PROP_ARRAY(options)) {
+			XmpIteratorPtr iter = xmp_iterator_new(xmp, ns, propname, 
+																						 XMP_ITER_JUSTLEAFNODES);
+			GString *string = g_string_new("");
+			if(iter) {
+				bool first = true;
+				while (xmp_iterator_next(iter, NULL, NULL, value, &options) 
+				       && !XMP_IS_PROP_QUALIFIER(options)) {
+					if(!first) {
+						g_string_append_printf(string, ", ");
+					}
+					else {
+						first = false;
+					}
+					g_string_append_printf(string, "%s",  xmp_string_cstr(value));
+				}
+				xmp_iterator_free(iter);
+			}
+			gtk_label_set_text (GTK_LABEL (w), string->str);
+		}
+	}
+	xmp_string_free(value);
+}
+#endif
+
+#if HAVE_METADATA
 static void
-pd_update_exif_tab (EogPropertiesDialog *prop_dlg, 
+pd_update_metadata_tab (EogPropertiesDialog *prop_dlg, 
 		    EogImage            *image)
 {
 	GtkNotebook *notebook;
-	ExifData *exif_data;
+#if HAVE_EXIF
+	ExifData    *exif_data;
+#endif
 	const gchar *exif_value = NULL;
+#if HAVE_EXEMPI
+	XmpPtr      xmp_data;
+#endif
 
 	notebook = GTK_NOTEBOOK (prop_dlg->priv->notebook);
 
-	if (!eog_image_has_data (image, EOG_IMAGE_DATA_EXIF)) {
+	if (!eog_image_has_data (image, EOG_IMAGE_DATA_EXIF)
+			&& !eog_image_has_data (image, EOG_IMAGE_DATA_EXIF)) {
 		if (gtk_notebook_get_current_page (notebook) ==	EOG_PROPERTIES_DIALOG_PAGE_EXIF) {
 			gtk_notebook_prev_page (notebook);
 		}
@@ -154,9 +217,10 @@ pd_update_exif_tab (EogPropertiesDialog *prop_dlg,
 		gtk_widget_show_all (prop_dlg->priv->exif_box);
 	}
 
+#if HAVE_EXIF
 	exif_data = (ExifData *) eog_image_get_exif_info (image);
 
-	exif_value = eog_exif_util_get_value (exif_data, EXIF_TAG_APERTURE_VALUE);
+	exif_value = eog_exif_util_get_value (exif_data, EXIF_TAG_FNUMBER);
 	gtk_label_set_text (GTK_LABEL (prop_dlg->priv->exif_aperture_label), 
 			    eog_util_make_valid_utf8 (exif_value));
 
@@ -190,6 +254,26 @@ pd_update_exif_tab (EogPropertiesDialog *prop_dlg,
 
 	eog_exif_details_update (EOG_EXIF_DETAILS (prop_dlg->priv->exif_details), 
 				 exif_data);
+	exif_data_unref(exif_data);
+#endif
+#if HAVE_EXEMPI
+	xmp_data = (XmpPtr) eog_image_get_xmp_info (image);
+	eog_xmp_set_label(xmp_data, NS_IPTC4XMP, "Location", 
+										prop_dlg->priv->xmp_location);
+	eog_xmp_set_label(xmp_data, NS_DC, "description", 
+										prop_dlg->priv->xmp_description);
+	eog_xmp_set_label(xmp_data, NS_DC, "subject", 
+										prop_dlg->priv->xmp_keywords);
+	eog_xmp_set_label(xmp_data, NS_DC, "creator", 
+										prop_dlg->priv->xmp_creator);
+	eog_xmp_set_label(xmp_data, NS_DC, "rights", 
+										prop_dlg->priv->xmp_rights);
+	eog_xmp_set_label(xmp_data, NS_XAP, "Rating", 
+										prop_dlg->priv->xmp_rating);
+	eog_exif_details_xmp_update (EOG_EXIF_DETAILS (prop_dlg->priv->exif_details),
+															 xmp_data);
+	xmp_free(xmp_data);
+#endif
 }
 
 static gboolean
@@ -333,7 +417,7 @@ eog_properties_dialog_init (EogPropertiesDialog *prop_dlg)
 {
 	EogPropertiesDialogPrivate *priv;
 	GtkWidget *dlg;
-#ifdef HAVE_EXIF
+#if HAVE_METADATA
 	GtkWidget *sw;
 #endif
 
@@ -363,7 +447,7 @@ eog_properties_dialog_init (EogPropertiesDialog *prop_dlg)
 			         "location_label", &priv->location_label,
 			         "created_label", &priv->created_label,
 			         "modified_label", &priv->modified_label,
-#ifdef HAVE_EXIF
+#if HAVE_METADATA
 			         "exif_box", &priv->exif_box,
 			         "exif_aperture_label", &priv->exif_aperture_label,
 			         "exif_exposure_label", &priv->exif_exposure_label,
@@ -374,6 +458,12 @@ eog_properties_dialog_init (EogPropertiesDialog *prop_dlg)
 			         "exif_model_label", &priv->exif_model_label,
 			         "exif_date_label", &priv->exif_date_label,
 			         "exif_details_expander", &priv->exif_details_expander,
+							 "xmp_location", &priv->xmp_location,
+							 "xmp_description", &priv->xmp_description,
+							 "xmp_keywords", &priv->xmp_keywords,
+							 "xmp_creator", &priv->xmp_creator,
+							 "xmp_rights", &priv->xmp_rights,
+							 "xmp_rating", &priv->xmp_rating,
 #endif
 			         NULL);
 
@@ -394,8 +484,8 @@ eog_properties_dialog_init (EogPropertiesDialog *prop_dlg)
 
 	gtk_widget_set_size_request (priv->thumbnail_image, 100, 100);
 
-#ifdef HAVE_EXIF
-	sw = gtk_scrolled_window_new (NULL, NULL);
+#if HAVE_METADATA
+ 	sw = gtk_scrolled_window_new (NULL, NULL);
 
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), 
 					     GTK_SHADOW_IN);
@@ -417,8 +507,8 @@ eog_properties_dialog_init (EogPropertiesDialog *prop_dlg)
 			  	G_CALLBACK (pd_exif_details_activated_cb), 
 			  	dlg);
 #else
-        gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), 
-				  EOG_PROPERTIES_DIALOG_PAGE_EXIF);
+	gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), 
+														EOG_PROPERTIES_DIALOG_PAGE_EXIF);
 #endif
 }
 
@@ -459,10 +549,9 @@ eog_properties_dialog_update (EogPropertiesDialog *prop_dlg,
 
 	pd_update_general_tab (prop_dlg, image);
 
-#ifdef HAVE_EXIF
-	pd_update_exif_tab (prop_dlg, image);
+#if HAVE_METADATA
+	pd_update_metadata_tab (prop_dlg, image);
 #endif
-
 	gtk_notebook_set_current_page (GTK_NOTEBOOK (prop_dlg->priv->notebook),
 				       prop_dlg->priv->current_page);
 
diff --git a/src/eog-properties-dialog.h b/src/eog-properties-dialog.h
index e181723..9223c1e 100644
--- a/src/eog-properties-dialog.h
+++ b/src/eog-properties-dialog.h
@@ -45,7 +45,8 @@ typedef struct _EogPropertiesDialogPrivate EogPropertiesDialogPrivate;
 
 typedef enum {
 	EOG_PROPERTIES_DIALOG_PAGE_GENERAL = 0,
-	EOG_PROPERTIES_DIALOG_PAGE_EXIF
+	EOG_PROPERTIES_DIALOG_PAGE_EXIF,
+	EOG_PROPERTIES_DIALOG_PAGE_XMP
 } EogPropertiesDialogPage;
 
 struct _EogPropertiesDialog {
diff --git a/src/main.c b/src/main.c
index e3ba29c..6ad6bd1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,6 +48,10 @@
 #include <libgnomeui/gnome-app-helper.h>
 #include <libgnomeui/gnome-authentication-manager.h>
 
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#endif
+
 static EogStartupFlags flags;
 
 static gboolean fullscreen = FALSE;
@@ -194,6 +198,9 @@ main (int argc, char **argv)
 	
 	gnome_authentication_manager_init ();
 
+#ifdef HAVE_EXEMPI
+ 	xmp_init();
+#endif
 	eog_debug_init ();
 	eog_job_queue_init ();
 	gdk_threads_init ();
@@ -216,5 +223,8 @@ main (int argc, char **argv)
 
 	g_object_unref (program);
 
+#ifdef HAVE_EXEMPI
+	xmp_terminate();
+#endif
 	return 0;
 }
