diff --git a/TODO.pep b/TODO.pep
new file mode 100644
index 0000000000000000000000000000000000000000..05c924dbf4e82ae837b1212dd8578540e2727539
--- /dev/null
+++ b/TODO.pep
@@ -0,0 +1,15 @@
+• configure access model when changing it in the combobox
+• PEP in status change
+
+Tune use cases:
+• on disconnection of an account set Tune to None
+
+Tooltips use cases:
+• Show PEP in contact tooltips
+• Show PEP in GC tooltips
+• Show PEP in account tooltips
+
+Mood/Activity use cases
+• on connection of an account set them to None
+• on disconnection of an account set them to None
+• on explicit set publish them
diff --git a/data/glade/account_context_menu.glade b/data/glade/account_context_menu.glade
index 08bd168596dcefa09b02ba8f7dbbbb7860c5ba49..4316c5f0c59c8656b006b05f257635444843967c 100644
--- a/data/glade/account_context_menu.glade
+++ b/data/glade/account_context_menu.glade
@@ -17,6 +17,20 @@
         </child>
       </widget>
     </child>
+    <child>
+      <widget class="GtkImageMenuItem" id="pep_menuitem">
+        <property name="visible">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="label" translatable="yes">_Personal Events</property>
+        <property name="use_underline">True</property>
+        <child internal-child="image">
+          <widget class="GtkImage" id="menu-item-image7">
+            <property name="stock">gtk-home</property>
+            <property name="icon_size">1</property>
+          </widget>
+        </child>
+      </widget>
+    </child>
     <child>
       <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
         <property name="visible">True</property>
diff --git a/data/glade/change_activity_dialog.glade b/data/glade/change_activity_dialog.glade
new file mode 100644
index 0000000000000000000000000000000000000000..7665916fdc7e5d66b56fbfbf402a78c550ecf43f
--- /dev/null
+++ b/data/glade/change_activity_dialog.glade
@@ -0,0 +1,158 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="change_activity_dialog">
+  <property name="border_width">6</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">270</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+  <signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox5">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkFrame" id="frame38">
+	  <property name="visible">True</property>
+	  <property name="label_xalign">0</property>
+	  <property name="label_yalign">0.5</property>
+	  <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment107">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox112">
+		  <property name="border_width">6</property>
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkComboBox" id="combobox1">
+		      <property name="visible">True</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBox" id="combobox2">
+		      <property name="visible">True</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="entry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">●</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/glade/change_mood_dialog.glade b/data/glade/change_mood_dialog.glade
new file mode 100644
index 0000000000000000000000000000000000000000..47122c8721e8fcfb7bf8215d8da936109db7ea56
--- /dev/null
+++ b/data/glade/change_mood_dialog.glade
@@ -0,0 +1,145 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="change_mood_dialog">
+  <property name="border_width">6</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">270</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+  <signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox5">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkFrame" id="frame38">
+	  <property name="visible">True</property>
+	  <property name="label_xalign">0</property>
+	  <property name="label_yalign">0.5</property>
+	  <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment107">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox112">
+		  <property name="border_width">6</property>
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkComboBox" id="combobox">
+		      <property name="visible">True</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="entry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">●</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/glade/manage_pep_services_window.glade b/data/glade/manage_pep_services_window.glade
new file mode 100644
index 0000000000000000000000000000000000000000..a3e5e61551c9505f7da6f0aa06a6117c2ac8afff
--- /dev/null
+++ b/data/glade/manage_pep_services_window.glade
@@ -0,0 +1,135 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="manage_pep_services_window">
+  <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">350</property>
+  <property name="default_height">150</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <signal name="destroy" handler="on_manage_pep_services_window_destroy"/>
+
+  <child>
+    <widget class="GtkVBox" id="vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+	<widget class="GtkScrolledWindow" id="scrolledwindow1">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	  <property name="shadow_type">GTK_SHADOW_NONE</property>
+	  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	  <child>
+	    <widget class="GtkTreeView" id="services_treeview">
+	      <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="headers_visible">True</property>
+	      <property name="rules_hint">False</property>
+	      <property name="reorderable">False</property>
+	      <property name="enable_search">True</property>
+	      <property name="fixed_height_mode">False</property>
+	      <property name="hover_selection">False</property>
+	      <property name="hover_expand">False</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHButtonBox" id="hbuttonbox1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkButton" id="add_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-add</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_add_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
+	    </widget>
+	  </child>
+	  <child>
+	    <widget class="GtkButton" id="delete_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-delete</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_delete_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
+	    </widget>
+	  </child>
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/glade/preferences_window.glade b/data/glade/preferences_window.glade
index 0bd3604fab7d161b41ef3b397885a18bf9f4f142..831599d4b1d5b5a82189471199410a16466f255d 100644
--- a/data/glade/preferences_window.glade
+++ b/data/glade/preferences_window.glade
@@ -438,9 +438,6 @@ Single message</property>
                   </packing>
                 </child>
               </widget>
-              <packing>
-                <property name="tab_expand">False</property>
-              </packing>
             </child>
             <child>
               <widget class="GtkLabel" id="label74">
@@ -449,7 +446,6 @@ Single message</property>
               </widget>
               <packing>
                 <property name="type">tab</property>
-                <property name="tab_expand">False</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -880,7 +876,6 @@ Disabled</property>
               </widget>
               <packing>
                 <property name="position">1</property>
-                <property name="tab_expand">False</property>
               </packing>
             </child>
             <child>
@@ -891,7 +886,6 @@ Disabled</property>
               <packing>
                 <property name="type">tab</property>
                 <property name="position">1</property>
-                <property name="tab_expand">False</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -1229,7 +1223,6 @@ Show only in roster</property>
               </widget>
               <packing>
                 <property name="position">2</property>
-                <property name="tab_expand">False</property>
               </packing>
             </child>
             <child>
@@ -1240,7 +1233,6 @@ Show only in roster</property>
               <packing>
                 <property name="type">tab</property>
                 <property name="position">2</property>
-                <property name="tab_expand">False</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -1638,7 +1630,6 @@ Show only in roster</property>
               </widget>
               <packing>
                 <property name="position">3</property>
-                <property name="tab_expand">False</property>
               </packing>
             </child>
             <child>
@@ -1649,7 +1640,6 @@ Show only in roster</property>
               <packing>
                 <property name="type">tab</property>
                 <property name="position">3</property>
-                <property name="tab_expand">False</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -2048,7 +2038,6 @@ Custom</property>
               </widget>
               <packing>
                 <property name="position">4</property>
-                <property name="tab_expand">False</property>
               </packing>
             </child>
             <child>
@@ -2059,7 +2048,193 @@ Custom</property>
               <packing>
                 <property name="type">tab</property>
                 <property name="position">4</property>
-                <property name="tab_expand">False</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">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="spacing">6</property>
+                <child>
+                  <widget class="GtkFrame" id="frame6">
+                    <property name="visible">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="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment6">
+                        <property name="visible">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="left_padding">12</property>
+                        <child>
+                          <widget class="GtkVBox" id="vbox3">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <child>
+                              <widget class="GtkCheckButton" id="publish_mood_checkbutton">
+                                <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="label" translatable="yes">Publish _Mood</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_publish_mood_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkCheckButton" id="publish_activity_checkbutton">
+                                <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="label" translatable="yes">Publish _Activity</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_publish_activity_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkCheckButton" id="publish_tune_checkbutton">
+                                <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="label" translatable="yes">Publish _Tune</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_publish_tune_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label10">
+                        <property name="visible">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="label" translatable="yes">&lt;b&gt;Publish Personal Events&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkFrame" id="frame7">
+                    <property name="visible">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="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment7">
+                        <property name="visible">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="left_padding">12</property>
+                        <child>
+                          <widget class="GtkVBox" id="vbox4">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <child>
+                              <widget class="GtkCheckButton" id="subscribe_mood_checkbutton">
+                                <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="label" translatable="yes">Subscribe to M_ood</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_subscribe_mood_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkCheckButton" id="subscribe_activity_checkbutton">
+                                <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="label" translatable="yes">Subscribe to A_ctivity</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_subscribe_activity_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkCheckButton" id="subscribe_tune_checkbutton">
+                                <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="label" translatable="yes">Subscribe to T_une</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_subscribe_tune_checkbutton_toggled"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label11">
+                        <property name="visible">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="label" translatable="yes">&lt;b&gt;Subscribe to Personal Events&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label9">
+                <property name="visible">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="label" translatable="yes">Personal Events</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">5</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
diff --git a/data/glade/roster_window.glade b/data/glade/roster_window.glade
index 625a713b22fab3c17e51c9f35eae7f017a43cf7e..dc482bb8a2c958999ee32a042c967e309bfabc84 100644
--- a/data/glade/roster_window.glade
+++ b/data/glade/roster_window.glade
@@ -193,6 +193,14 @@
                         </child>
                       </widget>
                     </child>
+                    <child>
+                      <widget class="GtkMenuItem" id="pep_services_menuitem">
+                        <property name="visible">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="label" translatable="yes">_Services</property>
+                        <property name="use_underline">True</property>
+                      </widget>
+                    </child>
                   </widget>
                 </child>
               </widget>
diff --git a/po/fr.po b/po/fr.po
index eb9988722dd6753005d55eb4f3427ec1586db471..7149ff9ffdc49a05e601cd84d63139b39583cb66 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -6537,6 +6537,406 @@ msgstr "Connecté"
 msgid "Disconnected"
 msgstr "Déconnecté"
 
+#pep
+msgid "afraid"
+msgstr "appeuré"
+
+msgid "amazed"
+msgstr "surpris, amusé"
+
+msgid "angry"
+msgstr "en colère"
+
+msgid "annoyed"
+msgstr "dérangé"
+
+msgid "anxious"
+msgstr "anxieux"
+
+msgid "aroused"
+msgstr "excité"
+
+msgid "ashamed"
+msgstr "honteux/éhonté"
+
+msgid "bored"
+msgstr "ennuyé"
+
+msgid "brave"
+msgstr "courageux"
+
+msgid "calm"
+msgstr "calme"
+
+msgid "cold"
+msgstr "froid"
+
+msgid "confused"
+msgstr "confus"
+
+msgid "contented"
+msgstr "contenté"
+
+msgid "cranky"
+msgstr "excentrique"
+
+msgid "curious"
+msgstr "curieux"
+
+msgid "depressed"
+msgstr "déprimé"
+
+msgid "disappointed"
+msgstr "décu"
+
+msgid "disgusted"
+msgstr "dégouté"
+
+msgid "distracted"
+msgstr "distrait"
+
+msgid "embarrassed"
+msgstr "embarssé"
+
+msgid "excited"
+msgstr "excité"
+
+msgid "flirtatious"
+msgstr "coquet"
+
+msgid "frustrated"
+msgstr "frustré"
+
+msgid "grumpy"
+msgstr "grognon"
+
+msgid "guilty"
+msgstr "coupable"
+
+msgid "happy"
+msgstr "joyeux"
+
+msgid "hot"
+msgstr "chaud"
+
+msgid "humbled"
+msgstr "humilié"
+
+msgid "humiliated"
+msgstr "humilié"
+
+msgid "hungry"
+msgstr "affamé"
+
+msgid "hurt"
+msgstr "blessé"
+
+msgid "impressed"
+msgstr "impressionné"
+
+msgid "in_awe"
+msgstr "dans la crainte"
+
+msgid "in_love"
+msgstr "amoureux"
+
+msgid "indignant"
+msgstr "indigné"
+
+msgid "interested"
+msgstr "interessé"
+
+msgid "intoxicated"
+msgstr "intoxiqué"
+
+msgid "invincible"
+msgstr "invincible"
+
+msgid "jealous"
+msgstr "jaloux"
+
+msgid "lonely"
+msgstr "seul/esseulé"
+
+msgid "mean"
+msgstr "méchant"
+
+msgid "moody"
+msgstr "déprimé"
+
+msgid "nervous"
+msgstr "nerveux"
+
+msgid "neutral"
+msgstr "neutre"
+
+msgid "offended"
+msgstr "offensé"
+
+msgid "playful"
+msgstr "joueur"
+
+msgid "proud"
+msgstr "fier"
+
+msgid "relieved"
+msgstr "soulagé"
+
+msgid "remorseful"
+msgstr "plein de remord"
+
+msgid "restless"
+msgstr "infatiguable"
+
+msgid "sad"
+msgstr "triste"
+
+msgid "sarcastic"
+msgstr "sarcastique"
+
+msgid "serious"
+msgstr "serieux"
+
+msgid "shocked"
+msgstr "choqué"
+
+msgid "shy"
+msgstr "timide"
+
+msgid "sick"
+msgstr "malade"
+
+msgid "sleepy"
+msgstr "endormi"
+
+msgid "stressed"
+msgstr "stressé"
+
+msgid "surprised"
+msgstr "surpris"
+
+msgid "thirsty"
+msgstr "assoiffé"
+
+msgid "worried"
+msgstr "inquiet"
+
+msgid "_Personnal Events"
+msgstr "Évènements _Personnels"
+
+msgid "Activity"
+msgstr "Activité"
+
+msgid "doing_chores"
+msgstr "fait des corvées"
+
+msgid "buying_groceries"
+msgstr "achète des épiceries"
+
+msgid "cleaning"
+msgstr "nettoie"
+
+msgid "cooking"
+msgstr "cuisine"
+
+msgid "doing_maintenance"
+msgstr "fait de la maintenance"
+
+msgid "doing_the_dishes"
+msgstr "fait la vaiselle"
+
+msgid "doing_the_laundry"
+msgstr "fait la blanchisserie"
+
+msgid "gardening"
+msgstr "jardine"
+
+msgid "running_an_errand"
+msgstr "fait une course"
+
+msgid "walking_the_dog"
+msgstr "promène le chien"
+
+msgid "drinking"
+msgstr "boit"
+
+msgid "having_a_beer"
+msgstr "prend une bière"
+
+msgid "having_coffee"
+msgstr "prend un café"
+
+msgid "having_tea"
+msgstr "prend un thé"
+
+msgid "eating"
+msgstr "mange"
+
+msgid "having_a_snack"
+msgstr "prend un snack"
+
+msgid "having_breakfast"
+msgstr "prend le petit-déjeuner"
+
+msgid "having_dinner"
+msgstr "soupe"
+
+msgid "having_lunch"
+msgstr "dîne"
+
+msgid "exercising"
+msgstr "fait de l'exercice"
+
+msgid "cycling"
+msgstr "fait du vélo"
+
+msgid "hiking"
+msgstr "fait de la randonnée"
+
+msgid "jogging"
+msgstr "fait un jogging"
+
+msgid "playing_sports"
+msgstr "fait du sport"
+
+msgid "running"
+msgstr "court"
+
+msgid "skiing"
+msgstr "skie"
+
+msgid "swimming"
+msgstr "nage"
+
+msgid "working_out"
+msgstr "élabore"
+
+msgid "grooming"
+msgstr "se toilette"
+
+msgid "at_the_spa"
+msgstr "à la station thermale"
+
+msgid "brushing_teeth"
+msgstr "se brosse les dents"
+
+msgid "getting_a_haircut"
+msgstr "se fait couper les cheveux"
+
+msgid "shaving"
+msgstr "se rase"
+
+msgid "taking_a_bath"
+msgstr "prend un bain"
+
+msgid "taking_a_shower"
+msgstr "prend une douche"
+
+msgid "having_appointment"
+msgstr "à un rendez-vous"
+
+msgid "inactive"
+msgstr "inactif"
+
+msgid "day_off"
+msgstr "en congé"
+
+msgid "hanging_out"
+msgstr "traîne"
+
+msgid "on_vacation"
+msgstr "en vacances"
+
+msgid "scheduled_holiday"
+msgstr "en vacances organisées"
+
+msgid "sleeping"
+msgstr "dort"
+
+msgid "relaxing"
+msgstr "se relaxe"
+
+msgid "gaming"
+msgstr "joue"
+
+msgid "going_out"
+msgstr "sort"
+
+msgid "partying"
+msgstr "fait la fête"
+
+msgid "reading"
+msgstr "lit"
+
+msgid "rehearsing"
+msgstr "se prépare"
+
+msgid "shopping"
+msgstr "fait les magasins"
+
+msgid "socializing"
+msgstr "se socialise"
+
+msgid "sunbathing"
+msgstr "prend un bain de soleil"
+
+msgid "watching_tv"
+msgstr "regarde la TV"
+
+msgid "watching_a_movie"
+msgstr "regarde un film"
+
+msgid "talking"
+msgstr "discute"
+
+msgid "in_real_life"
+msgstr "dans la vraie vie"
+
+msgid "on_the_phone"
+msgstr "au téléphone"
+
+msgid "traveling"
+msgstr "voyage"
+
+msgid "commuting"
+msgstr "permute"
+
+msgid "driving"
+msgstr "conduit"
+
+msgid "in_a_car"
+msgstr "en voiture"
+
+msgid "on_a_bus"
+msgstr "en bus"
+
+msgid "on_a_plane"
+msgstr "en avion"
+
+msgid "on_a_train"
+msgstr "en train"
+
+msgid "on_a_trip"
+msgstr "en séjour"
+
+msgid "walking"
+msgstr "marche"
+
+msgid "working"
+msgstr "travaille"
+
+msgid "coding"
+msgstr "programme"
+
+msgid "in_a_meeting"
+msgstr "en réunion"
+
+msgid "studying"
+msgstr "étudie"
+
+msgid "writing"
+msgstr "écrit"
+
 #~ msgid "2003-12-13T18:30:02Z"
 #~ msgstr "2003-12-13T18:30:02Z"
 #~ msgid "<small>Romeo and Juliet</small>"
diff --git a/src/common/config.py b/src/common/config.py
index 0e8282daf80a988786497e3de804694ae87dc012..1570059adeb415ae89515669f03130b9f14d6dcf 100644
--- a/src/common/config.py
+++ b/src/common/config.py
@@ -250,7 +250,14 @@ class Config:
 		'use_latex': [opt_bool, False, _('If True, Gajim will convert string between $$ and $$ to an image using dvips and convert before insterting it in chat window.')],
 		'change_status_window_timeout': [opt_int, 15, _('Time of inactivity needed before the change status window closes down.')],
 		'max_conversation_lines': [opt_int, 500, _('Maximum number of lines that are printed in conversations. Oldest lines are cleared.')],
+		'publish_mood': [opt_bool, False],
+		'publish_activity': [opt_bool, False],
+		'publish_tune': [opt_bool, False],
+		'subscribe_mood': [opt_bool, True],
+		'subscribe_activity': [opt_bool, True],
+		'subscribe_tune': [opt_bool, True],
 		'attach_notifications_to_systray': [opt_bool, False, _('If True, notification windows from notification-daemon will be attached to systray icon.')],
+		'use_pep': [opt_bool, False, 'temporary variable to enable pep support'],
 	}
 
 	__options_per_key = {
diff --git a/src/common/connection.py b/src/common/connection.py
index 34527e45aa955051d3e19ab7ee1edd87a68c8d27..91c89f22098593aba5b8129b933090ca1d86bc15 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -186,6 +186,8 @@ class Connection(ConnectionHandlers):
 
 	# We are doing disconnect at so many places, better use one function in all
 	def disconnect(self, on_purpose=False):
+		#FIXME: set the Tune to None before disconnection per account
+		#gajim.interface.roster._music_track_changed(None, None)
 		self.on_purpose = on_purpose
 		self.connected = 0
 		self.time_to_reconnect = None
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index baea7e087193828407da0a511161188c1b589986..6423d41544b212a13e8316f35482c00c5c21eb67 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -39,11 +39,17 @@ from common import GnuPG
 from common import helpers
 from common import gajim
 from common import atom
+from common import pep
 from common import exceptions
 from common.commands import ConnectionCommands
 from common.pubsub import ConnectionPubSub
 from common.caps import ConnectionCaps
 
+from common import dbus_support
+if dbus_support.supported:
+	import dbus
+	from music_track_listener import MusicTrackListener
+
 from common.stanza_session import EncryptedStanzaSession 
 
 STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
@@ -54,6 +60,7 @@ VCARD_ARRIVED = 'vcard_arrived'
 AGENT_REMOVED = 'agent_removed'
 METACONTACTS_ARRIVED = 'metacontacts_arrived'
 PRIVACY_ARRIVED = 'privacy_arrived'
+PEP_ACCESS_MODEL = 'pep_access_model'
 HAS_IDLE = True
 try:
 	import idle
@@ -750,6 +757,13 @@ class ConnectionDisco:
 				q.addChild('feature', attrs = {'var': common.xmpp.NS_MUC})
 				q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
 				q.addChild('feature', attrs = {'var': common.xmpp.NS_DISCO_INFO})
+				if gajim.config.get('use_pep'):
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY})
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY + '+notify'})
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE})
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE + '+notify'})
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD})
+					q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD + '+notify'})
 				q.addChild('feature', attrs = {'var': common.xmpp.NS_ESESSION_INIT})
 
 			if (node is None or extension == 'cstates') and gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
@@ -821,6 +835,11 @@ class ConnectionDisco:
 					if identity['category'] == 'pubsub' and identity['type'] == \
 					'pep':
 						self.pep_supported = True
+						listener = MusicTrackListener.get()
+						track = listener.get_playing_track()
+						if gajim.config.get('publish_tune'):
+							gajim.interface.roster._music_track_changed(listener,
+									track, self.name)
 						break
 			if features.__contains__(common.xmpp.NS_BYTESTREAM):
 				gajim.proxy65_manager.resolve(jid, self.connection, self.name)
@@ -1099,6 +1118,15 @@ class ConnectionVcard:
 				self.get_privacy_list('block')
 			# Ask metacontacts before roster
 			self.get_metacontacts()
+		elif self.awaiting_answers[id][0] == PEP_ACCESS_MODEL:
+			conf = iq_obj.getTag('pubsub').getTag('configure')
+			node = conf.getAttr('node')
+			form_tag = conf.getTag('x', namespace=common.xmpp.NS_DATA)
+			form = common.dataforms.ExtendForm(node=form_tag)
+			for field in form.iter_fields():
+				if field.var == 'pubsub#access_model':
+					self.dispatch('PEP_ACCESS_MODEL', (node, field.value))
+					break
 
 		del self.awaiting_answers[id]
 
@@ -1770,8 +1798,22 @@ returns the session that we last sent a message to.'''
 		''' Called when we receive <message/> with pubsub event. '''
 		# TODO: Logging? (actually services where logging would be useful, should
 		# TODO: allow to access archives remotely...)
+		jid = helpers.get_full_jid_from_iq(msg)
 		event = msg.getTag('event')
 
+		# XEP-0107: User Mood
+		items = event.getTag('items', {'node': common.xmpp.NS_MOOD})
+		if items: pep.user_mood(items, self.name, jid)
+		# XEP-0118: User Tune
+		items = event.getTag('items', {'node': common.xmpp.NS_TUNE})
+		if items: pep.user_tune(items, self.name, jid)
+		# XEP-0080: User Geolocation
+		items = event.getTag('items', {'node': common.xmpp.NS_GEOLOC})
+		if items: pep.user_geoloc(items, self.name, jid)
+		# XEP-0108: User Activity
+		items = event.getTag('items', {'node': common.xmpp.NS_ACTIVITY})
+		if items: pep.user_activity(items, self.name, jid)
+
 		items = event.getTag('items')
 		if items is None: return
 
diff --git a/src/common/contacts.py b/src/common/contacts.py
index 262edd1d875a5a1750361b143128051aaf7702f2..ef02f43dad6c144815b4328b52eca9ba04878d30 100644
--- a/src/common/contacts.py
+++ b/src/common/contacts.py
@@ -34,6 +34,10 @@ class Contact:
 		self.groups = groups
 		self.show = show
 		self.status = status
+		# FIXME
+		self.mood = dict()
+		self.activity = dict()
+		self.tune = dict()
 		self.sub = sub
 		self.ask = ask
 		self.resource = resource
@@ -169,8 +173,8 @@ class Contacts:
 	
 	def copy_contact(self, contact):
 		return self.create_contact(jid = contact.jid, name = contact.name,
-			groups = contact.groups, show = contact.show, status = contact.status,
-			sub = contact.sub, ask = contact.ask, resource = contact.resource,
+			groups = contact.groups, show = contact.show, status =
+			contact.status, sub = contact.sub, ask = contact.ask, resource = contact.resource,
 			priority = contact.priority, keyID = contact.keyID,
 			our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
 			last_status_time = contact.last_status_time)
diff --git a/src/common/gajim.py b/src/common/gajim.py
index dcb294034b74ae7c5081feb66040f4d734191034..bfc7a555a48e188bee4655114fa1fe230bf82198 100644
--- a/src/common/gajim.py
+++ b/src/common/gajim.py
@@ -56,7 +56,7 @@ If you start gajim from svn:
 
 interface = None # The actual interface (the gtk one for the moment)
 config = config.Config()
-version = config.get('version')
+version = config.get('version') + 'dh'
 connections = {} # 'account name': 'account (connection.Connection) instance'
 verbose = False
 
diff --git a/src/common/pep.py b/src/common/pep.py
new file mode 100644
index 0000000000000000000000000000000000000000..9259820f5c9e4ef7be227070ad5cb59a8d31d702
--- /dev/null
+++ b/src/common/pep.py
@@ -0,0 +1,129 @@
+from common import gajim, xmpp
+
+def user_mood(items, name, jid):
+	(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
+	contact = gajim.contacts.get_contact(name, user, resource=resource)
+	if not contact:
+		return
+	for item in items.getTags('item'):
+		child = item.getTag('mood')
+		if child is not None:
+			if contact.mood.has_key('mood'):
+				del contact.mood['mood']
+			if contact.mood.has_key('text'):
+				del contact.mood['text']
+			for ch in child.getChildren():
+				if ch.getName() != 'text':
+					contact.mood['mood'] = ch.getName()
+				else:
+					contact.mood['text'] = ch.getData()
+
+def user_tune(items, name, jid):
+	(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
+	contact = gajim.contacts.get_contact(name, user, resource=resource)
+	if not contact:
+		return
+	for item in items.getTags('item'):
+		child = item.getTag('tune')
+		if child is not None:
+			if contact.tune.has_key('artist'):
+				del contact.tune['artist']
+			if contact.tune.has_key('title'):
+				del contact.tune['title']
+			if contact.tune.has_key('source'):
+				del contact.tune['source']
+			if contact.tune.has_key('track'):
+				del contact.tune['track']
+			if contact.tune.has_key('length'):
+				del contact.tune['length']
+			for ch in child.getChildren():
+				if ch.getName() == 'artist':
+					contact.tune['artist'] = ch.getData()
+				elif ch.getName() == 'title':
+					contact.tune['title'] = ch.getData()
+				elif ch.getName() == 'source':
+					contact.tune['source'] = ch.getData()
+				elif ch.getName() == 'track':
+					contact.tune['track'] = ch.getData()
+				elif ch.getName() == 'length':
+					contact.tune['length'] = ch.getData()
+
+def user_geoloc(items, name, jid):
+	pass
+
+def user_activity(items, name, jid):
+	(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
+	contact = gajim.contacts.get_contact(name, user, resource=resource)
+	if not contact:
+		return
+	for item in items.getTags('item'):
+		child = item.getTag('activity')
+		if child is not None:
+			if contact.activity.has_key('activity'):
+				del contact.activity['activity']
+			if contact.activity.has_key('subactivity'):
+				del contact.activity['subactivity']
+			if contact.activity.has_key('text'):
+				del contact.activity['text']
+			for ch in child.getChildren():
+				if ch.getName() != 'text':
+					contact.activity['activity'] = ch.getName()
+					for chi in ch.getChildren():
+						contact.activity['subactivity'] = chi.getName()
+				else:
+					contact.activity['text'] = ch.getData()
+
+def user_send_mood(account, mood, message = ''):
+	print "Sending %s: %s" % (mood, message)
+	if gajim.config.get('publish_mood') == False:
+		return
+	item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
+	if mood != '':
+		item.addChild(mood)
+	if message != '':
+		i = item.addChild('text')
+		i.addData(message)
+
+	gajim.connections[account].send_pb_publish('', xmpp.NS_MOOD, item, '0')
+
+def user_send_activity(account, activity, subactivity = '', message = ''):
+	if gajim.config.get('publish_activity') == False:
+		return
+	item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
+	if activity != '':
+		i = item.addChild(activity)
+	if subactivity != '':
+		i.addChild(subactivity)
+	if message != '':
+		i = item.addChild('text')
+		i.addData(message)
+
+	gajim.connections[account].send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
+
+def user_send_tune(account, artist = '', title = '', source = '', track = 0,length = 0, items = None):
+	print "Tune to be created"
+	if (gajim.config.get('publish_tune') == False) or \
+	(gajim.connections[account].pep_supported == False):
+		return
+	print "publish_tune == True and pep_supported"
+	item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
+	if artist != '':
+		i = item.addChild('artist')
+		i.addData(artist)
+	if title != '':
+		i = item.addChild('title')
+		i.addData(title)
+	if source != '':
+		i = item.addChild('source')
+		i.addData(source)
+	if track != 0:
+		i = item.addChild('track')
+		i.addData(track)
+	if length != 0:
+		i = item.addChild('length')
+		i.addData(length)
+	if items is not None:
+		item.addChild(payload=items)
+
+	gajim.connections[account].send_pb_publish('', xmpp.NS_TUNE, item, '0')
+	print "Tune published"
diff --git a/src/common/pubsub.py b/src/common/pubsub.py
index 8a6da05cc60b94a1ae04d5ddd1fe9ad3ef0e686d..1cead4d4c0c4df33d70057b808666330b09bb58b 100644
--- a/src/common/pubsub.py
+++ b/src/common/pubsub.py
@@ -1,5 +1,7 @@
 import xmpp
 import gajim
+import dataforms
+import connection_handlers
 
 class ConnectionPubSub:
 	def __init__(self):
@@ -43,9 +45,61 @@ class ConnectionPubSub:
 
 		self.connection.send(query)
 
+	def send_pb_delete(self, jid, node):
+		'''Deletes node.'''
+		query = xmpp.Iq('set', to=jid)
+		d = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+		d = d.addChild('delete', {'node': node})
+
+		self.connection.send(query)
+
+	def send_pb_create(self, jid, node, configure = False, configure_form = None):
+		'''Creates new node.'''
+		query = xmpp.Iq('set', to=jid)
+		c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+		c = c.addChild('create', {'node': node})
+		if configure:
+			conf = c.addChild('configure')
+			if configure_form is not None:
+				conf.addChild(node=configuration_form)
+
+		self.connection.send(query)
+
+	def send_pb_configure(self, jid, node, cb, *cbargs, **cbkwargs):
+		query = xmpp.Iq('set', to=jid)
+		c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+		c = c.addChild('configure', {'node': node})
+
+		id = self.connection.send(query)
+
+		def on_configure(self, connection, query):
+			try:
+				filledform = cb(stanza['pubsub']['configure']['x'], *cbargs, **cbkwargs)
+				#TODO: Build a form
+				#TODO: Send it
+
+			except CancelConfigure:
+				cancel = xmpp.Iq('set', to=jid)
+				ca = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+				ca = ca.addChild('configure', {'node': node})
+				#ca = ca.addChild('x', namespace=xmpp.NS_DATA, {'type': 'cancel'})
+
+				self.connection.send(cancel)
+
+		self.__callbacks[id] = (on_configure, (), {})
+
 	def _PubSubCB(self, conn, stanza):
 		try:
 			cb, args, kwargs = self.__callbacks.pop(stanza.getID())
 			cb(conn, stanza, *args, **kwargs)
 		except:
 			pass
+
+	def request_pb_configuration(self, jid, node):
+		query = xmpp.Iq('get', to=jid)
+		e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
+		e = e.addChild('configure', {'node': node})
+		id = self.connection.getAnID()
+		query.setID(id)
+		self.awaiting_answers[id] = (connection_handlers.PEP_ACCESS_MODEL,)
+		self.connection.send(query)
diff --git a/src/common/xmpp/protocol.py b/src/common/xmpp/protocol.py
index 2edb5be837a962a78e18f25e8c5e3fcb715504f1..c09b9921f0ee34121f50bb236a1020738c7569c6 100644
--- a/src/common/xmpp/protocol.py
+++ b/src/common/xmpp/protocol.py
@@ -27,11 +27,14 @@ NS_AGENTS       ='jabber:iq:agents'
 NS_AMP          ='http://jabber.org/protocol/amp'
 NS_AMP_ERRORS   =NS_AMP+'#errors'
 NS_AUTH         ='jabber:iq:auth'
+NS_AVATAR       ='http://www.xmpp.org/extensions/xep-0084.html#ns-metadata'
 NS_BIND         ='urn:ietf:params:xml:ns:xmpp-bind'
 NS_BROWSE       ='jabber:iq:browse'
-NS_BYTESTREAM   ='http://jabber.org/protocol/bytestreams'               # XEP-0065
-NS_CAPS         ='http://jabber.org/protocol/caps'                      # XEP-0115
-NS_CHATSTATES   ='http://jabber.org/protocol/chatstates'                # XEP-0085
+NS_BROWSING     ='http://jabber.org/protocol/browsing'                  # XEP-0195
+NS_BYTESTREAM   ='http://jabber.org/protocol/bytestreams'               # JEP-0065
+NS_CAPS         ='http://jabber.org/protocol/caps'                      # JEP-0115
+NS_CHATSTATES   ='http://jabber.org/protocol/chatstates'                # JEP-0085
+NS_CHATTING     ='http://jabber.org/protocol/chatting'                  # XEP-0194
 NS_CLIENT       ='jabber:client'
 NS_COMMANDS     ='http://jabber.org/protocol/commands'
 NS_COMPONENT_ACCEPT='jabber:component:accept'
@@ -48,8 +51,9 @@ NS_ENCRYPTED    ='jabber:x:encrypted'                                   # XEP-00
 NS_ESESSION_INIT='http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
 NS_EVENT        ='jabber:x:event'                                       # XEP-0022
 NS_FEATURE      ='http://jabber.org/protocol/feature-neg'  
-NS_FILE         ='http://jabber.org/protocol/si/profile/file-transfer'  # XEP-0096
-NS_GEOLOC       ='http://jabber.org/protocol/geoloc'                    # XEP-0080
+NS_FILE         ='http://jabber.org/protocol/si/profile/file-transfer'  # JEP-0096
+NS_GAMING       ='http://jabber.org/protocol/gaming'                    # XEP-0196
+NS_GEOLOC       ='http://jabber.org/protocol/geoloc'                    # JEP-0080
 NS_GROUPCHAT    ='gc-1.0'
 NS_HTTP_AUTH    ='http://jabber.org/protocol/http-auth'                 # XEP-0070
 NS_HTTP_BIND    ='http://jabber.org/protocol/httpbind'                  # XEP-0124
@@ -72,6 +76,7 @@ NS_PRIVACY      ='jabber:iq:privacy'
 NS_PRIVATE      ='jabber:iq:private'
 NS_PROFILE      ='http://jabber.org/protocol/profile'                   # XEP-0154
 NS_PUBSUB       ='http://jabber.org/protocol/pubsub'                    # XEP-0060
+NS_PUBSUB_OWNER ='http://jabber.org/protocol/pubsub#owner'              # JEP-0060
 NS_REGISTER     ='jabber:iq:register'
 NS_ROSTER       ='jabber:iq:roster'
 NS_ROSTERX      ='http://jabber.org/protocol/rosterx'                   # XEP-0144
@@ -90,12 +95,14 @@ NS_STREAMS      ='http://etherx.jabber.org/streams'
 NS_TIME         ='jabber:iq:time'                                       # XEP-0900
 NS_TIME_REVISED ='urn:xmpp:time'                                        # XEP-0202
 NS_TLS          ='urn:ietf:params:xml:ns:xmpp-tls'
+NS_TUNE         ='http://jabber.org/protocol/tune'                      # XEP-0118
 NS_VACATION     ='http://jabber.org/protocol/vacation'
 NS_VCARD        ='vcard-temp'
 NS_GMAILNOTIFY  ='google:mail:notify'
 NS_GTALKSETTING ='google:setting'
 NS_VCARD_UPDATE =NS_VCARD+':x:update'
 NS_VERSION      ='jabber:iq:version'
+NS_VIEWING      ='http://jabber.org/protocol/viewing'                   # XEP--197
 NS_PING         ='urn:xmpp:ping'                                        # XEP-0199
 NS_WAITINGLIST  ='http://jabber.org/protocol/waitinglist'               # XEP-0130
 NS_XHTML_IM     ='http://jabber.org/protocol/xhtml-im'                  # XEP-0071
diff --git a/src/config.py b/src/config.py
index a47844400a730caff1cb5bcab911f4acec2e6944..e2a8999dc1bb2114cb10fe22cdbfa8991b64c823 100644
--- a/src/config.py
+++ b/src/config.py
@@ -49,6 +49,7 @@ from common import passwords
 from common import zeroconf
 from common import dbus_support
 from common import dataforms
+from common import pep
 
 from common.exceptions import GajimGeneralException
 
@@ -458,6 +459,25 @@ class PreferencesWindow:
 		else:
 			widget.set_sensitive(False)
 
+		# PEP
+		st = gajim.config.get('publish_mood')
+		self.xml.get_widget('publish_mood_checkbutton').set_active(st)
+
+		st = gajim.config.get('publish_activity')
+		self.xml.get_widget('publish_activity_checkbutton').set_active(st)
+
+		st = gajim.config.get('publish_tune')
+		self.xml.get_widget('publish_tune_checkbutton').set_active(st)
+
+		st = gajim.config.get('subscribe_mood')
+		self.xml.get_widget('subscribe_mood_checkbutton').set_active(st)
+
+		st = gajim.config.get('subscribe_activity')
+		self.xml.get_widget('subscribe_activity_checkbutton').set_active(st)
+
+		st = gajim.config.get('subscribe_tune')
+		self.xml.get_widget('subscribe_tune_checkbutton').set_active(st)
+
 		# Notify user of new gmail e-mail messages,
 		# only show checkbox if user has a gtalk account
 		frame_gmail = self.xml.get_widget('frame_gmail')
@@ -521,6 +541,8 @@ class PreferencesWindow:
 		self.theme_preferences = None
 		
 		self.notebook.set_current_page(0)
+		if not gajim.config.get('use_pep'):
+			self.notebook.remove_page(5)
 		self.window.show_all()
 		gtkgui_helpers.possibly_move_window_in_current_desktop(self.window)
 
@@ -536,6 +558,45 @@ class PreferencesWindow:
 				w.set_sensitive(widget.get_active())
 		gajim.interface.save_config()
 
+	def on_publish_mood_checkbutton_toggled(self, widget):
+		if widget.get_active() == False:
+			for account in gajim.connections:
+				if gajim.connections[account].pep_supported:
+					pep.user_send_mood(account, '')
+		self.on_checkbutton_toggled(widget, 'publish_mood')
+
+	def on_publish_activity_checkbutton_toggled(self, widget):
+		if widget.get_active() == False:
+			for account in gajim.connections:
+				if gajim.connections[account].pep_supported:
+					pep.user_send_activity(account, '')
+		self.on_checkbutton_toggled(widget, 'publish_activity')
+
+	def on_publish_tune_checkbutton_toggled(self, widget):
+		if widget.get_active() == False:
+			for account in gajim.connections:
+				if gajim.connections[account].pep_supported:
+					pep.user_send_tune(account, '')
+		self.on_checkbutton_toggled(widget, 'publish_tune')
+		gajim.interface.roster.enable_syncing_status_msg_from_current_music_track(
+			widget.get_active())
+
+	def on_subscribe_mood_checkbutton_toggled(self, widget):
+		self.on_checkbutton_toggled(widget, 'subscribe_mood')
+
+	def on_subscribe_activity_checkbutton_toggled(self, widget):
+		self.on_checkbutton_toggled(widget, 'subscribe_activity')
+
+	def on_subscribe_tune_checkbutton_toggled(self, widget):
+		self.on_checkbutton_toggled(widget, 'subscribe_tune')
+
+	def on_save_position_checkbutton_toggled(self, widget):
+		self.on_checkbutton_toggled(widget, 'saveposition')
+
+	def on_sort_by_show_checkbutton_toggled(self, widget):
+		self.on_checkbutton_toggled(widget, 'sort_by_show')
+		gajim.interface.roster.draw_roster()
+
 	def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
 		self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
 		gajim.interface.roster.draw_roster()
@@ -3406,3 +3467,278 @@ class AccountCreationWizardWindow:
 		gajim.interface.roster.draw_roster()
 		gajim.interface.roster.set_actions_menu_needs_rebuild()
 		gajim.interface.save_config()
+
+#---------- ZeroconfPropertiesWindow class -------------#
+class ZeroconfPropertiesWindow:
+	def __init__(self):
+		self.xml = gtkgui_helpers.get_glade('zeroconf_properties_window.glade')
+		self.window = self.xml.get_widget('zeroconf_properties_window')
+		self.window.set_transient_for(gajim.interface.roster.window)
+		self.xml.signal_autoconnect(self)
+
+		self.init_account()
+		self.init_account_gpg()
+
+		self.xml.get_widget('save_button').grab_focus()
+		self.window.show_all()
+	
+	def init_account(self):
+		st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'autoconnect')
+		if st:
+			self.xml.get_widget('autoconnect_checkbutton').set_active(st)
+		
+		list_no_log_for = gajim.config.get_per('accounts',
+			gajim.ZEROCONF_ACC_NAME,'no_log_for').split()
+		if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
+			self.xml.get_widget('log_history_checkbutton').set_active(0)
+		else:
+			self.xml.get_widget('log_history_checkbutton').set_active(1)
+
+
+		st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'sync_with_global_status')
+		if st:
+			self.xml.get_widget('sync_with_global_status_checkbutton').set_active(
+				st)
+
+		for opt in ('first_name', 'last_name', 'jabber_id', 'email'):
+			st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'zeroconf_' + opt)
+			if st:
+				self.xml.get_widget(opt + '_entry').set_text(st)
+
+		st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'custom_port')
+		if st:
+			self.xml.get_widget('custom_port_entry').set_text(str(st))
+		
+		st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'use_custom_host')
+		if st:
+			self.xml.get_widget('custom_port_checkbutton').set_active(st)
+	
+		self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
+
+		if not st:
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'custom_port', '5298')
+
+	def init_account_gpg(self):
+		keyid = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'keyid')
+		keyname = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'keyname')
+		savegpgpass = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'savegpgpass')
+
+		if not keyid or not gajim.config.get('usegpg'):
+			return
+
+		self.xml.get_widget('gpg_key_label').set_text(keyid)
+		self.xml.get_widget('gpg_name_label').set_text(keyname)
+		gpg_save_password_checkbutton = \
+			self.xml.get_widget('gpg_save_password_checkbutton')
+		gpg_save_password_checkbutton.set_sensitive(True)
+		gpg_save_password_checkbutton.set_active(savegpgpass)
+
+		if savegpgpass:
+			entry = self.xml.get_widget('gpg_password_entry')
+			entry.set_sensitive(True)
+			gpgpassword = gajim.config.get_per('accounts',
+						gajim.ZEROCONF_ACC_NAME, 'gpgpassword')
+			entry.set_text(gpgpassword)
+
+	def on_zeroconf_properties_window_destroy(self, widget):
+		# close window
+		if gajim.interface.instances.has_key('zeroconf_properties'):
+			del gajim.interface.instances['zeroconf_properties']
+	
+	def on_custom_port_checkbutton_toggled(self, widget):
+		st = self.xml.get_widget('custom_port_checkbutton').get_active()
+		self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
+	
+	def on_cancel_button_clicked(self, widget):
+		self.window.destroy()
+	
+	def on_save_button_clicked(self, widget):
+		config = {}
+
+		st = self.xml.get_widget('autoconnect_checkbutton').get_active()
+		config['autoconnect'] = st
+		list_no_log_for = gajim.config.get_per('accounts',
+				gajim.ZEROCONF_ACC_NAME, 'no_log_for').split()
+		if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
+			list_no_log_for.remove(gajim.ZEROCONF_ACC_NAME)
+		if not self.xml.get_widget('log_history_checkbutton').get_active():
+			list_no_log_for.append(gajim.ZEROCONF_ACC_NAME)
+		config['no_log_for'] =  ' '.join(list_no_log_for)
+		
+		st = self.xml.get_widget('sync_with_global_status_checkbutton').\
+			get_active()
+		config['sync_with_global_status'] = st
+
+		st = self.xml.get_widget('first_name_entry').get_text()
+		config['zeroconf_first_name'] = st.decode('utf-8')
+		
+		st = self.xml.get_widget('last_name_entry').get_text()
+		config['zeroconf_last_name'] = st.decode('utf-8')
+
+		st = self.xml.get_widget('jabber_id_entry').get_text()
+		config['zeroconf_jabber_id'] = st.decode('utf-8')
+
+		st = self.xml.get_widget('email_entry').get_text()
+		config['zeroconf_email'] = st.decode('utf-8')
+
+		use_custom_port = self.xml.get_widget('custom_port_checkbutton').\
+			get_active()
+		config['use_custom_host'] = use_custom_port
+
+		old_port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'custom_port')
+		if use_custom_port:
+			port = self.xml.get_widget('custom_port_entry').get_text()
+		else:
+			port = 5298
+			
+		config['custom_port'] = port
+	
+		config['keyname'] = self.xml.get_widget('gpg_name_label').get_text().\
+			decode('utf-8')
+		if config['keyname'] == '': # no key selected
+			config['keyid'] = ''
+			config['savegpgpass'] = False
+			config['gpgpassword'] = ''
+		else:
+			config['keyid'] = self.xml.get_widget('gpg_key_label').get_text().\
+				decode('utf-8')
+			config['savegpgpass'] = self.xml.get_widget(
+					'gpg_save_password_checkbutton').get_active()
+			config['gpgpassword'] = self.xml.get_widget('gpg_password_entry'
+				).get_text().decode('utf-8')
+
+		reconnect = False
+		for opt in ('zeroconf_first_name','zeroconf_last_name',
+			'zeroconf_jabber_id', 'zeroconf_email', 'custom_port'):
+			if gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, opt) != \
+			config[opt]:
+				reconnect = True
+
+		for opt	in config:
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, opt,
+				config[opt])
+
+		if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
+			if port != old_port or reconnect:
+				gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
+
+		self.window.destroy()
+
+	def on_gpg_choose_button_clicked(self, widget, data = None):
+		if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
+			secret_keys = gajim.connections[gajim.ZEROCONF_ACC_NAME].\
+				ask_gpg_secrete_keys()
+
+		# self.account is None and/or gajim.connections is {}
+		else:
+			from common import GnuPG
+			if GnuPG.USE_GPG:
+				secret_keys = GnuPG.GnuPG().get_secret_keys()
+			else:
+				secret_keys = []
+		if not secret_keys:
+			dialogs.ErrorDialog(_('Failed to get secret keys'),
+				_('There was a problem retrieving your OpenPGP secret keys.'))
+			return
+		secret_keys[_('None')] = _('None')
+		instance = dialogs.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
+			_('Choose your OpenPGP key'), secret_keys)
+		keyID = instance.run()
+		if keyID is None:
+			return
+		checkbutton = self.xml.get_widget('gpg_save_password_checkbutton')
+		gpg_key_label = self.xml.get_widget('gpg_key_label')
+		gpg_name_label = self.xml.get_widget('gpg_name_label')
+		if keyID[0] == _('None'):
+			gpg_key_label.set_text(_('No key selected'))
+			gpg_name_label.set_text('')
+			checkbutton.set_sensitive(False)
+			self.xml.get_widget('gpg_password_entry').set_sensitive(False)
+		else:
+			gpg_key_label.set_text(keyID[0])
+			gpg_name_label.set_text(keyID[1])
+			checkbutton.set_sensitive(True)
+		checkbutton.set_active(False)
+		self.xml.get_widget('gpg_password_entry').set_text('')
+
+	def on_gpg_save_password_checkbutton_toggled(self, widget):
+		st = widget.get_active()
+		w = self.xml.get_widget('gpg_password_entry')
+		w.set_sensitive(bool(st))
+
+class ManagePEPServicesWindow:
+	def __init__(self, account):
+		self.xml = gtkgui_helpers.get_glade('manage_pep_services_window.glade')
+		self.window = self.xml.get_widget('manage_pep_services_window')
+		self.window.set_transient_for(gajim.interface.roster.window)
+		self.xml.signal_autoconnect(self)
+		self.account = account
+
+		self.init_services()
+		self.window.show_all()
+
+	def on_manage_pep_services_window_destroy(self, widget):
+		'''close window'''
+		del gajim.interface.instances[self.account]['pep_services']
+
+	def on_ok_button_clicked(self, widget):
+		pass
+
+	def on_cancel_button_clicked(self, widget):
+		self.window.destroy()
+
+	def cellrenderer_combo_edited(self, cellrenderer, path, new_text):
+		self.treestore[path][1] = new_text
+
+	def init_services(self):
+		treeview = self.xml.get_widget('services_treeview')
+		# service, access_model, group
+		self.treestore = gtk.ListStore(str, str, str)
+		treeview.set_model(self.treestore)
+
+		col = gtk.TreeViewColumn('Service')
+		treeview.append_column(col)
+
+		cellrenderer_text = gtk.CellRendererText()
+		col.pack_start(cellrenderer_text)
+		col.add_attribute(cellrenderer_text, 'text', 0)
+
+		col = gtk.TreeViewColumn('access model')
+		treeview.append_column(col)
+
+		model = gtk.ListStore(str)
+		model.append(['open'])
+		model.append(['presence'])
+		model.append(['roster'])
+		model.append(['whitelist'])
+		cellrenderer_combo = gtk.CellRendererCombo()
+		cellrenderer_combo.set_property('text-column', 0)
+		cellrenderer_combo.set_property('model', model)
+		cellrenderer_combo.set_property('has-entry', False)
+		cellrenderer_combo.set_property('editable', True)
+		cellrenderer_combo.connect('edited', self.cellrenderer_combo_edited)
+		col.pack_start(cellrenderer_combo)
+		col.add_attribute(cellrenderer_combo, 'text', 1)
+
+		our_jid = gajim.get_jid_from_account(self.account)
+		gajim.connections[self.account].discoverItems(our_jid)
+
+	def items_received(self, items):
+		our_jid = gajim.get_jid_from_account(self.account)
+		for item in items:
+			if 'jid' in item and item['jid'] == our_jid and 'node' in item:
+				# ask <configure> to have access model
+				gajim.connections[self.account].request_pb_configuration(
+					item['jid'], item['node'])
+
+	def new_service(self, node, model):
+		self.treestore.append([node, model, ''])
diff --git a/src/dialogs.py b/src/dialogs.py
index 28e77f9de6a555b1909b3dbf959b1db85063c380..e50b3abbda166244ebfca10a45cdb09e09c9839b 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -370,6 +370,125 @@ class ChooseGPGKeyDialog:
 				self.keys_treeview.set_cursor(path)
 
 
+class ChangeActivityDialog:
+	activities = [_('doing_chores'), _('drinking'), _('eating'),
+	_('excercising'), _('grooming'), _('having_appointment'),
+	_('inactive'), _('relaxing'), _('talking'), _('traveling'),
+	_('working'), ]
+	subactivities = [_('at_the_spa'), _('brushing_teeth'),
+			_('buying_groceries'), _('cleaning'), _('coding'),
+			_('commuting'), _('cooking'), _('cycling'), _('day_off'),
+			_('doing_maintenance'), _('doing_the_dishes'),
+			_('doing_the_laundry'), _('driving'), _('gaming'),
+			_('gardening'), _('getting_a_haircut'), _('going_out'),
+			_('hanging_out'), _('having_a_beer'), _('having_a_snack'),
+			_('having_breakfast'), _('having_coffee'),
+			_('having_dinner'), _('having_lunch'), _('having_tea'),
+			_('hiking'), _('in_a_car'), _('in_a_meeting'),
+			_('in_real_life'), _('jogging'), _('on_a_bus'),
+			_('on_a_plane'), _('on_a_train'), _('on_a_trip'),
+			_('on_the_phone'), _('on_vacation'), _('other'),
+			_('partying'), _('playing_sports'), _('reading'),
+			_('rehearsing'), _('running'), _('running_an_errand'),
+			_('scheduled_holiday'), _('shaving'), _('shopping'),
+			_('skiing'), _('sleeping'), _('socializing'),
+			_('studying'), _('sunbathing'), _('swimming'),
+			_('taking_a_bath'), _('taking_a_shower'), _('walking'),
+			_('walking_the_dog'), _('watching_tv'),
+			_('watching_a_movie'), _('working_out'), _('writing'), ]
+	def __init__(self, account):
+		self.account = account
+		self.xml = gtkgui_helpers.get_glade('change_activity_dialog.glade')
+		self.window = self.xml.get_widget('change_activity_dialog')
+		self.window.set_transient_for(gajim.interface.roster.window)
+		self.window.set_title(_('Activity'))
+
+		self.entry = self.xml.get_widget('entry')
+
+		self.combo1 = self.xml.get_widget('combobox1')
+		self.liststore1 = gtk.ListStore(str)
+		self.combo1.set_model(self.liststore1)
+
+		for activity in self.activities:
+			self.liststore1.append((activity,))
+
+		cellrenderertext = gtk.CellRendererText()
+		self.combo1.pack_start(cellrenderertext, True)
+		self.combo1.add_attribute(cellrenderertext, 'text', 0)
+
+		self.combo2 = self.xml.get_widget('combobox2')
+		self.liststore2 = gtk.ListStore(str)
+		self.combo2.set_model(self.liststore2)
+
+		for subactivity in self.subactivities:
+			self.liststore2.append((subactivity,))
+
+		cellrenderertext = gtk.CellRendererText()
+		self.combo2.pack_start(cellrenderertext, True)
+		self.combo2.add_attribute(cellrenderertext, 'text', 0)
+
+		self.xml.signal_autoconnect(self)
+		self.window.show_all()
+
+	def on_ok_button_clicked(self, widget):
+		'''Return activity and messsage (None if no activity selected)'''
+		activity = None 
+		subactivity = None
+		message = None
+		active1 = self.combo1.get_active()
+		active2 = self.combo2.get_active()
+		if active1 > -1:
+			activity = self.liststore1[active1][0].decode('utf-8')
+			if active2 > -1:
+				subactivity = self.liststore2[active2][0].decode('utf-8')
+			message = self.entry.get_text().decode('utf-8')
+			from common import pep
+			pep.user_send_activity(self.account, activity,
+					subactivity, message)
+			self.window.destroy()
+
+	def on_cancel_button_clicked(self, widget):
+		self.window.destroy()
+
+class ChangeMoodDialog:
+	moods = [_('afraid'), _('amazed'), _('angry'), _('annoyed'), _('anxious'), _('aroused'), _('ashamed'), _('bored'), _('brave'), _('calm'), _('cold'), _('confused'), _('contented'), _('cranky'), _('curious'), _('depressed'), _('disappointed'), _('disgusted'), _('distracted'), _('embarrassed'), _('excited'), _('flirtatious'), _('frustrated'), _('grumpy'), _('guilty'), _('happy'), _('hot'), _('humbled'), _('humiliated'), _('hungry'), _('hurt'), _('impressed'), _('in_awe'), _('in_love'), _('indignant'), _('interested'), _('intoxicated'), _('invincible'), _('jealous'), _('lonely'), _('mean'), _('moody'), _('nervous'), _('neutral'), _('offended'), _('playful'), _('proud'), _('relieved'), _('remorseful'), _('restless'), _('sad'), _('sarcastic'), _('serious'), _('shocked'), _('shy'), _('sick'), _('sleepy'), _('stressed'), _('surprised'), _('thirsty'), _('worried')]
+	def __init__(self, account):
+		self.account = account
+		self.xml = gtkgui_helpers.get_glade('change_mood_dialog.glade')
+		self.window = self.xml.get_widget('change_mood_dialog')
+		self.window.set_transient_for(gajim.interface.roster.window)
+		self.window.set_title(_('Mood'))
+
+		self.entry = self.xml.get_widget('entry')
+
+		self.combo = self.xml.get_widget('combobox')
+		self.liststore = gtk.ListStore(str)
+		self.combo.set_model(self.liststore)
+
+		for mood in self.moods:
+			self.liststore.append((mood,))
+
+		cellrenderertext = gtk.CellRendererText()
+		self.combo.pack_start(cellrenderertext, True)
+		self.combo.add_attribute(cellrenderertext, 'text', 0)
+		self.xml.signal_autoconnect(self)
+		self.window.show_all()
+
+	def on_ok_button_clicked(self, widget):
+		'''Return mood and messsage (None if no mood selected)'''
+		mood = None 
+		message = None
+		active = self.combo.get_active()
+		if active > -1:
+			mood = self.liststore[active][0].decode('utf-8')
+			message = self.entry.get_text().decode('utf-8')
+			from common import pep
+			pep.user_send_mood(self.account, mood, message)
+			self.window.destroy()
+
+	def on_cancel_button_clicked(self, widget):
+		self.window.destroy()
+
 class ChangeStatusMessageDialog:
 	def __init__(self, show = None):
 		self.show = show
diff --git a/src/gajim.py b/src/gajim.py
index 4453ab8beb7577bec74298e425d8faff19681412..33cd8a6b40064f40a64d1d4b6da5c20b10262bf5 100755
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -999,6 +999,11 @@ class Interface:
 
 	def handle_event_agent_info_items(self, account, array):
 		#('AGENT_INFO_ITEMS', account, (agent, node, items))
+		our_jid = gajim.get_jid_from_account(account)
+		if gajim.interface.instances[account].has_key('pep_services') and \
+		array[0] == our_jid:
+			gajim.interface.instances[account]['pep_services'].items_received(
+				array[2])
 		try:
 			gajim.connections[account].services_cache.agent_items(array[0],
 				array[1], array[2])
@@ -2169,6 +2174,11 @@ class Interface:
 			_('You are already connected to this account with the same resource. Please type a new one'), input_str = gajim.connections[account].server_resource,
 			is_modal = False, ok_handler = on_ok)
 
+	def handle_event_pep_access_model(self, account, data):
+		# ('PEP_ACCESS_MODEL', account, (node, model))
+		if self.instances[account].has_key('pep_services'):
+			self.instances[account]['pep_services'].new_service(data[0], data[1])
+
 	def handle_event_unique_room_id_supported(self, account, data):
 		'''Receive confirmation that unique_room_id are supported'''
 		# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
@@ -2551,6 +2561,7 @@ class Interface:
 			'SEARCH_FORM': self.handle_event_search_form,
 			'SEARCH_RESULT': self.handle_event_search_result,
 			'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
+			'PEP_ACCESS_MODEL': self.handle_event_pep_access_model,
 			'UNIQUE_ROOM_ID_UNSUPPORTED': \
 				self.handle_event_unique_room_id_unsupported,
 			'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
diff --git a/src/roster_window.py b/src/roster_window.py
index da17f4c3bcadac1af1209bee5f920d3c587780ec..e7334dae2b66e0eed6f2eb601ba6e8fe0f91bc2f 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -931,7 +931,11 @@ class RosterWindow:
 		service_disco_menuitem = self.xml.get_widget('service_disco_menuitem')
 		advanced_menuitem = self.xml.get_widget('advanced_menuitem')
 		profile_avatar_menuitem = self.xml.get_widget('profile_avatar_menuitem')
+		pep_services_menuitem = self.xml.get_widget('pep_services_menuitem')
 
+		if not gajim.config.get('use_pep'):
+			pep_services_menuitem.set_no_show_all(True)
+			pep_services_menuitem.hide()
 		# destroy old advanced menus
 		for m in self.advanced_menus:
 			m.destroy()
@@ -954,6 +958,11 @@ class RosterWindow:
 				self.new_chat_menuitem_handler_id)
 			self.new_chat_menuitem_handler_id = None
 
+		if self.pep_services_menuitem_handler_id:
+			pep_services_menuitem.handler_disconnect(
+				self.pep_services_menuitem_handler_id)
+			self.pep_services_menuitem_handler_id = None
+
 		if self.single_message_menuitem_handler_id:
 			single_message_menuitem.handler_disconnect(
 				self.single_message_menuitem_handler_id)
@@ -964,7 +973,6 @@ class RosterWindow:
 				self.profile_avatar_menuitem_handler_id)
 			self.profile_avatar_menuitem_handler_id = None
 
-
 		# remove the existing submenus
 		add_new_contact_menuitem.remove_submenu()
 		service_disco_menuitem.remove_submenu()
@@ -973,6 +981,7 @@ class RosterWindow:
 		new_chat_menuitem.remove_submenu()
 		advanced_menuitem.remove_submenu()
 		profile_avatar_menuitem.remove_submenu()
+		pep_services_menuitem.remove_submenu()
 
 		# remove the existing accelerator
 		if self.have_new_chat_accel:
@@ -1131,7 +1140,21 @@ class RosterWindow:
 		if len(connected_accounts_with_vcard) > 1:
 			# 2 or more accounts? make submenus
 			profile_avatar_sub_menu = gtk.Menu()
+			pep_services_sub_menu = gtk.Menu()
 			for account in connected_accounts_with_vcard:
+				if gajim.connections[account].pep_supported:
+					# profile, avatar
+					profile_avatar_item = gtk.MenuItem(_('of account %s') % account,
+						False)
+					profile_avatar_sub_menu.append(profile_avatar_item)
+					profile_avatar_item.connect('activate',
+						self.on_profile_avatar_menuitem_activate, account)
+					# PEP services
+					pep_services_item = gtk.MenuItem(_('of account %s') % account,
+						False)
+					pep_services_sub_menu.append(pep_services_item)
+					pep_services_item.connect('activate',
+						self.on_pep_services_menuitem_activate, account)
 				# profile, avatar
 				profile_avatar_item = gtk.MenuItem(_('of account %s') % account,
 					False)
@@ -1140,18 +1163,27 @@ class RosterWindow:
 					self.on_profile_avatar_menuitem_activate, account)
 			profile_avatar_menuitem.set_submenu(profile_avatar_sub_menu)
 			profile_avatar_sub_menu.show_all()
+			pep_services_menuitem.set_submenu(pep_services_sub_menu)
+			pep_services_sub_menu.show_all()
 		elif len(connected_accounts_with_vcard) == 1: # user has only one account
 			account = connected_accounts_with_vcard[0]
 			# profile, avatar
 			if not self.profile_avatar_menuitem_handler_id:
 				self.profile_avatar_menuitem_handler_id = \
-				profile_avatar_menuitem.connect('activate', self.\
-				on_profile_avatar_menuitem_activate, account)
+					profile_avatar_menuitem.connect('activate',
+					self.on_profile_avatar_menuitem_activate, account)
+			# PEP services
+			if not self.pep_services_menuitem_handler_id:
+				self.pep_services_menuitem_handler_id = \
+					pep_services_menuitem.connect('activate',
+					self.on_pep_services_menuitem_activate, account)
 
 		if len(connected_accounts_with_vcard) == 0:
 			profile_avatar_menuitem.set_sensitive(False)
+			pep_services_menuitem.set_sensitive(False)
 		else:
 			profile_avatar_menuitem.set_sensitive(True)
+			pep_services_menuitem.set_sensitive(True)
 
 		# Advanced Actions
 		if len(gajim.connections) == 0: # user has no accounts
@@ -2945,6 +2977,12 @@ class RosterWindow:
 		if url:
 			helpers.launch_browser_mailer('url', url)
 
+	def on_change_activity_activate(self, widget, account):
+		dlg = dialogs.ChangeActivityDialog(account)
+
+	def on_change_mood_activate(self, widget, account):
+		dlg = dialogs.ChangeMoodDialog(account)
+
 	def on_change_status_message_activate(self, widget, account):
 		show = gajim.SHOW_LIST[gajim.connections[account].connected]
 		dlg = dialogs.ChangeStatusMessageDialog(show)
@@ -3010,6 +3048,23 @@ class RosterWindow:
 			sub_menu.append(item)
 			item.connect('activate', self.change_status, account, 'offline')
 
+			pep_menuitem = xml.get_widget('pep_menuitem')
+			if gajim.connections[account].pep_supported and gajim.config.get('use_pep'):
+				pep_submenu = gtk.Menu()
+				pep_menuitem.set_submenu(pep_submenu)
+				if gajim.config.get('publish_mood'):
+					item = gtk.MenuItem('Mood')
+					pep_submenu.append(item)
+					item.connect('activate', self.on_change_mood_activate, account)
+				if gajim.config.get('publish_activity'):
+					item = gtk.MenuItem('Activity')
+					pep_submenu.append(item)
+					item.connect('activate', self.on_change_activity_activate,
+						account)
+			else:
+				pep_menuitem.set_no_show_all(True)
+				pep_menuitem.hide()
+
 			if not gajim.connections[account].gmail_url:
 				open_gmail_inbox_menuitem.set_no_show_all(True)
 				open_gmail_inbox_menuitem.hide()
@@ -3038,8 +3093,7 @@ class RosterWindow:
 			# make some items insensitive if account is offline
 			if gajim.connections[account].connected < 2:
 				for widget in [add_contact_menuitem, service_discovery_menuitem,
-				join_group_chat_menuitem,
-				execute_command_menuitem,
+				join_group_chat_menuitem, execute_command_menuitem, pep_menuitem,
 				start_chat_menuitem]:
 					widget.set_sensitive(False)
 		else:
@@ -3663,14 +3717,14 @@ class RosterWindow:
 				listener = MusicTrackListener.get()
 				self._music_track_changed_signal = listener.connect(
 					'music-track-changed', self._music_track_changed)
-				track = listener.get_playing_track()
-				self._music_track_changed(listener, track)
+			track = listener.get_playing_track()
+			self._music_track_changed(listener, track)
 		else:
 			if self._music_track_changed_signal is not None:
 				listener = MusicTrackListener.get()
 				listener.disconnect(self._music_track_changed_signal)
 				self._music_track_changed_signal = None
-				self._music_track_changed(None, None)
+			self._music_track_changed(None, None)
 
 	## enable setting status msg from a Last.fm account
 	def enable_syncing_status_msg_from_lastfm(self, enabled):
@@ -3718,7 +3772,43 @@ class RosterWindow:
 		except Exception, e:
 			pass
 
-	def _music_track_changed(self, unused_listener, music_track_info):
+	def _music_track_changed(self, unused_listener, music_track_info,
+	account=''):
+		if gajim.config.get('use_pep'):
+			from common import pep
+			if account == '':
+				accounts = gajim.connections.keys()
+			if music_track_info is None:
+					artist = ''
+					title = ''
+					source = ''
+					track = ''
+					length = ''
+			elif hasattr(music_track_info, 'paused') and \
+			music_track_info.paused == 0:
+				artist = ''
+				title = ''
+				source = ''
+				track = ''
+				length = ''
+			else:
+				artist = music_track_info.artist
+				title = music_track_info.title
+				source = music_track_info.album
+			if account == '':
+				print "Multi accounts"
+				for account in accounts:
+					if not gajim.config.get_per('accounts', account,
+					'sync_with_global_status'):
+						continue
+					if not gajim.connections[account].pep_supported:
+						continue
+					pep.user_send_tune(account, artist, title, source)
+			else:
+				print "Single account"
+				pep.user_send_tune(account, artist, title, source)
+			return
+		# No PEP
 		accounts = gajim.connections.keys()
 		if music_track_info is None:
 			status_message = ''
@@ -4002,6 +4092,13 @@ class RosterWindow:
 		else:
 			gajim.interface.instances['preferences'] = config.PreferencesWindow()
 
+	def on_pep_services_menuitem_activate(self, widget, account):
+		if gajim.interface.instances[account].has_key('pep_services'):
+			gajim.interface.instances[account]['pep_services'].window.present()
+		else:
+			gajim.interface.instances[account]['pep_services'] = \
+				config.ManagePEPServicesWindow(account)
+
 	def on_add_new_contact(self, widget, account):
 		dialogs.AddNewContactWindow(account)
 
@@ -5249,6 +5346,7 @@ class RosterWindow:
 		self.new_chat_menuitem_handler_id = False
 		self.single_message_menuitem_handler_id = False
 		self.profile_avatar_menuitem_handler_id = False
+		self.pep_services_menuitem_handler_id = False
 		self.actions_menu_needs_rebuild = True
 		self.regroup = gajim.config.get('mergeaccounts')
 		self.clicked_path = None # Used remember on wich row we clicked
@@ -5414,18 +5512,20 @@ class RosterWindow:
 		self.tooltip = tooltips.RosterTooltip()
 		self.draw_roster()
 
-		## Music Track notifications
-		## FIXME: we use a timeout because changing status of
-		## accounts has no effect until they are connected.
-		st = gajim.config.get('set_status_msg_from_current_music_track')
-		if st:
-			gobject.timeout_add(1000,
-				self.enable_syncing_status_msg_from_current_music_track,
-				st)
+		if gajim.config.get('use_pep'):
+			self.enable_syncing_status_msg_from_current_music_track(gajim.config.get('publish_tune'))
 		else:
-			gobject.timeout_add(1000,
-				self.enable_syncing_status_msg_from_lastfm,
-				gajim.config.get('set_status_msg_from_lastfm'))
+			## Music Track notifications
+			## FIXME: we use a timeout because changing status of
+			## accounts has no effect until they are connected.
+			st = gajim.config.get('set_status_msg_from_current_music_track')
+			if st:
+				gobject.timeout_add(1000,
+					self.enable_syncing_status_msg_from_current_music_track, st)
+			else:
+				gobject.timeout_add(1000,
+					self.enable_syncing_status_msg_from_lastfm,
+					gajim.config.get('set_status_msg_from_lastfm'))
 
 		if gajim.config.get('show_roster_on_startup'):
 			self.window.show_all()
diff --git a/src/tooltips.py b/src/tooltips.py
index e07ae4675d38f2b6f051ddfcfa132d3cb993898f..ecc8741b8a7391b7a8b72c3400d16aa0a317a72b 100644
--- a/src/tooltips.py
+++ b/src/tooltips.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 ##	tooltips.py
 ##
 ## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
@@ -463,6 +464,10 @@ class RosterTooltip(NotificationAreaTooltip):
 						contact.last_status_time)
 			properties.append((self.table,	None))
 		else: # only one resource
+
+			#FIXME: User {Mood, Activity, Tune} not shown if there are
+			#multiple resources
+			#FIXME: User {Mood, Activity, Tune} not shown for self
 			if contact.show:
 				show = helpers.get_uf_show(contact.show) 
 				if contact.last_status_time:
@@ -494,6 +499,42 @@ class RosterTooltip(NotificationAreaTooltip):
 				show = '<i>' + show + '</i>'
 				# we append show below
 				
+				if contact.mood.has_key('mood'):
+					mood_string = 'Mood: <b>%s</b>' % contact.mood['mood'].strip()
+					if contact.mood.has_key('text') and contact.mood['text'] != '':
+						mood_string += ' (%s)' % contact.mood['text'].strip()
+					properties.append((mood_string, None))
+
+				if contact.activity.has_key('activity'):
+					activity = contact.activity['activity'].strip()
+					activity_string = 'Activity: <b>%s' % activity
+					if contact.activity.has_key('subactivity'):
+						activity_sub = contact.activity['subactivity'].strip()
+						activity_string += ' (%s)</b>' % activity_sub
+					else:
+						activity_string += '</b>'
+					if contact.activity.has_key('text'):
+						activity_text = contact.activity['text'].strip()
+						activity_string += ' (%s)' % activity_text
+					properties.append((activity_string, None))
+
+				if contact.tune.has_key('artist') or contact.tune.has_key('title'):
+					if contact.tune.has_key('artist'):
+						artist = contact.tune['artist'].strip()
+					else:
+						artist = _('Unknown Artist')
+					if contact.tune.has_key('title'):
+						title = contact.tune['title'].strip()
+					else:
+						title = _('Unknown Title')
+					if contact.tune.has_key('source'):
+						source = contact.tune['source'].strip()
+					else:
+						source = _('Unknown Source')
+					tune_string = '♪ ' + _('<b>"%(title)s"</b> by <i>%(artist)s</i>\nfrom <i>%(source)s</i>' %\
+							{'title': title, 'artist': artist, 'source': source}) + ' ♪'
+					properties.append((tune_string, None))
+
 				if contact.status:
 					status = contact.status.strip()
 					if status: