diff --git a/src/common/connection.py b/src/common/connection.py
index e2b6d2166a7e0ef033df93bdb88ff4e2caa70f7a..3cd3acd43e0c716d5302322b2fc33fd3040e967b 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -98,17 +98,491 @@ ssl_error = {
 32: _("Key usage does not include certificate signing"),
 50: _("Application verification failure")
 }
-class Connection(ConnectionHandlers):
+
+class CommonConnection:
+	'''
+	Common connection class, can be derivated for normal connection or zeroconf
+	connection
+	'''
+	def __init__(self, name):
+		self.name = name
+		# self.connected:
+		# 0=>offline,
+		# 1=>connection in progress,
+		# 2=>online
+		# 3=>free for chat
+		# ...
+		self.connected = 0
+		self.connection = None # xmpppy ClientCommon instance
+		self.on_purpose = False
+		self.is_zeroconf = False
+		self.password = ''
+		self.server_resource = self._compute_resource()
+		self.gpg = None
+		self.USE_GPG = False
+		if gajim.HAVE_GPG:
+			self.USE_GPG = True
+			self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
+		self.status = ''
+		self.old_show = ''
+		self.priority = gajim.get_priority(name, 'offline')
+		self.time_to_reconnect = None
+		self.bookmarks = []
+
+		self.blocked_list = []
+		self.blocked_contacts = []
+		self.blocked_groups = []
+		self.blocked_all = False
+
+		self.pep_supported = False
+		self.pep = {}
+		# Do we continue connection when we get roster (send presence,get vcard..)
+		self.continue_connect_info = None
+
+		# To know the groupchat jid associated with a sranza ID. Useful to
+		# request vcard or os info... to a real JID but act as if it comes from
+		# the fake jid
+		self.groupchat_jids = {} # {ID : groupchat_jid}
+
+		self.privacy_rules_supported = False
+		self.vcard_supported = False
+		self.private_storage_supported = False
+
+		self.muc_jid = {} # jid of muc server for each transport type
+
+		self.get_config_values_or_default()
+
+	def _compute_resource(self):
+		resource = gajim.config.get_per('accounts', self.name, 'resource')
+		# All valid resource substitution strings should be added to this hash.
+		if resource:
+			resource = Template(resource).safe_substitute({
+				'hostname': socket.gethostname()
+			})
+
+	def dispatch(self, event, data):
+		'''always passes account name as first param'''
+		gajim.interface.dispatch(event, self.name, data)
+
+	def _reconnect(self):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def quit(self, kill_core):
+		if kill_core and gajim.account_is_connected(self.name):
+			self.disconnect(on_purpose=True)
+
+	def test_gpg_passphrase(self, password):
+		'''Returns 'ok', 'bad_pass' or 'expired' '''
+		if not self.gpg:
+			return False
+		self.gpg.passphrase = password
+		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
+		signed = self.gpg.sign('test', keyID)
+		self.gpg.password = None
+		if signed == 'KEYEXPIRED':
+			return 'expired'
+		elif signed == 'BAD_PASSPHRASE':
+			return 'bad_pass'
+		return 'ok'
+
+	def get_signed_msg(self, msg, callback = None):
+		'''returns the signed message if possible
+		or an empty string if gpg is not used
+		or None if waiting for passphrase.
+		callback is the function to call when user give the passphrase'''
+		signed = ''
+		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
+		if keyID and self.USE_GPG:
+			use_gpg_agent = gajim.config.get('use_gpg_agent')
+			if self.gpg.passphrase is None and not use_gpg_agent:
+				# We didn't set a passphrase
+				return None
+			if self.gpg.passphrase is not None or use_gpg_agent:
+				signed = self.gpg.sign(msg, keyID)
+				if signed == 'BAD_PASSPHRASE':
+					self.USE_GPG = False
+					signed = ''
+					self.dispatch('BAD_PASSPHRASE', ())
+		return signed
+
+	def _on_disconnected(self):
+		''' called when a disconnect request has completed successfully'''
+		self.disconnect(on_purpose=True)
+		self.dispatch('STATUS', 'offline')
+
+	def get_status(self):
+		return gajim.SHOW_LIST[self.connected]
+
+	def check_jid(self, jid):
+		'''this function must be implemented by derivated classes.
+		It has to return the valid jid, or raise a helpers.InvalidFormat exception
+		'''
+		raise NotImplementedError
+
+	def _prepare_message(self, jid, msg, keyID, type_='chat', subject='',
+	chatstate=None, msg_id=None, composing_xep=None, resource=None,
+	user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
+	original_message=None, delayed=None, callback=None):
+		if not self.connection or self.connected < 2:
+			return 1
+		try:
+			jid = self.check_jid(jid)
+		except helpers.InvalidFormat:
+			self.dispatch('ERROR', (_('Invalid Jabber ID'),
+				_('It is not possible to send a message to %s, this JID is not '
+				'valid.') % jid))
+			return
+
+		if msg and not xhtml and gajim.config.get(
+		'rst_formatting_outgoing_messages'):
+			from common.rst_xhtml_generator import create_xhtml
+			xhtml = create_xhtml(msg)
+		if not msg and chatstate is None and form_node is None:
+			return
+		fjid = jid
+		if resource:
+			fjid += '/' + resource
+		msgtxt = msg
+		msgenc = ''
+
+		if session:
+			fjid = session.get_to()
+
+		if keyID and self.USE_GPG:
+			xhtml = None
+			if keyID ==  'UNKNOWN':
+				error = _('Neither the remote presence is signed, nor a key was '
+					'assigned.')
+			elif keyID.endswith('MISMATCH'):
+				error = _('The contact\'s key (%s) does not match the key assigned '
+					'in Gajim.' % keyID[:8])
+			else:
+				def encrypt_thread(msg, keyID, always_trust=False):
+					# encrypt message. This function returns (msgenc, error)
+					return self.gpg.encrypt(msg, [keyID], always_trust)
+				def _on_encrypted(output):
+					msgenc, error = output
+					if error == 'NOT_TRUSTED':
+						def _on_always_trust(answer):
+							if answer:
+								gajim.thread_interface(encrypt_thread, [msg, keyID,
+									True], _on_encrypted, [])
+							else:
+								self._message_encrypted_cb(output, type_, msg, msgtxt,
+									original_message, fjid, resource, jid, xhtml,
+									subject, chatstate, composing_xep, forward_from,
+									delayed, session, form_node, user_nick, keyID,
+									callback)
+						self.dispatch('GPG_ALWAYS_TRUST', _on_always_trust)
+					else:
+						self._message_encrypted_cb(output, type_, msg, msgtxt,
+							original_message, fjid, resource, jid, xhtml, subject,
+							chatstate, composing_xep, forward_from, delayed, session,
+							form_node, user_nick, keyID, callback)
+				gajim.thread_interface(encrypt_thread, [msg, keyID, False],
+					_on_encrypted, [])
+				return
+
+			self._message_encrypted_cb(('', error), type_, msg, msgtxt,
+				original_message, fjid, resource, jid, xhtml, subject, chatstate,
+				composing_xep, forward_from, delayed, session, form_node, user_nick,
+				keyID, callback)
+
+		self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
+			resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
+			forward_from, delayed, session, form_node, user_nick, callback)
+
+	def _message_encrypted_cb(self, output, type_, msg, msgtxt, original_message,
+	fjid, resource, jid, xhtml, subject, chatstate, composing_xep, forward_from,
+	delayed, session, form_node, user_nick, keyID, callback):
+		msgenc, error = output
+
+		if msgenc and not error:
+			msgtxt = '[This message is *encrypted* (See :XEP:`27`]'
+			lang = os.getenv('LANG')
+			if lang is not None and lang != 'en': # we're not english
+				# one in locale and one en
+				msgtxt = _('[This message is *encrypted* (See :XEP:`27`]') + \
+					' (' + msgtxt + ')'
+			self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
+				resource, jid, xhtml, subject, msgenc, keyID, chatstate,
+				composing_xep, forward_from, delayed, session, form_node, user_nick,
+				callback)
+			return
+		# Encryption failed, do not send message
+		tim = localtime()
+		self.dispatch('MSGNOTSENT', (jid, error, msgtxt, tim, session))
+
+	def _on_continue_message(self, type_, msg, msgtxt, original_message, fjid,
+	resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
+	forward_from, delayed, session, form_node, user_nick, callback):
+		if type_ == 'chat':
+			msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
+				xhtml=xhtml)
+		else:
+			if subject:
+				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
+					subject=subject, xhtml=xhtml)
+			else:
+				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
+					xhtml=xhtml)
+		if msgenc:
+			msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
+
+		if form_node:
+			msg_iq.addChild(node=form_node)
+
+		# XEP-0172: user_nickname
+		if user_nick:
+			msg_iq.setTag('nick', namespace = common.xmpp.NS_NICK).setData(
+				user_nick)
+
+		# TODO: We might want to write a function so we don't need to
+		#	reproduce that ugly if somewhere else.
+		if resource:
+			contact = gajim.contacts.get_contact(self.name, jid, resource)
+		else:
+			contact = gajim.contacts.get_contact_with_highest_priority(self.name,
+				jid)
+
+		# chatstates - if peer supports xep85 or xep22, send chatstates
+		# please note that the only valid tag inside a message containing a <body>
+		# tag is the active event
+		if chatstate is not None and contact:
+			if ((composing_xep == 'XEP-0085' or not composing_xep) \
+			and composing_xep != 'asked_once') or \
+			contact.supports(common.xmpp.NS_CHATSTATES):
+				# XEP-0085
+				msg_iq.setTag(chatstate, namespace=common.xmpp.NS_CHATSTATES)
+			if composing_xep in ('XEP-0022', 'asked_once') or \
+			not composing_xep:
+				# XEP-0022
+				chatstate_node = msg_iq.setTag('x', namespace=common.xmpp.NS_EVENT)
+				if chatstate is 'composing' or msgtxt:
+					chatstate_node.addChild(name='composing')
+
+		if forward_from:
+			addresses = msg_iq.addChild('addresses',
+				namespace=common.xmpp.NS_ADDRESS)
+			addresses.addChild('address', attrs = {'type': 'ofrom',
+				'jid': forward_from})
+
+		# XEP-0203
+		if delayed:
+			our_jid = gajim.get_jid_from_account(self.name) + '/' + \
+				self.server_resource
+			timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(delayed))
+			msg_iq.addChild('delay', namespace=common.xmpp.NS_DELAY2,
+				attrs={'from': our_jid, 'stamp': timestamp})
+
+		# XEP-0184
+		if msgtxt and gajim.config.get_per('accounts', self.name,
+		'request_receipt') and contact and contact.supports(
+		common.xmpp.NS_RECEIPTS):
+			msg_iq.setTag('request', namespace=common.xmpp.NS_RECEIPTS)
+
+		if session:
+			# XEP-0201
+			session.last_send = time.time()
+			msg_iq.setThread(session.thread_id)
+
+			# XEP-0200
+			if session.enable_encryption:
+				msg_iq = session.encrypt_stanza(msg_iq)
+
+		if callback:
+			callback(jid, msg, keyID, forward_from, session, original_message,
+				subject, type_, msg_iq)
+
+	def log_message(self, jid, msg, forward_from, session, original_message,
+	subject, type_):
+		if not forward_from and session and session.is_loggable():
+			ji = gajim.get_jid_without_resource(jid)
+			if gajim.config.should_log(self.name, ji):
+				log_msg = msg
+				if original_message is not None:
+					log_msg = original_message
+				if subject:
+					log_msg = _('Subject: %(subject)s\n%(message)s') % \
+					{'subject': subject, 'message': log_msg}
+				if log_msg:
+					if type_ == 'chat':
+						kind = 'chat_msg_sent'
+					else:
+						kind = 'single_msg_sent'
+					try:
+						gajim.logger.write(kind, jid, log_msg)
+					except exceptions.PysqliteOperationalError, e:
+						self.dispatch('ERROR', (_('Disk Write Error'), str(e)))
+					except exceptions.DatabaseMalformed:
+						pritext = _('Database Error')
+						sectext = _('The database file (%s) cannot be read. Try to '
+							'repair it (see http://trac.gajim.org/wiki/DatabaseBackup)'
+							' or remove it (all history will be lost).') % \
+							common.logger.LOG_DB_PATH
+
+	def ack_subscribed(self, jid):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def ack_unsubscribed(self, jid):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def request_subscription(self, jid, msg='', name='', groups=[],
+	auto_auth=False):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def send_authorization(self, jid):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def refuse_authorization(self, jid):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def unsubscribe(self, jid, remove_auth = True):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def unsubscribe_agent(self, agent):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def update_contact(self, jid, name, groups):
+		if self.connection:
+			self.connection.getRoster().setItem(jid=jid, name=name, groups=groups)
+
+	def update_contacts(self, contacts):
+		'''update multiple roster items'''
+		if self.connection:
+			self.connection.getRoster().setItemMulti(contacts)
+
+	def new_account(self, name, config, sync=False):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def _on_new_account(self, con=None, con_type=None):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def account_changed(self, new_name):
+		self.name = new_name
+
+	def request_last_status_time(self, jid, resource):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def request_os_info(self, jid, resource):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def get_settings(self):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def get_bookmarks(self):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def store_bookmarks(self):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def get_metacontacts(self):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def send_agent_status(self, agent, ptype):
+		'''To be implemented by derivated classes'''
+		raise NotImplementedError
+
+	def gpg_passphrase(self, passphrase):
+		if self.gpg:
+			use_gpg_agent = gajim.config.get('use_gpg_agent')
+			if use_gpg_agent:
+				self.gpg.passphrase = None
+			else:
+				self.gpg.passphrase = passphrase
+
+	def ask_gpg_keys(self):
+		if self.gpg:
+			keys = self.gpg.get_keys()
+			return keys
+		return None
+
+	def ask_gpg_secrete_keys(self):
+		if self.gpg:
+			keys = self.gpg.get_secret_keys()
+			return keys
+		return None
+
+	def load_roster_from_db(self):
+		# Do nothing by default
+		return
+
+	def _event_dispatcher(self, realm, event, data):
+		if realm == '':
+			if event == common.xmpp.transports_nb.DATA_RECEIVED:
+				self.dispatch('STANZA_ARRIVED', unicode(data, errors='ignore'))
+			elif event == common.xmpp.transports_nb.DATA_SENT:
+				self.dispatch('STANZA_SENT', unicode(data))
+
+	def change_status(self, show, msg, auto=False):
+		if not show in ['offline', 'online', 'chat', 'away', 'xa', 'dnd']:
+			return -1
+		if not msg:
+			msg = ''
+		sign_msg = False
+		if not auto and not show == 'offline':
+			sign_msg = True
+		if show != 'invisible':
+			# We save it only when privacy list is accepted
+			self.status = msg
+		if show != 'offline' and self.connected < 1:
+			# set old_show to requested 'show' in case we need to
+			# recconect before we auth to server
+			self.old_show = show
+			self.on_purpose = False
+			self.server_resource = self._compute_resource()
+			if gajim.HAVE_GPG:
+				self.USE_GPG = True
+				self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
+			self.connect_and_init(show, msg, sign_msg)
+
+		elif show == 'offline':
+			if self.connection:
+				p = common.xmpp.Presence(typ = 'unavailable')
+				p = self.add_sha(p, False)
+				if msg:
+					p.setStatus(msg)
+
+				self.connection.RegisterDisconnectHandler(self._on_disconnected)
+				self.connection.send(p, now=True)
+				self.connection.start_disconnect()
+			else:
+				self._on_disconnected()
+
+		elif show != 'offline' and self.connected > 0:
+			# dont'try to connect, when we are in state 'connecting'
+			if self.connected == 1:
+				return
+			if show == 'invisible':
+				self._change_to_invisible(msg)
+				return
+			was_invisible = self.connected == gajim.SHOW_LIST.index('invisible')
+			self.connected = gajim.SHOW_LIST.index(show)
+			if was_invisible:
+				self._change_from_invisible()
+			self._update_status(show, msg)
+
+class Connection(CommonConnection, ConnectionHandlers):
 	'''Connection class'''
 	def __init__(self, name):
