diff --git a/data/glade/roster_item_exchange_window.glade b/data/glade/roster_item_exchange_window.glade
new file mode 100644
index 0000000000000000000000000000000000000000..03ee6092e23773392f5258faa9a8ef4c2e4bca58
--- /dev/null
+++ b/data/glade/roster_item_exchange_window.glade
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.16 -->
+  <!-- interface-naming-policy project-wide -->
+  <widget class="GtkWindow" id="roster_item_exchange_window">
+    <property name="title" translatable="yes">Roster Item Exchange</property>
+    <child>
+      <widget class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <widget class="GtkLabel" id="type_label">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">&lt;b&gt;someone@somewhere.com&lt;/b&gt; would like you to &lt;b&gt;add&lt;/b&gt; some contacts in your roster.</property>
+            <property name="use_markup">True</property>
+            <property name="justify">center</property>
+          </widget>
+          <packing>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkScrolledWindow" id="body_scrolledwindow">
+            <property name="can_focus">True</property>
+            <property name="no_show_all">True</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <child>
+              <widget class="GtkTextView" id="body_textview">
+                <property name="can_focus">True</property>
+                <property name="no_show_all">True</property>
+                <property name="editable">False</property>
+                <property name="justification">center</property>
+                <property name="cursor_visible">False</property>
+                <property name="text" translatable="yes">Message Body</property>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkScrolledWindow" id="scrolledwindow2">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <child>
+              <widget class="GtkTreeView" id="items_list_treeview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <property name="spacing">3</property>
+            <child>
+              <widget class="GtkButton" id="cancel_button">
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="on_cancel_button_clicked"/>
+              </widget>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="accept_button">
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="on_accept_button_clicked"/>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index ed4c01c3b8b993602813ca5a7dda84bdaf4970f5..e05b9ef7b27a73693803541ecff6cff0b64afe8a 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -1771,6 +1771,27 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
 				self.dispatch('GMAIL_NOTIFY', (jid, newmsgs, gmail_messages_list))
 			raise common.xmpp.NodeProcessed
 
+		
+	def _rosterItemExchangeCB(self, con, msg):
+		''' XEP-0144 Roster Item Echange '''
+		exchange_items_list = {}
+		jid_from = msg.getAttr('from')
+		items_list = msg.getTag('x').getChildren()
+		action = items_list[0].getAttr('action')
+		if action == None:
+			action = 'add'
+		for item in msg.getTag('x').getChildren():
+			jid = item.getAttr('jid')
+			name = item.getAttr('name')
+			groups=[]
+			for group in item.getChildren():
+				groups.append(group.getData())
+			exchange_items_list[jid] = []
+			exchange_items_list[jid].append(name)
+			exchange_items_list[jid].append(groups)
+		self.dispatch('ROSTERX', (action, exchange_items_list, jid_from))
+
+
 	def _messageCB(self, con, msg):
 		'''Called when we receive a message'''
 		log.debug('MessageCB')
@@ -1780,6 +1801,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
 			if msg.getTag('error') is None:
 				self._pubsubEventCB(con, msg)
 			return
+		
+		# check if the message is a roster item exchange (XEP-0144)
+		#if msg.getTag('x') and msg.getTag('x').namespace == common.xmpp.NS_ROSTERX:
+			#self._rosterItemExchangeCB(con, msg)
+			#return
 
 		# check if the message is a XEP-0070 confirmation request
 		if msg.getTag('confirm', namespace=common.xmpp.NS_HTTP_AUTH):
@@ -2579,6 +2605,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
 			common.xmpp.NS_ROSTER)
 		con.RegisterHandler('iq', self._siSetCB, 'set',
 			common.xmpp.NS_SI)
+		con.RegisterHandler('iq', self._rosterItemExchangeCB, 'set',
+			common.xmpp.NS_ROSTERX)
 		con.RegisterHandler('iq', self._siErrorCB, 'error',
 			common.xmpp.NS_SI)
 		con.RegisterHandler('iq', self._siResultCB, 'result',
diff --git a/src/common/gajim.py b/src/common/gajim.py
index 18ee77a8b6ba44f1a568ef3f9a7580b940511259..6b160c3b821a45c3abb07ea67cbc0d62682dd76b 100644
--- a/src/common/gajim.py
+++ b/src/common/gajim.py
@@ -195,7 +195,7 @@ gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,
 	'jabber:iq:gateway', xmpp.NS_LAST, xmpp.NS_PRIVACY, xmpp.NS_PRIVATE,
 	xmpp.NS_REGISTER, xmpp.NS_VERSION, xmpp.NS_DATA, xmpp.NS_ENCRYPTED, 'msglog',
 	'sslc2s', 'stringprep', xmpp.NS_PING, xmpp.NS_TIME_REVISED, xmpp.NS_SSN,
-	xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK]
+	xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX]
 
 # Optional features gajim supports per account
 gajim_optional_features = {}
diff --git a/src/dialogs.py b/src/dialogs.py
index 6a996d7354a52b3d205bea0ed6a76af95ca26129..0859c02f70c7a3eb4a9729a79f247603c1eed6b4 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -88,7 +88,7 @@ class EditGroupsDialog:
 		if self.changes_made:
 			for (contact, account) in self.list_:
 				gajim.connections[account].update_contact(contact.jid, contact.name,
-					contact.groups)
+														  contact.groups)
 
 	def on_edit_groups_dialog_response(self, widget, response_id):
 		if response_id == gtk.RESPONSE_CLOSE:
@@ -200,7 +200,7 @@ class EditGroupsDialog:
 class PassphraseDialog:
 	'''Class for Passphrase dialog'''
 	def __init__(self, titletext, labeltext, checkbuttontext=None,
-	ok_handler=None, cancel_handler=None):
+				 ok_handler=None, cancel_handler=None):
 		self.xml = gtkgui_helpers.get_glade('passphrase_dialog.glade')
 		self.window = self.xml.get_widget('passphrase_dialog')
 		self.passphrase_entry = self.xml.get_widget('passphrase_entry')
@@ -236,7 +236,7 @@ class PassphraseDialog:
 
 		if self.check:
 			checked = self.xml.get_widget('save_passphrase_checkbutton').\
-				get_active()
+					get_active()
 		else:
 			checked = False
 
@@ -259,7 +259,7 @@ class PassphraseDialog:
 class ChooseGPGKeyDialog:
 	'''Class for GPG key dialog'''
 	def __init__(self, title_text, prompt_text, secret_keys, on_response,
-	selected=None):
+				 selected=None):
 		'''secret_keys : {keyID: userName, ...}'''
 		self.on_response = on_response
 		xml = gtkgui_helpers.get_glade('choose_gpg_key_dialog.glade')
@@ -275,11 +275,11 @@ class ChooseGPGKeyDialog:
 		#columns
 		renderer = gtk.CellRendererText()
 		col = self.keys_treeview.insert_column_with_attributes(-1, _('KeyID'),
-			renderer, text = 0)
+															   renderer, text = 0)
 		col.set_sort_column_id(0)
 		renderer = gtk.CellRendererText()
 		col = self.keys_treeview.insert_column_with_attributes(-1,
-			_('Contact name'), renderer, text=1)
+															   _('Contact name'), renderer, text=1)
 		col.set_sort_column_id(1)
 		self.keys_treeview.set_search_column(1)
 		self.fill_tree(secret_keys, selected)
@@ -303,7 +303,7 @@ class ChooseGPGKeyDialog:
 		(model, iter_) = selection.get_selected()
 		if iter_ and response == gtk.RESPONSE_OK:
 			keyID = [ model[iter_][0].decode('utf-8'),
-				model[iter_][1].decode('utf-8') ]
+					  model[iter_][1].decode('utf-8') ]
 		else:
 			keyID = None
 		self.on_response(keyID)
@@ -320,8 +320,8 @@ class ChooseGPGKeyDialog:
 
 class ChangeActivityDialog:
 	PAGELIST = ['doing_chores', 'drinking', 'eating', 'exercising', 'grooming',
-		'having_appointment', 'inactive', 'relaxing', 'talking', 'traveling',
-		'working']
+				'having_appointment', 'inactive', 'relaxing', 'talking', 'traveling',
+				'working']
 
 	def __init__(self, on_response, activity=None, subactivity=None, text=''):
 		self.on_response = on_response
@@ -359,13 +359,13 @@ class ChangeActivityDialog:
 
 			hbox = gtk.HBox(False, 5)
 			hbox.pack_start(gtkgui_helpers.load_activity_icon(category),
-				False, False, 0)
+							False, False, 0)
 			lbl = gtk.Label('<b>' + pep.ACTIVITIES[category]['category'] + '</b>')
 			lbl.set_use_markup(True)
 			hbox.pack_start(lbl, False, False, 0)
 			rbtns[act].add(hbox)
 			rbtns[act].connect('toggled', self.on_rbtn_toggled,
-				[category, 'other'])
+							   [category, 'other'])
 			vbox.pack_start(rbtns[act], False, False, 0)
 
 			activities = []
@@ -386,11 +386,11 @@ class ChangeActivityDialog:
 
 				hbox = gtk.HBox(False, 5)
 				hbox.pack_start(gtkgui_helpers.load_activity_icon(category,
-					activity), False, False, 0)
+																  activity), False, False, 0)
 				hbox.pack_start(gtk.Label(pep.ACTIVITIES[category][activity]),
-					False, False, 0)
+								False, False, 0)
 				rbtns[act].connect('toggled', self.on_rbtn_toggled,
-					[category, activity])
+								   [category, activity])
 				rbtns[act].add(hbox)
 				vbox.pack_start(rbtns[act], False, False, 0)
 
@@ -432,7 +432,7 @@ class ChangeActivityDialog:
 		'''
 		if self.checkbutton.get_active():
 			self.on_response(self.activity, self.subactivity,
-				self.entry.get_text().decode('utf-8'))
+							 self.entry.get_text().decode('utf-8'))
 		else:
 			self.on_response(None, None, '')
 		self.window.destroy()
@@ -460,7 +460,7 @@ class ChangeMoodDialog:
 		no_mood_button = self.xml.get_widget('no_mood_button')
 		no_mood_button.set_mode(False)
 		no_mood_button.connect('clicked',
-			self.on_mood_button_clicked, None)
+							   self.on_mood_button_clicked, None)
 
 		x = 1
 		y = 0
@@ -479,7 +479,7 @@ class ChangeMoodDialog:
 			self.mood_buttons[mood].set_relief(gtk.RELIEF_NONE)
 			gtk.Tooltips().set_tip(self.mood_buttons[mood], pep.MOODS[mood])
 			self.mood_buttons[mood].connect('clicked',
-				self.on_mood_button_clicked, mood)
+											self.on_mood_button_clicked, mood)
 			table.attach(self.mood_buttons[mood], x, x + 1, y, y + 1)
 
 			# Calculate the next position
@@ -536,17 +536,17 @@ class ChangeStatusMessageDialog:
 			uf_show = helpers.get_uf_show(show)
 			self.title_text = _('%s Status Message') % uf_show
 			msg = gajim.config.get_per('statusmsg', '_last_' + self.show,
-				'message')
+									   'message')
 			self.pep_dict['activity'] = gajim.config.get_per('statusmsg',
-				'_last_' + self.show, 'activity')
+															 '_last_' + self.show, 'activity')
 			self.pep_dict['subactivity'] = gajim.config.get_per('statusmsg',
-				'_last_' + self.show, 'subactivity')
+																'_last_' + self.show, 'subactivity')
 			self.pep_dict['activity_text'] = gajim.config.get_per('statusmsg',
-				'_last_' + self.show, 'activity_text')
+																  '_last_' + self.show, 'activity_text')
 			self.pep_dict['mood'] = gajim.config.get_per('statusmsg',
-				'_last_' + self.show, 'mood')
+														 '_last_' + self.show, 'mood')
 			self.pep_dict['mood_text'] = gajim.config.get_per('statusmsg',
-				'_last_' + self.show, 'mood_text')
+															  '_last_' + self.show, 'mood_text')
 		else:
 			self.title_text = _('Status Message')
 		self.window.set_title(self.title_text)
@@ -554,7 +554,7 @@ class ChangeStatusMessageDialog:
 		message_textview = self.xml.get_widget('message_textview')
 		self.message_buffer = message_textview.get_buffer()
 		self.message_buffer.connect('changed',
-			self.toggle_sensitiviy_of_save_as_preset)
+									self.toggle_sensitiviy_of_save_as_preset)
 		if not msg:
 			msg = ''
 		msg = helpers.from_one_line(msg)
@@ -567,7 +567,7 @@ class ChangeStatusMessageDialog:
 				continue
 			opts = []
 			for opt in ['message', 'activity', 'subactivity', 'activity_text',
-			'mood', 'mood_text']:
+						'mood', 'mood_text']:
 				opts.append(gajim.config.get_per('statusmsg', msg_name, opt))
 			opts[0] = helpers.from_one_line(opts[0])
 			self.preset_messages_dict[msg_name] = opts
@@ -613,12 +613,12 @@ class ChangeStatusMessageDialog:
 		img = self.xml.get_widget('activity_image')
 		label = self.xml.get_widget('activity_button_label')
 		if 'activity' in self.pep_dict and self.pep_dict['activity'] in \
-		pep.ACTIVITIES:
+		   pep.ACTIVITIES:
 			if 'subactivity' in self.pep_dict and self.pep_dict['subactivity'] in \
-			pep.ACTIVITIES[self.pep_dict['activity']]:
+			   pep.ACTIVITIES[self.pep_dict['activity']]:
 				img.set_from_pixbuf(gtkgui_helpers.load_activity_icon(
 					self.pep_dict['activity'], self.pep_dict['subactivity']).\
-					get_pixbuf())
+									get_pixbuf())
 			else:
 				img.set_from_pixbuf(gtkgui_helpers.load_activity_icon(
 					self.pep_dict['activity']).get_pixbuf())
@@ -654,7 +654,7 @@ class ChangeStatusMessageDialog:
 				self.window.response(gtk.RESPONSE_OK)
 				return False
 			self.window.set_title('%s [%s]' % (self.title_text,
-				str(self.countdown_left)))
+											   str(self.countdown_left)))
 			self.countdown_left -= 1
 			return True
 		else:
@@ -665,23 +665,23 @@ class ChangeStatusMessageDialog:
 		if response == gtk.RESPONSE_OK:
 			beg, end = self.message_buffer.get_bounds()
 			message = self.message_buffer.get_text(beg, end).decode('utf-8')\
-				.strip()
+					.strip()
 			message = helpers.remove_invalid_xml_chars(message)
 			msg = helpers.to_one_line(message)
 			if self.show:
 				gajim.config.set_per('statusmsg', '_last_' + self.show, 'message',
-					msg)
+									 msg)
 				if self.show_pep:
 					gajim.config.set_per('statusmsg', '_last_' + self.show,
-						'activity', self.pep_dict['activity'])
+										 'activity', self.pep_dict['activity'])
 					gajim.config.set_per('statusmsg', '_last_' + self.show,
-						'subactivity', self.pep_dict['subactivity'])
+										 'subactivity', self.pep_dict['subactivity'])
 					gajim.config.set_per('statusmsg', '_last_' + self.show,
-						'activity_text', self.pep_dict['activity_text'])
+										 'activity_text', self.pep_dict['activity_text'])
 					gajim.config.set_per('statusmsg', '_last_' + self.show, 'mood',
-						self.pep_dict['mood'])
+										 self.pep_dict['mood'])
 					gajim.config.set_per('statusmsg', '_last_' + self.show,
-						'mood_text', self.pep_dict['mood_text'])
+										 'mood_text', self.pep_dict['mood_text'])
 		else:
 			message = None # user pressed Cancel button or X wm button
 		self.window.destroy()
@@ -706,7 +706,7 @@ class ChangeStatusMessageDialog:
 	def on_change_status_message_dialog_key_press_event(self, widget, event):
 		self.countdown_enabled = False
 		if event.keyval == gtk.keysyms.Return or \
-		event.keyval == gtk.keysyms.KP_Enter: # catch CTRL+ENTER
+		   event.keyval == gtk.keysyms.KP_Enter: # catch CTRL+ENTER
 			if (event.state & gtk.gdk.CONTROL_MASK):
 				self.window.response(gtk.RESPONSE_OK)
 				# Stop the event
@@ -733,23 +733,23 @@ class ChangeStatusMessageDialog:
 			def on_ok2():
 				self.preset_messages_dict[msg_name] = [msg_text, self.pep_dict.get(
 					'activity'), self.pep_dict.get('subactivity'), self.pep_dict.get(
-					'activity_text'), self.pep_dict.get('mood'), self.pep_dict.get(
-					'mood_text')]
+						'activity_text'), self.pep_dict.get('mood'), self.pep_dict.get(
+							'mood_text')]
 				gajim.config.set_per('statusmsg', msg_name, 'message', msg_text_1l)
 				gajim.config.set_per('statusmsg', msg_name, 'activity',
-					self.pep_dict.get('activity'))
+									 self.pep_dict.get('activity'))
 				gajim.config.set_per('statusmsg', msg_name, 'subactivity',
-					self.pep_dict.get('subactivity'))
+									 self.pep_dict.get('subactivity'))
 				gajim.config.set_per('statusmsg', msg_name, 'activity_text',
-					self.pep_dict.get('activity_text'))
+									 self.pep_dict.get('activity_text'))
 				gajim.config.set_per('statusmsg', msg_name, 'mood',
-					self.pep_dict.get('mood'))
+									 self.pep_dict.get('mood'))
 				gajim.config.set_per('statusmsg', msg_name, 'mood_text',
-					self.pep_dict.get('mood_text'))
+									 self.pep_dict.get('mood_text'))
 			if msg_name in self.preset_messages_dict:
 				ConfirmationDialog(_('Overwrite Status Message?'),
-					_('This name is already used. Do you want to overwrite this '
-					'status message?'), on_response_ok=on_ok2)
+								   _('This name is already used. Do you want to overwrite this '
+									 'status message?'), on_response_ok=on_ok2)
 				return
 			gajim.config.add_per('statusmsg', msg_name)
 			on_ok2()
@@ -757,8 +757,8 @@ class ChangeStatusMessageDialog:
 			# select in combobox the one we just saved
 			self.message_combobox.set_active_iter(iter_)
 		InputDialog(_('Save as Preset Status Message'),
-			_('Please type a name for this status message'), is_modal=False,
-			ok_handler=on_ok)
+					_('Please type a name for this status message'), is_modal=False,
+					ok_handler=on_ok)
 
 	def on_activity_button_clicked(self, widget):
 		self.countdown_enabled = False
@@ -768,7 +768,7 @@ class ChangeStatusMessageDialog:
 			self.pep_dict['activity_text'] = text
 			self.draw_activity()
 		ChangeActivityDialog(on_response, self.pep_dict['activity'],
-			self.pep_dict['subactivity'], self.pep_dict['activity_text'])
+							 self.pep_dict['subactivity'], self.pep_dict['activity_text'])
 
 	def on_mood_button_clicked(self, widget):
 		self.countdown_enabled = False
@@ -777,16 +777,16 @@ class ChangeStatusMessageDialog:
 			self.pep_dict['mood_text'] = text
 			self.draw_mood()
 		ChangeMoodDialog(on_response, self.pep_dict['mood'],
-			self.pep_dict['mood_text'])
+						 self.pep_dict['mood_text'])
 
 class AddNewContactWindow:
 	'''Class for AddNewContactWindow'''
 	uid_labels = {'jabber': _('Jabber ID:'),
-		'aim': _('AIM Address:'),
-		'gadu-gadu': _('GG Number:'),
-		'icq': _('ICQ Number:'),
-		'msn': _('MSN Address:'),
-		'yahoo': _('Yahoo! Address:')}
+				  'aim': _('AIM Address:'),
+				  'gadu-gadu': _('GG Number:'),
+				  'icq': _('ICQ Number:'),
+				  'msn': _('MSN Address:'),
+				  'yahoo': _('Yahoo! Address:')}
 	def __init__(self, account=None, jid=None, user_nick=None, group=None):
 		self.account = account
 		if account is None:
@@ -814,11 +814,11 @@ class AddNewContactWindow:
 		self.xml.signal_autoconnect(self)
 		self.window = self.xml.get_widget('add_new_contact_window')
 		for w in ('account_combobox', 'account_hbox', 'account_label',
-		'uid_label', 'uid_entry', 'protocol_combobox', 'protocol_jid_combobox',
-		'protocol_hbox', 'nickname_entry', 'message_scrolledwindow',
-		'register_hbox', 'subscription_table', 'add_button',
-		'message_textview', 'connected_label', 'group_comboboxentry',
-		'auto_authorize_checkbutton'):
+				  'uid_label', 'uid_entry', 'protocol_combobox', 'protocol_jid_combobox',
+				  'protocol_hbox', 'nickname_entry', 'message_scrolledwindow',
+				  'register_hbox', 'subscription_table', 'add_button',
+				  'message_textview', 'connected_label', 'group_comboboxentry',
+				  'auto_authorize_checkbutton'):
 			self.__dict__[w] = self.xml.get_widget(w)
 		if account and len(gajim.connections) >= 2:
 			prompt_text =\
@@ -862,7 +862,7 @@ _('Please fill in the data of the contact you want to add in account %s') %accou
 		self.protocol_combobox.add_attribute(cell, 'text', 0)
 		self.protocol_combobox.set_model(liststore)
 		uf_type = {'jabber': 'Jabber', 'aim': 'AIM', 'gadu-gadu': 'Gadu Gadu',
-			'icq': 'ICQ', 'msn': 'MSN', 'yahoo': 'Yahoo'}
+				   'icq': 'ICQ', 'msn': 'MSN', 'yahoo': 'Yahoo'}
 		# Jabber as first
 		img = gajim.interface.jabber_state_images['16']['online']
 		liststore.append(['Jabber', img.get_pixbuf(), 'jabber'])
@@ -1008,7 +1008,7 @@ _('Please fill in the data of the contact you want to add in account %s') %accou
 			c = gajim.contacts.get_first_contact_from_jid(self.account, jid)
 			if _('Not in Roster') not in c.groups and c.sub in ('both', 'to'):
 				ErrorDialog(_('Contact already in roster'),
-				_('This contact is already listed in your roster.'))
+							_('This contact is already listed in your roster.'))
 				return
 
 		if type_ == 'jabber':
@@ -1024,7 +1024,7 @@ _('Please fill in the data of the contact you want to add in account %s') %accou
 			groups = [group]
 		auto_auth = self.auto_authorize_checkbutton.get_active()
 		gajim.interface.roster.req_sub(self, jid, message, self.account,
-			groups = groups, nickname = nickname, auto_auth = auto_auth)
+									   groups = groups, nickname = nickname, auto_auth = auto_auth)
 		self.window.destroy()
 
 	def on_protocol_combobox_changed(self, widget):
@@ -1060,7 +1060,7 @@ _('Please fill in the data of the contact you want to add in account %s') %accou
 			if type_ != 'jabber':
 				jid = self.protocol_jid_combobox.get_active_text()
 				contact = gajim.contacts.get_first_contact_from_jid(self.account,
-					jid)
+																	jid)
 				if contact.show in ('offline', 'error'):
 					self.subscription_table.hide()
 					self.connected_label.show()
@@ -1102,9 +1102,9 @@ class AboutDialog:
 			dlg.set_license(text)
 
 		dlg.set_comments('%s\n%s %s\n%s %s'
-			% (_('A GTK+ jabber client'), \
-			_('GTK+ Version:'), self.tuple2str(gtk.gtk_version), \
-			_('PyGTK Version:'), self.tuple2str(gtk.pygtk_version)))
+						 % (_('A GTK+ jabber client'), \
+							_('GTK+ Version:'), self.tuple2str(gtk.gtk_version), \
+							_('PyGTK Version:'), self.tuple2str(gtk.pygtk_version)))
 		dlg.set_website('http://www.gajim.org/')
 
 		authors_file_path = self.get_path('AUTHORS')
@@ -1129,7 +1129,7 @@ class AboutDialog:
 				text = '\n'.join(text_splitted[:-2]) # remove one english sentence
 				# and add it manually as translatable
 				text += '\n%s\n' % _('Last but not least, we would like to thank all '
-					'the package maintainers.')
+									 'the package maintainers.')
 				authors.append(text)
 
 			dlg.set_authors(authors)
@@ -1171,7 +1171,7 @@ class AboutDialog:
 
 class Dialog(gtk.Dialog):
 	def __init__(self, parent, title, buttons, default=None,
-	on_response_ok=None, on_response_cancel=None):
+				 on_response_ok=None, on_response_cancel=None):
 		gtk.Dialog.__init__(self, title, parent, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR)
 
 		self.user_response_ok = on_response_ok
@@ -1181,7 +1181,7 @@ class Dialog(gtk.Dialog):
 		self.set_resizable(False)
 
 		possible_responses = {gtk.STOCK_OK: self.on_response_ok,
-			gtk.STOCK_CANCEL: self.on_response_cancel}
+							  gtk.STOCK_CANCEL: self.on_response_cancel}
 		for stock, response in buttons:
 			b = self.add_button(stock, response)
 			for response in possible_responses:
@@ -1220,18 +1220,18 @@ class Dialog(gtk.Dialog):
 
 class HigDialog(gtk.MessageDialog):
 	def __init__(self, parent, type_, buttons, pritext, sectext,
-	on_response_ok = None, on_response_cancel = None, on_response_yes = None,
-	on_response_no = None):
+				 on_response_ok = None, on_response_cancel = None, on_response_yes = None,
+				 on_response_no = None):
 		gtk.MessageDialog.__init__(self, parent,
-				gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
-				type_, buttons, message_format = pritext)
+								   gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
+								   type_, buttons, message_format = pritext)
 
 		self.format_secondary_markup(sectext)
 
 		buttons = self.action_area.get_children()
 		possible_responses = {gtk.STOCK_OK: on_response_ok,
-			gtk.STOCK_CANCEL: on_response_cancel, gtk.STOCK_YES: on_response_yes,
-			gtk.STOCK_NO: on_response_no}
+							  gtk.STOCK_CANCEL: on_response_cancel, gtk.STOCK_YES: on_response_yes,
+							  gtk.STOCK_NO: on_response_no}
 		for b in buttons:
 			for response in possible_responses:
 				if b.get_label() == response:
@@ -1259,11 +1259,11 @@ class HigDialog(gtk.MessageDialog):
 class FileChooserDialog(gtk.FileChooserDialog):
 	'''Non-blocking FileChooser Dialog around gtk.FileChooserDialog'''
 	def __init__(self, title_text, action, buttons, default_response,
-	select_multiple = False, current_folder = None, on_response_ok = None,
-	on_response_cancel = None):
+				 select_multiple = False, current_folder = None, on_response_ok = None,
+				 on_response_cancel = None):
 
 		gtk.FileChooserDialog.__init__(self, title=title_text, action=action,
-			buttons=buttons)
+									   buttons=buttons)
 
 		self.set_default_response(default_response)
 		self.set_select_multiple(select_multiple)
@@ -1304,19 +1304,19 @@ class AspellDictError:
 		ErrorDialog(
 			_('Dictionary for lang %s not available') % lang,
 			_('You have to install %s dictionary to use spellchecking, or '
-			'choose another language by setting the speller_language option.'
-			'\n\nHighlighting misspelled words feature will not be used') % lang)
+			  'choose another language by setting the speller_language option.'
+			  '\n\nHighlighting misspelled words feature will not be used') % lang)
 		gajim.config.set('use_speller', False)
 
 class ConfirmationDialog(HigDialog):
 	'''HIG compliant confirmation dialog.'''
 	def __init__(self, pritext, sectext='', on_response_ok=None,
-	on_response_cancel=None):
+				 on_response_cancel=None):
 		self.user_response_ok = on_response_ok
 		self.user_response_cancel = on_response_cancel
 		HigDialog.__init__(self, None,
-			gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext,
-			self.on_response_ok, self.on_response_cancel)
+						   gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext,
+						   self.on_response_ok, self.on_response_cancel)
 		self.popup()
 
 	def on_response_ok(self, widget):
@@ -1338,12 +1338,12 @@ class ConfirmationDialog(HigDialog):
 class NonModalConfirmationDialog(HigDialog):
 	'''HIG compliant non modal confirmation dialog.'''
 	def __init__(self, pritext, sectext='', on_response_ok=None,
-	on_response_cancel=None):
+				 on_response_cancel=None):
 		self.user_response_ok = on_response_ok
 		self.user_response_cancel = on_response_cancel
 		HigDialog.__init__(self, None,
-			gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext,
-			self.on_response_ok, self.on_response_cancel)
+						   gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext,
+						   self.on_response_ok, self.on_response_cancel)
 		self.set_modal(False)
 
 	def on_response_ok(self, widget):
@@ -1366,7 +1366,7 @@ class WarningDialog(HigDialog):
 	def __init__(self, pritext, sectext=''):
 		'''HIG compliant warning dialog.'''
 		HigDialog.__init__( self, None,
-			gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, pritext, sectext)
+							gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, pritext, sectext)
 		self.set_modal(False)
 		self.set_transient_for(gajim.interface.roster.window)
 		self.popup()
@@ -1375,7 +1375,7 @@ class InformationDialog(HigDialog):
 	def __init__(self, pritext, sectext=''):
 		'''HIG compliant info dialog.'''
 		HigDialog.__init__(self, None,
-			gtk.MESSAGE_INFO, gtk.BUTTONS_OK, pritext, sectext)
+						   gtk.MESSAGE_INFO, gtk.BUTTONS_OK, pritext, sectext)
 		self.set_modal(False)
 		self.set_transient_for(gajim.interface.roster.window)
 		self.popup()
@@ -1384,19 +1384,19 @@ class ErrorDialog(HigDialog):
 	def __init__(self, pritext, sectext=''):
 		'''HIG compliant error dialog.'''
 		HigDialog.__init__( self, None,
-			gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, pritext, sectext)
+							gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, pritext, sectext)
 		self.popup()
 
 class YesNoDialog(HigDialog):
 	def __init__(self, pritext, sectext='', checktext='', on_response_yes=None,
-	on_response_no=None):
+				 on_response_no=None):
 		'''HIG compliant YesNo dialog.'''
 		self.user_response_yes = on_response_yes
 		self.user_response_no = on_response_no
 		HigDialog.__init__( self, None,
-			gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext,
-				on_response_yes=self.on_response_yes,
-				on_response_no=self.on_response_no)
+							gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext,
+							on_response_yes=self.on_response_yes,
+							on_response_no=self.on_response_no)
 
 		if checktext:
 			self.checkbutton = gtk.CheckButton(checktext)
@@ -1410,7 +1410,7 @@ class YesNoDialog(HigDialog):
 		if self.user_response_yes:
 			if isinstance(self.user_response_yes, tuple):
 				self.user_response_yes[0](self.is_checked(),
-					*self.user_response_yes[1:])
+										  *self.user_response_yes[1:])
 			else:
 				self.user_response_yes(self.is_checked())
 		self.destroy()
@@ -1432,13 +1432,13 @@ class YesNoDialog(HigDialog):
 class ConfirmationDialogCheck(ConfirmationDialog):
 	'''HIG compliant confirmation dialog with checkbutton.'''
 	def __init__(self, pritext, sectext='', checktext='',
-	on_response_ok=None, on_response_cancel=None, is_modal=True):
+				 on_response_ok=None, on_response_cancel=None, is_modal=True):
 		self.user_response_ok = on_response_ok
 		self.user_response_cancel = on_response_cancel
 
 		HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION,
-			gtk.BUTTONS_OK_CANCEL, pritext, sectext, self.on_response_ok,
-			self.on_response_cancel)
+						   gtk.BUTTONS_OK_CANCEL, pritext, sectext, self.on_response_ok,
+						   self.on_response_cancel)
 
 		self.set_default_response(gtk.RESPONSE_OK)
 
@@ -1456,7 +1456,7 @@ class ConfirmationDialogCheck(ConfirmationDialog):
 		if self.user_response_ok:
 			if isinstance(self.user_response_ok, tuple):
 				self.user_response_ok[0](self.is_checked(),
-					*self.user_response_ok[1:])
+										 *self.user_response_ok[1:])
 			else:
 				self.user_response_ok(self.is_checked())
 		self.destroy()
@@ -1465,7 +1465,7 @@ class ConfirmationDialogCheck(ConfirmationDialog):
 		if self.user_response_cancel:
 			if isinstance(self.user_response_cancel, tuple):
 				self.user_response_cancel[0](self.is_checked(),
-					*self.user_response_cancel[1:])
+											 *self.user_response_cancel[1:])
 			else:
 				self.user_response_cancel(self.is_checked())
 		self.destroy()
@@ -1477,13 +1477,13 @@ class ConfirmationDialogCheck(ConfirmationDialog):
 class ConfirmationDialogDubbleCheck(ConfirmationDialog):
 	'''HIG compliant confirmation dialog with 2 checkbuttons.'''
 	def __init__(self, pritext, sectext='', checktext1='', checktext2='',
-	on_response_ok=None, on_response_cancel=None, is_modal=True):
+				 on_response_ok=None, on_response_cancel=None, is_modal=True):
 		self.user_response_ok = on_response_ok
 		self.user_response_cancel = on_response_cancel
 
 		HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION,
-			gtk.BUTTONS_OK_CANCEL, pritext, sectext, self.on_response_ok,
-			self.on_response_cancel)
+						   gtk.BUTTONS_OK_CANCEL, pritext, sectext, self.on_response_ok,
+						   self.on_response_cancel)
 
 		self.set_default_response(gtk.RESPONSE_OK)
 
@@ -1510,7 +1510,7 @@ class ConfirmationDialogDubbleCheck(ConfirmationDialog):
 		if self.user_response_ok:
 			if isinstance(self.user_response_ok, tuple):
 				self.user_response_ok[0](self.is_checked(),
-					*self.user_response_ok[1:])
+										 *self.user_response_ok[1:])
 			else:
 				self.user_response_ok(self.is_checked())
 		self.destroy()
@@ -1538,9 +1538,9 @@ class ConfirmationDialogDubbleCheck(ConfirmationDialog):
 class FTOverwriteConfirmationDialog(ConfirmationDialog):
 	'''HIG compliant confirmation dialog to overwrite or resume a file transfert'''
 	def __init__(self, pritext, sectext='', propose_resume=True,
-	on_response=None):
+				 on_response=None):
 		HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION, gtk.BUTTONS_CANCEL,
-			pritext, sectext)
+						   pritext, sectext)
 
 		self.on_response = on_response
 
@@ -1610,10 +1610,10 @@ class CommonInputDialog:
 class InputDialog(CommonInputDialog):
 	'''Class for Input dialog'''
 	def __init__(self, title, label_str, input_str=None, is_modal=True,
-	ok_handler=None, cancel_handler=None):
+				 ok_handler=None, cancel_handler=None):
 		self.xml = gtkgui_helpers.get_glade('input_dialog.glade')
 		CommonInputDialog.__init__(self, title, label_str, is_modal, ok_handler,
-			cancel_handler)
+								   cancel_handler)
 		self.input_entry = self.xml.get_widget('input_entry')
 		if input_str:
 			self.input_entry.set_text(input_str)
@@ -1625,10 +1625,10 @@ class InputDialog(CommonInputDialog):
 class InputTextDialog(CommonInputDialog):
 	'''Class for multilines Input dialog (more place than InputDialog)'''
 	def __init__(self, title, label_str, input_str=None, is_modal=True,
-	ok_handler=None, cancel_handler=None):
+				 ok_handler=None, cancel_handler=None):
 		self.xml = gtkgui_helpers.get_glade('input_text_dialog.glade')
 		CommonInputDialog.__init__(self, title, label_str, is_modal, ok_handler,
-			cancel_handler)
+								   cancel_handler)
 		self.input_buffer = self.xml.get_widget('input_textview').get_buffer()
 		if input_str:
 			self.input_buffer.set_text(input_str)
@@ -1642,7 +1642,7 @@ class InputTextDialog(CommonInputDialog):
 class DubbleInputDialog:
 	'''Class for Dubble Input dialog'''
 	def __init__(self, title, label_str1, label_str2, input_str1=None,
-	input_str2=None, is_modal=True, ok_handler=None, cancel_handler=None):
+				 input_str2=None, is_modal=True, ok_handler=None, cancel_handler=None):
 		self.xml = gtkgui_helpers.get_glade('dubbleinput_dialog.glade')
 		self.dialog = self.xml.get_widget('dubbleinput_dialog')
 		label1 = self.xml.get_widget('label1')
@@ -1707,8 +1707,8 @@ class SubscriptionRequestWindow:
 		self.user_nick = user_nick
 		if len(gajim.connections) >= 2:
 			prompt_text = \
-				_('Subscription request for account %(account)s from %(jid)s')\
-				% {'account': account, 'jid': self.jid}
+						_('Subscription request for account %(account)s from %(jid)s')\
+						% {'account': account, 'jid': self.jid}
 		else:
 			prompt_text = _('Subscription request from %s') % self.jid
 		xml.get_widget('from_label').set_text(prompt_text)
@@ -1739,13 +1739,13 @@ class SubscriptionRequestWindow:
 			gajim.interface.instances[self.account]['infos'][self.jid].window.present()
 		else:
 			contact = gajim.contacts.create_contact(jid=self.jid, name='',
-			groups=[], show='', status='', sub='', ask='', resource='',
-			priority=5, keyID='', our_chatstate=None, chatstate=None)
+													groups=[], show='', status='', sub='', ask='', resource='',
+													priority=5, keyID='', our_chatstate=None, chatstate=None)
 			gajim.interface.instances[self.account]['infos'][self.jid] = \
-				vcard.VcardWindow(contact, self.account)
+				 vcard.VcardWindow(contact, self.account)
 			# Remove jabber page
 			gajim.interface.instances[self.account]['infos'][self.jid].xml.\
-				get_widget('information_notebook').remove_page(0)
+				 get_widget('information_notebook').remove_page(0)
 
 	def on_start_chat_activate(self, widget):
 		'''open chat'''
@@ -1768,13 +1768,13 @@ class SubscriptionRequestWindow:
 
 class JoinGroupchatWindow:
 	def __init__(self, account, room_jid='', nick='', password='',
-	automatic=False):
+				 automatic=False):
 		'''automatic is a dict like {'invities': []}
 		If automatic is not empty, this means room must be automaticaly configured
 		and when done, invities must be automatically invited'''
 		if room_jid != '':
 			if room_jid in gajim.gc_connected[account] and\
-			gajim.gc_connected[account][room_jid]:
+			   gajim.gc_connected[account][room_jid]:
 				ErrorDialog(_('You are already in group chat %s') % room_jid)
 				raise GajimGeneralException, 'You are already in this group chat'
 		self.account = account
@@ -1783,7 +1783,7 @@ class JoinGroupchatWindow:
 			nick = gajim.nicks[self.account]
 		if gajim.connections[account].connected < 2:
 			ErrorDialog(_('You are not connected to the server'),
-				_('You can not join a group chat unless you are connected.'))
+						_('You can not join a group chat unless you are connected.'))
 			raise GajimGeneralException, 'You must be connected to join a groupchat'
 
 		self._empty_required_widgets = []
@@ -1874,25 +1874,25 @@ class JoinGroupchatWindow:
 			nickname = helpers.parse_resource(nickname)
 		except Exception:
 			ErrorDialog(_('Invalid Nickname'),
-				_('The nickname has not allowed characters.'))
+						_('The nickname has not allowed characters.'))
 			return
 		user, server, resource = helpers.decompose_jid(room_jid)
 		if not user or not server or resource:
 			ErrorDialog(_('Invalid group chat Jabber ID'),
-				_('The group chat Jabber ID has not allowed characters.'))
+						_('The group chat Jabber ID has not allowed characters.'))
 			return
 		try:
 			room_jid = helpers.parse_jid(room_jid)
 		except Exception:
 			ErrorDialog(_('Invalid group chat Jabber ID'),
-				_('The group chat Jabber ID has not allowed characters.'))
+						_('The group chat Jabber ID has not allowed characters.'))
 			return
 
 		if gajim.interface.msg_win_mgr.has_window(room_jid, self.account):
 			ctrl = gajim.interface.msg_win_mgr.get_gc_control(room_jid, self.account)
 			if ctrl.type_id != message_control.TYPE_GC:
 				ErrorDialog(_('This is not a group chat'),
-					_('%s is not the name of a group chat.') % room_jid)
+							_('%s is not the name of a group chat.') % room_jid)
 				return
 		if room_jid in self.recently_groupchat:
 			self.recently_groupchat.remove(room_jid)
@@ -1900,13 +1900,13 @@ class JoinGroupchatWindow:
 		if len(self.recently_groupchat) > 10:
 			self.recently_groupchat = self.recently_groupchat[0:10]
 		gajim.config.set('recently_groupchat',
-			' '.join(self.recently_groupchat))
+						 ' '.join(self.recently_groupchat))
 
 		if self.xml.get_widget('auto_join_checkbutton').get_active():
 			# Add as bookmark, with autojoin and not minimized
 			name = gajim.get_nick_from_jid(room_jid)
 			gajim.interface.add_gc_bookmark(self.account, name, room_jid, '1', \
-				'0', password, nickname)
+											'0', password, nickname)
 
 		if self.automatic:
 			gajim.automatic_rooms[self.account][room_jid] = self.automatic
@@ -1919,7 +1919,7 @@ class SynchroniseSelectAccountDialog:
 		# 'account' can be None if we are about to create our first one
 		if not account or gajim.connections[account].connected < 2:
 			ErrorDialog(_('You are not connected to the server'),
-				_('Without a connection, you can not synchronise your contacts.'))
+						_('Without a connection, you can not synchronise your contacts.'))
 			raise GajimGeneralException, 'You are not connected to the server'
 		self.account = account
 		self.xml = gtkgui_helpers.get_glade('synchronise_select_account_dialog.glade')
@@ -1930,10 +1930,10 @@ class SynchroniseSelectAccountDialog:
 		# columns
 		renderer = gtk.CellRendererText()
 		self.accounts_treeview.insert_column_with_attributes(-1,
-					_('Name'), renderer, text=0)
+															 _('Name'), renderer, text=0)
 		renderer = gtk.CellRendererText()
 		self.accounts_treeview.insert_column_with_attributes(-1,
-					_('Server'), renderer, text=1)
+															 _('Server'), renderer, text=1)
 
 		self.xml.signal_autoconnect(self)
 		self.init_accounts()
@@ -1967,7 +1967,7 @@ class SynchroniseSelectAccountDialog:
 
 		if gajim.connections[remote_account].connected < 2:
 			ErrorDialog(_('This account is not connected to the server'),
-				_('You cannot synchronize with an account unless it is connected.'))
+						_('You cannot synchronize with an account unless it is connected.'))
 			return
 		else:
 			try:
@@ -1991,10 +1991,10 @@ class SynchroniseSelectContactsDialog:
 		renderer1.set_property('activatable', True)
 		renderer1.connect('toggled', self.toggled_callback)
 		self.contacts_treeview.insert_column_with_attributes(-1,
-					_('Synchronise'), renderer1, active=0)
+															 _('Synchronise'), renderer1, active=0)
 		renderer2 = gtk.CellRendererText()
 		self.contacts_treeview.insert_column_with_attributes(-1,
-					_('Name'), renderer2, text=1)
+															 _('Name'), renderer2, text=1)
 
 		self.xml.signal_autoconnect(self)
 		self.init_contacts()
@@ -2034,13 +2034,13 @@ class SynchroniseSelectContactsDialog:
 				# it is selected
 				remote_jid = model[iter_][1].decode('utf-8')
 				message = 'I\'m synchronizing my contacts from my %s account, could you please add this address to your contact list?' % \
-					gajim.get_hostname_from_account(self.remote_account)
+						gajim.get_hostname_from_account(self.remote_account)
 				remote_contact = gajim.contacts.get_first_contact_from_jid(
 					self.remote_account, remote_jid)
 				# keep same groups and same nickname
 				gajim.interface.roster.req_sub(self, remote_jid, message,
-					self.local_account, groups = remote_contact.groups,
-					nickname = remote_contact.name, auto_auth = True)
+											   self.local_account, groups = remote_contact.groups,
+											   nickname = remote_contact.name, auto_auth = True)
 			iter_ = model.iter_next(iter_)
 		self.dialog.destroy()
 
@@ -2077,7 +2077,7 @@ class NewChatDialog(InputDialog):
 		if gajim.connections[self.account].connected <= 1:
 			#if offline or connecting
 			ErrorDialog(_('Connection not available'),
-		_('Please make sure you are connected with "%s".') % self.account)
+						_('Please make sure you are connected with "%s".') % self.account)
 			return
 
 		if jid in self.completion_dict:
@@ -2098,7 +2098,7 @@ class ChangePasswordDialog:
 		# 'account' can be None if we are about to create our first one
 		if not account or gajim.connections[account].connected < 2:
 			ErrorDialog(_('You are not connected to the server'),
-				_('Without a connection, you can not change your password.'))
+						_('Without a connection, you can not change your password.'))
 			raise GajimGeneralException, 'You are not connected to the server'
 		self.account = account
 		self.on_response = on_response
@@ -2122,14 +2122,14 @@ class ChangePasswordDialog:
 		password2 = self.password2_entry.get_text().decode('utf-8')
 		if password1 != password2:
 			ErrorDialog(_('Passwords do not match'),
-				_('The passwords typed in both fields must be identical.'))
+						_('The passwords typed in both fields must be identical.'))
 			return
 		dialog.destroy()
 		self.on_response(password1)
 
 class PopupNotificationWindow:
 	def __init__(self, event_type, jid, account, msg_type='',
-	path_to_image=None, title=None, text=None):
+				 path_to_image=None, title=None, text=None):
 		self.account = account
 		self.jid = jid
 		self.msg_type = msg_type
@@ -2159,21 +2159,21 @@ class PopupNotificationWindow:
 		if not path_to_image:
 			path_to_image = os.path.abspath(
 				os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
-					'chat_msg_recv.png')) # img to display
+							 'chat_msg_recv.png')) # img to display
 
 		if event_type == _('Contact Signed In'):
 			bg_color = 'limegreen'
 		elif event_type == _('Contact Signed Out'):
 			bg_color = 'red'
 		elif event_type in (_('New Message'), _('New Single Message'),
-			_('New Private Message'), _('New E-mail')):
+							_('New Private Message'), _('New E-mail')):
 			bg_color = 'dodgerblue'
 		elif event_type == _('File Transfer Request'):
 			bg_color = 'khaki'
 		elif event_type == _('File Transfer Error'):
 			bg_color = 'firebrick'
 		elif event_type in (_('File Transfer Completed'),
-			_('File Transfer Stopped')):
+							_('File Transfer Stopped')):
 			bg_color = 'yellowgreen'
 		elif event_type == _('Groupchat Invitation'):
 			bg_color = 'tan1'
@@ -2185,7 +2185,7 @@ class PopupNotificationWindow:
 		close_button.modify_bg(gtk.STATE_NORMAL, popup_bg_color)
 		eventbox.modify_bg(gtk.STATE_NORMAL, popup_bg_color)
 		event_description_label.set_markup('<span foreground="black">%s</span>' %
-			gobject.markup_escape_text(text))
+										   gobject.markup_escape_text(text))
 
 		# set the image
 		image.set_from_file(path_to_image)
@@ -2199,7 +2199,7 @@ class PopupNotificationWindow:
 		pos_y = gajim.config.get('notification_position_y')
 		if pos_y < 0:
 			pos_y = gtk.gdk.screen_height() - \
-				gajim.interface.roster.popups_notification_height + pos_y + 1
+				  gajim.interface.roster.popups_notification_height + pos_y + 1
 		self.window.move(pos_x, pos_y)
 
 		xml.signal_autoconnect(self)
@@ -2228,8 +2228,8 @@ class PopupNotificationWindow:
 			window_width, window_height = window_instance.window.get_size()
 			gajim.interface.roster.popups_notification_height += window_height
 			window_instance.window.move(gtk.gdk.screen_width() - window_width,
-				gtk.gdk.screen_height() - \
-				gajim.interface.roster.popups_notification_height)
+										gtk.gdk.screen_height() - \
+										gajim.interface.roster.popups_notification_height)
 
 	def on_popup_notification_window_button_press_event(self, widget, event):
 		if event.button != 1:
@@ -2246,7 +2246,7 @@ class SingleMessageWindow:
 	# Keep a reference on windows so garbage collector don't restroy them
 	instances = []
 	def __init__(self, account, to='', action='', from_whom='', subject='',
-	message='', resource='', session=None, form_node=None):
+				 message='', resource='', session=None, form_node=None):
 		self.instances.append(self)
 		self.account = account
 		self.action = action
@@ -2281,15 +2281,15 @@ class SingleMessageWindow:
 
 		self.form_widget = None
 		parent_box = self.xml.get_widget('conversation_scrolledwindow').\
-			get_parent()
+				   get_parent()
 		if form_node:
 			dataform = dataforms.ExtendForm(node=form_node)
 			self.form_widget = dataforms_widget.DataFormWidget(dataform)
 			self.form_widget.show_all()
 			parent_box.add(self.form_widget)
 			parent_box.child_set_property(self.form_widget, 'position',
-				parent_box.child_get_property(self.xml.get_widget(
-					'conversation_scrolledwindow'), 'position'))
+										  parent_box.child_get_property(self.xml.get_widget(
+											  'conversation_scrolledwindow'), 'position'))
 			self.action = 'form'
 
 		self.send_button = self.xml.get_widget('send_button')
@@ -2337,11 +2337,11 @@ class SingleMessageWindow:
 
 		# get window position and size from config
 		gtkgui_helpers.resize_window(self.window,
-			gajim.config.get('single-msg-width'),
-			gajim.config.get('single-msg-height'))
+									 gajim.config.get('single-msg-width'),
+									 gajim.config.get('single-msg-height'))
 		gtkgui_helpers.move_window(self.window,
-			gajim.config.get('single-msg-x-position'),
-			gajim.config.get('single-msg-y-position'))
+								   gajim.config.get('single-msg-x-position'),
+								   gajim.config.get('single-msg-y-position'))
 
 		self.window.show_all()
 
@@ -2450,7 +2450,7 @@ class SingleMessageWindow:
 		if gajim.connections[self.account].connected <= 1:
 			# if offline or connecting
 			ErrorDialog(_('Connection not available'),
-				_('Please make sure you are connected with "%s".') % self.account)
+						_('Please make sure you are connected with "%s".') % self.account)
 			return
 		if isinstance(self.to, list):
 			sender_list = [i[0].jid + '/' + i[0].resource for i in self.to]
@@ -2464,8 +2464,8 @@ class SingleMessageWindow:
 				to_whom_jid = helpers.parse_jid(to_whom_jid)
 			except helpers.InvalidFormat:
 				ErrorDialog(_('Invalid Jabber ID'),
-					_('It is not possible to send a message to %s, this JID is not '
-					'valid.') % to_whom_jid)
+							_('It is not possible to send a message to %s, this JID is not '
+							  'valid.') % to_whom_jid)
 				return
 
 			subject = self.subject_entry.get_text().decode('utf-8')
@@ -2474,7 +2474,7 @@ class SingleMessageWindow:
 
 			if '/announce/' in to_whom_jid:
 				gajim.connections[self.account].send_motd(to_whom_jid, subject,
-					message)
+														  message)
 				continue
 
 			if self.session:
@@ -2489,8 +2489,8 @@ class SingleMessageWindow:
 				form_node = None
 			# FIXME: allow GPG message some day
 			gajim.connections[self.account].send_message(to_whom_jid, message,
-				keyID=None, type_='normal', subject=subject, session=session,
-				form_node=form_node)
+														 keyID=None, type_='normal', subject=subject, session=session,
+														 form_node=form_node)
 
 		self.subject_entry.set_text('') # we sent ok, clear the subject
 		self.message_tv_buffer.set_text('') # we sent ok, clear the textview
@@ -2506,8 +2506,8 @@ class SingleMessageWindow:
 		self.message = self.message.replace('\n', '\n> ') + '\n\n'
 		self.window.destroy()
 		SingleMessageWindow(self.account, to=self.from_whom, action='send',
-			from_whom=self.from_whom, subject=self.subject, message=self.message,
-			session=self.session)
+							from_whom=self.from_whom, subject=self.subject, message=self.message,
+							session=self.session)
 
 	def on_send_and_close_button_clicked(self, widget):
 		self.send_single_message()
@@ -2598,13 +2598,13 @@ class XMLConsoleWindow:
 		end_iter = buffer.get_end_iter()
 		if kind == 'incoming':
 			buffer.insert_with_tags_by_name(end_iter, '<!-- In -->\n',
-					'in_comment')
+											'in_comment')
 		elif kind == 'outgoing':
 			buffer.insert_with_tags_by_name(end_iter, '<!-- Out -->\n',
-					'out_comment')
+											'out_comment')
 		end_iter = buffer.get_end_iter()
 		buffer.insert_with_tags_by_name(end_iter, stanza.replace('><', '>\n<') + \
-			'\n\n', kind)
+										'\n\n', kind)
 		if at_the_end:
 			gobject.idle_add(self.scroll_to_end)
 
@@ -2612,7 +2612,7 @@ class XMLConsoleWindow:
 		if gajim.connections[self.account].connected <= 1:
 			#if offline or connecting
 			ErrorDialog(_('Connection not available'),
-		_('Please make sure you are connected with "%s".') % self.account)
+						_('Please make sure you are connected with "%s".') % self.account)
 			return
 		begin_iter, end_iter = self.input_tv_buffer.get_bounds()
 		stanza = self.input_tv_buffer.get_text(begin_iter, end_iter).decode(
@@ -2623,7 +2623,7 @@ class XMLConsoleWindow:
 
 	def on_presence_button_clicked(self, widget):
 		self.input_tv_buffer.set_text(
-		'<presence><show></show><status></status><priority></priority></presence>'
+			'<presence><show></show><status></status><priority></priority></presence>'
 		)
 
 	def on_iq_button_clicked(self, widget):
@@ -2641,6 +2641,199 @@ class XMLConsoleWindow:
 			# it's expanded!!
 			self.input_textview.grab_focus()
 
+class RosterItemExchangeWindow:
+	''' Windows used when someone send you a exchange contact suggestion '''
+	def __init__(self, account, action, exchange_list, jid_from, message_body=None):
+		self.account = account
+		self.action = action
+		self.exchange_list = exchange_list
+		self.message_body = message_body
+		self.jid_from = jid_from
+
+		# Connect to glade
+		self.xml = gtkgui_helpers.get_glade('roster_item_exchange_window.glade')
+		self.window = self.xml.get_widget('roster_item_exchange_window')
+
+		# Add Widgets.
+		for widget_to_add in ['cancel_button', 'accept_button', 'type_label',
+							  'body_scrolledwindow', 'body_textview', 'items_list_treeview']:
+			self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
+
+		# Set labels
+		#self.action can be 'add', 'modify' or 'remove'
+		self.type_label.set_label(\
+			_('<b>%s</b> would like you to <b>%s</b> some contacts in your roster.') \
+			% (jid_from, _(self.action)))
+		if message_body:
+			buffer = self.body_textview.get_buffer()
+			buffer.set_text(self.message_body)
+		else:
+			self.body_scrolledwindow.hide()
+		# Treeview
+		model = gtk.ListStore(bool, str, str, str, str)
+		self.items_list_treeview.set_model(model)
+		# columns
+		renderer1 = gtk.CellRendererToggle()
+		renderer1.set_property('activatable', True)
+		renderer1.connect('toggled', self.toggled_callback)
+		self.items_list_treeview.insert_column_with_attributes(-1,
+															   _(self.action), renderer1, active = 0)
+		renderer2 = gtk.CellRendererText()
+		self.items_list_treeview.insert_column_with_attributes(-1,
+															   _('Jabber ID'), renderer2, text = 1)
+		renderer3 = gtk.CellRendererText()
+		self.items_list_treeview.insert_column_with_attributes(-1,
+															   _('Name'), renderer3, text = 2)
+		renderer4 = gtk.CellRendererText()
+		self.items_list_treeview.insert_column_with_attributes(-1,
+															   _('Groups'), renderer4, text = 3)
+
+		# Init contacts
+		model = self.items_list_treeview.get_model()
+		model.clear()
+
+		if action == 'add':
+			for jid in self.exchange_list:
+				groups = ''
+				is_in_roster = True
+				contact = gajim.contacts.get_contact_with_highest_priority(\
+					self.account, jid)
+				if not contact:
+					is_in_roster = False
+				name = self.exchange_list[jid][0]
+				num_list = len(self.exchange_list[jid][1])
+				current = 0
+				for group in self.exchange_list[jid][1]:
+					current += 1
+					if contact and not group in contact.groups:
+						is_in_roster = False
+					if current == num_list:
+						groups = groups + group
+					else:
+						groups = groups + group + ', '
+				if not is_in_roster:
+					iter = model.append()
+					model.set(iter, 0, True, 1, jid, 2, name, 3, groups)
+		elif action == 'modify':
+			for jid in self.exchange_list:
+				groups = ''
+				is_in_roster = True
+				is_right = True
+				contact = gajim.contacts.get_contact_with_highest_priority(\
+					self.account, jid)
+				name = self.exchange_list[jid][0]
+				if not contact:
+					is_in_roster = False
+					is_right = False
+				else:
+					if name != contact.name:
+						is_right = False
+				num_list = len(self.exchange_list[jid][1])
+				current = 0
+				for group in self.exchange_list[jid][1]:
+					current += 1
+					if contact and not group in contact.groups:
+						is_right = False
+					if current == num_list:
+						groups = groups + group
+					else:
+						groups = groups + group + ', '
+				if not is_right and is_in_roster:
+					iter = model.append()
+					model.set(iter, 0, True, 1, jid, 2, name, 3, groups)
+		elif action == 'delete':
+			for jid in self.exchange_list:
+				groups = ''
+				is_in_roster = True
+				contact = gajim.contacts.get_contact_with_highest_priority(\
+					self.account, jid)
+				name = self.exchange_list[jid][0]
+				if not contact:
+					is_in_roster = False
+				num_list = len(self.exchange_list[jid][1])
+				current = 0
+				for group in self.exchange_list[jid][1]:
+					current += 1
+					if current == num_list:
+						groups = groups + group
+					else:
+						groups = groups + group + ', '
+				if not is_right and is_in_roster:
+					iter = model.append()
+					model.set(iter, 0, True, 1, jid, 2, name, 3, groups)        
+
+		self.window.show_all()
+
+		self.xml.signal_autoconnect(self)
+
+	def toggled_callback(self, cell, path):
+		model = self.items_list_treeview.get_model()
+		iter = model.get_iter(path)
+		model[iter][0] = not cell.get_active()
+
+	def on_accept_button_clicked(self, widget):
+		model = self.items_list_treeview.get_model()
+		iter = model.get_iter_root()
+		if self.action == 'add':
+			a = 0
+			while iter:
+				if model[iter][0]:
+					a+=1
+					# it is selected
+					#remote_jid = model[iter][1].decode('utf-8')
+					message = _('%s suggested me to add you in my roster.' % self.jid_from)
+					# keep same groups and same nickname
+					groups = model[iter][3].split(', ')
+					if groups == ['']:
+						groups = []
+					gajim.interface.roster.req_sub(self, model[iter][1], message,
+												   self.account, groups = groups,
+												   nickname = model[iter][2], auto_auth = True)
+				iter = model.iter_next(iter)
+			InformationDialog('Added  %s contacts' % str(a))
+		elif self.action == 'modify':
+			a = 0
+			while iter:
+				if model[iter][0]:
+					a+=1
+					# it is selected
+					jid = model[iter][1].decode('utf-8')
+					# message = _('%s suggested me to add you in my roster.' % self.jid_from)
+					# keep same groups and same nickname
+					groups = model[iter][3].split(', ')
+					if groups == ['']:
+						groups = []
+					for u in gajim.contacts.get_contact(self.account, jid):
+						u.name = model[iter][2]
+					gajim.connections[self.account].update_contact(jid, model[iter][2], groups)
+					self.draw_contact(jid, account)
+					# Update opened chat
+					ctrl = gajim.interface.msg_win_mgr.get_control(jid, self.account)
+					if ctrl:
+						ctrl.update_ui()
+						win = gajim.interface.msg_win_mgr.get_window(jid, self.account)
+						win.redraw_tab(ctrl)
+						win.show_title()
+				iter = model.iter_next(iter)
+		elif self.action == 'delete':
+			a = 0
+			while iter:
+				if model[iter][0]:
+					a+=1
+					# it is selected
+					jid = model[iter][1].decode('utf-8')
+					gajim.connections[self.account].unsubscribe(jid)
+					for c in gajim.contacts.get_contact(self.account, jid):
+						self.remove_contact(c, self.account)
+					gajim.contacts.remove_jid(self.account, jid)
+				iter = model.iter_next(iter)
+			InformationDialog('Added  %s contacts' % str(a))
+		self.window.destroy()
+		
+	def on_cancel_button_clicked(self, widget):
+		self.window.destroy()
+		
+
 class PrivacyListWindow:
 	'''Window that is used for creating NEW or EDITING already there privacy
 	lists'''
@@ -2666,20 +2859,20 @@ class PrivacyListWindow:
 		# Add Widgets
 
 		for widget_to_add in ('title_hbox', 'privacy_lists_title_label',
-		'list_of_rules_label', 'add_edit_rule_label', 'delete_open_buttons_hbox',
-		'privacy_list_active_checkbutton', 'privacy_list_default_checkbutton',
-		'list_of_rules_combobox', 'delete_open_buttons_hbox',
-		'delete_rule_button', 'open_rule_button', 'edit_allow_radiobutton',
-		'edit_deny_radiobutton', 'edit_type_jabberid_radiobutton',
-		'edit_type_jabberid_entry', 'edit_type_group_radiobutton',
-		'edit_type_group_combobox', 'edit_type_subscription_radiobutton',
-		'edit_type_subscription_combobox', 'edit_type_select_all_radiobutton',
-		'edit_queries_send_checkbutton', 'edit_send_messages_checkbutton',
-		'edit_view_status_checkbutton', 'edit_order_spinbutton',
-		'new_rule_button', 'save_rule_button', 'privacy_list_refresh_button',
-		'privacy_list_close_button', 'edit_send_status_checkbutton',
-		'add_edit_vbox', 'privacy_list_active_checkbutton',
-		'privacy_list_default_checkbutton'):
+							  'list_of_rules_label', 'add_edit_rule_label', 'delete_open_buttons_hbox',
+							  'privacy_list_active_checkbutton', 'privacy_list_default_checkbutton',
+							  'list_of_rules_combobox', 'delete_open_buttons_hbox',
+							  'delete_rule_button', 'open_rule_button', 'edit_allow_radiobutton',
+							  'edit_deny_radiobutton', 'edit_type_jabberid_radiobutton',
+							  'edit_type_jabberid_entry', 'edit_type_group_radiobutton',
+							  'edit_type_group_combobox', 'edit_type_subscription_radiobutton',
+							  'edit_type_subscription_combobox', 'edit_type_select_all_radiobutton',
+							  'edit_queries_send_checkbutton', 'edit_send_messages_checkbutton',
+							  'edit_view_status_checkbutton', 'edit_order_spinbutton',
+							  'new_rule_button', 'save_rule_button', 'privacy_list_refresh_button',
+							  'privacy_list_close_button', 'edit_send_status_checkbutton',
+							  'add_edit_vbox', 'privacy_list_active_checkbutton',
+							  'privacy_list_default_checkbutton'):
 			self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
 
 		self.privacy_lists_title_label.set_label(
@@ -2744,12 +2937,12 @@ class PrivacyListWindow:
 		for rule in rules:
 			if 'type' in rule:
 				text_item = _('Order: %(order)s, action: %(action)s, type: %(type)s'
-				', value: %(value)s') % {'order': rule['order'],
-				'action': rule['action'], 'type': rule['type'],
-				'value': rule['value']}
+							  ', value: %(value)s') % {'order': rule['order'],
+													   'action': rule['action'], 'type': rule['type'],
+													   'value': rule['value']}
 			else:
 				text_item = _('Order: %(order)s, action: %(action)s') % \
-				{'order': rule['order'], 'action': rule['action']}
+						  {'order': rule['order'], 'action': rule['action']}
 			self.global_rules[text_item] = rule
 			self.list_of_rules_combobox.append_text(text_item)
 		if len(rules) == 0:
@@ -2909,7 +3102,7 @@ class PrivacyListWindow:
 			child.append('presence-in')
 		if edit_type != '':
 			return {'order': edit_order, 'action': edit_deny,
-				'type': edit_type, 'value': edit_value, 'child': child}
+					'type': edit_type, 'value': edit_value, 'child': child}
 		return {'order': edit_order, 'action': edit_deny, 'child': child}
 
 	def on_save_rule_button_clicked(self, widget):
@@ -2961,9 +3154,9 @@ class PrivacyListsWindow:
 
 		self.window = self.xml.get_widget('privacy_lists_first_window')
 		for widget_to_add in ('list_of_privacy_lists_combobox',
-		'delete_privacy_list_button', 'open_privacy_list_button',
-		'new_privacy_list_button', 'new_privacy_list_entry',
-		'privacy_lists_refresh_button', 'close_privacy_lists_window_button'):
+							  'delete_privacy_list_button', 'open_privacy_list_button',
+							  'new_privacy_list_button', 'new_privacy_list_entry',
+							  'privacy_lists_refresh_button', 'close_privacy_lists_window_button'):
 			self.__dict__[widget_to_add] = self.xml.get_widget(
 				widget_to_add)
 
@@ -3046,14 +3239,14 @@ class PrivacyListsWindow:
 		name = self.new_privacy_list_entry.get_text()
 		if not name:
 			ErrorDialog(_('Invalid List Name'),
-				_('You must enter a name to create a privacy list.'))
+						_('You must enter a name to create a privacy list.'))
 			return
 		key_name = 'privacy_list_%s' % name
 		if key_name in gajim.interface.instances[self.account]:
 			gajim.interface.instances[self.account][key_name].window.present()
 		else:
 			gajim.interface.instances[self.account][key_name] = \
-				PrivacyListWindow(self.account, name, 'NEW')
+				 PrivacyListWindow(self.account, name, 'NEW')
 		self.new_privacy_list_entry.set_text('')
 
 	def on_privacy_lists_refresh_button_clicked(self, widget):
@@ -3067,11 +3260,11 @@ class PrivacyListsWindow:
 			gajim.interface.instances[self.account][key_name].window.present()
 		else:
 			gajim.interface.instances[self.account][key_name] = \
-				PrivacyListWindow(self.account, name, 'EDIT')
+				 PrivacyListWindow(self.account, name, 'EDIT')
 
 class InvitationReceivedDialog:
 	def __init__(self, account, room_jid, contact_jid, password=None,
-	comment=None, is_continued=False):
+				 comment=None, is_continued=False):
 
 		self.room_jid = room_jid
 		self.account = account
@@ -3084,7 +3277,7 @@ class InvitationReceivedDialog:
 			sectext = _('$Contact has invited you to join a discussion')
 		else:
 			sectext = _('$Contact has invited you to group chat %(room_jid)s')\
-				% {'room_jid': room_jid}
+					% {'room_jid': room_jid}
 		contact = gajim.contacts.get_first_contact_from_jid(account, contact_jid)
 		contact_text = contact and contact.name or contact_jid
 		sectext = sectext.replace('$Contact', contact_text)
@@ -3099,7 +3292,7 @@ class InvitationReceivedDialog:
 			try:
 				if self.is_continued:
 					gajim.interface.join_gc_room(self.account, self.room_jid,
-						gajim.nicks[self.account], None, is_continued=True)
+												 gajim.nicks[self.account], None, is_continued=True)
 				else:
 					JoinGroupchatWindow(self.account, self.room_jid)
 			except GajimGeneralException:
@@ -3124,7 +3317,7 @@ class ProgressDialog:
 		self.xml.signal_autoconnect(self)
 
 		self.update_progressbar_timeout_id = gobject.timeout_add(100,
-					self.update_progressbar)
+																 self.update_progressbar)
 
 	def update_progressbar(self):
 		if self.dialog:
@@ -3138,7 +3331,7 @@ class ProgressDialog:
 
 class SoundChooserDialog(FileChooserDialog):
 	def __init__(self, path_to_snd_file='', on_response_ok=None,
-	on_response_cancel=None):
+				 on_response_cancel=None):
 		'''optionally accepts path_to_snd_file so it has that as selected'''
 		def on_ok(widget, callback):
 			'''check if file exists and call callback'''
@@ -3149,14 +3342,14 @@ class SoundChooserDialog(FileChooserDialog):
 				callback(widget, path_to_snd_file)
 
 		FileChooserDialog.__init__(self,
-			title_text = _('Choose Sound'),
-			action = gtk.FILE_CHOOSER_ACTION_OPEN,
-			buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-				gtk.STOCK_OPEN, gtk.RESPONSE_OK),
-			default_response = gtk.RESPONSE_OK,
-			current_folder = gajim.config.get('last_sounds_dir'),
-			on_response_ok = (on_ok, on_response_ok),
-			on_response_cancel = on_response_cancel)
+								   title_text = _('Choose Sound'),
+								   action = gtk.FILE_CHOOSER_ACTION_OPEN,
+								   buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+											  gtk.STOCK_OPEN, gtk.RESPONSE_OK),
+								   default_response = gtk.RESPONSE_OK,
+								   current_folder = gajim.config.get('last_sounds_dir'),
+								   on_response_ok = (on_ok, on_response_ok),
+								   on_response_cancel = on_response_cancel)
 
 		filter_ = gtk.FileFilter()
 		filter_.set_name(_('All files'))
@@ -3177,7 +3370,7 @@ class SoundChooserDialog(FileChooserDialog):
 
 class ImageChooserDialog(FileChooserDialog):
 	def __init__(self, path_to_file='', on_response_ok=None,
-	on_response_cancel=None):
+				 on_response_cancel=None):
 		'''optionally accepts path_to_snd_file so it has that as selected'''
 		def on_ok(widget, callback):
 			'''check if file exists and call callback'''
@@ -3200,14 +3393,14 @@ class ImageChooserDialog(FileChooserDialog):
 		except Exception:
 			path = ''
 		FileChooserDialog.__init__(self,
-			title_text = _('Choose Image'),
-			action = gtk.FILE_CHOOSER_ACTION_OPEN,
-			buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-				gtk.STOCK_OPEN, gtk.RESPONSE_OK),
-			default_response = gtk.RESPONSE_OK,
-			current_folder = path,
-			on_response_ok = (on_ok, on_response_ok),
-			on_response_cancel = on_response_cancel)
+								   title_text = _('Choose Image'),
+								   action = gtk.FILE_CHOOSER_ACTION_OPEN,
+								   buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+											  gtk.STOCK_OPEN, gtk.RESPONSE_OK),
+								   default_response = gtk.RESPONSE_OK,
+								   current_folder = path,
+								   on_response_ok = (on_ok, on_response_ok),
+								   on_response_cancel = on_response_cancel)
 
 		if on_response_cancel:
 			self.connect('destroy', on_response_cancel)
@@ -3250,9 +3443,9 @@ class ImageChooserDialog(FileChooserDialog):
 
 class AvatarChooserDialog(ImageChooserDialog):
 	def __init__(self, path_to_file='', on_response_ok=None,
-	on_response_cancel=None, on_response_clear=None):
+				 on_response_cancel=None, on_response_clear=None):
 		ImageChooserDialog.__init__(self, path_to_file, on_response_ok,
-			on_response_cancel)
+									on_response_cancel)
 		button = gtk.Button(None, gtk.STOCK_CLEAR)
 		self.response_clear = on_response_clear
 		if on_response_clear:
@@ -3306,11 +3499,11 @@ class AddSpecialNotificationDialog:
 				widget.set_active(0) # go back to No Sound
 
 			self.dialog = SoundChooserDialog(on_response_ok=on_ok,
-				on_response_cancel=on_cancel)
+											 on_response_cancel=on_cancel)
 
 	def on_ok_button_clicked(self, widget):
 		conditions = ('online', 'chat', 'online_and_chat',
-			'away', 'xa', 'away_and_xa', 'dnd', 'xa_and_dnd', 'offline')
+					  'away', 'xa', 'away_and_xa', 'dnd', 'xa_and_dnd', 'offline')
 		active = self.condition_combobox.get_active()
 
 		active_iter = self.listen_sound_combobox.get_active_iter()
@@ -3318,23 +3511,23 @@ class AddSpecialNotificationDialog:
 
 class AdvancedNotificationsWindow:
 	events_list = ['message_received', 'contact_connected',
-		'contact_disconnected', 'contact_change_status', 'gc_msg_highlight',
-		'gc_msg', 'ft_request', 'ft_started', 'ft_finished']
+				   'contact_disconnected', 'contact_change_status', 'gc_msg_highlight',
+				   'gc_msg', 'ft_request', 'ft_started', 'ft_finished']
 	recipient_types_list = ['contact', 'group', 'all']
 	config_options = ['event', 'recipient_type', 'recipients', 'status',
-		'tab_opened', 'sound', 'sound_file', 'popup', 'auto_open',
-		'run_command', 'command', 'systray', 'roster', 'urgency_hint']
+					  'tab_opened', 'sound', 'sound_file', 'popup', 'auto_open',
+					  'run_command', 'command', 'systray', 'roster', 'urgency_hint']
 	def __init__(self):
 		self.xml = gtkgui_helpers.get_glade('advanced_notifications_window.glade')
 		self.window = self.xml.get_widget('advanced_notifications_window')
 		for w in ('conditions_treeview', 'config_vbox', 'event_combobox',
-		'recipient_type_combobox', 'recipient_list_entry', 'delete_button',
-		'status_hbox', 'use_sound_cb', 'disable_sound_cb', 'use_popup_cb',
-		'disable_popup_cb', 'use_auto_open_cb', 'disable_auto_open_cb',
-		'use_systray_cb', 'disable_systray_cb', 'use_roster_cb',
-		'disable_roster_cb', 'tab_opened_cb', 'not_tab_opened_cb',
-		'sound_entry', 'sound_file_hbox', 'up_button', 'down_button',
-		'run_command_cb', 'command_entry', 'urgency_hint_cb'):
+				  'recipient_type_combobox', 'recipient_list_entry', 'delete_button',
+				  'status_hbox', 'use_sound_cb', 'disable_sound_cb', 'use_popup_cb',
+				  'disable_popup_cb', 'use_auto_open_cb', 'disable_auto_open_cb',
+				  'use_systray_cb', 'disable_systray_cb', 'use_roster_cb',
+				  'disable_roster_cb', 'tab_opened_cb', 'not_tab_opened_cb',
+				  'sound_entry', 'sound_file_hbox', 'up_button', 'down_button',
+				  'run_command_cb', 'command_entry', 'urgency_hint_cb'):
 			self.__dict__[w] = self.xml.get_widget(w)
 
 		# Contains status checkboxes
@@ -3395,14 +3588,14 @@ class AdvancedNotificationsWindow:
 			return
 		# event
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'event')
+									 'event')
 		if value:
 			self.event_combobox.set_active(self.events_list.index(value))
 		else:
 			self.event_combobox.set_active(-1)
 		# recipient_type
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'recipient_type')
+									 'recipient_type')
 		if value:
 			self.recipient_type_combobox.set_active(
 				self.recipient_types_list.index(value))
@@ -3410,13 +3603,13 @@ class AdvancedNotificationsWindow:
 			self.recipient_type_combobox.set_active(-1)
 		# recipient
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'recipients')
+									 'recipients')
 		if not value:
 			value = ''
 		self.recipient_list_entry.set_text(value)
 		# status
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'status')
+									 'status')
 		if value == 'all':
 			self.all_status_rb.set_active(True)
 		else:
@@ -3430,7 +3623,7 @@ class AdvancedNotificationsWindow:
 		self.on_status_radiobutton_toggled(self.all_status_rb)
 		# tab_opened
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'tab_opened')
+									 'tab_opened')
 		self.tab_opened_cb.set_active(True)
 		self.not_tab_opened_cb.set_active(True)
 		if value == 'no':
@@ -3439,12 +3632,12 @@ class AdvancedNotificationsWindow:
 			self.not_tab_opened_cb.set_active(False)
 		# sound_file
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'sound_file')
+									 'sound_file')
 		self.sound_entry.set_text(value)
 		# sound, popup, auto_open, systray, roster
 		for option in ('sound', 'popup', 'auto_open', 'systray', 'roster'):
 			value = gajim.config.get_per('notifications', str(self.active_num),
-				option)
+										 option)
 			if value == 'yes':
 				self.__dict__['use_' + option + '_cb'].set_active(True)
 			else:
@@ -3455,15 +3648,15 @@ class AdvancedNotificationsWindow:
 				self.__dict__['disable_' + option + '_cb'].set_active(False)
 		# run_command
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'run_command')
+									 'run_command')
 		self.run_command_cb.set_active(value)
 		# command
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'command')
+									 'command')
 		self.command_entry.set_text(value)
 		# urgency_hint
 		value = gajim.config.get_per('notifications', str(self.active_num),
-			'urgency_hint')
+									 'urgency_hint')
 		self.urgency_hint_cb.set_active(value)
 
 	def set_treeview_string(self):
@@ -3483,7 +3676,7 @@ class AdvancedNotificationsWindow:
 				if self.__dict__[st + '_cb'].get_active():
 					status += helpers.get_uf_show(st) + ' '
 		model[iter_][1] = "When %s for %s %s %s" % (event, recipient_type,
-			recipient, status)
+													recipient, status)
 
 	def on_conditions_treeview_cursor_changed(self, widget):
 		(model, iter_) = widget.get_selection().get_selected()
@@ -3539,16 +3732,16 @@ class AdvancedNotificationsWindow:
 
 	def on_up_button_clicked(self, widget):
 		(model, iter_) = self.conditions_treeview.get_selection().\
-			get_selected()
+		 get_selected()
 		if not iter_:
 			return
 		for opt in self.config_options:
 			val = gajim.config.get_per('notifications', str(self.active_num), opt)
 			val2 = gajim.config.get_per('notifications', str(self.active_num - 1),
-				opt)
+										opt)
 			gajim.config.set_per('notifications', str(self.active_num), opt, val2)
 			gajim.config.set_per('notifications', str(self.active_num - 1), opt,
-				val)
+								 val)
 
 		model[iter_][0] = self.active_num - 1
 		# get previous iter
@@ -3564,10 +3757,10 @@ class AdvancedNotificationsWindow:
 		for opt in self.config_options:
 			val = gajim.config.get_per('notifications', str(self.active_num), opt)
 			val2 = gajim.config.get_per('notifications', str(self.active_num + 1),
-				opt)
+										opt)
 			gajim.config.set_per('notifications', str(self.active_num), opt, val2)
 			gajim.config.set_per('notifications', str(self.active_num + 1), opt,
-				val)
+								 val)
 
 		model[iter_][0] = self.active_num + 1
 		iter_ = model.iter_next(iter_)
@@ -3583,16 +3776,16 @@ class AdvancedNotificationsWindow:
 		else:
 			event = self.events_list[active]
 		gajim.config.set_per('notifications', str(self.active_num), 'event',
-			event)
+							 event)
 		self.set_treeview_string()
 
 	def on_recipient_type_combobox_changed(self, widget):
 		if self.active_num < 0:
 			return
 		recipient_type = self.recipient_types_list[self.recipient_type_combobox.\
-			get_active()]
+												   get_active()]
 		gajim.config.set_per('notifications', str(self.active_num),
-			'recipient_type', recipient_type)
+							 'recipient_type', recipient_type)
 		if recipient_type == 'all':
 			self.recipient_list_entry.hide()
 		else:
@@ -3605,7 +3798,7 @@ class AdvancedNotificationsWindow:
 		recipients = widget.get_text().decode('utf-8')
 		#TODO: do some check
 		gajim.config.set_per('notifications', str(self.active_num),
-			'recipients', recipients)
+							 'recipients', recipients)
 		self.set_treeview_string()
 
 	def set_status_config(self):
@@ -3618,7 +3811,7 @@ class AdvancedNotificationsWindow:
 		if status:
 			status = status[:-1]
 		gajim.config.set_per('notifications', str(self.active_num), 'status',
-			status)
+							 status)
 		self.set_treeview_string()
 
 	def on_status_radiobutton_toggled(self, widget):
@@ -3626,7 +3819,7 @@ class AdvancedNotificationsWindow:
 			return
 		if self.all_status_rb.get_active():
 			gajim.config.set_per('notifications', str(self.active_num), 'status',
-				'all')
+								 'all')
 			# 'All status' clicked
 			for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
 				self.__dict__[st + '_cb'].hide()
@@ -3653,14 +3846,14 @@ class AdvancedNotificationsWindow:
 		if self.tab_opened_cb.get_active():
 			if self.not_tab_opened_cb.get_active():
 				gajim.config.set_per('notifications', str(self.active_num),
-					'tab_opened', 'both')
+									 'tab_opened', 'both')
 			else:
 				gajim.config.set_per('notifications', str(self.active_num),
-					'tab_opened', 'yes')
+									 'tab_opened', 'yes')
 		elif not self.not_tab_opened_cb.get_active():
 			self.not_tab_opened_cb.set_active(True)
 			gajim.config.set_per('notifications', str(self.active_num),
-				'tab_opened', 'no')
+								 'tab_opened', 'no')
 
 	def on_not_tab_opened_cb_toggled(self, widget):
 		if self.active_num < 0:
@@ -3668,24 +3861,24 @@ class AdvancedNotificationsWindow:
 		if self.not_tab_opened_cb.get_active():
 			if self.tab_opened_cb.get_active():
 				gajim.config.set_per('notifications', str(self.active_num),
-					'tab_opened', 'both')
+									 'tab_opened', 'both')
 			else:
 				gajim.config.set_per('notifications', str(self.active_num),
-					'tab_opened', 'no')
+									 'tab_opened', 'no')
 		elif not self.tab_opened_cb.get_active():
 			self.tab_opened_cb.set_active(True)
 			gajim.config.set_per('notifications', str(self.active_num),
-				'tab_opened', 'yes')
+								 'tab_opened', 'yes')
 
 	def on_use_it_toggled(self, widget, oposite_widget, option):
 		if widget.get_active():
 			if oposite_widget.get_active():
 				oposite_widget.set_active(False)
 			gajim.config.set_per('notifications', str(self.active_num), option,
-				'yes')
+								 'yes')
 		elif oposite_widget.get_active():
 			gajim.config.set_per('notifications', str(self.active_num), option,
-				'no')
+								 'no')
 		else:
 			gajim.config.set_per('notifications', str(self.active_num), option, '')
 
@@ -3694,10 +3887,10 @@ class AdvancedNotificationsWindow:
 			if oposite_widget.get_active():
 				oposite_widget.set_active(False)
 			gajim.config.set_per('notifications', str(self.active_num), option,
-				'no')
+								 'no')
 		elif oposite_widget.get_active():
 			gajim.config.set_per('notifications', str(self.active_num), option,
-				'yes')
+								 'yes')
 		else:
 			gajim.config.set_per('notifications', str(self.active_num), option, '')
 
@@ -3717,7 +3910,7 @@ class AdvancedNotificationsWindow:
 			if not path_to_snd_file:
 				path_to_snd_file = ''
 			gajim.config.set_per('notifications', str(self.active_num),
-				'sound_file', path_to_snd_file)
+								 'sound_file', path_to_snd_file)
 			self.sound_entry.set_text(path_to_snd_file)
 
 		path_to_snd_file = self.sound_entry.get_text().decode('utf-8')
@@ -3732,7 +3925,7 @@ class AdvancedNotificationsWindow:
 
 	def on_sound_entry_changed(self, widget):
 		gajim.config.set_per('notifications', str(self.active_num),
-			'sound_file', widget.get_text().decode('utf-8'))
+							 'sound_file', widget.get_text().decode('utf-8'))
 
 	def on_use_popup_cb_toggled(self, widget):
 		self.on_use_it_toggled(widget, self.disable_popup_cb, 'popup')
@@ -3748,7 +3941,7 @@ class AdvancedNotificationsWindow:
 
 	def on_run_command_cb_toggled(self, widget):
 		gajim.config.set_per('notifications', str(self.active_num), 'run_command',
-			widget.get_active())
+							 widget.get_active())
 		if widget.get_active():
 			self.command_entry.set_sensitive(True)
 		else:
@@ -3756,7 +3949,7 @@ class AdvancedNotificationsWindow:
 
 	def on_command_entry_changed(self, widget):
 		gajim.config.set_per('notifications', str(self.active_num), 'command',
-			widget.get_text().decode('utf-8'))
+							 widget.get_text().decode('utf-8'))
 
 	def on_use_systray_cb_toggled(self, widget):
 		self.on_use_it_toggled(widget, self.disable_systray_cb, 'systray')
@@ -3772,7 +3965,7 @@ class AdvancedNotificationsWindow:
 
 	def on_urgency_hint_cb_toggled(self, widget):
 		gajim.config.set_per('notifications', str(self.active_num),
-			'uregency_hint', widget.get_active())
+							 'uregency_hint', widget.get_active())
 
 	def on_close_window(self, widget):
 		self.window.destroy()
@@ -3793,8 +3986,8 @@ class TransformChatToMUC:
 		self.window = self.xml.get_widget('chat_to_muc_window')
 
 		for widget_to_add in ('invite_button', 'cancel_button',
-		'server_list_comboboxentry', 'guests_treeview',
-		'server_and_guests_hseparator', 'server_select_label'):
+							  'server_list_comboboxentry', 'guests_treeview',
+							  'server_and_guests_hseparator', 'server_select_label'):
 			self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
 
 		server_list = []
@@ -3840,10 +4033,10 @@ class TransformChatToMUC:
 		# 	transports, zeroconf contacts, minimized groupchats
 		def invitable(contact, contact_transport=None):
 			return (contact.jid not in self.auto_jids and
-			contact.jid != gajim.get_jid_from_account(self.account) and
-			contact.jid not in gajim.interface.minimized_controls[account] and
-			not contact.is_transport() and
-			not contact_transport)
+					contact.jid != gajim.get_jid_from_account(self.account) and
+					contact.jid not in gajim.interface.minimized_controls[account] and
+					not contact.is_transport() and
+					not contact_transport)
 
 		# set jabber id and pseudos
 		for account in gajim.contacts.get_accounts():
@@ -3851,11 +4044,11 @@ class TransformChatToMUC:
 				continue
 			for jid in gajim.contacts.get_jid_list(account):
 				contact = \
-					gajim.contacts.get_contact_with_highest_priority(account, jid)
+						gajim.contacts.get_contact_with_highest_priority(account, jid)
 				contact_transport = gajim.get_transport_name_from_jid(jid)
 				# Add contact if it can be invited
 				if invitable(contact, contact_transport) and \
-						contact.show not in ('offline', 'error'):
+				   contact.show not in ('offline', 'error'):
 					img = gajim.interface.jabber_state_images['16'][contact.show]
 					name = contact.name
 					if name == '':
@@ -3898,7 +4091,7 @@ class TransformChatToMUC:
 		gajim.automatic_rooms[self.account][room_jid]['invities'] = guest_list
 		gajim.automatic_rooms[self.account][room_jid]['continue_tag'] = True
 		gajim.interface.join_gc_room(self.account, room_jid,
-			gajim.nicks[self.account], None, is_continued=True)
+									 gajim.nicks[self.account], None, is_continued=True)
 		self.window.destroy()
 
 	def on_cancel_button_clicked(self, widget):
@@ -3906,15 +4099,15 @@ class TransformChatToMUC:
 
 	def unique_room_id_error(self, server):
 		self.unique_room_id_supported(server,
-			gajim.nicks[self.account].lower().replace(' ','') + str(randrange(
-				9999999)))
+									  gajim.nicks[self.account].lower().replace(' ','') + str(randrange(
+										  9999999)))
 
 class DataFormWindow(Dialog):
 	def __init__(self, form, on_response_ok):
 		self.df_response_ok = on_response_ok
 		Dialog.__init__(self, None, 'test', [(gtk.STOCK_CANCEL,
-			gtk.RESPONSE_REJECT), (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)],
-			on_response_ok=self.on_ok)
+											  gtk.RESPONSE_REJECT), (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)],
+						on_response_ok=self.on_ok)
 		self.set_resizable(True)
 		gtkgui_helpers.resize_window(self, 600, 400)
 		self.dataform_widget =  dataforms_widget.DataFormWidget()
@@ -3958,7 +4151,7 @@ class ESessionInfoWindow:
 			security_image = 'security-high-big.png'
 			if self.session.control:
 				self.session.control._show_lock_image(True, 'E2E', True,
-					self.session.is_loggable(), True)
+													  self.session.is_loggable(), True)
 
 			verification_status = _('''Contact's identity verified''')
 			self.window.set_title(verification_status)
@@ -3972,7 +4165,7 @@ class ESessionInfoWindow:
 		else:
 			if self.session.control:
 				self.session.control._show_lock_image(True, 'E2E', True,
-					self.session.is_loggable(), False)
+													  self.session.is_loggable(), False)
 			labeltext += '\n\n' + _('''To be certain that <b>only</b> the expected person can read your messages or send you messages, you need to verify their identity by clicking the button below.''')
 			security_image = 'security-low-big.png'
 
@@ -4030,30 +4223,30 @@ class GPGInfoWindow:
 		if keyID.endswith('MISMATCH'):
 			verification_status = _('''Contact's identity NOT verified''')
 			info = _('The contact\'s key (%s) <b>does not match</b> the key '
-				'assigned in Gajim.') % keyID[:8]
+					 'assigned in Gajim.') % keyID[:8]
 			image = 'security-low-big.png'
 		elif not keyID:
 			# No key assigned nor a key is used by remote contact
 			verification_status = _('No GPG key assigned')
 			info = _('No GPG key is assigned to this contact. So you cannot '
-				'encrypt messages.')
+					 'encrypt messages.')
 			image = 'security-low-big.png'
 		else:
 			error = gajim.connections[account].gpg.encrypt('test', [keyID])[1]
 			if error:
 				verification_status = _('''Contact's identity NOT verified''')
 				info = _('GPG key is assigned to this contact, but <b>you do not '
-					'trust his key</b>, so message <b>cannot</b> be encrypted. Use '
-					'your GPG client to trust this key.')
+						 'trust his key</b>, so message <b>cannot</b> be encrypted. Use '
+						 'your GPG client to trust this key.')
 				image = 'security-low-big.png'
 			else:
 				verification_status = _('''Contact's identity verified''')
 				info = _('GPG Key is assigned to this contact, and you trust his '
-					'key, so messages will be encrypted.')
+						 'key, so messages will be encrypted.')
 				image = 'security-high-big.png'
 
 		status_label.set_markup('<b><span size="x-large">%s</span></b>' % \
-			verification_status)
+								verification_status)
 		info_label.set_markup(info)
 
 		dir_ = os.path.join(gajim.DATA_DIR, 'pixmaps')
diff --git a/src/gajim.py b/src/gajim.py
index 88f3b050c6ca50e0f81fc28f4a4e0f1c41381b28..9fe7016b6c221386920afc0aea56c4f449661455 100644
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -2059,6 +2059,10 @@ class Interface:
 		# ('PEP_CONFIG', account, (node, form))
 		if 'pep_services' in self.instances[account]:
 			self.instances[account]['pep_services'].config(data[0], data[1])
+			
+	def handle_event_roster_item_exchange(self, account, data):
+		# data = (action in [add, delete, modify], exchange_list, jid_from)
+		dialogs.RosterItemExchangeWindow(account, data[0], data[1], data[2])
 
 	def handle_event_unique_room_id_supported(self, account, data):
 		'''Receive confirmation that unique_room_id are supported'''
@@ -2294,6 +2298,7 @@ class Interface:
 			'SEARCH_FORM': self.handle_event_search_form,
 			'SEARCH_RESULT': self.handle_event_search_result,
 			'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
+			'ROSTERX': self.handle_event_roster_item_exchange,
 			'PEP_CONFIG': self.handle_event_pep_config,
 			'UNIQUE_ROOM_ID_UNSUPPORTED': \
 				self.handle_event_unique_room_id_unsupported,