+		CommonConnection.__init__(self, name)
 		ConnectionHandlers.__init__(self)
-		self.name = name
-		# self.connected:
-		# 0=>offline,
-		# 1=>connection in progress,
-		# 2=>authorised
-		self.connected = 0
-		self.connection = None # xmpppy ClientCommon instance
 		# this property is used to prevent double connections
 		self.last_connection = None # last ClientCommon instance
 		# If we succeed to connect, remember it so next time we try (after a
@@ -117,85 +591,52 @@ class Connection(ConnectionHandlers):
 		self.lang = None
 		if locale.getdefaultlocale()[0]:
 			self.lang = locale.getdefaultlocale()[0].split('_')[0]
-		self.is_zeroconf = False
-		self.gpg = None
-		self.USE_GPG = False
-		if gajim.HAVE_GPG:
-			self.USE_GPG = True
-			self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
-		self.status = ''
-		self.priority = gajim.get_priority(name, 'offline')
-		self.old_show = ''
 		# increase/decrease default timeout for server responses
 		self.try_connecting_for_foo_secs = 45
 		# holds the actual hostname to which we are connected
 		self.connected_hostname = None
-		self.time_to_reconnect = None
 		self.last_time_to_reconnect = None
 		self.new_account_info = None
 		self.new_account_form = None
-		self.bookmarks = []
 		self.annotations = {}
-		self.on_purpose = False
 		self.last_io = gajim.idlequeue.current_time()
 		self.last_sent = []
 		self.last_history_time = {}
 		self.password = passwords.get_password(name)
-		self.server_resource = gajim.config.get_per('accounts', name, 'resource')
-		# All valid resource substitution strings should be added to this hash.
-		if self.server_resource:
-			self.server_resource = Template(self.server_resource).safe_substitute({
-				'hostname': socket.gethostname()
-			})
-		if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
-			self.keepalives = gajim.config.get_per('accounts', self.name,
-				'keep_alive_every_foo_secs')
-		else:
-			self.keepalives = 0
-		if gajim.config.get_per('accounts', self.name, 'ping_alives_enabled'):
-			self.pingalives = gajim.config.get_per('accounts', self.name,
-				'ping_alive_every_foo_secs')
-		else:
-			self.pingalives = 0
-		self.privacy_rules_supported = False
+
 		# Used to ask privacy only once at connection
-		self.privacy_rules_requested = False
-		self.blocked_list = []
-		self.blocked_contacts = []
-		self.blocked_groups = []
-		self.blocked_all = False
 		self.music_track_info = 0
 		self.pubsub_supported = False
 		self.pubsub_publish_options_supported = False
-		self.pep_supported = False
-		self.pep = {}
-		# Do we continue connection when we get roster (send presence,get vcard..)
-		self.continue_connect_info = None
 		# Do we auto accept insecure connection
 		self.connection_auto_accepted = False
-		# To know the groupchat jid associated with a sranza ID. Useful to
-		# request vcard or os info... to a real JID but act as if it comes from
-		# the fake jid
-		self.groupchat_jids = {} # {ID : groupchat_jid}
 		self.pasword_callback = None
 
 		self.on_connect_success = None
 		self.on_connect_failure = None
 		self.retrycount = 0
 		self.jids_for_auto_auth = [] # list of jid to auto-authorize
-		self.muc_jid = {} # jid of muc server for each transport type
 		self.available_transports = {} # list of available transports on this
 		# server {'icq': ['icq.server.com', 'icq2.server.com'], }
-		self.vcard_supported = False
 		self.private_storage_supported = True
 		self.streamError = ''
 		self.secret_hmac = str(random.random())[2:]
 	# END __init__
 
-	def dispatch(self, event, data):
-		'''always passes account name as first param'''
-		gajim.interface.dispatch(event, self.name, data)
+	def get_config_values_or_default():
+		if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
+			self.keepalives = gajim.config.get_per('accounts', self.name,
+				'keep_alive_every_foo_secs')
+		else:
+			self.keepalives = 0
+		if gajim.config.get_per('accounts', self.name, 'ping_alives_enabled'):
+			self.pingalives = gajim.config.get_per('accounts', self.name,
+				'ping_alive_every_foo_secs')
+		else:
+			self.pingalives = 0
 
+	def check_jid(self, jid):
+		return helpers.parse_jid(jid)
 
 	def _reconnect(self):
 		# Do not try to reco while we are already trying
@@ -222,6 +663,8 @@ class Connection(ConnectionHandlers):
 		if self.connection:
 			# make sure previous connection is completely closed
 			gajim.proxy65_manager.disconnect(self.connection)
+			self.terminate_sessions()
+			self.remove_all_transfers()
 			self.connection.disconnect()
 			self.last_connection = None
 			self.connection = None
@@ -277,6 +720,7 @@ class Connection(ConnectionHandlers):
 			_('Reconnect manually.')))
 
 	def _event_dispatcher(self, realm, event, data):
+		CommonConnection._event_dispatcher(self, realm, event, data)
 		if realm == common.xmpp.NS_REGISTER:
 			if event == common.xmpp.features_nb.REGISTER_DATA_RECEIVED:
 				# data is (agent, DataFrom, is_form, error_msg)
@@ -382,11 +826,6 @@ class Connection(ConnectionHandlers):
 			elif event == common.xmpp.features_nb.PRIVACY_LISTS_ACTIVE_DEFAULT:
 				# data is (dict)
 				self.dispatch('PRIVACY_LISTS_ACTIVE_DEFAULT', (data))
-		elif realm == '':
-			if event == common.xmpp.transports_nb.DATA_RECEIVED:
-				self.dispatch('STANZA_ARRIVED', unicode(data, errors = 'ignore'))
-			elif event == common.xmpp.transports_nb.DATA_SENT:
-				self.dispatch('STANZA_SENT', unicode(data))
 
 	def _select_next_host(self, hosts):
 		'''Selects the next host according to RFC2782 p.3 based on it's
@@ -800,10 +1239,6 @@ class Connection(ConnectionHandlers):
 				self.on_connect_auth = None
 	# END connect
 
-	def quit(self, kill_core):
-		if kill_core and gajim.account_is_connected(self.name):
-			self.disconnect(on_purpose=True)
-
 	def add_lang(self, stanza):
 		if self.lang:
 			stanza.setAttr('xml:lang', self.lang)
@@ -983,45 +1418,11 @@ class Connection(ConnectionHandlers):
 			#Inform GUI we just signed in
 			self.dispatch('SIGNED_IN', ())
 
-	def test_gpg_passphrase(self, password):
-		'''Returns 'ok', 'bad_pass' or 'expired' '''
-		if not self.gpg:
-			return False
-		self.gpg.passphrase = password
-		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
-		signed = self.gpg.sign('test', keyID)
-		self.gpg.password = None
-		if signed == 'KEYEXPIRED':
-			return 'expired'
-		elif signed == 'BAD_PASSPHRASE':
-			return 'bad_pass'
-		return 'ok'
-
 	def get_signed_presence(self, msg, callback = None):
 		if gajim.config.get_per('accounts', self.name, 'gpg_sign_presence'):
 			return self.get_signed_msg(msg, callback)
 		return ''
 
-	def get_signed_msg(self, msg, callback = None):
-		'''returns the signed message if possible
-		or an empty string if gpg is not used
-		or None if waiting for passphrase.
-		callback is the function to call when user give the passphrase'''
-		signed = ''
-		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
-		if keyID and self.USE_GPG:
-			use_gpg_agent = gajim.config.get('use_gpg_agent')
-			if self.gpg.passphrase is None and not use_gpg_agent:
-				# We didn't set a passphrase
-				return None
-			if self.gpg.passphrase is not None or use_gpg_agent:
-				signed = self.gpg.sign(msg, keyID)
-				if signed == 'BAD_PASSPHRASE':
-					self.USE_GPG = False
-					signed = ''
-					self.dispatch('BAD_PASSPHRASE', ())
-		return signed
-
 	def connect_and_auth(self):
 		self.on_connect_success = self._connect_success
 		self.on_connect_failure = self._connect_failure
@@ -1041,126 +1442,64 @@ class Connection(ConnectionHandlers):
 		self.connection.onreceive(None)
 		self.discoverInfo(gajim.config.get_per('accounts', self.name, 'hostname'),
 			id_prefix='Gajim_')
-		self.privacy_rules_requested = False
-
-	def _request_privacy(self):
-		iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
-		id_ = self.connection.getAnID()
-		iq.setID(id_)
-		self.awaiting_answers[id_] = (PRIVACY_ARRIVED, )
-		self.connection.send(iq)
-
-	def send_custom_status(self, show, msg, jid):
-		if not show in gajim.SHOW_LIST:
-			return -1
-		if not self.connection:
-			return
-		sshow = helpers.get_xmpp_show(show)
-		if not msg:
-			msg = ''
-		if show == 'offline':
-			p = common.xmpp.Presence(typ = 'unavailable', to = jid)
-			p = self.add_sha(p, False)
-			if msg:
-				p.setStatus(msg)
-		else:
-			signed = self.get_signed_presence(msg)
-			priority = unicode(gajim.get_priority(self.name, sshow))
-			p = common.xmpp.Presence(typ = None, priority = priority, show = sshow,
-				to = jid)
-			p = self.add_sha(p)
-			if msg:
-				p.setStatus(msg)
-			if signed:
-				p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
-		self.connection.send(p)
-
-	def change_status(self, show, msg, auto = False):
-		if not show in gajim.SHOW_LIST:
-			return -1
-		sshow = helpers.get_xmpp_show(show)
-		if not msg:
-			msg = ''
-		sign_msg = False
-		if not auto and not show == 'offline':
-			sign_msg = True
-		if show != 'invisible':
-			# We save it only when privacy list is accepted
-			self.status = msg
-		if show != 'offline' and self.connected < 1:
-			# set old_show to requested 'show' in case we need to
-			# recconect before we auth to server
-			self.old_show = show
-			self.on_purpose = False
-			self.server_resource = gajim.config.get_per('accounts', self.name,
-				'resource')
-			# All valid resource substitution strings should be added to this hash.
-			if self.server_resource:
-				self.server_resource = Template(self.server_resource).\
-					safe_substitute({
-						'hostname': socket.gethostname()
-					})
-			if gajim.HAVE_GPG:
-				self.USE_GPG = True
-				self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
-			self.connect_and_init(show, msg, sign_msg)
-
-		elif show == 'offline':
-			self.connected = 0
-			if self.connection:
-				self.terminate_sessions()
-
-				self.on_purpose = True
-				p = common.xmpp.Presence(typ = 'unavailable')
-				p = self.add_sha(p, False)
-				if msg:
-					p.setStatus(msg)
-				self.remove_all_transfers()
-				self.time_to_reconnect = None
-
-				self.connection.RegisterDisconnectHandler(self._on_disconnected)
-				self.connection.send(p, now=True)
-				self.connection.start_disconnect()
-				#self.connection.start_disconnect(p, self._on_disconnected)
-			else:
-				self.time_to_reconnect = None
-				self._on_disconnected()
+		self.privacy_rules_requested = False
 
-		elif show != 'offline' and self.connected > 0:
-			# dont'try to connect, when we are in state 'connecting'
-			if self.connected == 1:
-				return
-			if show == 'invisible':
-				signed = self.get_signed_presence(msg)
-				self.send_invisible_presence(msg, signed)
-				return
-			was_invisible = self.connected == gajim.SHOW_LIST.index('invisible')
-			self.connected = gajim.SHOW_LIST.index(show)
-			if was_invisible and self.privacy_rules_supported:
-				iq = self.build_privacy_rule('visible', 'allow')
-				self.connection.send(iq)
-				self.activate_privacy_rule('visible')
+	def _request_privacy(self):
+		iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
+		id_ = self.connection.getAnID()
+		iq.setID(id_)
+		self.awaiting_answers[id_] = (PRIVACY_ARRIVED, )
+		self.connection.send(iq)
+
+	def send_custom_status(self, show, msg, jid):
+		if not show in gajim.SHOW_LIST:
+			return -1
+		if not self.connection:
+			return
+		sshow = helpers.get_xmpp_show(show)
+		if not msg:
+			msg = ''
+		if show == 'offline':
+			p = common.xmpp.Presence(typ = 'unavailable', to = jid)
+			p = self.add_sha(p, False)
+			if msg:
+				p.setStatus(msg)
+		else:
+			signed = self.get_signed_presence(msg)
 			priority = unicode(gajim.get_priority(self.name, sshow))
-			p = common.xmpp.Presence(typ = None, priority = priority, show = sshow)
+			p = common.xmpp.Presence(typ = None, priority = priority, show = sshow,
+				to = jid)
 			p = self.add_sha(p)
 			if msg:
 				p.setStatus(msg)
-			signed = self.get_signed_presence(msg)
 			if signed:
 				p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
-			if self.connection:
-				self.connection.send(p)
-				self.priority = priority
-			self.dispatch('STATUS', show)
+		self.connection.send(p)
 
-	def _on_disconnected(self):
-		''' called when a disconnect request has completed successfully'''
-		self.disconnect(on_purpose=True)
-		self.dispatch('STATUS', 'offline')
+	def _change_to_invisible(self, msg):
+		signed = self.get_signed_presence(msg)
+		self.send_invisible_presence(msg, signed)
 
-	def get_status(self):
-		return gajim.SHOW_LIST[self.connected]
+	def _change_from_invisible(self):
+		if self.privacy_rules_supported:
+			iq = self.build_privacy_rule('visible', 'allow')
+			self.connection.send(iq)
+			self.activate_privacy_rule('visible')
 
+	def _update_status(self, show, msg):
+		xmpp_show = helpers.get_xmpp_show(show)
+		priority = unicode(gajim.get_priority(self.name, xmpp_show))
+		p = common.xmpp.Presence(typ=None, priority=priority, show=xmpp_show)
+		p = self.add_sha(p)
+		if msg:
+			p.setStatus(msg)
+		signed = self.get_signed_presence(msg)
+		if signed:
+			p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
+		if self.connection:
+			self.connection.send(p)
+			self.priority = priority
+		self.dispatch('STATUS', show)
 
 	def send_motd(self, jid, subject = '', msg = '', xhtml = None):
 		if not self.connection:
@@ -1174,202 +1513,23 @@ class Connection(ConnectionHandlers):
 	chatstate=None, msg_id=None, composing_xep=None, resource=None,
 	user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
 	original_message=None, delayed=None, callback=None, callback_args=[]):
-		if not self.connection or self.connected < 2:
-			return 1
-		try:
-			jid = helpers.parse_jid(jid)
-		except helpers.InvalidFormat:
-			self.dispatch('ERROR', (_('Invalid Jabber ID'),
-				_('It is not possible to send a message to %s, this JID is not '
-				'valid.') % jid))
-			return
-
-		if msg and not xhtml and gajim.config.get(
-		'rst_formatting_outgoing_messages'):
-			from common.rst_xhtml_generator import create_xhtml
-			xhtml = create_xhtml(msg)
-		if not msg and chatstate is None and form_node is None:
-			return
-		fjid = jid
-		if resource:
-			fjid += '/' + resource
-		msgtxt = msg
-		msgenc = ''
-
-		if session:
-			fjid = session.get_to()
-
-		if keyID and self.USE_GPG:
-			xhtml = None
-			if keyID ==  'UNKNOWN':
-				error = _('Neither the remote presence is signed, nor a key was assigned.')
-			elif keyID.endswith('MISMATCH'):
-				error = _('The contact\'s key (%s) does not match the key assigned in Gajim.' % keyID[:8])
-			else:
-				def encrypt_thread(msg, keyID, always_trust=False):
-					# encrypt message. This function returns (msgenc, error)
-					return self.gpg.encrypt(msg, [keyID], always_trust)
-				def _on_encrypted(output):
-					msgenc, error = output
-					if error == 'NOT_TRUSTED':
-						def _on_always_trust(answer):
-							if answer:
-								gajim.thread_interface(encrypt_thread, [msg, keyID,
-									True], _on_encrypted, [])
-							else:
-								self._on_message_encrypted(output, type_, msg, msgtxt,
-									original_message, fjid, resource, jid, xhtml,
-									subject, chatstate, composing_xep, forward_from,
-									delayed, session, form_node, user_nick, keyID,
-									callback, callback_args)
-						self.dispatch('GPG_ALWAYS_TRUST', _on_always_trust)
-					else:
-						self._on_message_encrypted(output, type_, msg, msgtxt,
-							original_message, fjid, resource, jid, xhtml, subject,
-							chatstate, composing_xep, forward_from, delayed, session,
-							form_node, user_nick, keyID, callback, callback_args)
-				gajim.thread_interface(encrypt_thread, [msg, keyID, False],
-					_on_encrypted, [])
-				return
-
-			self._on_message_encrypted(('', error), type_, msg, msgtxt,
-				original_message, fjid, resource, jid, xhtml, subject, chatstate,
-				composing_xep, forward_from, delayed, session, form_node, user_nick,
-				keyID, callback, callback_args)
-
-		self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
-			resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
-			forward_from, delayed, session, form_node, user_nick, callback,
-			callback_args)
-
-	def _on_message_encrypted(self, output, type_, msg, msgtxt, original_message,
-	fjid, resource, jid, xhtml, subject, chatstate, composing_xep, forward_from,
-	delayed, session, form_node, user_nick, keyID, callback, callback_args):
-		msgenc, error = output
-
-		if msgenc and not error:
-			msgtxt = '[This message is *encrypted* (See :XEP:`27`]'
-			lang = os.getenv('LANG')
-			if lang is not None and lang != 'en': # we're not english
-				# one in locale and one en
-				msgtxt = _('[This message is *encrypted* (See :XEP:`27`]') + \
-					' (' + msgtxt + ')'
-			self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
-				resource, jid, xhtml, subject, msgenc, keyID, chatstate,
-				composing_xep, forward_from, delayed, session, form_node, user_nick,
-				callback, callback_args)
-			return
-		# Encryption failed, do not send message
-		tim = localtime()
-		self.dispatch('MSGNOTSENT', (jid, error, msgtxt, tim, session))
-
-	def _on_continue_message(self, type_, msg, msgtxt, original_message, fjid,
-	resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
-	forward_from, delayed, session, form_node, user_nick, callback,
-	callback_args):
-		if type_ == 'chat':
-			msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
-				xhtml=xhtml)
-		else:
-			if subject:
-				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
-					subject=subject, xhtml=xhtml)
-			else:
-				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
-					xhtml=xhtml)
-		if msgenc:
-			msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
-
-		if form_node:
-			msg_iq.addChild(node=form_node)
-
-		# XEP-0172: user_nickname
-		if user_nick:
-			msg_iq.setTag('nick', namespace = common.xmpp.NS_NICK).setData(
-				user_nick)
-
-		# TODO: We might want to write a function so we don't need to
-		#	reproduce that ugly if somewhere else.
-		if resource:
-			contact = gajim.contacts.get_contact(self.name, jid, resource)
-		else:
-			contact = gajim.contacts.get_contact_with_highest_priority(self.name,
-				jid)
-
-		# chatstates - if peer supports xep85 or xep22, send chatstates
-		# please note that the only valid tag inside a message containing a <body>
-		# tag is the active event
-		if chatstate is not None and contact:
-			if ((composing_xep == 'XEP-0085' or not composing_xep) \
-			and composing_xep != 'asked_once') or \
-			contact.supports(common.xmpp.NS_CHATSTATES):
-				# XEP-0085
-				msg_iq.setTag(chatstate, namespace=common.xmpp.NS_CHATSTATES)
-			if composing_xep in ('XEP-0022', 'asked_once') or \
-			not composing_xep:
-				# XEP-0022
-				chatstate_node = msg_iq.setTag('x', namespace=common.xmpp.NS_EVENT)
-				if chatstate is 'composing' or msgtxt:
-					chatstate_node.addChild(name='composing')
-
-		if forward_from:
-			addresses = msg_iq.addChild('addresses',
-				namespace=common.xmpp.NS_ADDRESS)
-			addresses.addChild('address', attrs = {'type': 'ofrom',
-				'jid': forward_from})
-
-		# XEP-0203
-		if delayed:
-			our_jid = gajim.get_jid_from_account(self.name) + '/' + \
-				self.server_resource
-			timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(delayed))
-			msg_iq.addChild('delay', namespace=common.xmpp.NS_DELAY2,
-				attrs={'from': our_jid, 'stamp': timestamp})
-
-		# XEP-0184
-		if msgtxt and gajim.config.get_per('accounts', self.name,
-		'request_receipt') and contact and contact.supports(
-		common.xmpp.NS_RECEIPTS):
-			msg_iq.setTag('request', namespace=common.xmpp.NS_RECEIPTS)
-
-		if session:
-			# XEP-0201
-			session.last_send = time.time()
-			msg_iq.setThread(session.thread_id)
 
-			# XEP-0200
-			if session.enable_encryption:
-				msg_iq = session.encrypt_stanza(msg_iq)
+		def cb(jid, msg, keyID, forward_from, session, original_message, subject,
+		type_, msg_iq):
+			msg_id = self.connection.send(msg_iq)
+			jid = helpers.parse_jid(jid)
+			self.dispatch('MSGSENT', (jid, msg, keyID))
+			if callback:
+				callback(msg_id, *callback_args)
 
-		msg_id = self.connection.send(msg_iq)
-		if not forward_from and session and session.is_loggable():
-			ji = gajim.get_jid_without_resource(jid)
-			if gajim.config.should_log(self.name, ji):
-				log_msg = msg
-				if original_message is not None:
-					log_msg = original_message
-				if subject:
-					log_msg = _('Subject: %(subject)s\n%(message)s') % \
-					{'subject': subject, 'message': msg}
-				if log_msg:
-					if type_ == 'chat':
-						kind = 'chat_msg_sent'
-					else:
-						kind = 'single_msg_sent'
-					try:
-						gajim.logger.write(kind, jid, log_msg)
-					except exceptions.PysqliteOperationalError, e:
-						self.dispatch('ERROR', (_('Disk Write Error'), str(e)))
-					except exceptions.DatabaseMalformed:
-						pritext = _('Database Error')
-						sectext = _('The database file (%s) cannot be read. Try to '
-							'repair it (see http://trac.gajim.org/wiki/DatabaseBackup)'
-							' or remove it (all history will be lost).') % \
-							common.logger.LOG_DB_PATH
-		self.dispatch('MSGSENT', (jid, msg, keyID))
+			self.log_message(jid, msg, forward_from, session, original_message,
+				subject, type_)
 
-		if callback:
-			callback(msg_id, *callback_args)
+		self._prepare_message(jid, msg, keyID, type_=type_, subject=subject,
+			chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
+			resource=resource, user_nick=user_nick, xhtml=xhtml, session=session,
+			forward_from=forward_from, form_node=form_node,
+			original_message=original_message, delayed=delayed, callback=cb)
 
 	def send_contacts(self, contacts, jid):
 		'''Send contacts with RosterX (Xep-0144)'''
@@ -1474,17 +1634,6 @@ class Connection(ConnectionHandlers):
 		self.connection.send(iq)
 		self.connection.getRoster().delItem(agent)
 
-	def update_contact(self, jid, name, groups):
-		'''update roster item on jabber server'''
-		if self.connection:
-			self.connection.getRoster().setItem(jid = jid, name = name,
-				groups = groups)
-
-	def update_contacts(self, contacts):
-		'''update multiple roster items on jabber server'''
-		if self.connection:
-			self.connection.getRoster().setItemMulti(contacts)
-
 	def send_new_account_infos(self, form, is_form):
 		if is_form:
 			# Get username and password and put them in new_account_info
@@ -1502,7 +1651,7 @@ class Connection(ConnectionHandlers):
 		self.new_account_form = form
 		self.new_account(self.name, self.new_account_info)
 
-	def new_account(self, name, config, sync = False):
+	def new_account(self, name, config, sync=False):
 		# If a connection already exist we cannot create a new account
 		if self.connection:
 			return
@@ -1513,7 +1662,7 @@ class Connection(ConnectionHandlers):
 		self.on_connect_failure = self._on_new_account
 		self.connect(config)
 
-	def _on_new_account(self, con = None, con_type = None):
+	def _on_new_account(self, con=None, con_type=None):
 		if not con_type:
 			if len(self._connection_types) or len(self._hosts):
 				# There are still other way to try to connect
@@ -1525,9 +1674,6 @@ class Connection(ConnectionHandlers):
 		self.connection = con
 		common.xmpp.features_nb.getRegInfo(con, self._hostname)
 
-	def account_changed(self, new_name):
-		self.name = new_name
-
 	def request_last_status_time(self, jid, resource, groupchat_jid=None):
 		'''groupchat_jid is used when we want to send a request to a real jid
 		and act as if the answer comes from the groupchat_jid'''
@@ -1918,26 +2064,6 @@ class Connection(ConnectionHandlers):
 		query.addChild(node = form)
 		self.connection.send(iq)
 
-	def gpg_passphrase(self, passphrase):
-		if self.gpg:
-			use_gpg_agent = gajim.config.get('use_gpg_agent')
-			if use_gpg_agent:
-				self.gpg.passphrase = None
-			else:
-				self.gpg.passphrase = passphrase
-
-	def ask_gpg_keys(self):
-		if self.gpg:
-			keys = self.gpg.get_keys()
-			return keys
-		return None
-
-	def ask_gpg_secrete_keys(self):
-		if self.gpg:
-			keys = self.gpg.get_secret_keys()
-			return keys
-		return None
-
 	def change_password(self, password):
 		if not self.connection:
 			return
diff --git a/src/common/xmpp/transports_nb.py b/src/common/xmpp/transports_nb.py
index 704cad170121bcbb641c8fb4c654bfb78daed9c3..dd60269bff7b47ff5bf1fbb525d8bfbdc52b1a5f 100644
--- a/src/common/xmpp/transports_nb.py
+++ b/src/common/xmpp/transports_nb.py
@@ -92,6 +92,7 @@ RECV_BUFSIZE = 32768 # 2x maximum size of ssl packet, should be plenty
 
 DATA_RECEIVED = 'DATA RECEIVED'
 DATA_SENT = 'DATA SENT'
+DATA_ERROR = 'DATA ERROR'
 
 DISCONNECTED = 'DISCONNECTED'
 DISCONNECTING = 'DISCONNECTING'
diff --git a/src/common/zeroconf/client_zeroconf.py b/src/common/zeroconf/client_zeroconf.py
index 730eb3ec34f0841d6a6a8c17c478f009b264f312..6b50a9feae63ff833dfbb23f8546ce5d382337a0 100644
--- a/src/common/zeroconf/client_zeroconf.py
+++ b/src/common/zeroconf/client_zeroconf.py
@@ -23,7 +23,7 @@ from common.xmpp.idlequeue import IdleObject
 from common.xmpp import dispatcher_nb, simplexml
 from common.xmpp.plugin import *
 from common.xmpp.simplexml import ustr
-from common.xmpp.transports_nb import DATA_RECEIVED, DATA_SENT
+from common.xmpp.transports_nb import DATA_RECEIVED, DATA_SENT, DATA_ERROR
 from common.zeroconf import zeroconf
 
 from common.xmpp.protocol import *
@@ -395,6 +395,7 @@ class P2PConnection(IdleObject, PlugIn):
 		False, else send it instantly.
 		If supplied data is unicode string, encode it to utf-8.
 		'''
+		print 'ici'
 		if self.state <= 0:
 			return
 
@@ -416,8 +417,11 @@ class P2PConnection(IdleObject, PlugIn):
 		ids = self.client.conn_holder.ids_of_awaiting_messages
 		if self.fd in ids and len(ids[self.fd]) > 0:
 			for (id_, thread_id) in ids[self.fd]:
-				self._owner.Dispatcher.Event('', DATA_ERROR, (self.client.to,
-					thread_id))
+				if hasattr(self._owner, 'Dispatcher'):
+					self._owner.Dispatcher.Event('', DATA_ERROR, (self.client.to,
+						thread_id))
+				else:
+					self._owner.on_not_ok('conenction timeout')
 			ids[self.fd] = []
 		self.pollend()
 
@@ -578,6 +582,8 @@ class ClientZeroconf:
 		self.hash_to_port = {}
 		self.listener = None
 		self.ids_of_awaiting_messages = {}
+		self.disconnect_handlers = []
+		self.disconnecting = False
 
 	def connect(self, show, msg):
 		self.port = self.start_listener(self.caller.port)
@@ -632,6 +638,9 @@ class ClientZeroconf:
 		self.last_msg = msg
 
 	def disconnect(self):
+		# to avoid recursive calls
+		if self.disconnecting:
+			return
 		if self.listener:
 			self.listener.disconnect()
 			self.listener = None
@@ -642,6 +651,14 @@ class ClientZeroconf:
 			self.roster.zeroconf = None
 			self.roster._data = None
 			self.roster = None
+		self.disconnecting = True
+		for i in reversed(self.disconnect_handlers):
+			log.debug('Calling disconnect handler %s' % i)
+			i()
+		self.disconnecting = False
+
+	def start_disconnect(self):
+		self.disconnect()
 
 	def kill_all_connections(self):
 		for connection in self.connections.values():
@@ -720,6 +737,14 @@ class ClientZeroconf:
 		P2PClient(None, item['address'], item['port'], self,
 			[(stanza, is_message)], to, on_ok=on_ok, on_not_ok=on_not_ok)
 
+	def RegisterDisconnectHandler(self, handler):
+		''' Register handler that will be called on disconnect.'''
+		self.disconnect_handlers.append(handler)
+
+	def UnregisterDisconnectHandler(self, handler):
+		''' Unregister handler that is called on disconnect.'''
+		self.disconnect_handlers.remove(handler)
+
 	def SendAndWaitForResponse(self, stanza, timeout=None, func=None, args=None):
 		'''
 		Send stanza and wait for recipient's response to it. Will call transports
diff --git a/src/common/zeroconf/connection_handlers_zeroconf.py b/src/common/zeroconf/connection_handlers_zeroconf.py
index 09818be47dc766cbe4c13fa12bcccb353800e57d..b08fba1ced51337e319ab8331e9d02db59b7d006 100644
--- a/src/common/zeroconf/connection_handlers_zeroconf.py
+++ b/src/common/zeroconf/connection_handlers_zeroconf.py
@@ -57,10 +57,10 @@ from session import ChatControlSession
 
 class ConnectionVcard(connection_handlers.ConnectionVcard):
 	def add_sha(self, p, send_caps = True):
-		pass
+		return p
 
 	def add_caps(self, p):
-		pass
+		return p
 
 	def request_vcard(self, jid = None, is_fake_jid = False):
 		pass
diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py
index 26725f5f00208f0b2b062d7b1eb51778ec512315..52876c8d6f0581fae9715f3a86e1db2fc08f13d9 100644
--- a/src/common/zeroconf/connection_zeroconf.py
+++ b/src/common/zeroconf/connection_zeroconf.py
@@ -5,7 +5,7 @@
 ##	- Nikos Kouremenos <nkour@jabber.org>
 ##	- Dimitur Kirov <dkirov@gmail.com>
 ##	- Travis Shirk <travis@pobox.com>
-##  - Stefan Bethge <stefan@lanpartei.de>
+## - Stefan Bethge <stefan@lanpartei.de>
 ##
 ## Copyright (C) 2003-2004 Yann Leboulanger <asterix@lagaule.org>
 ##                         Vincent Hanquez <tab@snarc.org>
@@ -43,64 +43,29 @@ if os.name != 'nt':
 import getpass
 import gobject
 
+from common.connection import CommonConnection
 from common import gajim
 from common import GnuPG
 from common.zeroconf import client_zeroconf
 from common.zeroconf import zeroconf
 from connection_handlers_zeroconf import *
 
-class ConnectionZeroconf(ConnectionHandlersZeroconf):
+class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
 	'''Connection class'''
 	def __init__(self, name):
+		CommonConnection.__init__(self, name)
 		ConnectionHandlersZeroconf.__init__(self)
 		# system username
 		self.username = None
-		self.name = name
 		self.server_resource = '' # zeroconf has no resource, fake an empty one
-		self.connected = 0 # offline
-		self.connection = None
-		self.gpg = None
-		self.USE_GPG = False
-		if gajim.HAVE_GPG:
-			self.USE_GPG = True
-			self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
 		self.is_zeroconf = True
-		self.privacy_rules_supported = False
-		self.blocked_list = []
-		self.blocked_contacts = []
-		self.blocked_groups = []
-		self.blocked_all = False
-		self.status = ''
-		self.old_show = ''
-		self.priority = 0
-
 		self.call_resolve_timeout = False
-
-		self.time_to_reconnect = None
-		#self.new_account_info = None
-		self.bookmarks = []
-
-		#we don't need a password, but must be non-empty
+		# we don't need a password, but must be non-empty
 		self.password = 'zeroconf'
-
 		self.autoconnect = False
-		self.sync_with_global_status = True
-		self.no_log_for = False
-
-		self.pep_supported = False
-		self.pep = {}
-		# Do we continue connection when we get roster (send presence,get vcard...)
-		self.continue_connect_info = None
-		if gajim.HAVE_GPG:
-			self.USE_GPG = True
-			self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
 
 		self.get_config_values_or_default()
 
-		self.muc_jid = {} # jid of muc server for each transport type
-		self.vcard_supported = False
-		self.private_storage_supported = False
-
 	def get_config_values_or_default(self):
 		''' get name, host, port from config, or
 		create zeroconf account with default values'''
@@ -108,79 +73,61 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 		if not gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name'):
 			gajim.log.debug('Creating zeroconf account')
 			gajim.config.add_per('accounts', gajim.ZEROCONF_ACC_NAME)
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'autoconnect', True)
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for', '')
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'password', 'zeroconf')
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status', True)
-
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port', 5298)
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'is_zeroconf', True)
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'autoconnect', True)
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for',
+				'')
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'password',
+				'zeroconf')
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'sync_with_global_status', True)
+
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'custom_port', 5298)
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'is_zeroconf', True)
 		#XXX make sure host is US-ASCII
 		self.host = unicode(socket.gethostname())
-		gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'hostname', self.host)
-		self.port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port')
-		self.autoconnect = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'autoconnect')
-		self.sync_with_global_status = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status')
-		self.no_log_for = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for')
-		self.first = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_first_name')
-		self.last = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_last_name')
-		self.jabber_id = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_jabber_id')
-		self.email = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_email')
+		gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'hostname',
+			self.host)
+		self.port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'custom_port')
+		self.autoconnect = gajim.config.get_per('accounts',
+			gajim.ZEROCONF_ACC_NAME, 'autoconnect')
+		self.sync_with_global_status = gajim.config.get_per('accounts',
+			gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status')
+		self.first = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'zeroconf_first_name')
+		self.last = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'zeroconf_last_name')
+		self.jabber_id = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'zeroconf_jabber_id')
+		self.email = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+			'zeroconf_email')
 
 		if not self.username:
 			self.username = unicode(getpass.getuser())
-			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name', self.username)
+			gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name',
+				self.username)
 		else:
-			self.username = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name')
+			self.username = gajim.config.get_per('accounts',
+				gajim.ZEROCONF_ACC_NAME, 'name')
 	# END __init__
 
-	def dispatch(self, event, data):
-		gajim.interface.dispatch(event, self.name, data)
+	def check_jid(self, jid):
+		return jid
 
 	def _reconnect(self):
 		# Do not try to reco while we are already trying
 		self.time_to_reconnect = None
 		gajim.log.debug('reconnect')
 
-#		signed = self.get_signed_msg(self.status)
 		self.disconnect()
 		self.change_status(self.old_show, self.status)
 
-	def quit(self, kill_core):
-		if kill_core and self.connected > 1:
-			self.disconnect()
-
 	def disable_account(self):
 		self.disconnect()
 
-	def test_gpg_passphrase(self, password):
-		self.gpg.passphrase = password
-		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
-		signed = self.gpg.sign('test', keyID)
-		self.gpg.password = None
-		return signed != 'BAD_PASSPHRASE'
-
-	def get_signed_msg(self, msg):
-		signed = ''
-		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
-		if keyID and self.USE_GPG:
-			use_gpg_agent = gajim.config.get('use_gpg_agent')
-			if self.connected < 2 and self.gpg.passphrase is None and \
-			not use_gpg_agent:
-				# We didn't set a passphrase
-				self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
-					#%s is the account name here
-					_('You will be connected to %s without OpenPGP.') % self.name))
-				self.USE_GPG = False
-			elif self.gpg.passphrase is not None or use_gpg_agent:
-				signed = self.gpg.sign(msg, keyID)
-				if signed == 'BAD_PASSPHRASE':
-					self.USE_GPG = False
-					signed = ''
-					if self.connected < 2:
-						self.dispatch('BAD_PASSPHRASE', ())
-		return signed
-
 	def _on_resolve_timeout(self):
 		if self.connected:
 			self.connection.resolve_all()
@@ -197,8 +144,10 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 	# callbacks called from zeroconf
 	def _on_new_service(self, jid):
 		self.roster.setItem(jid)
-		self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no', self.roster.getGroups(jid)))
-		self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), self.roster.getMessage(jid), 'local', 0, None, 0, None))
+		self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no',
+			self.roster.getGroups(jid)))
+		self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid),
+			self.roster.getMessage(jid), 'local', 0, None, 0, None))
 
 	def _on_remove_service(self, jid):
 		self.roster.delItem(jid)
@@ -206,15 +155,6 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 		# keyID, timestamp, contact_nickname))
 		self.dispatch('NOTIFY', (jid, 'offline', '', 'local', 0, None, 0, None))
 
-	def _on_disconnected(self):
-		self.disconnect()
-		self.dispatch('STATUS', 'offline')
-		self.dispatch('CONNECTION_LOST',
-			(_('Connection with account "%s" has been lost') % self.name,
-			_('To continue sending and receiving messages, you will need to reconnect.')))
-		self.status = 'offline'
-		self.disconnect()
-
 	def _disconnectedReconnCB(self):
 		'''Called when we are disconnected. Comes from network manager for example
 		we don't try to reconnect, network manager will tell us when we can'''
@@ -234,9 +174,10 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 		self.dispatch('ZC_NAME_CONFLICT', alt_name)
 
 	def _on_error(self, message):
-		self.dispatch('ERROR', (_('Avahi error'), _("%s\nLink-local messaging might not work properly.") % message))
+		self.dispatch('ERROR', (_('Avahi error'),
+			_('%s\nLink-local messaging might not work properly.') % message))
 
-	def connect(self, show = 'online', msg = ''):
+	def connect(self, show='online', msg=''):
 		self.get_config_values_or_default()
 		if not self.connection:
 			self.connection = client_zeroconf.ClientZeroconf(self)
@@ -267,10 +208,12 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 		self.roster = self.connection.getRoster()
 		self.dispatch('ROSTER', self.roster)
 
-		#display contacts already detected and resolved
+		# display contacts already detected and resolved
 		for jid in self.roster.keys():
-			self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no', self.roster.getGroups(jid)))
-			self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), self.roster.getMessage(jid), 'local', 0, None, 0, None))
+			self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both',
+				'no', self.roster.getGroups(jid)))
+			self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid),
+				self.roster.getMessage(jid), 'local', 0, None, 0, None))
 
 		self.connected = STATUS_LIST.index(show)
 
@@ -279,7 +222,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 		gobject.timeout_add_seconds(5, self._on_resolve_timeout)
 		return True
 
-	def disconnect(self, on_purpose = False):
+	def disconnect(self, on_purpose=False):
 		self.connected = 0
 		self.time_to_reconnect = None
 		if self.connection:
@@ -291,15 +234,20 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 	def reannounce(self):
 		if self.connected:
 			txt = {}
-			txt['1st'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_first_name')
-			txt['last'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_last_name')
-			txt['jid'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_jabber_id')
-			txt['email'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_email')
+			txt['1st'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'zeroconf_first_name')
+			txt['last'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'zeroconf_last_name')
+			txt['jid'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'zeroconf_jabber_id')
+			txt['email'] = gajim.config.get_per('accounts',
+				gajim.ZEROCONF_ACC_NAME, 'zeroconf_email')
 			self.connection.reannounce(txt)
 
 	def update_details(self):
 		if self.connection:
-			port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port')
+			port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
+				'custom_port')
 			if port != self.port:
 				self.port = port
 				last_msg = self.connection.last_msg
@@ -311,41 +259,18 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 			else:
 				self.reannounce()
 
-	def change_status(self, show, msg, sync = False, auto = False):
-		if not show in STATUS_LIST:
-			return -1
-		self.status = show
-
-		check = True		#to check for errors from zeroconf
-		# 'connect'
-		if show != 'offline' and not self.connected:
-			if not self.connect(show, msg):
-				return
-			if show != 'invisible':
-				check = self.connection.announce()
-			else:
-				self.connected = STATUS_LIST.index(show)
-			self.dispatch('SIGNED_IN', ())
-
-		# 'disconnect'
-		elif show == 'offline' and self.connected:
-			self.disconnect()
-			self.time_to_reconnect = None
-
-		# update status
-		elif show != 'offline' and self.connected:
-			was_invisible = self.connected == STATUS_LIST.index('invisible')
+	def connect_and_init(self, show, msg, sign_msg):
+		# to check for errors from zeroconf
+		check = True
+		if not self.connect(show, msg):
+			return
+		if show != 'invisible':
+			check = self.connection.announce()
+		else:
 			self.connected = STATUS_LIST.index(show)
-			if show == 'invisible':
-				check = check and self.connection.remove_announce()
-			elif was_invisible:
-				if not self.connected:
-					check = check and self.connect(show, msg)
-				check = check and self.connection.announce()
-			if self.connection and not show == 'invisible':
-				check = check and self.connection.set_show_msg(show, msg)
-
-		#stay offline when zeroconf does something wrong
+		self.dispatch('SIGNED_IN', ())
+
+		# stay offline when zeroconf does something wrong
 		if check:
 			self.dispatch('STATUS', show)
 		else:
@@ -356,136 +281,63 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 				(_('Could not change status of account "%s"') % self.name,
 				_('Please check if avahi-daemon is running.')))
 
-	def get_status(self):
-		return STATUS_LIST[self.connected]
+	def _change_to_invisible(self, msg):
+		if self.connection.remove_announce():
+			self.dispatch('STATUS', 'invisible')
+		else:
+			# show notification that avahi or system bus is down
+			self.dispatch('STATUS', 'offline')
+			self.status = 'offline'
+			self.dispatch('CONNECTION_LOST',
+				(_('Could not change status of account "%s"') % self.name,
+				_('Please check if avahi-daemon is running.')))
+
+	def _change_from_invisible(self):
+		self.connection.announce()
+
+	def _update_status(self, show, msg):
+		if self.connection.set_show_msg(show, msg):
+			self.dispatch('STATUS', show)
+		else:
+			# show notification that avahi or system bus is down
+			self.dispatch('STATUS', 'offline')
+			self.status = 'offline'
+			self.dispatch('CONNECTION_LOST',
+				(_('Could not change status of account "%s"') % self.name,
+				_('Please check if avahi-daemon is running.')))
 
 	def send_message(self, jid, msg, keyID, type_='chat', subject='',
 	chatstate=None, msg_id=None, composing_xep=None, resource=None,
 	user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
 	original_message=None, delayed=None, callback=None, callback_args=[]):
-		fjid = jid
-
-		if msg and not xhtml and gajim.config.get(
-		'rst_formatting_outgoing_messages'):
-			from common.rst_xhtml_generator import create_xhtml
-			xhtml = create_xhtml(msg)
-		if not self.connection:
-			return
-		if not msg and chatstate is None:
-			return
-
-		if self.status in ('invisible', 'offline'):
-			self.dispatch('MSGERROR', [unicode(jid), -1,
-				 _('You are not connected or not visible to others. Your message '
-				'could not be sent.'), None, None, session])
-			return
-
-		msgtxt = msg
-		msgenc = ''
-		if keyID and self.USE_GPG:
-			if keyID ==  'UNKNOWN':
-				error = _('Neither the remote presence is signed, nor a key was assigned.')
-			elif keyID.endswith('MISMATCH'):
-				error = _('The contact\'s key (%s) does not match the key assigned in Gajim.' % keyID[:8])
-			else:
-				# encrypt
-				msgenc, error = self.gpg.encrypt(msg, [keyID])
-			if msgenc and not error:
-				msgtxt = '[This message is encrypted]'
-				lang = os.getenv('LANG')
-				if lang is not None or lang != 'en': # we're not english
-					msgtxt = _('[This message is encrypted]') +\
-						' ([This message is encrypted])' # one  in locale and one en
-			else:
-				# Encryption failed, do not send message
-				tim = time.localtime()
-				self.dispatch('MSGNOTSENT', (jid, error, msgtxt, tim, session))
-				return
-
-		if type_ == 'chat':
-			msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
-				xhtml=xhtml)
-
-		else:
-			if subject:
-				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
-					subject=subject, xhtml=xhtml)
-			else:
-				msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
-					xhtml=xhtml)
-
-		if msgenc:
-			msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
-
-		# chatstates - if peer supports jep85 or jep22, send chatstates
-		# please note that the only valid tag inside a message containing a <body>
-		# tag is the active event
-		if chatstate is not None:
-			if composing_xep == 'XEP-0085' or not composing_xep:
-				# JEP-0085
-				msg_iq.setTag(chatstate, namespace = common.xmpp.NS_CHATSTATES)
-			if composing_xep == 'XEP-0022' or not composing_xep:
-				# JEP-0022
-				chatstate_node = msg_iq.setTag('x', namespace = common.xmpp.NS_EVENT)
-				if not msgtxt: # when no <body>, add <id>
-					if not msg_id: # avoid putting 'None' in <id> tag
-						msg_id = ''
-					chatstate_node.setTagData('id', msg_id)
-				# when msgtxt, requests JEP-0022 composing notification
-				if chatstate is 'composing' or msgtxt:
-					chatstate_node.addChild(name = 'composing')
-
-		if forward_from:
-			addresses = msg_iq.addChild('addresses',
-				namespace=common.xmpp.NS_ADDRESS)
-			addresses.addChild('address', attrs = {'type': 'ofrom',
-				'jid': forward_from})
-
-		# XEP-0203
-		if delayed:
-			our_jid = gajim.get_jid_from_account(self.name) + '/' + \
-				self.server_resource
-			timestamp = time.strftime('%Y-%m-%dT%TZ', time.gmtime(delayed))
-			msg_iq.addChild('delay', namespace=common.xmpp.NS_DELAY2,
-				attrs={'from': our_jid, 'stamp': timestamp})
-
-		if session:
-			session.last_send = time.time()
-			msg_iq.setThread(session.thread_id)
-
-			if session.enable_encryption:
-				msg_iq = session.encrypt_stanza(msg_iq)
-
-		def on_send_ok(id):
-			no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
-			ji = gajim.get_jid_without_resource(jid)
-			if session.is_loggable() and self.name not in no_log_for and\
-			ji not in no_log_for:
-				log_msg = msg
-				if subject:
-					log_msg = _('Subject: %(subject)s\n%(message)s') % \
-					{'subject': subject, 'message': msg}
-				if log_msg:
-					if type_ == 'chat':
-						kind = 'chat_msg_sent'
-					else:
-						kind = 'single_msg_sent'
-					gajim.logger.write(kind, jid, log_msg)
 
+		def on_send_ok(msg_id):
 			self.dispatch('MSGSENT', (jid, msg, keyID))
-
 			if callback:
-				callback(id, *callback_args)
+				callback(msg_id, *callback_args)
+
+			self.log_message(jid, msg, forward_from, session, original_message,
+				subject, type_)
 
 		def on_send_not_ok(reason):
 			reason += ' ' + _('Your message could not be sent.')
 			self.dispatch('MSGERROR', [jid, -1, reason, None, None, session])
-		ret = self.connection.send(msg_iq, msg is not None, on_ok=on_send_ok,
-			on_not_ok=on_send_not_ok)
-		if ret == -1:
-			# Contact Offline
-			self.dispatch('MSGERROR', [jid, -1, _('Contact is offline. Your message could not be sent.'), None, None, session])
 
+		def cb(jid, msg, keyID, forward_from, session, original_message, subject,
+		type_, msg_iq):
+			ret = self.connection.send(msg_iq, msg is not None, on_ok=on_send_ok,
+				on_not_ok=on_send_not_ok)
+
+			if ret == -1:
+				# Contact Offline
+				self.dispatch('MSGERROR', [jid, -1, _('Contact is offline. Your '
+					'message could not be sent.'), None, None, session])
+
+		self._prepare_message(jid, msg, keyID, type_=type_, subject=subject,
+			chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
+			resource=resource, user_nick=user_nick, xhtml=xhtml, session=session,
+			forward_from=forward_from, form_node=form_node,
+			original_message=original_message, delayed=delayed, callback=cb)
 
 	def send_stanza(self, stanza):
 		# send a stanza untouched
@@ -495,95 +347,10 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 			stanza = common.xmpp.Protocol(node=stanza)
 		self.connection.send(stanza)
 
-	def ack_subscribed(self, jid):
-		gajim.log.debug('This should not happen (ack_subscribed)')
-
-	def ack_unsubscribed(self, jid):
-		gajim.log.debug('This should not happen (ack_unsubscribed)')
-
-	def request_subscription(self, jid, msg = '', name = '', groups = [],
-	auto_auth = False):
-		gajim.log.debug('This should not happen (request_subscription)')
-
-	def send_authorization(self, jid):
-		gajim.log.debug('This should not happen (send_authorization)')
-
-	def refuse_authorization(self, jid):
-		gajim.log.debug('This should not happen (refuse_authorization)')
-
-	def unsubscribe(self, jid, remove_auth = True):
-		gajim.log.debug('This should not happen (unsubscribe)')
-
-	def unsubscribe_agent(self, agent):
-		gajim.log.debug('This should not happen (unsubscribe_agent)')
-
-	def update_contact(self, jid, name, groups):
-		if self.connection:
-			self.connection.getRoster().setItem(jid = jid, name = name,
-				groups = groups)
-
-	def update_contacts(self, contacts):
-		'''update multiple roster items'''
-		if self.connection:
-			self.connection.getRoster().setItemMulti(contacts)
-
-	def new_account(self, name, config, sync = False):
-		gajim.log.debug('This should not happen (new_account)')
-
-	def _on_new_account(self, con = None, con_type = None):
-		gajim.log.debug('This should not happen (_on_new_account)')
-
-	def account_changed(self, new_name):
-		self.name = new_name
-
-	def request_last_status_time(self, jid, resource):
-		gajim.log.debug('This should not happen (request_last_status_time)')
-
-	def request_os_info(self, jid, resource):
-		gajim.log.debug('This should not happen (request_os_info)')
-
-	def get_settings(self):
-		gajim.log.debug('This should not happen (get_settings)')
-
-	def get_bookmarks(self):
-		gajim.log.debug('This should not happen (get_bookmarks)')
-
-	def store_bookmarks(self):
-		gajim.log.debug('This should not happen (store_bookmarks)')
-
-	def get_metacontacts(self):
-		gajim.log.debug('This should not happen (get_metacontacts)')
-
-	def send_agent_status(self, agent, ptype):
-		gajim.log.debug('This should not happen (send_agent_status)')
-
-	def gpg_passphrase(self, passphrase):
-		if self.gpg:
-			use_gpg_agent = gajim.config.get('use_gpg_agent')
-			if use_gpg_agent:
-				self.gpg.passphrase = None
-			else:
-				self.gpg.passphrase = passphrase
-
-	def ask_gpg_keys(self):
-		if self.gpg:
-			keys = self.gpg.get_keys()
-			return keys
-		return None
-
-	def ask_gpg_secrete_keys(self):
-		if self.gpg:
-			keys = self.gpg.get_secret_keys()
-			return keys
-		return None
-
 	def _event_dispatcher(self, realm, event, data):
+		CommonConnection._event_dispatcher(self, realm, event, data)
 		if realm == '':
-			if event == common.xmpp.transports_nb.DATA_RECEIVED:
-				self.dispatch('STANZA_ARRIVED', unicode(data, errors = 'ignore'))
-			elif event == common.xmpp.transports_nb.DATA_SENT:
-				self.dispatch('STANZA_SENT', unicode(data))
-			elif event == common.xmpp.transports.DATA_ERROR:
+			if event == common.xmpp.transports_nb.DATA_ERROR:
 				thread_id = data[1]
 				frm = unicode(data[0])
 				session = self.get_or_create_session(frm, thread_id)
@@ -591,9 +358,6 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
 	            _('Connection to host could not be established: Timeout while '
 					'sending data.'), None, None, session])
 
-	def load_roster_from_db(self):
-		return
-
 # END ConnectionZeroconf
 
 # vim: se ts=3: