one more merge with trunk
authorNikita Kozlov <nikita@elyzion.net>
Tue, 05 Jun 2012 16:44:38 +0200
changeset 1004 bcacb829dc28
parent 988 d7ddcccdff8a (current diff)
parent 1003 1e9c4a0a9acf (diff)
child 1005 a2cad81f348b
one more merge with trunk
project.properties
res/drawable/shape_line_green.xml
res/layout/preferences.xml
res/values-fr/strings.xml
res/values-nb/strings.xml
res/values/strings.xml
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/service/XmppConnectionAdapter.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/ContactListFragment.java
Binary file libs/android-support-v13.jar has changed
Binary file res/drawable/beem_status_icon_available.png has changed
Binary file res/drawable/beem_status_icon_away.png has changed
Binary file res/drawable/beem_status_icon_busy.png has changed
Binary file res/drawable/beem_status_icon_gray.png has changed
--- a/res/drawable/shape_line_green.xml	Tue Jun 05 16:29:25 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android" type="line">
-<stroke android:width="1dp"
-		android:height="2dp"
-		android:color="#D6F94C" />
-	<size android:height="1dp" />
-</shape>
--- a/res/layout/chat.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/layout/chat.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -51,7 +51,7 @@
 			android:layout_height="fill_parent" android:layout_weight="1"
 			android:maxLines="5"
 			android:inputType="textShortMessage|textAutoCorrect|textMultiLine|textCapSentences"
-			android:imeOptions="actionSend" android:cursorVisible="true"
+			android:imeOptions="actionSend|flagNoExtractUi" android:cursorVisible="true"
 			android:hint="@string/chat_input_default_value" />
 		<Button android:id="@+id/chat_send_message"
 			android:layout_width="wrap_content" android:layout_height="wrap_content"
--- a/res/layout/chat_compact.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/layout/chat_compact.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -18,7 +18,7 @@
 			android:layout_height="fill_parent" android:layout_weight="1"
 			android:maxLines="5"
 			android:inputType="textShortMessage|textAutoCorrect|textMultiLine|textCapSentences"
-			android:imeOptions="actionSend" android:cursorVisible="true"
+			android:imeOptions="actionSend|flagNoExtractUi" android:cursorVisible="true"
 			android:hint="@string/chat_input_default_value" />
 		<Button android:id="@+id/chat_send_message"
 			android:layout_width="wrap_content" android:layout_height="fill_parent"
--- a/res/layout/contactlist.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/layout/contactlist.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -4,12 +4,21 @@
 	android:orientation="vertical">
 	<ViewStub android:id="@+id/contactlist_stub" android:inflatedId="@+id/contactlist_groupstub" android:layout_width="fill_parent"
 		android:layout_height="wrap_content" android:layout="@layout/contactlist_groupstub"/>
+		
+		<!-- 
+	
 	<LinearLayout android:layout_width="fill_parent"
 		android:layout_height="fill_parent" android:orientation="horizontal"
 		android:padding="2px">
 		<ListView android:id="@+id/contactlist" android:layout_width="fill_parent"
 		    android:layout_height="fill_parent" android:transcriptMode="disabled"
 		    android:textFilterEnabled="true" />
-
 	</LinearLayout>
+	 	-->
+	 	
+	 	<android.support.v4.view.ViewPager android:id="@+id/pager"
+	 	    android:layout_width="fill_parent"
+	 	    android:layout_height="fill_parent"
+	 	    android:padding="2px"/>
+	
 </LinearLayout>
--- a/res/layout/contactlist_group.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/layout/contactlist_group.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -1,5 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    BEEM is a videoconference application on the Android Platform.
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+-->
+<com.beem.project.beem.ui.views.SectionTextView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:beem="http://schemas.android.com/apk/res/com.beem.project.beem"
 	android:textColor="@color/white" android:textColorHighlight="@color/red"
 	android:textSize="18sp" android:typeface="normal" android:textStyle="bold"
-	android:id="@+id/contactlist_group"></TextView>
\ No newline at end of file
+	android:paddingLeft="20dp" android:paddingRight="20dp"
+	beem:principalColor="@color/vert_manu"
+	android:id="@+id/contactlist_group"
+	/>
--- a/res/layout/contactlist_groupstub.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/layout/contactlist_groupstub.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -1,10 +1,36 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	android:id="@+id/contactlist_groupstub" android:layout_width="wrap_content"
 	android:layout_height="wrap_content">
 	<Gallery xmlns:android="http://schemas.android.com/apk/res/android"
 		android:id="@+id/contactlist_banner" android:layout_width="fill_parent"
-		android:layout_height="40dp" android:spacing="25dp"
+		android:layout_height="40dp" android:spacing="0dp"
 		android:unselectedAlpha="0.4" android:background="#222222" />
 	<View android:layout_width="fill_parent" android:layout_height="2dp"
 		android:fadingEdge="horizontal" android:background="#555555" />
--- a/res/layout/preferences.xml	Tue Jun 05 16:29:25 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
-    The format of the preference key is defined in
-    src/com/beem/project/beem/BeemApplication.java
-    Basically it is just a simple name like account_username.
-    TODO: There is still a lot of keys to convert
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-	android:shouldDisableView="true" android:selectable="true">
-	<PreferenceCategory android:title="@string/general_preferences">
-		<PreferenceScreen android:key="contact_list"
-			android:title="@string/contact_list_preferences" android:summary="@string/contact_list_preferences_sum">
-			<CheckBoxPreference android:title="@string/CLP_hidden_contact"
-				android:defaultValue="false" android:summary="@string/CLP_hidden_contact_sum"
-				android:key="show_offline_contacts" />
-			<CheckBoxPreference android:title="@string/CLP_hide_groups"
-				android:defaultValue="false" android:summary="@string/CLP_hide_groups_sum"
-				android:key="hide_groups" />
-			<CheckBoxPreference android:title="@string/away_chk_title"
-				android:defaultValue="true" android:summary="@string/away_chk_sum"
-				android:key="use_auto_away" />
-			<EditTextPreference android:dependency="use_auto_away"
-				android:singleLine="true" android:summary="@string/away_message_sum"
-				android:title="@string/away_message_title" android:key="auto_away_msg"
-				android:hint="@string/away_message_hint" />
-		</PreferenceScreen>
-		<PreferenceScreen android:key="chat"
-			android:title="@string/chat_preferences" android:summary="@string/chat_preferences_sum">
-			<PreferenceCategory android:title="@string/history_preferences">
-				<CheckBoxPreference android:id="@+id/chat_history"
-					android:title="@string/history" android:summary="@string/history_sum"
-					 android:defaultValue="false" android:key="settings_key_history" />
-				<EditTextPreference android:dependency="settings_key_history"
-					android:singleLine="true" android:title="@string/chat_history_path"
-					android:summary="@string/chat_history_path_sum" android:key="settings_chat_history_path"
-					android:hint="/Android/data/com.beem.project.beem/chat/" />
-			</PreferenceCategory>
-			<PreferenceCategory android:title="@string/chat_layout_option">
-				<CheckBoxPreference android:title="@string/settings_chat_compact"
-					android:defaultValue="false" android:summary="@string/settings_chat_compact_sum"
-					android:key="use_compact_chat_ui" />
-			</PreferenceCategory>
-			</PreferenceScreen>
-		<PreferenceScreen android:title="@string/notification_preferences">
-			<CheckBoxPreference android:title="@string/notification_enable_vibrate_title"
-				android:defaultValue="false" android:summary="@string/notification_enable_vibrate_sum"
-				android:key="notification_vibrate" />
-			<RingtonePreference android:title="@string/notification_snd_title"
-				android:key="notification_sound" android:summary="@string/notification_snd_sum"
-				android:ringtoneType="notification" android:showDefault="true" />
-		</PreferenceScreen>
-	</PreferenceCategory>
-	<PreferenceCategory android:title="@string/user_preferences">
-		<EditTextPreference android:singleLine="true"
-			android:summary="@string/SettingsText" android:title="@string/settings_account_username"
-			android:key="account_username" android:hint="@string/login_username_info_default"
-			android:inputType="textEmailAddress" />
-		<EditTextPreference android:name="password"
-			android:singleLine="true" android:password="true" android:summary="@string/SettingsPassword"
-			android:title="@string/settings_account_password" android:key="account_password" />
-	</PreferenceCategory>
-	<PreferenceCategory android:title="@string/user_preferences_advanced">
-		<EditTextPreference android:key="connection_resource"
-			android:title="@string/SettingsResourceTitle" android:summary="@string/SettingsResourceSummary"
-			android:defaultValue="Beem" />
-		<EditTextPreference android:key="connection_priority"
-			android:title="@string/SettingsPriorityTitle" android:summary="@string/SettingsPrioritySummary"
-			android:numeric="signed" android:defaultValue="0" />
-	</PreferenceCategory>
-	<PreferenceCategory android:title="@string/network_preferences">
-		<PreferenceScreen android:key="proxy" android:title="@string/SettingsProxy"
-			android:summary="@string/settings_proxy_sum">
-			<CheckBoxPreference android:title="@string/SettingsProxyProxy"
-				android:defaultValue="false" android:summary="@string/SettingsProxySummary"
-				android:key="proxy_use" />
-			<PreferenceCategory android:title="@string/proxy_proxy_settings">
-				<ListPreference android:dependency="proxy_use"
-					android:title="@string/SettingsProxyType" android:entries="@array/proxy_types"
-					android:summary="@string/SettingsProxyTypeSummary"
-					android:defaultValue="HTTP" android:entryValues="@array/proxy_types"
-					android:key="proxy_type" />
-				<EditTextPreference android:singleLine="true"
-					android:dependency="proxy_use" android:name="serveur"
-					android:summary="@string/SettingsProxyServer" android:title="@string/settings_proxy_server"
-					android:key="proxy_server" />
-				<EditTextPreference android:singleLine="true"
-					android:dependency="proxy_use" android:name="port"
-					android:summary="@string/SettingsProxyPort" android:title="@string/settings_proxy_port"
-					android:key="proxy_port" android:numeric="signed"
-					android:hint="@string/comments_proxy_port" />
-			</PreferenceCategory>
-			<PreferenceCategory android:title="@string/proxy_user_settings">
-				<EditTextPreference android:singleLine="true"
-					android:dependency="proxy_use" android:name="Utilisateur"
-					android:summary="@string/SettingsProxyUser" android:title="@string/settings_proxy_username"
-					android:key="proxy_username" />
-				<EditTextPreference android:singleLine="true"
-					android:dependency="proxy_use" android:name="pass_user"
-					android:password="true" android:summary="@string/SettingsProxyPassword"
-					android:title="@string/settings_proxy_password" android:key="proxy_password" />
-			</PreferenceCategory>
-		</PreferenceScreen>
-
-		<PreferenceScreen android:key="advanced"
-			android:title="@string/SettingsAdvanced" android:summary="@string/settings_advanced_sum">
-			<PreferenceCategory android:title="@string/settings_advanced_service_behaviour">
-				<CheckBoxPreference android:title="@string/settings_xmpp_use_tls"
-					android:defaultValue="false" android:key="settings_key_xmpp_tls_use" />
-				<CheckBoxPreference android:title="@string/settings_smack_debug"
-					android:defaultValue="false" android:key="smack_debug" />
-				<EditTextPreference android:singleLine="true"
-					android:title="@string/settings_reco_delay" android:name="Reconnect delay"
-					android:summary="@string/SettingsAdvancedRecoDelay" android:key="settings_key_reco_delay"
-					android:defaultValue="10" />
-			</PreferenceCategory>
-			<CheckBoxPreference android:title="@string/SettingsAdvancedOptions"
-				android:defaultValue="false" android:summary="@string/SettingsAdvancedSpecOpt"
-				android:key="settings_key_specific_server" />
-			<EditTextPreference android:singleLine="true"
-				android:dependency="settings_key_specific_server" android:name="adresse"
-				android:summary="@string/SettingsAdvancedAddOpt" android:title="@string/settings_xmpp_server"
-				android:key="settings_key_xmpp_server" android:hint="@string/comments_xmpp_server" />
-			<EditTextPreference android:singleLine="true"
-				android:dependency="settings_key_specific_server" android:name="port"
-				android:summary="@string/SettingsAdvancedPortOpt" android:title="@string/settings_xmpp_port"
-				android:defaultValue="5222" android:numeric="signed" android:key="settings_key_xmpp_port"
-				android:hint="@string/comments_xmpp_port" />
-			<CheckBoxPreference android:title="@string/settings_full_jid_login"
-				android:defaultValue="false" android:summary="@string/settings_full_jid_login_sum"
-				android:key="full_jid_login" />
-		</PreferenceScreen>
-	</PreferenceCategory>
-</PreferenceScreen>
--- a/res/values-fr/strings.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/values-fr/strings.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -90,7 +90,9 @@
 		d\'ami(e)s</string>
 	<string name="CLP_hide_groups">Cachez les groupes</string>	
 	<string name="CLP_hide_groups_sum">Cochez cette option pour cacher les groupes</string>
-	<string name="CLP_hidden_contact">Cachez les contacts</string>
+	<string name="CLP_show_jid">Affichez les JID</string>
+	<string name="CLP_show_jid_sum">Cochez cette option pour afficher les JIDs des contacts</string>
+	<string name="CLP_hidden_contact">Cachez les contacts déconnectés</string>
 	<string name="CLP_hidden_contact_sum">Cochez cette option pour cacher les contacts déconnectés</string>
 	<string name="settings_account_username">Nom d\'utilisateur (JID)</string>
 	<string name="login_username_info_default">beem@beem-project.com</string>
--- a/res/values-nb/strings.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/values-nb/strings.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -3,217 +3,217 @@
 <!-- Generic terms -->
 <string name="app_name">Beem</string>
 <string name="OkButton">Ok</string>
-<string name="ClearButton">Löschen</string>
-<string name="CancelButton">Abbrechen</string>
-<string name="AcceptButton">Authorisieren</string>
-<string name="RefuseButton">Ablehnen</string>
-<string name="JabberID">Jabber ID</string>
-<string name="Password">Passwort</string>
-<string name="Continue">Fortfahren</string>
+<string name="ClearButton">Tøm</string>
+<string name="CancelButton">Avbryt</string>
+<string name="AcceptButton">Godkjenn</string>
+<string name="RefuseButton">Avslå</string>
+<string name="JabberID">Jabber-ID</string>
+<string name="Password">Passord</string>
+<string name="Continue">Fortsett</string>
 
 <!--  AccountConfigure class -->
-<string name="AccountConfigureManualConfiguration">Manuelle Konfiguration</string>
+<string name="AccountConfigureManualConfiguration">Manuelt oppsett</string>
 
 <!--  Beem class -->
-<string name="BeemJabberID">Jabber ID</string>
+<string name="BeemJabberID">Jabber-ID</string>
 
 <!--  BeemApplication class -->
-<string name="BeemApplicationConnect">Verbinden...</string>
+<string name="BeemApplicationConnect">Kobler til ...</string>
 
 <!--  BeemService class -->
-<string name="BeemServiceDescription">Benutze Beem Service</string>
-<string name="BeemServiceCreated">Beem Service erstellt</string>
-<string name="BeemServiceDestroyed">Beem Service verworfen</string>
+<string name="BeemServiceDescription">Bruk Beem tjeneste </string>
+<string name="BeemServiceCreated">Beem tjeneste opprettet</string>
+<string name="BeemServiceDestroyed">Beem tjeneste slettet</string>
 
 <!--  ContactDialog class -->
-<string name="CDChat">Chatten</string>
-<string name="CDCall">Anrufen</string>
-<string name="CDInfos">Kontakt bearbeiten</string>
+<string name="CDChat">Prat</string>
+<string name="CDCall">Ring</string>
+<string name="CDInfos">Behandle kontakt</string>
 
 <!-- AddContact class -->
-<string name="AddCActTitle">Beem - Kontakt hinzufügen</string>
+<string name="AddCActTitle">Beem - legg til en kontakt</string>
 
-<string name="AddCLogin">Benutzername</string>
+<string name="AddCLogin">Brukernavn</string>
 <string name="AddCAlias">Alias</string>
 <string name="AddCGroup">Gruppe</string>
-<string name="AddCOkButton">Hinzufügen</string>
-<string name="AddCContactAdded">Kontakt hinzugefügt</string>
-<string name="AddCContactAddedError">Fehler, Benutzer nicht hinzugefügt</string>
-<string name="AddCContactAddedLoginError">Fehler bei der Anmeldung</string>
-<string name="AddCBadForm">Mangelhafte Form</string>
-<string name="AddCContactAlready">Kontakt existiert bereits</string>
+<string name="AddCOkButton">Legg til</string>
+<string name="AddCContactAdded">Kontakt lagt til</string>
+<string name="AddCContactAddedError">Feil ved lagring av kontakt</string>
+<string name="AddCContactAddedLoginError">Feil ved innlogging</string>
+<string name="AddCBadForm">Feil utfylt</string>
+<string name="AddCContactAlready">Kontakten finnes allerede</string>
 
 <!--  ChangeStatus class -->
-<string name="ChangeStatusActTitle">Beem - Meinen Status ändern</string>
-<string name="ChangeStatusType">Mein Status</string>
-<string name="ChangeStatusMessage">Meine persönliche Nachricht</string>
-<string name="OpenContactList">Kontaktliste öffnen</string>
+<string name="ChangeStatusActTitle">Beem - Endre status</string>
+<string name="ChangeStatusType">Min status</string>
+<string name="ChangeStatusMessage">Min personlige melding</string>
+<string name="OpenContactList">Åpne kontaktlista</string>
 
-<string name="MenuAddContact">Kontakt hinzufügen</string>
-<string name="MenuAccountAbout">Beem Project</string>
-<string name="MenuAccountCreate">Konto erstellen</string>
-<string name="MenuConnection">Konto bearbeiten</string>
-<string name="ChangeStatusOk">Aktualisiere Status</string>
-<string name="ChangeStatusNoChange">Nichts zu ändern</string>
-<string name="my_avatar">Mein Avatar</string>
-<string name="select_avatar">Wähle Avatar</string>
-<string name="take_photo">Foto machen</string>
-<string name="pick_photo">Bild auswählen</string>
-<string name="delete_avatar">Kein Avatar</string>
-<string name="photoPickerNotFoundText">Fotoauswahl nicht gefunden</string>
+<string name="MenuAddContact">Legg til ny kontakt</string>
+<string name="MenuAccountAbout">Beem-prosjektet</string>
+<string name="MenuAccountCreate">Opprett konto</string>
+<string name="MenuConnection">Rediger konto</string>
+<string name="ChangeStatusOk">Oppdaterer status</string>
+<string name="ChangeStatusNoChange">Ingen endringer</string>
+<string name="my_avatar">Mitt personbilde</string>
+<string name="select_avatar">Velg ditt personbilde</string>
+<string name="take_photo">Ta et bilde</string>
+<string name="pick_photo">Velg et bilde</string>
+<string name="delete_avatar">Ingen personbilde</string>
+<string name="photoPickerNotFoundText">Bildevelger ikke funnet</string>
 
 
 <!-- Settings class -->
-<string name="SettingsText">Benutzername bearbeiten</string>
-<string name="SettingsPassword">Passwort bearbeiten</string>
-<string name="SettingsProxy">Proxy</string>
-<string name="SettingsProxyProxy">Benutze einen Proxyserver</string>
-<string name="SettingsProxySummary">Anmeldung über einen Proxyserver</string>
+<string name="SettingsText">Rediger brukernavn</string>
+<string name="SettingsPassword">Rediger passord</string>
+<string name="SettingsProxy">Mellomtjener</string>
+<string name="SettingsProxyProxy">Bruk en mellomtjener</string>
+<string name="SettingsProxySummary">Logg inn via en mellomtjener</string>
 <string name="SettingsProxyType">Protokoll</string>
-<string name="SettingsProxyTypeSummary">Art des Proxyservers wählen</string>
-<string name="SettingsProxyServer">Adresse des Proxyservers bearbeiten</string>
-<string name="SettingsProxyPort">Port des Proxyservers bearbeiten</string>
-<string name="SettingsProxyUser">Optional, erlaubt das Authentifizieren mit dem Proxyserver</string>
-<string name="SettingsProxyPassword">Optional, erlaubt das Authentifizieren mit dem Proxyserver</string>
-<string name="SettingsAdvanced">Erweitert</string>
-<string name="SettingsAdvancedOptions">Spezifische Server Optionen</string>
-<string name="SettingsAdvancedRecoDelay">Bearbeite die Verzögerung bei der Wiederverbindung</string>
-<string name="SettingsAdvancedSpecOpt">Aktivieren, um einen spezifischen Server für die Verbindung zu benutzen</string>
-<string name="SettingsAdvancedAddOpt">Adresse des Servers bearbeiten</string>
-<string name="SettingsAdvancedPortOpt">Port des Servers bearbeiten</string>
-<string name="SettingsResourceTitle">Ressource</string>
-<string name="SettingsPriorityTitle">Priorität</string>
-<string name="SettingsResourceSummary">XMPP Ressource des Clients einstellen</string>
-<string name="SettingsPrioritySummary">Priorität des Clients einstellen</string>
+<string name="SettingsProxyTypeSummary">Velg mellomtjenertype</string>
+<string name="SettingsProxyServer">Rediger mellomtjeneradresse</string>
+<string name="SettingsProxyPort">Rediger mellomtjenerport</string>
+<string name="SettingsProxyUser">Valgfritt, tillat autentisering på mellomtjeneren</string>
+<string name="SettingsProxyPassword">Valgfritt, tillat autentisering på mellomtjeneren</string>
+<string name="SettingsAdvanced">Avansert</string>
+<string name="SettingsAdvancedOptions">Spesielle tjenerinnstilling</string>
+<string name="SettingsAdvancedRecoDelay">Endre forsinkelse ved ny tilkobling</string>
+<string name="SettingsAdvancedSpecOpt">Aktiver hvis du vil bruke en spesifikk tjener for din tilkobling</string>
+<string name="SettingsAdvancedAddOpt">Rediger tjeneradresse</string>
+<string name="SettingsAdvancedPortOpt">Rediger tjenerport</string>
+<string name="SettingsResourceTitle">Ressurs</string>
+<string name="SettingsPriorityTitle">Prioritet</string>
+<string name="SettingsResourceSummary">Velg XMPP ressurs for denne klienten</string>
+<string name="SettingsPrioritySummary">Velg prioritet for denne klienten</string>
 <string name="contact_list_preferences">Kontaktliste</string>
 <string name="contact_list_preferences_sum">A set of display options for your buddy list
 </string>
-<string name="CLP_hide_groups">Gruppen ausblenden</string>
-<string name="CLP_hide_groups_sum">Aktivieren, um Gruppen auszublenden</string>
-<string name="CLP_hidden_contact">Kontakte ausblenden</string>
+<string name="CLP_hide_groups">Skjul grupper</string>
+<string name="CLP_hide_groups_sum">Aktiver for å skjule grupper</string>
+<string name="CLP_hidden_contact">Skjul kontakter</string>
 <string name="CLP_hidden_contact_sum">Check this option to hide unconnected buddies
 </string>
-<string name="settings_account_username">Benutzername (JID)</string>
+<string name="settings_account_username">Brukernavn (JID)</string>
 <string name="login_username_info_default">beem@beem-project.com</string>
-<string name="settings_account_password">Passwort</string>
-<string name="settings_account_server">Server</string>
+<string name="settings_account_password">Passord</string>
+<string name="settings_account_server">Tjener</string>
 <string name="settings_account_port">Port</string>
-<string name="settings_advanced_service_behaviour">Verhalten des Dienstes</string>
-<string name="settings_advanced_sum">Erweiterte Einstellungen für fortgeschrittene Benutzer</string>
+<string name="settings_advanced_service_behaviour">Tjenesteoppførsel</string>
+<string name="settings_advanced_sum">Innstillinger for avanserte brukere</string>
 <string name="settings_xmpp_server">Adresse</string>
 <string name="comments_xmpp_server">example.com</string>
 <string name="settings_xmpp_port">Port</string>
-<string name="settings_xmpp_use_tls">Verwende SSL/TLS</string>
-<string name="settings_reco_delay">Verzögerung bei der Wiederverbindung</string>
+<string name="settings_xmpp_use_tls">Krev SSL/TLS</string>
+<string name="settings_reco_delay">Forsinkelse ved ny tilkobling</string>
 <string name="comments_xmpp_port">Standard: 5222</string>
-<string name="settings_proxy_sum">Einstellungen für das Benutzen eines Proxyservers</string>
-<string name="settings_proxy_use">Benutze einen Proxyserver</string>
-<string name="settings_proxy_type_prompt">Art des Proxyservers wählen</string>
-<string name="settings_proxy_server">Server</string>
+<string name="settings_proxy_sum">Innstillinger for bruk av mellomtjener</string>
+<string name="settings_proxy_use">Koble til via en mellomtjener</string>
+<string name="settings_proxy_type_prompt">Velg mellomtjenertype</string>
+<string name="settings_proxy_server">Tjener</string>
 <string name="settings_proxy_port">Port</string>
 <string name="comments_proxy_port">Standard: 1080</string>
-<string name="settings_proxy_username">Benutzername</string>
-<string name="settings_proxy_password">Passwort</string>
-<string name="away_chk_title">Aktiviere automatische Abwesenheit</string>
-<string name="away_chk_sum">Status auf Abwesend wenn Bildschirm aus</string>
-<string name="away_message_title">Abwesenheitsnachricht</string>
-<string name="away_message_sum">Angezeigte Abwesenheitsnachricht</string>
-<string name="away_message_hint">Ich bin abwesend, mein Telefonbildschirm ist aus</string>
-<string name="notification_preferences">Benachrichtigungseinstellungen</string>
-<string name="notification_enable_vibrate_title">Aktiviere Vibration</string>
-<string name="notification_enable_vibrate_sum">Aktiviere Vibration für eingehende Nachrichten</string>
-<string name="notification_snd_title">Nachrichtensignalton</string>
-<string name="notification_snd_sum">Lege den Signalton für eingehende Nachrichten fest</string>
-<string name="settings_chat_compact">Kompakter Chat</string>
-<string name="settings_chat_compact_sum">Benutze kompakte Chatfenster</string>
-<string name="history">Chronik</string>
-<string name="history_sum">Aktivieren, um Unterhaltungen auf die Speicherkarte zu speichern</string>
-<string name="history_mount">Die Speicherkarte muss eingehängt und beschreibbar sein, um die Chronik zu aktivieren</string>
-<string name="history_on_off">Aktiviere Nachrichtenchronik</string>
-<string name="chat_preferences">Chat</string>
-<string name="chat_preferences_sum">Chronik, Layout Größe ...</string>
-<string name="chat_history_path">Chronik Pfad</string>
-<string name="chat_history_path_sum">Unterhaltungen werden in einem Ordner auf der Speicherkarte gespeichert</string>
-<string name="settings_smack_debug">Aktiviere XMPP Debug Modus</string>
-<string name="settings_full_jid_login">Benutze meine vollständige JID als Benutzername</string>
-<string name="settings_full_jid_login_sum">Wird von einigen Servern, z.b. Google Talk, vorausgesetzt</string>
+<string name="settings_proxy_username">Brukernavn</string>
+<string name="settings_proxy_password">Passord</string>
+<string name="away_chk_title">Bruk auto-borte</string>
+<string name="away_chk_sum">Endre status til borte når skjermen er av</string>
+<string name="away_message_title">Borte-melding</string>
+<string name="away_message_sum">Borte-melding som vil bli vist</string>
+<string name="away_message_hint">Jeg er borte, telefonens skjerm er av</string>
+<string name="notification_preferences">Varslingsinnstillinger</string>
+<string name="notification_enable_vibrate_title">Bruk vibrasjon</string>
+<string name="notification_enable_vibrate_sum">Bruk vibrasjon ved innkommende meldinger</string>
+<string name="notification_snd_title">Meldingsringetone</string>
+<string name="notification_snd_sum">Velg ringetone for innkommende meldinger</string>
+<string name="settings_chat_compact">Kompakt pratevindu</string>
+<string name="settings_chat_compact_sum">Velg kompakt pratevindu</string>
+<string name="history">Historikk</string>
+<string name="history_sum">Aktiver for å lagre meldinger på minnekortet</string>
+<string name="history_mount">Du trenger et montert og skrivebart minnekort for å kunne aktivere historikk</string>
+<string name="history_on_off">Aktiver historikk</string>
+<string name="chat_preferences">Prat</string>
+<string name="chat_preferences_sum">Historikk, utseende ...</string>
+<string name="chat_history_path">Sti til historikk</string>
+<string name="chat_history_path_sum">Samtaler lagres i en mappe på minnekortet</string>
+<string name="settings_smack_debug">Aktiver XMPP feilsøking</string>
+<string name="settings_full_jid_login">Bruk full JID som brukernavn</string>
+<string name="settings_full_jid_login_sum">Kreves på visse tjenere slik som Google Talk</string>
 
 <!-- Subscription class -->
-<string name="SubscriptAccept">Zustimmung angenommen</string>
-<string name="SubscriptError">Zustimmungsfehler</string>
-<string name="SubscriptRefused">Zustimmung abgelehnt</string>
-<string name="SubscriptText">%s will dich zu seiner/ihrer Kontaktliste hinzufügen. Willst du ihn/sie authorisieren?</string>
-<string name="SubscriptTitle">Kontakt authorisieren?</string>
+<string name="SubscriptAccept">Abonnement godkjent</string>
+<string name="SubscriptError">Feil ved abonnement</string>
+<string name="SubscriptRefused">Abonnement avslått</string>
+<string name="SubscriptText">%s ønsker å legge deg til sin kontaktliste. Godkjenne forespørselen?</string>
+<string name="SubscriptTitle">Godkjenne kontakt?</string>
 
 <!--  BeemChatManager -->
-<string name="BeemChatManagerNewMessage">Du hast eine neue Nachricht</string>
+<string name="BeemChatManagerNewMessage">Du har en ny melding</string>
 
 <!--  BeemBroadcastReceiver class -->
-<string name="BeemBroadcastReceiverDisconnect">BEEM: Die Verbindung wurde getrennt</string>
+<string name="BeemBroadcastReceiverDisconnect">BEEM: du har koblet fra</string>
 
 <!--  XmppConnectionAdapter class -->
-<string name="AcceptContactRequest">%s hat dich gerade zu seiner/ihrer Kontaktliste hinzugefügt.</string>
-<string name="AcceptContactRequestFrom">Authorisiere %s dich zu kontaktieren.</string>
+<string name="AcceptContactRequest">%s har lagt deg til sin kontaktliste</string>
+<string name="AcceptContactRequestFrom">Godkjenn at %s kontakter deg</string>
 
 <!-- Activities -->
-<string name="login_tag">Beem - Anmeldung</string>
-<string name="edit_settings_name">Beem - Einstellungen</string>
-<string name="edit_settings_tag">Beem - Einstellungen bearbeiten</string>
-<string name="create_account_name">Beem - Konto erstellen</string>
-<string name="create_account_tag">Beem - Konto erstellen</string>
-<string name="contact_list_name">Beem - Kontakte</string>
-<string name="contact_list_tag">Beem - Kontaktliste</string>
-<string name="user_info_name">Beem - Benutzerinformation</string>
+<string name="login_tag">Beem - Aktivitet innlogging</string>
+<string name="edit_settings_name">Beem - Innstillinger</string>
+<string name="edit_settings_tag">Beem - Aktivitet innstillinger</string>
+<string name="create_account_name">Beem - Opprett konto</string>
+<string name="create_account_tag">Beem - Aktivitet opprett konto</string>
+<string name="contact_list_name">Beem - Kontakter</string>
+<string name="contact_list_tag">Beem - Aktivitet kontaktliste</string>
+<string name="user_info_name">Beem - Brukerinformasjon</string>
 
 <!-- Buttons -->
-<string name="button_create_account">Dieses Konto erstellen</string>
-<string name="button_create_login_account">Dieses Konto erstellen und benutzen</string>
+<string name="button_create_account">Opprett kontoen</string>
+<string name="button_create_login_account">Opprett og bruk kontoen</string>
 
 <!-- LogAs Activity -->
-<string name="login_username">Benutzername</string>
-<string name="login_password">Passwort</string>
-<string name="login_error_dialog_title">Anmeldung - Fehler</string>
-<string name="login_close_dialog_button">Schließen</string>
-<string name="login_menu_create_account">Konto erstellen</string>
-<string name="login_menu_settings">Einstellungen</string>
-<string name="login_menu_about">Über</string>
-<string name="login_about_title">Beem %s - Über</string>
+<string name="login_username">Brukernavn</string>
+<string name="login_password">Passord</string>
+<string name="login_error_dialog_title">Feil ved innlogging</string>
+<string name="login_close_dialog_button">Lukk</string>
+<string name="login_menu_create_account">Opprett konto</string>
+<string name="login_menu_settings">Innstillinger</string>
+<string name="login_menu_about">Om</string>
+<string name="login_about_title">Beem %s - Om</string>
 <string name="login_about_msg">
 Beem is an EPITECH Innovative Project. Visit us at
 http://www.beem-project.com !
 </string>
-<string name="login_about_button">Schließen</string>
-<string name="login_settings_button">Einstellungen</string>
-<string name="login_login_button">Anmelden</string>
-<string name="login_login_progress">Verbinden. Bitte warten...</string>
+<string name="login_about_button">Lukk</string>
+<string name="login_settings_button">Innstillinger</string>
+<string name="login_login_button">Logg inn</string>
+<string name="login_login_progress">Kobler til ...</string>
 <string name="login_error_msg">Unfortunately, an error occured.\n\nError
 detail:\n%s</string>
-<string name="login_menu_login">Anmelden</string>
-<string name="login_no_connectivity">Keine Internetverbindung gefunden</string>
-<string name="login_start_msg">Konfiguration der Einstellungen im Menü</string>
+<string name="login_menu_login">Innlogging</string>
+<string name="login_no_connectivity">Ingen nettforbindelse funnet</string>
+<string name="login_start_msg">Innstillinger i menyen</string>
 
 <!-- LoginAnim activity -->
-<string name="loganim_connecting">Verbinden...</string>
-<string name="loganim_authenticating">Authentifizieren...</string>
-<string name="loganim_login_success">Erfolgreich angemeldet</string>
-<string name="loganim_login_failed">Anmeldung gescheitert</string>
+<string name="loganim_connecting">Kobler til ...</string>
+<string name="loganim_authenticating">Autentiserer ...</string>
+<string name="loganim_login_success">Innlogging vellykket</string>
+<string name="loganim_login_failed">Feil ved innlogging</string>
 
 <!-- EditSettings Activity -->
-<string name="settings_menu_create_account">Konto erstellen</string>
-<string name="settings_menu_privacy_lists">Meine Privatsphärenliste verwalten</string>
-<string name="settings_saved_ok">Die Einstellungen wurden erfolgreich gespeichert.</string>
+<string name="settings_menu_create_account">Opprett en konto</string>
+<string name="settings_menu_privacy_lists">Behandle personvernlister</string>
+<string name="settings_saved_ok">Innstillinger lagret</string>
 
 
 
 <!-- EditSettings Activity Categories -->
-<string name="general_preferences">Allgemeine Einstellungen</string>
-<string name="user_preferences">Benutzereinstellungen (notwendig)</string>
-<string name="user_preferences_advanced">Zusätzliche Benutzereinstellungen (optional)</string>
-<string name="network_preferences">Netzwerk Einstellungen</string>
-<string name="proxy_proxy_settings">Proxy Einstellungen</string>
-<string name="proxy_user_settings">Proxy Einstellungen</string>
-<string name="history_preferences">Chronik</string>
-<string name="chat_layout_option">Chat Ansicht</string>
+<string name="general_preferences">Generelle innstillinger</string>
+<string name="user_preferences">Brukerinnstillinger (kreves)</string>
+<string name="user_preferences_advanced">Avanserte brukerinnstillinger (valgfritt)</string>
+<string name="network_preferences">Nettverksinnstillinger</string>
+<string name="proxy_proxy_settings">Tjenerinnstillinger</string>
+<string name="proxy_user_settings">Tjenerinnstillinger</string>
+<string name="history_preferences">Historikk</string>
+<string name="chat_layout_option">Utseende</string>
 
 
 <!-- EditSettings Activity Tabs -->
@@ -222,132 +222,132 @@
 <string name="settings_tab_tag_xmpp">edit_settings_tab_xmpp</string>
 <string name="settings_tab_label_xmpp">XMPP</string>
 <string name="settings_tab_tag_proxy">edit_settings_tab_proxy</string>
-<string name="settings_tab_label_proxy">Proxy</string>
+<string name="settings_tab_label_proxy">Tjener</string>
 
 
 <!-- wizard activities -->
-<string name="account_wizard_text1"><b>Willkommen bei BEEM.</b>nnDu hast noch kein XMPP (Jabber) Konto konfiguriert. Wähle eine der folgenden Optionen:</string>
-<string name="account_wizard_configure_text"><b>Bitte trage die Zugangsdaten für dein vorhandenes Konto ein</b></string>
-<string name="account_wizard_configure_account">Ich habe bereits ein Konto, das ich benutzen will</string>
-<string name="account_wizard_create_account">Ich möchte ein neues Konto registrieren</string>
+<string name="account_wizard_text1"><b>Velkomment til BEEM.</b>nnDu har ikke satt opp en XMPP (Jabber) konto.nVelg et av følgende alternativ :</string>
+<string name="account_wizard_configure_text"><b>Fyll inn informasjon for din eksisterende konto</b></string>
+<string name="account_wizard_configure_account">Jeg har en konto som jeg ønsker å bruke</string>
+<string name="account_wizard_create_account">Jeg ønsker å registrer en ny konto</string>
 
 <!-- Create an account Activity -->
-<string name="create_account_instr_dialog_title">Konto erstellen - Anweisungen</string>
-<string name="create_account_err_dialog_title">Konto erstellen - Fehler</string>
-<string name="create_account_err_dialog_settings_button">Einstellungen ändern</string>
-<string name="create_account_close_dialog_button">Schließen</string>
-<string name="create_account_successfull_after">Das Konto %s wurde erfolgreich erstellt</string>
-<string name="create_account_err_username">Mangelhafte Jabber ID</string>
-<string name="create_account_err_passwords">Passwörter stimmen nicht überein.</string>
-<string name="create_account_username">Benutzername</string>
-<string name="create_account_password">Passwort</string>
-<string name="create_account_confirm_password">Passwort bestätigen</string>
+<string name="create_account_instr_dialog_title">Opprett en konto - Veiledning</string>
+<string name="create_account_err_dialog_title">Opprett en konto - Feil</string>
+<string name="create_account_err_dialog_settings_button">Endre innstillinger</string>
+<string name="create_account_close_dialog_button">Lukk</string>
+<string name="create_account_successfull_after">Konto %s opprettet</string>
+<string name="create_account_err_username">Ugyldig JabberID</string>
+<string name="create_account_err_passwords">Passordene er ikke like</string>
+<string name="create_account_username">Brukernavn</string>
+<string name="create_account_password">Passord</string>
+<string name="create_account_confirm_password">Bekreft passord</string>
 
 <!-- ContactList Activity  -->
-<string name="contact_list_menu_add_contact">Kontakt hinzufügen</string>
-<string name="contact_list_menu_status">Status ändern</string>
-<string name="contact_list_menu_settings">Einstellungen</string>
-<string name="contact_list_menu_disconnect">Verbindung trennen</string>
-<string name="contact_list_all_contact">Alle Kontakte</string>
-<string name="contact_list_no_group">Keine Gruppe</string>
+<string name="contact_list_menu_add_contact">Legg til kontakt</string>
+<string name="contact_list_menu_status">Endre status</string>
+<string name="contact_list_menu_settings">Innstillinger</string>
+<string name="contact_list_menu_disconnect">Koble fra</string>
+<string name="contact_list_all_contact">Alle kontakter</string>
+<string name="contact_list_no_group">Ingen gruppe</string>
 
 <!-- UserInfo dialog -->
 <string name="userinfo_label_alias">Alias</string>
-<string name="userinfo_label_chg_group">Gruppen verwalten</string>
-<string name="userinfo_label_re_subscription">Einladung erneut senden</string>
-<string name="userinfo_label_block">Sperren</string>
-<string name="userinfo_label_delete">Löschen</string>
-<string name="userinfo_resend">Zustimmung erneut senden</string>
+<string name="userinfo_label_chg_group">Behandle grupper</string>
+<string name="userinfo_label_re_subscription">Send invitasjon på nytt</string>
+<string name="userinfo_label_block">Blokker</string>
+<string name="userinfo_label_delete">Slett</string>
+<string name="userinfo_resend">Send abonnement på nytt</string>
 <string name="userinfo_sure2delete">Are you sure you want to delete this contact?
 </string>
 <string name="userinfo_yes">Ja</string>
-<string name="userinfo_no">Nein</string>
-<string name="userinfo_sureresend">Bist du sicher, dass du die Einladung erneut senden willst?</string>
+<string name="userinfo_no">Nei</string>
+<string name="userinfo_sureresend">Sende invitasjon på nytt?</string>
 
-<string name="chat_name">Beem - Chat</string>
-<string name="chat_input_default_value">Nachricht eingeben</string>
-<string name="chat_self">Ich</string>
-<string name="chat_error">Fehler</string>
-<string name="chat_send_message">Senden</string>
+<string name="chat_name">Beep - Prat</string>
+<string name="chat_input_default_value">Skriv melding</string>
+<string name="chat_self">Meg</string>
+<string name="chat_error">Feil</string>
+<string name="chat_send_message">Send</string>
 <string name="chat_menu_contacts_list">Kontaktliste</string>
-<string name="chat_menu_change_chat">Chat wechseln</string>
-<string name="chat_menu_start_otr_session">OTR Sitzung starten</string>
-<string name="chat_menu_stop_otr_session">OTR Sitzung beenden</string>
-<string name="chat_menu_otr_verify_key">OTR Schlüssel authentifizieren</string>
-<string name="chat_menu_otr_submenu">OTR Optionen</string>
-<string name="chat_dialog_change_chat_title">Offene Chats</string>
-<string name="chat_menu_close_chat">Diesen Chat schließen</string>
-<string name="chat_no_more_chats">Keine weiteren aktiven Chats</string>
-<string name="chat_state_composing">schreibt gerade</string>
-<string name="chat_state_gone">hat die Unterhaltung verlassen</string>
-<string name="chat_state_active">verfolgt die Unterhaltung</string>
-<string name="chat_state_inactive">macht etwas anderes</string>
-<string name="chat_otrstate_plaintext">KLARTEXT</string>
-<string name="chat_otrstate_encrypted">VERSCHLÜSSELT</string>
-<string name="chat_otrstate_finished">BEENDET</string>
-<string name="chat_otrstate_authenticated">AUTHENTIFIZIERT</string>
+<string name="chat_menu_change_chat">Veksle prateøkt</string>
+<string name="chat_menu_start_otr_session">Start OTR-økt</string>
+<string name="chat_menu_stop_otr_session">Stopp OTR-økt</string>
+<string name="chat_menu_otr_verify_key">OTR-kontrollnøkkel</string>
+<string name="chat_menu_otr_submenu">OTR-handlinger</string>
+<string name="chat_dialog_change_chat_title">Åpne prateøkter</string>
+<string name="chat_menu_close_chat">Lukk denne prateøkten</string>
+<string name="chat_no_more_chats">Ingen flere aktive prateøkter</string>
+<string name="chat_state_composing">skriver en melding</string>
+<string name="chat_state_gone">har lukket prateøkten</string>
+<string name="chat_state_active">følger med på prateøkten</string>
+<string name="chat_state_inactive">gjør noe annet</string>
+<string name="chat_otrstate_plaintext">KLARTEKST</string>
+<string name="chat_otrstate_encrypted">KRYPTERT</string>
+<string name="chat_otrstate_finished">AVSLUTTET</string>
+<string name="chat_otrstate_authenticated">AUTENTISERT</string>
 <string name="chat_otr_verify_key" formatted="false">
 Authenticating a buddy helps ensure that the person you are talking to is who they claim to be.\n\n
 To verify the fingerprint, contact your buddy via some <i>other</i> authenticated channel, such as the telephone or GPG-signed email.  Each of you should tell your fingerprint to the other.\n\n
 If everything matches up, you should indicate in the above dialog that you <b>have</b> verified the fingerprint.\n\n
 Local fingerprint %s\n\nRemote fingerprint %s\n\nVerify fingerprint ?</string>
 
-<string name="contact_status_msg_available">Online</string>
-<string name="contact_status_msg_available_chat">Bereit zum Chatten</string>
-<string name="contact_status_msg_dnd">Beschäftigt</string>
-<string name="contact_status_msg_away">Abwesend</string>
-<string name="contact_status_msg_xa">N/A</string>
-<string name="contact_status_msg_offline">Offline</string>
+<string name="contact_status_msg_available">Tilgjengelig</string>
+<string name="contact_status_msg_available_chat">Tilgjengelig for prat</string>
+<string name="contact_status_msg_dnd">Ikke forstyrr</string>
+<string name="contact_status_msg_away">Borte</string>
+<string name="contact_status_msg_xa">Ikke tilgjengelig</string>
+<string name="contact_status_msg_offline">Koblet fra</string>
 
-<string name="privacy_list_name">Beem - Meine Privatsphärenliste verwalten</string>
-<string name="privacy_list_no_data">Keine Privatsphärenliste vorhanden.</string>
-<string name="privacy_list_menu_create">Privatsphärenliste erstellen</string>
-<string name="privacy_list_create_dialog_title">Privatsphärenliste erstellen</string>
-<string name="privacy_list_create_dialog_list_name_label">Titel</string>
-<string name="privacy_list_create_dialog_create_button">Erstellen</string>
-<string name="privacy_list_select_dialog_buddies">Kontakte</string>
-<string name="privacy_list_select_dialog_groups">Gruppen</string>
-<string name="privacy_list_select_dialog_delete">Löschen</string>
-<string name="privacy_list_delete_dialog_msg">Bist du sicher, dass du die Privatsphärenliste mit dem Titel \'%s\' löschen willst?</string>
+<string name="privacy_list_name">Beem - Behandle personvernlister</string>
+<string name="privacy_list_no_data">Ingen registrerte personvernlister</string>
+<string name="privacy_list_menu_create">Opprett en personvernliste</string>
+<string name="privacy_list_create_dialog_title">Opprett en personvernliste</string>
+<string name="privacy_list_create_dialog_list_name_label">Tittel</string>
+<string name="privacy_list_create_dialog_create_button">Opprett</string>
+<string name="privacy_list_select_dialog_buddies">Kontakter</string>
+<string name="privacy_list_select_dialog_groups">Grupper</string>
+<string name="privacy_list_select_dialog_delete">Slett</string>
+<string name="privacy_list_delete_dialog_msg">Slette personvernliste \'%s\'?</string>
 <string name="privacy_list_delete_dialog_yes">Ja</string>
-<string name="privacy_list_delete_dialog_no">Nein</string>
+<string name="privacy_list_delete_dialog_no">Nei</string>
 
-<string name="UpdateButton">Aktualisieren</string>
+<string name="UpdateButton">Oppdater</string>
 
 <!-- MemorizingTrustManager library -->
-<string name="mtm_accept_cert">Unbekanntes Zertifikat akzeptieren?</string>
-<string name="mtm_decision_always">Immer</string>
-<string name="mtm_decision_once">Einmalig</string>
-<string name="mtm_decision_abort">Abbrechen</string>
+<string name="mtm_accept_cert">Godkjenn ukjent sertifikat</string>
+<string name="mtm_decision_always">Alltid</string>
+<string name="mtm_decision_once">Denne gangen</string>
+<string name="mtm_decision_abort">Avbryt</string>
 
-<string name="mtm_notification">Zertifikatprüfung</string>
+<string name="mtm_notification">Sertifikatkontroll</string>
 
 <!-- Error messages -->
 
-<string name="error_login_authentication">Ein Fehler ist während der Authentifizierung aufgetreten: mangelhafter Benutzername oder Passwort.</string>
+<string name="error_login_authentication">Feil ved innlogging, feil brukernavn eller passord</string>
 
-<string name="interna_server_error">Remoteserver Fehler</string>
-<string name="bad_request">Mangelhafte Anfrage</string>
-<string name="forbidden">Verboten</string>
-<string name="item_not_found">Eintrag nicht gefunden</string>
-<string name="conflict">Konflikt</string>
-<string name="feature_not_implemented">Feature nicht vorhanden</string>
-<string name="gone">verloren</string>
-<string name="jid_malformed">JID mangelhaft</string>
-<string name="no_acceptable">nicht akzeptabel</string>
-<string name="not_allowed">nicht erlaubt</string>
-<string name="not_authorized">nicht authorisiert</string>
-<string name="payment_required">Bezahlung erforderlich</string>
-<string name="recipient_unavailable">Empfänger unerreichbar</string>
-<string name="redirect">weiterleiten</string>
-<string name="registration_required">Anmeldung wird benötigt</string>
-<string name="remote_server_not_found">Remoteserver nicht gefunden</string>
-<string name="remote_server_timeout">Keine Antwort vom Server</string>
-<string name="remote_server_error">Remoteserver Fehler</string>
-<string name="resource_constraint">Ressourcen Einschränkung</string>
-<string name="service_unavailable">Dienst unerreichbar</string>
-<string name="subscription_required">Zustimmung wird benötigt</string>
-<string name="undefined_condition">Undefinierte Bedingung</string>
-<string name="unexpected_condition">Unerwartete Bedingung</string>
-<string name="request_timeout">Zeitüberschreitung bei der Anfrage</string>
+<string name="interna_server_error">Remote server error</string>
+<string name="bad_request">bad-request</string>
+<string name="forbidden">forbidden</string>
+<string name="item_not_found">item-not-found</string>
+<string name="conflict">conflict</string>
+<string name="feature_not_implemented">feature-not-implemented</string>
+<string name="gone">gone</string>
+<string name="jid_malformed">jid-malformed</string>
+<string name="no_acceptable">no-acceptable</string>
+<string name="not_allowed">not-allowed</string>
+<string name="not_authorized">not-authorized</string>
+<string name="payment_required">payment-required</string>
+<string name="recipient_unavailable">recipient-unavailable</string>
+<string name="redirect">redirect</string>
+<string name="registration_required">registration-required</string>
+<string name="remote_server_not_found">Remote server not found</string>
+<string name="remote_server_timeout">No server response</string>
+<string name="remote_server_error">Remote server error</string>
+<string name="resource_constraint">resource-constraint</string>
+<string name="service_unavailable">service-unavailable</string>
+<string name="subscription_required">subscription-required</string>
+<string name="undefined_condition">undefined-condition</string>
+<string name="unexpected_condition">unexpected-condition</string>
+<string name="request_timeout">request-timeout</string>
 </resources>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/values/attrs.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+-->
+<resources>
+    <declare-styleable name="SectionTextView">
+        <attr name="principalColor" format="color" />
+        <attr name="nonPrincipalColor" format="color" />
+        <attr name="principalLineSize" format="dimension" />
+        <attr name="nonPrincipalLineSize" format="dimension" />
+    </declare-styleable>
+</resources>
--- a/res/values/strings.xml	Tue Jun 05 16:29:25 2012 +0200
+++ b/res/values/strings.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -90,6 +90,8 @@
 	</string>
 	<string name="CLP_hide_groups">Hide groups</string>	
 	<string name="CLP_hide_groups_sum">Check this option to hide groups</string>
+	<string name="CLP_show_jid">Show JID</string>
+	<string name="CLP_show_jid_sum">Check this option to always show Contact\'s JID</string>
 	<string name="CLP_hidden_contact">Hide buddies</string>
 	<string name="CLP_hidden_contact_sum">Check this option to hide unconnected buddies
 	</string>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/xml/preferences.xml	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+-->
+<!-- 
+    The format of the preference key is defined in
+    src/com/beem/project/beem/BeemApplication.java
+    Basically it is just a simple name like account_username.
+    TODO: There is still a lot of keys to convert
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+	android:shouldDisableView="true" android:selectable="true">
+	<PreferenceCategory android:title="@string/general_preferences">
+		<PreferenceScreen android:key="contact_list"
+			android:title="@string/contact_list_preferences" android:summary="@string/contact_list_preferences_sum">
+			<CheckBoxPreference android:title="@string/CLP_hidden_contact"
+				android:defaultValue="false" android:summary="@string/CLP_hidden_contact_sum"
+				android:key="show_offline_contacts" />
+			<CheckBoxPreference android:title="@string/CLP_hide_groups"
+				android:defaultValue="false" android:summary="@string/CLP_hide_groups_sum"
+				android:key="hide_groups" />
+			<CheckBoxPreference android:title="@string/CLP_show_jid"
+				android:defaultValue="false" android:key="show_jid" 
+				android:summary="@string/CLP_show_jid_sum"/>
+			<CheckBoxPreference android:title="@string/away_chk_title"
+				android:defaultValue="true" android:summary="@string/away_chk_sum"
+				android:key="use_auto_away" />
+			<EditTextPreference android:dependency="use_auto_away"
+				android:singleLine="true" android:summary="@string/away_message_sum"
+				android:title="@string/away_message_title" android:key="auto_away_msg"
+				android:hint="@string/away_message_hint" />
+		</PreferenceScreen>
+		<PreferenceScreen android:key="chat"
+			android:title="@string/chat_preferences" android:summary="@string/chat_preferences_sum">
+			<PreferenceCategory android:title="@string/history_preferences">
+				<CheckBoxPreference android:id="@+id/chat_history"
+					android:title="@string/history" android:summary="@string/history_sum"
+					 android:defaultValue="false" android:key="settings_key_history" />
+				<EditTextPreference android:dependency="settings_key_history"
+					android:singleLine="true" android:title="@string/chat_history_path"
+					android:summary="@string/chat_history_path_sum" android:key="settings_chat_history_path"
+					android:hint="/Android/data/com.beem.project.beem/chat/" />
+			</PreferenceCategory>
+			<PreferenceCategory android:title="@string/chat_layout_option">
+				<CheckBoxPreference android:title="@string/settings_chat_compact"
+					android:defaultValue="false" android:summary="@string/settings_chat_compact_sum"
+					android:key="use_compact_chat_ui" />
+			</PreferenceCategory>
+			</PreferenceScreen>
+		<PreferenceScreen android:title="@string/notification_preferences">
+			<CheckBoxPreference android:title="@string/notification_enable_vibrate_title"
+				android:defaultValue="true" android:summary="@string/notification_enable_vibrate_sum"
+				android:key="notification_vibrate" />
+			<RingtonePreference android:title="@string/notification_snd_title"
+				android:key="notification_sound" android:summary="@string/notification_snd_sum"
+				android:defaultValue="content://settings/system/notification_sound"
+				android:ringtoneType="notification" android:showDefault="true" />
+		</PreferenceScreen>
+	</PreferenceCategory>
+	<PreferenceCategory android:title="@string/user_preferences">
+		<EditTextPreference android:singleLine="true"
+			android:summary="@string/SettingsText" android:title="@string/settings_account_username"
+			android:key="account_username" android:hint="@string/login_username_info_default"
+			android:inputType="textEmailAddress" />
+		<EditTextPreference android:name="password"
+			android:singleLine="true" android:password="true" android:summary="@string/SettingsPassword"
+			android:title="@string/settings_account_password" android:key="account_password" />
+	</PreferenceCategory>
+	<PreferenceCategory android:title="@string/user_preferences_advanced">
+		<EditTextPreference android:key="connection_resource"
+			android:title="@string/SettingsResourceTitle" android:summary="@string/SettingsResourceSummary"
+			android:defaultValue="Beem" />
+		<EditTextPreference android:key="connection_priority"
+			android:title="@string/SettingsPriorityTitle" android:summary="@string/SettingsPrioritySummary"
+			android:numeric="signed" android:defaultValue="0" />
+	</PreferenceCategory>
+	<PreferenceCategory android:title="@string/network_preferences">
+		<PreferenceScreen android:key="proxy" android:title="@string/SettingsProxy"
+			android:summary="@string/settings_proxy_sum">
+			<CheckBoxPreference android:title="@string/SettingsProxyProxy"
+				android:defaultValue="false" android:summary="@string/SettingsProxySummary"
+				android:key="proxy_use" />
+			<PreferenceCategory android:title="@string/proxy_proxy_settings">
+				<ListPreference android:dependency="proxy_use"
+					android:title="@string/SettingsProxyType" android:entries="@array/proxy_types"
+					android:summary="@string/SettingsProxyTypeSummary"
+					android:defaultValue="HTTP" android:entryValues="@array/proxy_types"
+					android:key="proxy_type" />
+				<EditTextPreference android:singleLine="true"
+					android:dependency="proxy_use" android:name="serveur"
+					android:summary="@string/SettingsProxyServer" android:title="@string/settings_proxy_server"
+					android:key="proxy_server" />
+				<EditTextPreference android:singleLine="true"
+					android:dependency="proxy_use" android:name="port"
+					android:summary="@string/SettingsProxyPort" android:title="@string/settings_proxy_port"
+					android:key="proxy_port" android:numeric="signed"
+					android:hint="@string/comments_proxy_port" />
+			</PreferenceCategory>
+			<PreferenceCategory android:title="@string/proxy_user_settings">
+				<EditTextPreference android:singleLine="true"
+					android:dependency="proxy_use" android:name="Utilisateur"
+					android:summary="@string/SettingsProxyUser" android:title="@string/settings_proxy_username"
+					android:key="proxy_username" />
+				<EditTextPreference android:singleLine="true"
+					android:dependency="proxy_use" android:name="pass_user"
+					android:password="true" android:summary="@string/SettingsProxyPassword"
+					android:title="@string/settings_proxy_password" android:key="proxy_password" />
+			</PreferenceCategory>
+		</PreferenceScreen>
+
+		<PreferenceScreen android:key="advanced"
+			android:title="@string/SettingsAdvanced" android:summary="@string/settings_advanced_sum">
+			<PreferenceCategory android:title="@string/settings_advanced_service_behaviour">
+				<CheckBoxPreference android:title="@string/settings_xmpp_use_tls"
+					android:defaultValue="false" android:key="settings_key_xmpp_tls_use" />
+				<CheckBoxPreference android:title="@string/settings_smack_debug"
+					android:defaultValue="false" android:key="smack_debug" />
+				<EditTextPreference android:singleLine="true"
+					android:title="@string/settings_reco_delay" android:name="Reconnect delay"
+					android:summary="@string/SettingsAdvancedRecoDelay" android:key="settings_key_reco_delay"
+					android:defaultValue="10" />
+			</PreferenceCategory>
+			<CheckBoxPreference android:title="@string/SettingsAdvancedOptions"
+				android:defaultValue="false" android:summary="@string/SettingsAdvancedSpecOpt"
+				android:key="settings_key_specific_server" />
+			<EditTextPreference android:singleLine="true"
+				android:dependency="settings_key_specific_server" android:name="adresse"
+				android:summary="@string/SettingsAdvancedAddOpt" android:title="@string/settings_xmpp_server"
+				android:key="settings_key_xmpp_server" android:hint="@string/comments_xmpp_server" />
+			<EditTextPreference android:singleLine="true"
+				android:dependency="settings_key_specific_server" android:name="port"
+				android:summary="@string/SettingsAdvancedPortOpt" android:title="@string/settings_xmpp_port"
+				android:defaultValue="5222" android:numeric="signed" android:key="settings_key_xmpp_port"
+				android:hint="@string/comments_xmpp_port" />
+			<CheckBoxPreference android:title="@string/settings_full_jid_login"
+				android:defaultValue="false" android:summary="@string/settings_full_jid_login_sum"
+				android:key="full_jid_login" />
+		</PreferenceScreen>
+	</PreferenceCategory>
+</PreferenceScreen>
--- a/src/com/beem/project/beem/BeemApplication.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/BeemApplication.java	Tue Jun 05 16:44:38 2012 +0200
@@ -103,6 +103,8 @@
     public static final String USE_COMPACT_CHAT_UI_KEY = "use_compact_chat_ui";
     /** Preference key for history path on the SDCard. */
     public static final String CHAT_HISTORY_KEY = "settings_chat_history_path";
+    /** Preference key to show the jid in the contact list. */
+    public static final String SHOW_JID = "show_jid";
 
     //TODO add the other one
 
--- a/src/com/beem/project/beem/BeemService.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Tue Jun 05 16:44:38 2012 +0200
@@ -215,6 +215,7 @@
 	mPort = DEFAULT_XMPP_PORT;
 	mService = StringUtils.parseServer(tmpJid);
 	mHost = mService;
+	initMemorizingTrustManager();
 
 	if (mSettings.getBoolean("settings_key_specific_server", false)) {
 	    mHost = mSettings.getString("settings_key_xmpp_server", "").trim();
@@ -350,10 +351,8 @@
 
     /**
      * Install the MemorizingTrustManager in the ConnectionConfiguration of Smack.
-     *
-     * @param config the configuration to modify
      */
-    private void initMemorizingTrustManager(ConnectionConfiguration config) {
+    private void initMemorizingTrustManager() {
 	try {
 	    sslContext = SSLContext.getInstance("TLS");
 	    sslContext.init(null, MemorizingTrustManager.getInstanceList(this),
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Tue Jun 05 16:44:38 2012 +0200
@@ -40,7 +40,7 @@
     Flavien Astraud, November 26, 2009
     Head of the EIP Laboratory.
 
-*/
+ */
 package com.beem.project.beem.service;
 
 import java.util.Iterator;
@@ -119,8 +119,7 @@
     private BeemAvatarManager mAvatarManager;
     private PepSubManager mPepManager;
     private SharedPreferences mPref;
-    private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners =
-	new RemoteCallbackList<IBeemConnectionListener>();
+    private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
     private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener();
     private final PingListener mPingListener = new PingListener();
 
@@ -136,8 +135,8 @@
      * @param password password to use on connect
      * @param service the background service associated with the connection.
      */
-    public XmppConnectionAdapter(final ConnectionConfiguration config,
-	    final String login, final String password, final BeemService service) {
+    public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password,
+	final BeemService service) {
 	this(new XMPPConnection(config), login, password, service);
     }
 
@@ -148,8 +147,8 @@
      * @param password password to use on connect
      * @param service the background service associated with the connection.
      */
-    public XmppConnectionAdapter(final String serviceName,
-	    final String login, final String password, final BeemService service) {
+    public XmppConnectionAdapter(final String serviceName, final String login, final String password,
+	final BeemService service) {
 	this(new XMPPConnection(serviceName), login, password, service);
     }
 
@@ -160,8 +159,8 @@
      * @param password The password to use
      * @param service the background service associated with the connection.
      */
-    public XmppConnectionAdapter(final XMPPConnection con,
-	    final String login, final String password, final BeemService service) {
+    public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password,
+	final BeemService service) {
 	mAdaptee = con;
 	PrivacyListManager.getInstanceFor(mAdaptee);
 	mLogin = login;
@@ -203,8 +202,8 @@
 		try {
 		    //TODO NIKITA DOES SOME SHIT !!! Fix this monstruosity
 		    String str = mService.getResources().getString(
-			mService.getResources().getIdentifier(
-			    e.getXMPPError().getCondition().replace("-", "_"), "string", "com.beem.project.beem"));
+			mService.getResources().getIdentifier(e.getXMPPError().getCondition().replace("-", "_"),
+			    "string", "com.beem.project.beem"));
 		    mErrorMsg = str;
 		} catch (NullPointerException e2) {
 		    if (!"".equals(e.getMessage()))
@@ -328,7 +327,7 @@
 	mPreviousPriority = p;
 	pres.setPriority(p);
 	mAdaptee.sendPacket(pres);
-	updateNotification(m);
+	updateNotification(Status.getStatusFromPresence(pres), m);
     }
 
     /**
@@ -341,7 +340,6 @@
 
     /**
      * Get the AvatarManager of this connection.
-     *
      * @return the AvatarManager or null if there is not
      */
     public BeemAvatarManager getAvatarManager() {
@@ -366,17 +364,17 @@
 
     /**
      * Update the notification for the Beem status.
+     * @param status the status to display.
      * @param text the text to display.
      */
-    private void updateNotification(String text) {
+    private void updateNotification(int status, String text) {
 	Notification mStatusNotification;
-	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.beem_status_icon, text, System
-	    .currentTimeMillis());
+	mStatusNotification = new Notification(Status.getIconBarFromStatus(status), text, System.currentTimeMillis());
 	mStatusNotification.defaults = Notification.DEFAULT_LIGHTS;
 	mStatusNotification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
 
-	mStatusNotification.setLatestEventInfo(mService, "Beem Status", text, PendingIntent.getActivity(mService, 0,
-	    new Intent(mService, ChangeStatus.class), 0));
+	mStatusNotification.setLatestEventInfo(mService, "Beem Status", text,
+	    PendingIntent.getActivity(mService, 0, new Intent(mService, ChangeStatus.class), 0));
 	// bypass the preferences for notification
 	mService.getNotificationManager().notify(BeemService.NOTIFICATION_STATUS_ID, mStatusNotification);
     }
@@ -423,7 +421,6 @@
 
     /**
      * Get the user informations.
-     *
      * @return the user infos or null if not logged
      */
     public UserInfo getUserInfo() {
@@ -679,13 +676,14 @@
 			R.string.AcceptContactRequest, from), System.currentTimeMillis());
 		    notif.flags = Notification.FLAG_AUTO_CANCEL;
 		    Intent intent = new Intent(mService, Subscription.class);
-		    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-			.putExtra("from", from);
-		    notif.setLatestEventInfo(mService, from, mService
-			.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
-			    intent, PendingIntent.FLAG_ONE_SHOT));
+		    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from);
+		    notif.setLatestEventInfo(mService, from,
+			mService.getString(R.string.AcceptContactRequestFrom, from),
+			PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
 		    int id = packet.hashCode();
 		    mService.sendNotification(id, notif);
+		    Presence p = (Presence) packet;
+		    updateNotification(Status.getStatusFromPresence(p), p.getStatus());
 		}
 	    }, filter);
 
@@ -731,9 +729,9 @@
 	    notification.flags = Notification.FLAG_AUTO_CANCEL;
 	    Intent intent = new Intent(mService, Subscription.class);
 	    intent.setData(Contact.makeXmppUri(from));
-	    notification.setLatestEventInfo(mService, from, mService
-		.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
-		    intent, PendingIntent.FLAG_ONE_SHOT));
+	    notification.setLatestEventInfo(mService, from,
+		mService.getString(R.string.AcceptContactRequestFrom, from),
+		PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
 	    int id = p.hashCode();
 	    mService.sendNotification(id, notification);
 	}
@@ -761,11 +759,17 @@
     }
 
     /**
-     * Listener for Ping request.
-     * It will respond with a Pong.
+     * Listener for Ping request. It will respond with a Pong.
      */
     private class PingListener implements PacketListener {
 
+	/**
+	 * Constructor.
+	 */
+	public PingListener() {
+
+	}
+
 	@Override
 	public void processPacket(Packet packet) {
 	    if (!(packet instanceof PingExtension))
--- a/src/com/beem/project/beem/ui/Chat.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/ui/Chat.java	Tue Jun 05 16:44:38 2012 +0200
@@ -52,9 +52,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.jivesoftware.smack.packet.Presence.Mode;
-import org.jivesoftware.smack.util.StringUtils;
-
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.ComponentName;
@@ -62,6 +59,7 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
@@ -81,8 +79,9 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
+import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.BaseAdapter;
 import android.widget.Button;
@@ -109,6 +108,10 @@
 import com.beem.project.beem.utils.BeemBroadcastReceiver;
 import com.beem.project.beem.utils.Status;
 
+import org.jivesoftware.smack.packet.Presence.Mode;
+import org.jivesoftware.smack.util.StringUtils;
+
+
 /**
  * This class represents an activity which allows the user to chat with his/her contacts.
  * @author Jean-Manuel Da Silva <dasilvj at beem-project dot com>
@@ -167,6 +170,11 @@
 	super.onCreate(savedBundle);
 	this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 	SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
+
+	if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+	    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
+	}
+
 	mCompact = settings.getBoolean(BeemApplication.USE_COMPACT_CHAT_UI_KEY, false);
 	// UI
 	if (!mCompact) {
@@ -437,6 +445,165 @@
 	return result;
     }
 
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+	if (v == mInputField && actionId == EditorInfo.IME_ACTION_SEND) {
+	    sendMessage();
+	    return true;
+	}
+	return false;
+    }
+
+    /**
+     * Send an XMPP message.
+     */
+    private void sendMessage() {
+	final String inputContent = mInputField.getText().toString();
+
+	if (!"".equals(inputContent)) {
+	    Message msgToSend = new Message(mContact.getJIDWithRes(), Message.MSG_TYPE_CHAT);
+	    msgToSend.setBody(inputContent);
+
+	    try {
+		if (mChat == null) {
+		    mChat = mChatManager.createChat(mContact, mMessageListener);
+		    mChat.setOpen(true);
+		}
+		mChat.sendMessage(msgToSend);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+
+	    final String self = getString(R.string.chat_self);
+	    MessageText lastMessage = null;
+	    if (mListMessages.size() != 0)
+		lastMessage = mListMessages.get(mListMessages.size() - 1);
+
+	    if (lastMessage != null && lastMessage.getName().equals(self)) {
+		lastMessage.setMessage(lastMessage.getMessage().concat("\n" + inputContent));
+		lastMessage.setTimestamp(new Date());
+	    } else
+		mListMessages.add(new MessageText(self, self, inputContent, false, new Date()));
+	    mMessagesListAdapter.notifyDataSetChanged();
+	    mInputField.setText(null);
+	}
+    }
+
+
+    /**
+     * Update the contact informations.
+     */
+    private void updateContactInformations() {
+	// Check for a contact name update
+	String name = mContact.getName();
+	String res = mContact.getSelectedRes();
+	if (!"".equals(res))
+	    name += "(" + res + ")";
+	if (!mCompact) {
+	    if (!(mContactNameTextView.getText().toString().equals(name)))
+		mContactNameTextView.setText(name);
+	    //Check for a contact status message update
+	    if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) {
+		mContactStatusMsgTextView.setText(mContact.getMsgState());
+		Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS);
+	    }
+	} else {
+	    Mode m = Status.getPresenceModeFromStatus(mContact.getStatus());
+	    if (m == null)
+		setTitle(getString(R.string.chat_name) + " " + name + " ("
+			+ getString(R.string.contact_status_msg_offline) + ")");
+	    else
+		setTitle(getString(R.string.chat_name) + " " + name + " (" + m.name() + ")");
+	}
+    }
+
+    /**
+     * Update the OTR informations.
+     * @param otrState the otr state
+     */
+    private void updateOtrInformations(final String otrState) {
+	String text = null;
+	if ("ENCRYPTED".equals(otrState)) {
+	    text = Chat.this.getString(R.string.chat_otrstate_encrypted);
+	} else if ("FINISHED".equals(otrState)) {
+	    text = Chat.this.getString(R.string.chat_otrstate_finished);
+	} else if ("AUTHENTICATED".equals(otrState)) {
+	    text = Chat.this.getString(R.string.chat_otrstate_authenticated);
+	} else {
+	    text = Chat.this.getString(R.string.chat_otrstate_plaintext);
+	}
+	if (mContactOtrState != null)
+	    mContactOtrState.setText(text);
+    }
+
+    /**
+     * Update the contact status icon.
+     */
+    private void updateContactStatusIcon() {
+	if (mCompact)
+	    return;
+	String id = mContact.getAvatarId();
+	if (id == null)
+	    id = "";
+	Log.d(TAG, "update contact icon  : " + id);
+	if (!id.equals(mCurrentAvatarId)) {
+	    Drawable avatar = getAvatarDrawable(mContact.getAvatarId());
+	    mAvatarStatusDrawable.setDrawableByLayerId(R.id.avatar, avatar);
+	    mCurrentAvatarId = id;
+	}
+	mContactStatusIcon.setImageLevel(mContact.getStatus());
+    }
+
+    /**
+     * Get a Drawable containing the avatar icon.
+     * @param avatarId the avatar id to retrieve or null to get default
+     * @return a Drawable
+     */
+    private Drawable getAvatarDrawable(String avatarId) {
+	Drawable avatarDrawable = null;
+	if (avatarId != null) {
+	    Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
+	    InputStream in = null;
+	    try {
+		try {
+		    in = getContentResolver().openInputStream(uri);
+		    avatarDrawable = Drawable.createFromStream(in, avatarId);
+		} finally {
+		    if (in != null)
+			in.close();
+		}
+	    } catch (IOException e) {
+		Log.w(TAG, "Error while setting the avatar", e);
+	    }
+	}
+	if (avatarDrawable == null)
+	    avatarDrawable = getResources().getDrawable(R.drawable.beem_launcher_icon_silver);
+	return avatarDrawable;
+    }
+
+    /**
+     * Prepare the status icons map.
+     */
+    private void prepareIconsStatus() {
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE,
+		BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_online));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT,
+		BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_online));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY,
+		BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_away));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY,
+		BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_busy));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT,
+		BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_offline));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE,
+		BitmapFactory.decodeResource(getResources(), R.drawable.status_requested));
+    }
+
+
     /**
      * {@inheritDoc}.
      */
@@ -623,115 +790,6 @@
     }
 
     /**
-     * Update the contact informations.
-     */
-    private void updateContactInformations() {
-	// Check for a contact name update
-	String name = mContact.getName();
-	String res = mContact.getSelectedRes();
-	if (!"".equals(res))
-	    name += "(" + res + ")";
-	if (!mCompact) {
-	    if (!(mContactNameTextView.getText().toString().equals(name)))
-		mContactNameTextView.setText(name);
-	    //Check for a contact status message update
-	    if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) {
-		mContactStatusMsgTextView.setText(mContact.getMsgState());
-		Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS);
-	    }
-	} else {
-	    Mode m = Status.getPresenceModeFromStatus(mContact.getStatus());
-	    if (m == null)
-		setTitle(getString(R.string.chat_name) + " " + name + " ("
-		    + getString(R.string.contact_status_msg_offline) + ")");
-	    else
-		setTitle(getString(R.string.chat_name) + " " + name + " (" + m.name() + ")");
-	}
-    }
-
-    /**
-     * Update the OTR informations.
-     * @param otrState the otr state
-     */
-    private void updateOtrInformations(final String otrState) {
-	String text = null;
-	if ("ENCRYPTED".equals(otrState)) {
-	    text = Chat.this.getString(R.string.chat_otrstate_encrypted);
-	} else if ("FINISHED".equals(otrState)) {
-	    text = Chat.this.getString(R.string.chat_otrstate_finished);
-	} else if ("AUTHENTICATED".equals(otrState)) {
-	    text = Chat.this.getString(R.string.chat_otrstate_authenticated);
-	} else {
-	    text = Chat.this.getString(R.string.chat_otrstate_plaintext);
-	}
-	if (mContactOtrState != null)
-		mContactOtrState.setText(text);
-    }
-
-    /**
-     * Update the contact status icon.
-     */
-    private void updateContactStatusIcon() {
-	if (mCompact)
-	    return;
-	String id = mContact.getAvatarId();
-	if (id == null)
-	    id = "";
-	Log.d(TAG, "update contact icon  : " + id);
-	if (!id.equals(mCurrentAvatarId)) {
-	    Drawable avatar = getAvatarDrawable(mContact.getAvatarId());
-	    mAvatarStatusDrawable.setDrawableByLayerId(R.id.avatar, avatar);
-	    mCurrentAvatarId = id;
-	}
-	mContactStatusIcon.setImageLevel(mContact.getStatus());
-    }
-
-    /**
-     * Get a Drawable containing the avatar icon.
-     * @param avatarId the avatar id to retrieve or null to get default
-     * @return a Drawable
-     */
-    private Drawable getAvatarDrawable(String avatarId) {
-	Drawable avatarDrawable = null;
-	if (avatarId != null) {
-	    Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
-	    InputStream in = null;
-	    try {
-		try {
-		    in = getContentResolver().openInputStream(uri);
-		    avatarDrawable = Drawable.createFromStream(in, avatarId);
-		} finally {
-		    if (in != null)
-			in.close();
-		}
-	    } catch (IOException e) {
-		Log.w(TAG, "Error while setting the avatar", e);
-	    }
-	}
-	if (avatarDrawable == null)
-	    avatarDrawable = getResources().getDrawable(R.drawable.beem_launcher_icon_silver);
-	return avatarDrawable;
-    }
-
-    /**
-     * Prepare the status icons map.
-     */
-    private void prepareIconsStatus() {
-	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE,
-	    BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_online));
-	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT,
-	    BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_online));
-	mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY,
-	    BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_away));
-	mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY,
-	    BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_busy));
-	mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT,
-	    BitmapFactory.decodeResource(getResources(), android.R.drawable.presence_offline));
-	mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE,
-	    BitmapFactory.decodeResource(getResources(), R.drawable.status_requested));
-    }
-
-    /**
      * {@inheritDoc}.
      */
     private class MessagesListAdapter extends BaseAdapter {
@@ -942,53 +1000,6 @@
     }
 
     /**
-     * {@inheritDoc}.
-     */
-    @Override
-    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-	if (v == mInputField && actionId == EditorInfo.IME_ACTION_SEND) {
-	    sendMessage();
-	    return true;
-	}
-	return false;
-    }
-
-    /**
-     * Send an XMPP message.
-     */
-    private void sendMessage() {
-	final String inputContent = mInputField.getText().toString();
-
-	if (!"".equals(inputContent)) {
-	    Message msgToSend = new Message(mContact.getJIDWithRes(), Message.MSG_TYPE_CHAT);
-	    msgToSend.setBody(inputContent);
-
-	    try {
-		if (mChat == null) {
-		    mChat = mChatManager.createChat(mContact, mMessageListener);
-		    mChat.setOpen(true);
-		}
-		mChat.sendMessage(msgToSend);
-	    } catch (RemoteException e) {
-		Log.e(TAG, e.getMessage());
-	    }
-
-	    final String self = getString(R.string.chat_self);
-	    MessageText lastMessage = null;
-	    if (mListMessages.size() != 0)
-		lastMessage = mListMessages.get(mListMessages.size() - 1);
-
-	    if (lastMessage != null && lastMessage.getName().equals(self)) {
-		lastMessage.setMessage(lastMessage.getMessage().concat("\n" + inputContent));
-		lastMessage.setTimestamp(new Date());
-	    } else
-		mListMessages.add(new MessageText(self, self, inputContent, false, new Date()));
-	    mMessagesListAdapter.notifyDataSetChanged();
-	    mInputField.setText(null);
-	}
-    }
-
-    /**
      * This class is in charge of getting the new chat in the activity if someone talk to you.
      */
     private class ChatManagerListener extends IChatManagerListener.Stub {
--- a/src/com/beem/project/beem/ui/ContactList.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Tue Jun 05 16:44:38 2012 +0200
@@ -44,31 +44,27 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
-import java.io.InputStream;
-import java.io.IOException;
 
-import org.jivesoftware.smack.util.StringUtils;
-
-import android.app.Activity;
 import android.app.Dialog;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
-import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
 import android.util.Log;
-import android.view.ContextMenu;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -77,22 +73,13 @@
 import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
-import android.widget.Filter;
-import android.widget.Filterable;
 import android.widget.Gallery;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
 
+import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
-import com.beem.project.beem.BeemApplication;
-import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.service.Contact;
 import com.beem.project.beem.service.PresenceAdapter;
 import com.beem.project.beem.service.aidl.IBeemRosterListener;
@@ -103,14 +90,15 @@
 import com.beem.project.beem.ui.dialogs.builders.ChatList;
 import com.beem.project.beem.ui.dialogs.builders.DeleteContact;
 import com.beem.project.beem.ui.dialogs.builders.ResendSubscription;
+import com.beem.project.beem.ui.views.SectionTextView;
 import com.beem.project.beem.utils.BeemBroadcastReceiver;
-import com.beem.project.beem.utils.SortedList;
-import com.beem.project.beem.utils.Status;
+
+import org.jivesoftware.smack.util.StringUtils;
 
 /**
  * The contact list activity displays the roster of the user.
  */
-public class ContactList extends Activity {
+public class ContactList extends FragmentActivity {
 
     private static final Intent SERVICE_INTENT = new Intent();
     static {
@@ -118,30 +106,27 @@
     }
 
     private static final String TAG = "ContactList";
-    private final BeemContactList mAdapterContactList = new BeemContactList();
-    private final List<String> mListGroup = new ArrayList<String>();
+    private final List<GroupHolder> mListGroup = new ArrayList<GroupHolder>();
 
     /** Map containing a list of the different contacts of a given group.
      * Each list is a @{link SortedList} so there is no need to sort it again.
      * */
     private final Map<String, List<Contact>> mContactOnGroup = new HashMap<String, List<Contact>>();
-    private final BeemContactListOnClick mOnContactClick = new BeemContactListOnClick();
-    private final Handler mHandler = new Handler();
     private final ServiceConnection mServConn = new BeemServiceConnection();
     private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
-    private final ComparatorContactListByStatusAndName<Contact> mComparator =
-	new ComparatorContactListByStatusAndName<Contact>();
+    private final BeemBanner mAdapterBanner = new BeemBanner();
+    private final Map<String, ContactListAdapter> contactListAdapters = new HashMap<String, ContactListAdapter>();
+
     private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
-    private List<Contact> mListContact;
-    private String mSelectedGroup;
     private IRoster mRoster;
-    private Contact mSelectedContact;
     private IXmppFacade mXmppFacade;
     private IChatManager mChatManager;
     private SharedPreferences mSettings;
     private LayoutInflater mInflater;
-    private BeemBanner mAdapterBanner;
     private boolean mBinded;
+    private ViewPager viewPager;
+    private ListPagerAdapter groupsPagesAdapter;
+    private Gallery groupGallery;
 
     /**
      * Constructor.
@@ -195,92 +180,6 @@
     }
 
     @Override
-    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-	super.onCreateContextMenu(menu, v, menuInfo);
-	MenuInflater inflater = getMenuInflater();
-	inflater.inflate(R.menu.contactlist_context, menu);
-	AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
-	Contact c = mListContact.get(info.position);
-	try {
-	    mSelectedContact = mRoster.getContact(c.getJID());
-	} catch (RemoteException e) {
-	    e.printStackTrace();
-	}
-	menu.setHeaderTitle(mSelectedContact.getJID());
-    }
-
-    @Override
-    public boolean onContextItemSelected(MenuItem item) {
-	Intent in;
-	boolean result;
-	if (mSelectedContact != null) {
-	    switch (item.getItemId()) {
-		case R.id.contact_list_context_menu_chat_item:
-		    List<String> res = mSelectedContact.getMRes();
-		    if (res.isEmpty()) {
-			result = false;
-			break;
-		    }
-		    for (String resv : res) {
-			in = new Intent(this, Chat.class);
-			in.setData(mSelectedContact.toUri(resv));
-			item.getSubMenu().add(resv).setIntent(in);
-		    }
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_call_item:
-			res = mSelectedContact.getMRes();
-			if (res.isEmpty()) {
-				result = false;
-				break;
-			}
-			for (String resv : res) {
-				in = new Intent(this, Call.class);
-				in.setData(mSelectedContact.toUri(resv));
-				in.putExtra("isCaller", true);
-				item.getSubMenu().add(resv).setIntent(in);
-			}
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_user_info:
-		    item.getSubMenu().setHeaderTitle(mSelectedContact.getJID());
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_userinfo_alias:
-		    Dialog alias = new Alias(ContactList.this, mRoster, mSelectedContact).create();
-		    alias.show();
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_userinfo_group:
-		    in = new Intent(this, GroupList.class);
-		    in.putExtra("contact", mSelectedContact);
-		    startActivity(in);
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_userinfo_subscription:
-		    Dialog subscription = new ResendSubscription(ContactList.this,
-			mXmppFacade, mSelectedContact).create();
-		    subscription.show();
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_userinfo_block:
-		    result = true;
-		    break;
-		case R.id.contact_list_context_menu_userinfo_delete:
-		    Dialog delete = new DeleteContact(ContactList.this, mRoster, mSelectedContact).create();
-		    delete.show();
-		    result = true;
-		    break;
-		default:
-		    result = super.onContextItemSelected(item);
-		    break;
-	    }
-	    return result;
-	}
-	return super.onContextItemSelected(item);
-    }
-
-    @Override
     protected void onCreate(Bundle saveBundle) {
 	super.onCreate(saveBundle);
 	mSettings = PreferenceManager.getDefaultSharedPreferences(this);
@@ -289,17 +188,24 @@
 	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 
 	mInflater = getLayoutInflater();
-	mAdapterBanner = new BeemBanner(mInflater, mListGroup);
-	mListContact = new ArrayList<Contact>();
-	ListView listView = (ListView) findViewById(R.id.contactlist);
-	listView.setOnItemClickListener(mOnContactClick);
-	registerForContextMenu(listView);
-	listView.setAdapter(mAdapterContactList);
+
+	viewPager = (ViewPager) findViewById(R.id.pager);
+	viewPager.setOnPageChangeListener(new OnPageChangeListener());
+	groupsPagesAdapter = new ListPagerAdapter(getSupportFragmentManager(), viewPager);
+
+	mListGroup.add(new GroupHolder(getString(R.string.contact_list_all_contact)));
+	mListGroup.add(new GroupHolder(getString(R.string.contact_list_no_group)));
+	mAdapterBanner.notifyDataSetChanged();
     }
 
     @Override
-    protected void onResume() {
-	super.onResume();
+    protected void onStart() {
+	super.onStart();
+	if (!mSettings.getBoolean(BeemApplication.HIDE_GROUPS_KEY, false))
+	    showGroups();
+	else
+	    hideGroups();
+
 	if (!mBinded)
 	    mBinded = bindService(SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
     }
@@ -333,14 +239,75 @@
     }
 
     /**
-     * Build and display the contact list.
-     * @param group name of the contact list.
+     * Get a {@link ContactListAdapter} for a group.
+     * The {@link ContactListAdapter} will be created if it is not exist.
+     * @param group the group
+     * @return the adapter
      */
-    private void buildContactList(String group) {
-	mListContact = mContactOnGroup.get(group);
-	mSelectedGroup = group;
-	Log.d(TAG, "buildContactList for group " + group);
-	mAdapterContactList.notifyDataSetChanged();
+    ContactListAdapter getContactListAdapter(String group) {
+	synchronized (contactListAdapters) {
+	    ContactListAdapter contactListAdapter = contactListAdapters.get(group);
+	    if (contactListAdapter == null) {
+		contactListAdapter = new ContactListAdapter(ContactList.this);
+		contactListAdapters.put(group, contactListAdapter);
+		List<GroupHolder> realGroups = mListGroup.subList(1, mListGroup.size() - 1);
+		if (!GroupHolder.contains(mListGroup, group)) {
+		    GroupHolder gh = new GroupHolder(group);
+		    boolean added = false;
+		    // insert group in sorted list
+		    for (ListIterator<GroupHolder> iterator = realGroups.listIterator(); iterator.hasNext();) {
+			GroupHolder currentGroup = (GroupHolder) iterator.next();
+			if (currentGroup.group.compareTo(group) > 0) {
+			    iterator.previous();
+			    iterator.add(gh);
+			    added = true;
+			    break;
+			}
+		    }
+		    if (!added)
+			realGroups.add(gh);
+		    groupsPagesAdapter.notifyDataSetChanged();
+		    mAdapterBanner.notifyDataSetChanged();
+		}
+	    }
+	    boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
+	    contactListAdapter.setOnlineOnly(hideDisconnected);
+	    return contactListAdapter;
+	}
+    }
+
+    /**
+     * Exectute a context menu action on a specified contact.
+     * @param itemId the id of the menu action
+     * @param contact the contact
+     */
+    void doContextMenuAction(int itemId, Contact contact) {
+	switch (itemId) {
+	    case R.id.contact_list_context_menu_call_item:
+		try {
+		    mXmppFacade.call(contact.getJID() + "/psi");
+		} catch (RemoteException e) {
+		    e.printStackTrace();
+		}
+		break;
+	    case R.id.contact_list_context_menu_userinfo_alias:
+		Dialog alias = new Alias(ContactList.this, mRoster, contact).create();
+		alias.show();
+		break;
+	    case R.id.contact_list_context_menu_userinfo_subscription:
+		Dialog subscription = new ResendSubscription(ContactList.this,
+			mXmppFacade, contact).create();
+		subscription.show();
+		break;
+	    case R.id.contact_list_context_menu_userinfo_delete:
+		Dialog delete = new DeleteContact(ContactList.this, mRoster, contact).create();
+		delete.show();
+		break;
+	    default:
+		Log.w(TAG, "Context menu action not supported" + itemId);
+		break;
+	}
+
     }
 
     /**
@@ -351,15 +318,16 @@
 	ViewStub stub = (ViewStub) findViewById(R.id.contactlist_stub);
 	if (stub != null) {
 	    View v = stub.inflate();
-	    Gallery g = (Gallery) v.findViewById(R.id.contactlist_banner);
-	    g.setOnItemClickListener(new OnItemClickGroupName());
-	    g.setAdapter(mAdapterBanner);
-	    g.setSelection(0);
+	    groupGallery = (Gallery) v.findViewById(R.id.contactlist_banner);
+	    groupGallery.setOnItemClickListener(new OnItemClickGroupName());
+	    groupGallery.setAdapter(mAdapterBanner);
+	    groupGallery.setSelection(0);
 	} else {
 	    ((LinearLayout) findViewById(R.id.contactlist_groupstub)).setVisibility(View.VISIBLE);
-	    Gallery g = (Gallery) findViewById(R.id.contactlist_banner);
-	    g.setSelection(0);
+	    groupGallery = (Gallery) findViewById(R.id.contactlist_banner);
+	    groupGallery.setSelection(0);
 	}
+	GroupHolder.setUniquePrincipal(mListGroup, 0);
     }
 
     /**
@@ -372,6 +340,42 @@
     }
 
     /**
+     * Remove old groups on the banner.
+     * @throws RemoteException if an error occur when communicating with the service
+     */
+    private void cleanBannerGroup() throws RemoteException {
+	if (mListGroup.size() <= 2)
+	    return;
+	List<String> rosterGroups = mRoster.getGroupsNames();
+	Collections.sort(rosterGroups);
+	List<GroupHolder> realGroups = mListGroup.subList(1, mListGroup.size() - 1);
+	realGroups.clear();
+	realGroups.addAll(GroupHolder.createFrom(rosterGroups));
+	// restore principal
+	GroupHolder.setUniquePrincipal(mListGroup, viewPager.getCurrentItem());
+	mAdapterBanner.notifyDataSetChanged();
+	groupsPagesAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Add a contact to the special list No Group and All contacts.
+     * The contact will be added if the list is not the current list otherwise
+     * the list must be modified in a Handler.
+     *
+     * @param contact the contact to add.
+     */
+    private void addToSpecialList(Contact contact) {
+	List<String> groups = contact.getGroups();
+
+	ContactListAdapter adapter = getContactListAdapter(getString(R.string.contact_list_all_contact));
+	adapter.put(contact);
+	if (groups.isEmpty()) {
+	    adapter = getContactListAdapter(getString(R.string.contact_list_no_group));
+	    adapter.put(contact);
+	}
+    }
+
+	/**
      * Listener on service event.
      */
     private class BeemRosterListener extends IBeemRosterListener.Stub {
@@ -392,29 +396,9 @@
 	 */
 	@Override
 	public void onEntriesAdded(final List<String> addresses) throws RemoteException {
-	    final boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
 	    for (String newName : addresses) {
-		Contact contact = mRoster.getContact(newName);
-		boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-		List<String> groups = contact.getGroups();
-		if (visible) {
-		    for (String group : groups) {
-			if (!mListGroup.contains(group)) {
-			    mListGroup.add(mListGroup.size() - 1, group);
-			    List<Contact> tmplist = new SortedList<Contact>(new LinkedList<Contact>(), mComparator);
-			    mContactOnGroup.put(group, tmplist);
-			}
-			List<Contact> contactByGroups = mContactOnGroup.get(group);
-			if (mSelectedGroup.equals(group)) {
-			    updateCurrentList(group, contact);
-			    continue;
-			}
-			contactByGroups.add(contact);
-		    }
-
-		    // add the contact to all and no groups
-		    addToSpecialList(contact);
-		}
+	    	final Contact contact = mRoster.getContact(StringUtils.parseBareAddress(newName));
+	    	putContactInList(contact);
 	    }
 	}
 
@@ -429,26 +413,18 @@
 	public void onEntriesDeleted(final List<String> addresses) throws RemoteException {
 	    Log.d(TAG, "onEntries deleted " + addresses);
 	    for (String cToDelete : addresses) {
-		Contact contact = new Contact(cToDelete);
-		for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		    List<Contact> contactByGroups = entry.getValue();
-		    if (mSelectedGroup.equals(entry.getKey())) {
-			updateCurrentList(entry.getKey(), contact);
-			continue;
-		    }
-		    contactByGroups.remove(contact);
+		final Contact contact = new Contact(cToDelete);
+		for (final ContactListAdapter adapter : contactListAdapters.values()) {
+		    runOnUiThread(new Runnable() {
+
+			@Override
+			public void run() {
+			    adapter.remove(contact);
+			}
+		    });
 		}
-		cleanBannerGroup();
 	    }
-
-	    mHandler.post(new Runnable() {
-		public void run() {
-		    mSelectedGroup = getString(R.string.contact_list_all_contact);
-		    mListContact = mContactOnGroup.get(mSelectedGroup);
-
-		    mAdapterContactList.notifyDataSetChanged();
-		}
-	    });
+	    cleanBannerGroup();
 
 	}
 
@@ -463,36 +439,16 @@
 	 */
 	@Override
 	public void onEntriesUpdated(final List<String> addresses) throws RemoteException {
-	    final boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
-	    for (String adr : addresses) {
-		Contact contact = mRoster.getContact(adr);
-		boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-		List<String> groups = contact.getGroups();
-		for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		    List<Contact> contactByGroups = entry.getValue();
-		    if (mSelectedGroup.equals(entry.getKey())) {
-			updateCurrentList(entry.getKey(), contact);
-			continue;
-		    }
-		    contactByGroups.remove(contact);
-		    if (visible) {
-			for (String group : groups) {
-			    if (!mListGroup.contains(group)) {
-				mListGroup.add(mListGroup.size() - 1, group);
-				List<Contact> tmplist = new SortedList<Contact>(
-				    new LinkedList<Contact>(), mComparator);
-				mContactOnGroup.put(group, tmplist);
-			    }
-			    mContactOnGroup.get(group).remove(contact);
-			}
-		    }
-
+	    Log.d(TAG, "onEntries updated " + addresses);
+	    for (String cToDelete : addresses) {
+		Contact contact = new Contact(cToDelete);
+		for (ContactListAdapter adapter : contactListAdapters.values()) {
+		    adapter.remove(contact);
 		}
-
-		// add the contact to all and no groups
-		if (visible) {
-		    addToSpecialList(contact);
-		}
+	    }
+	    for (String newName : addresses) {
+		final Contact contact = mRoster.getContact(StringUtils.parseBareAddress(newName));
+		putContactInList(contact);
 	    }
 	    cleanBannerGroup();
 	}
@@ -509,266 +465,56 @@
 	@Override
 	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
 	    String from = presence.getFrom();
-	    final boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
 	    final Contact contact = mRoster.getContact(StringUtils.parseBareAddress(from));
-	    boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-	    List<String> groups = contact.getGroups();
-	    for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		List<Contact> contactByGroups = entry.getValue();
-		if (mSelectedGroup.equals(entry.getKey())) {
-		    updateCurrentList(entry.getKey(), contact);
-		    continue;
-		}
-		contactByGroups.remove(contact);
-		if (visible) {
-		    if (groups.contains(entry.getKey())) {
-			contactByGroups.add(contact);
-		    }
-		}
-	    }
-	    if (visible) {
-		addToSpecialList(contact);
-	    }
-	}
-
-	/**
-	 * Add a contact to the special list No Group and All contacts.
-	 * The contact will be added if the list is not the current list otherwise
-	 * the list must be modified in a Handler.
-	 *
-	 * @param contact the contact to add.
-	 */
-	private void addToSpecialList(Contact contact) {
-	    List<String> groups = contact.getGroups();
-	    List<Contact> list = mContactOnGroup.get(getString(R.string.contact_list_all_contact));
-	    if (list != mListContact) {
-		list.add(contact);
-	    }
-	    list = mContactOnGroup.get(getString(R.string.contact_list_no_group));
-	    if (list != mListContact && groups.isEmpty()) {
-		list.add(contact);
-	    }
-	}
-
-	/**
-	 * Update the current list with the status of contact.
-	 *
-	 * @param listName name of the current list
-	 * @param contact contact to update
-	 */
-	private void updateCurrentList(String listName, final Contact contact) {
-	    final boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
-	    final List<String> groups = contact.getGroups();
-	    String noGroup = getString(R.string.contact_list_no_group);
-	    String allGroup = getString(R.string.contact_list_all_contact);
-	    final boolean add = ((!hideDisconnected || Status.statusOnline(contact.getStatus())) &&	// must show and
-		(
-		    (listName.equals(noGroup) && groups.isEmpty()) ||			// in no group
-		    groups.contains(listName) ||					// or in current
-		    listName.equals(allGroup)						// or in all
-		));
-	    mHandler.post(new Runnable() {
-		public void run() {
-		    mListContact.remove(contact);
-		    if (add) {
-			mListContact.add(contact);
-		    }
-		    mAdapterContactList.notifyDataSetChanged();
-		}
-	    });
-
-	}
-
-	/**
-	 * Remove old groups on the banner.
-	 * @throws RemoteException if an error occur when communicating with the service
-	 */
-	private void cleanBannerGroup() throws RemoteException {
-	    List<String> rosterGroups = mRoster.getGroupsNames();
-	    List<String> realGroups = mListGroup.subList(1, mListContact.size() - 1);
-	    realGroups.retainAll(rosterGroups);
-	}
-
-    }
-
-    /**
-     * Adapter contact list.
-     */
-    private class BeemContactList extends BaseAdapter implements Filterable {
-
-	private final ContactFilter mFilter;
-
-	/**
-	 * Constructor.
-	 */
-	public BeemContactList() {
-	    mFilter = new ContactFilter();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getCount() {
-	    return mListContact.size();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object getItem(int position) {
-	    return mListContact.get(position);
+	    putContactInList(contact);
 	}
 
 	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public long getItemId(int position) {
-	    return mListContact.get(position).hashCode();
-	}
-
-
-	/**
-	 * {@inheritDoc}
+	 * Put a contact in the different group list.
+	 * @param contact the contact
 	 */
-	@Override
-	public View getView(int position, View convertView, ViewGroup parent) {
-	    View v = convertView;
-	    if (convertView == null) {
-		v = mInflater.inflate(R.layout.contactlistcontact, null);
-	    }
-	    Contact c = mListContact.get(position);
-	    if (mRoster != null) {
-		try {
-		    c = mRoster.getContact(c.getJID());
-		} catch (RemoteException e) {
-		    e.printStackTrace();
-		}
-	    }
-	    bindView(v, c);
-	    return v;
-	}
-
-	@Override
-	public Filter getFilter() {
-	    return mFilter;
-	}
-
-	/**
-	 * Adapte curContact to the view.
-	 * @param view the row view.
-	 * @param curContact the current contact.
-	 */
-	private void bindView(View view, Contact curContact) {
-	    if (curContact != null) {
-		TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
-		v.setText(curContact.getName());
-		v = (TextView) view.findViewById(R.id.contactlistmsgperso);
-		v.setText(curContact.getMsgState());
-		ImageView img = (ImageView) view.findViewById(R.id.avatar);
-		String avatarId = curContact.getAvatarId();
-		int contactStatus = curContact.getStatus();
-		Drawable avatar = getAvatarStatusDrawable(avatarId);
-		img.setImageDrawable(avatar);
-		img.setImageLevel(contactStatus);
-	    }
-	}
+	private void putContactInList(final Contact contact) {
+	    List<String> groups = contact.getGroups();
+	    for (final String group : groups) {
+		runOnUiThread(new Runnable() {
 
-	/**
-	 * Get a LayerDrawable containing the avatar and the status icon.
-	 * The status icon will change with the level of the drawable.
-	 * @param avatarId the avatar id to retrieve or null to get default
-	 * @return a LayerDrawable
-	 */
-	private Drawable getAvatarStatusDrawable(String avatarId) {
-	    Drawable avatarDrawable = null;
-	    if (avatarId != null) {
-		Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
-		InputStream in = null;
-		try {
-		    try {
-			in = getContentResolver().openInputStream(uri);
-			avatarDrawable = Drawable.createFromStream(in, avatarId);
-		    } finally {
-			if (in != null)
-			    in.close();
+		    @Override
+		    public void run() {
+			ContactListAdapter contactListAdapter = getContactListAdapter(group);
+			contactListAdapter.put(contact);
 		    }
-		} catch (IOException e) {
-		    Log.w(TAG, "Error while setting the avatar " + avatarId, e);
-		}
-	    }
-	    if (avatarDrawable == null)
-		avatarDrawable = getResources().getDrawable(R.drawable.beem_launcher_icon_silver);
-	    LayerDrawable ld = (LayerDrawable) getResources().getDrawable(R.drawable.avatar_status);
-	    ld.setLayerInset(1, 36, 36, 0, 0);
-	    ld.setDrawableByLayerId(R.id.avatar, avatarDrawable);
-	    return ld;
-	}
-
-	/**
-	 * A Filter which select Contact to display by searching in ther Jid.
-	 */
-	private class ContactFilter extends Filter {
-
-	    /**
-	     * Create a ContactFilter.
-	     */
-	    public ContactFilter() { }
-
-	    @Override
-	    protected Filter.FilterResults performFiltering(CharSequence constraint) {
-		Log.d(TAG, "performFiltering");
-		List<Contact> result = mListContact;
-		if (constraint.length() > 0) {
-		    result = new LinkedList<Contact>();
-		    for (Contact c : mContactOnGroup.get(mSelectedGroup)) {
-			if (c.getJID().contains(constraint))
-			    result.add(c);
-		    }
-		}
-		Filter.FilterResults fr = new Filter.FilterResults();
-		fr.values = result;
-		fr.count = result.size();
-		return fr;
+		});
 	    }
 
-	    @Override
-	    protected void publishResults(CharSequence constraint, Filter.FilterResults  results) {
-		Log.d(TAG, "publishResults");
-		List<Contact> contacts = (List<Contact>) results.values;
-		mListContact = contacts;
-		notifyDataSetChanged();
-	    }
+	    runOnUiThread(new Runnable() {
+
+		@Override
+		public void run() {
+		    addToSpecialList(contact);
+		}
+	    });
 	}
     }
 
     /**
      * Adapter banner list.
      */
-    private static class BeemBanner extends BaseAdapter {
-	private List<String> mGroups;
-	private LayoutInflater mInflater;
+    private class BeemBanner extends BaseAdapter {
 
 	/**
 	 * Constructor.
-	 * @param inflater the inflater use to create the view for the banner
-	 * @param groups list of the differents groups to adapt
 	 */
-	public BeemBanner(final LayoutInflater inflater, final List<String> groups) {
-	    mGroups = groups;
-	    mInflater = inflater;
+	public BeemBanner() {
 	}
 
 	@Override
 	public int getCount() {
-	    return mGroups.size();
+	    return mListGroup.size();
 	}
 
 	@Override
 	public Object getItem(int position) {
-	    return mGroups.get(position);
+	    return mListGroup.get(position);
 	}
 
 	@Override
@@ -778,11 +524,13 @@
 
 	@Override
 	public View getView(int position, View convertView, ViewGroup parent) {
-	    View v = convertView;
+	    SectionTextView v = (SectionTextView) convertView;
 	    if (convertView == null) {
-		v = mInflater.inflate(R.layout.contactlist_group, null);
+	    	v = (SectionTextView) mInflater.inflate(R.layout.contactlist_group, null);
 	    }
-	    ((TextView) v).setText(mGroups.get(position));
+	    GroupHolder gh = (GroupHolder) getItem(position);
+	    v.setText(gh.group);
+	    v.setPrincipal(gh.isPrincipal);
 	    return v;
 	}
     }
@@ -805,19 +553,14 @@
 		mRoster = mXmppFacade.getRoster();
 		if (mRoster != null) {
 		    List<String> tmpGroupList = mRoster.getGroupsNames();
-		    Collections.sort(tmpGroupList);
-		    mListGroup.clear();
-		    mListGroup.add(getString(R.string.contact_list_all_contact));
-		    mListGroup.addAll(tmpGroupList);
-		    mListGroup.add(getString(R.string.contact_list_no_group));
+		    cleanBannerGroup();
+		    synchronized (contactListAdapters) {
+			for (ContactListAdapter ca : contactListAdapters.values()) {
+			    ca.clear();
+			}
+		    }
 		    assignContactToGroups(mRoster.getContactList(), tmpGroupList);
-		    makeSortedList(mContactOnGroup);
-		    if (!mSettings.getBoolean(BeemApplication.HIDE_GROUPS_KEY, false))
-			showGroups();
-		    else
-			hideGroups();
-		    String group = getString(R.string.contact_list_all_contact);
-		    buildContactList(group);
+
 		    mRoster.addRosterListener(mBeemRosterListener);
 		    Log.d(TAG, "add roster listener");
 		    mChatManager = mXmppFacade.getChatManager();
@@ -837,10 +580,10 @@
 	    mXmppFacade = null;
 	    mChatManager = null;
 	    mRoster = null;
-	    mListContact.clear();
 	    mListGroup.clear();
 	    mContactOnGroup.clear();
 	    mBinded = false;
+
 	}
 
 	/**
@@ -851,88 +594,38 @@
 	 * @param groupNames list of existing groups
 	 */
 	private void assignContactToGroups(List<Contact> contacts, List<String> groupNames) {
-	    boolean hideDisconnected = mSettings.getBoolean(BeemApplication.SHOW_OFFLINE_CONTACTS_KEY, false);
-	    mContactOnGroup.clear();
-	    List<Contact> all = new LinkedList<Contact>();
-	    List<Contact> noGroups = new LinkedList<Contact>();
-	    for (String group : groupNames) {
-		mContactOnGroup.put(group, new LinkedList<Contact>());
-	    }
 	    for (Contact c : contacts) {
-		if (hideDisconnected && !Status.statusOnline(c.getStatus())) {
-		    continue;
-		}
-		all.add(c);
+		addToSpecialList(c);
+
 		List<String> groups = c.getGroups();
-		if (groups.isEmpty())
-		    noGroups.add(c);
-		else {
-		    for (String currentGroup : groups) {
-			List<Contact> contactsByGroups = mContactOnGroup.get(currentGroup);
-			contactsByGroups.add(c);
-		    }
+
+		for (String currentGroup : groups) {
+		    ContactListAdapter cl = getContactListAdapter(currentGroup);
+		    cl.put(c);
 		}
 	    }
-	    mContactOnGroup.put(getString(R.string.contact_list_no_group), noGroups);
-	    mContactOnGroup.put(getString(R.string.contact_list_all_contact), all);
 	}
 
-	/**
-	 * Make the List of the map became Insertion sorted list.
-	 *
-	 * @param map the map to convert.
-	 */
-	private void makeSortedList(Map<String, List<Contact>> map) {
-	    for (Map.Entry<String, List<Contact>> entry : map.entrySet()) {
-		List<Contact> l = entry.getValue();
-		entry.setValue(new SortedList<Contact>(l, mComparator));
-	    }
-	}
     }
 
 
-
-
     /**
-     * Comparator Contact by status and name.
+     * Listener on page change event.
      */
-    private static class ComparatorContactListByStatusAndName<T> implements Comparator<T> {
-	/**
-	 * Constructor.
-	 */
-	public ComparatorContactListByStatusAndName() {
-	}
-
-	@Override
-	public int compare(T c1, T c2) {
-	    if (((Contact) c1).getStatus() < ((Contact) c2).getStatus()) {
-		return 1;
-	    } else if (((Contact) c1).getStatus() > ((Contact) c2).getStatus()) {
-		return -1;
-	    } else
-		return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName());
-	}
-    }
-
-    /**
-     * Event simple click on item of the contact list.
-     */
-    private class BeemContactListOnClick implements OnItemClickListener {
-	/**
-	 * Constructor.
-	 */
-	public BeemContactListOnClick() {
-	}
+    private class OnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
 
 	/**
-	 * {@inheritDoc}
+	 * Create a {@link OnPageChangeListener}.
 	 */
+	public OnPageChangeListener() {
+	}
 	@Override
-	public void onItemClick(AdapterView<?> arg0, View v, int pos, long lpos) {
-	    Contact c = mListContact.get(pos);
-	    Intent i = new Intent(ContactList.this, Chat.class);
-	    i.setData(c.toUri());
-	    startActivity(i);
+	public void onPageSelected(int position) {
+	    GroupHolder.setUniquePrincipal(mListGroup, position);
+	    if (groupGallery != null) {
+		groupGallery.setSelection(position);
+	    }
+	    mAdapterBanner.notifyDataSetChanged();
 	}
     }
 
@@ -949,9 +642,96 @@
 
 	@Override
 	public void onItemClick(AdapterView<?> arg0, View v, int i, long l) {
-	    String group = mListGroup.get(i);
-	    buildContactList(group);
+	    viewPager.setCurrentItem(i, true);
 	}
     }
 
+    /**
+     * PagerAdapter for the contact list.
+     */
+    private class ListPagerAdapter extends FragmentPagerAdapter {
+
+	/**
+	 * Create a {@link ListPagerAdapter}.
+	 * @param fm the {@link FragmentManager}
+	 * @param viewPager the {@link ViewPager} associate with this adapter
+	 */
+	public ListPagerAdapter(final FragmentManager fm, final ViewPager viewPager) {
+	    super(fm);
+	    viewPager.setAdapter(this);
+	}
+
+	@Override
+	public Fragment getItem(int position) {
+	    String group = mListGroup.get(position).group;
+	    ContactListFragment f = ContactListFragment.newInstance(group);
+	    f.setListAdapter(getContactListAdapter(group));
+	    return f;
+	}
+
+	@Override
+	public int getCount() {
+	    return mListGroup.size();
+	}
+
+    }
+
+    /**
+     * A holder for a group name and is principal state.
+     * It is an helper class to manage the state of the tabs.
+     */
+    private static class GroupHolder {
+
+	String group;
+	boolean isPrincipal;
+
+	/**
+	 * Create a {@link GroupHolder}.
+	 * @param group the group name
+	 */
+	public GroupHolder(final String group) {
+	    this.group = group;
+	}
+
+	/**
+	 * Create a list of GroupHolder.
+	 * @param groups list of group name
+	 * @return a list of {@link GroupHolder}
+	 */
+	public static List<GroupHolder> createFrom(List<String> groups) {
+	    List<GroupHolder> result = new ArrayList<ContactList.GroupHolder>();
+	    for (String s : groups) {
+		result.add(new GroupHolder(s));
+	    }
+	    return result;
+	}
+
+	/**
+	 * Test if a group exist in a list of {@link GroupHolder}.
+	 * @param list the list
+	 * @param group the group
+	 * @return true if the group is in the list false otherwise
+	 */
+	public static boolean contains(List<GroupHolder> list, String group) {
+	    for (GroupHolder groupHolder : list) {
+		if (groupHolder.group.equals(group))
+		    return true;
+	    }
+	    return false;
+	}
+
+	/**
+	 * Set a unique principal in the {@link GroupHolder} list.
+	 * @param groups the list
+	 * @param position the position of the principal
+	 */
+	public static void setUniquePrincipal(List<GroupHolder> groups, int position) {
+	    for (GroupHolder gh : groups) {
+		gh.isPrincipal = false;
+	    }
+	    groups.get(position).isPrincipal = true;
+	}
+    }
+
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/ContactListAdapter.java	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,294 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+*/
+package com.beem.project.beem.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.R;
+import com.beem.project.beem.providers.AvatarProvider;
+import com.beem.project.beem.service.Contact;
+import com.beem.project.beem.utils.SortedList;
+import com.beem.project.beem.utils.Status;
+
+/**
+ * An Adapter for the contact list.
+ * It displays a list of contact in a particular group.
+ *
+ */
+public class ContactListAdapter extends BaseAdapter implements Filterable {
+    private static final String TAG = ContactListAdapter.class.getSimpleName();
+    private final ComparatorContactListByStatusAndName<Contact> mComparator =
+	new ComparatorContactListByStatusAndName<Contact>();
+    private List<Contact> mCurrentList;
+    private final List<Contact> allContacts = new SortedList<Contact>(new LinkedList<Contact>(), mComparator);
+    private final List<Contact> onlineContacts = new SortedList<Contact>(new LinkedList<Contact>(), mComparator);
+    private final Filter mFilter = new ContactFilter();
+    private final Context context;
+    private LayoutInflater mInflater;
+
+    private boolean showOnlineOnly;
+
+    /**
+     * Create a ContactListAdapter.
+     * @param c the android context
+     */
+    public ContactListAdapter(final Context c) {
+    	mCurrentList = allContacts;
+    	context = c;
+    	mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    @Override
+    public int getCount() {
+	return mCurrentList.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+	return mCurrentList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+	return mCurrentList.get(position).hashCode();
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+	View v = convertView;
+	if (convertView == null) {
+	    v = mInflater.inflate(R.layout.contactlistcontact, null);
+	}
+	Contact c = mCurrentList.get(position);
+	bindView(v, c);
+	return v;
+    }
+
+    /**
+     * Put a contact in the list.
+     * @param c the contact
+     */
+    public void put(Contact c) {
+	put(c, allContacts);
+	if (Status.statusOnline(c.getStatus()))
+	    put(c, onlineContacts);
+	notifyDataSetChanged();
+    }
+
+    /**
+     * Remove a contact from the list.
+     *
+     * @param c the contact
+     */
+    public void remove(Contact c) {
+	allContacts.remove(c);
+	onlineContacts.remove(c);
+	notifyDataSetChanged();
+    }
+
+    /**
+     * Clear the contact list.
+     */
+    public void clear() {
+	allContacts.clear();
+	onlineContacts.clear();
+	notifyDataSetChanged();
+    }
+
+    @Override
+    public Filter getFilter() {
+	return mFilter;
+    }
+
+    /**
+     * Bind a contact to the view.
+     * @param view the row view.
+     * @param curContact the contact.
+     */
+    private void bindView(View view, Contact curContact) {
+	if (curContact != null) {
+	    TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
+	    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
+	    if (settings.getBoolean(BeemApplication.SHOW_JID, false))
+	    	v.setText(curContact.getJID());
+	    else
+		v.setText(curContact.getName());
+	    v = (TextView) view.findViewById(R.id.contactlistmsgperso);
+	    v.setText(curContact.getMsgState());
+	    ImageView img = (ImageView) view.findViewById(R.id.avatar);
+	    String avatarId = curContact.getAvatarId();
+	    int contactStatus = curContact.getStatus();
+	    Drawable avatar = getAvatarStatusDrawable(avatarId);
+	    img.setImageDrawable(avatar);
+	    img.setImageLevel(contactStatus);
+	}
+    }
+
+    /**
+     * Get a LayerDrawable containing the avatar and the status icon.
+     * The status icon will change with the level of the drawable.
+     * @param avatarId the avatar id to retrieve or null to get default
+     * @return a LayerDrawable
+     */
+    private Drawable getAvatarStatusDrawable(String avatarId) {
+	Drawable avatarDrawable = null;
+	if (avatarId != null) {
+	    Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
+	    InputStream in = null;
+	    try {
+		try {
+		    in = context.getContentResolver().openInputStream(uri);
+		    avatarDrawable = Drawable.createFromStream(in, avatarId);
+		} finally {
+		    if (in != null)
+			in.close();
+		}
+	    } catch (IOException e) {
+		Log.w(TAG, "Error while setting the avatar " + avatarId, e);
+	    }
+	}
+	if (avatarDrawable == null)
+	    avatarDrawable = context.getResources().getDrawable(R.drawable.beem_launcher_icon_silver);
+	LayerDrawable ld = (LayerDrawable) context.getResources().getDrawable(R.drawable.avatar_status);
+	ld.setLayerInset(1, 36, 36, 0, 0);
+	ld.setDrawableByLayerId(R.id.avatar, avatarDrawable);
+	return ld;
+    }
+
+    /**
+     * Put a contact in a list.
+     * Helper method.
+     *
+     * @param c the contact
+     * @param list the list
+     */
+    private void put(Contact c, List<Contact> list) {
+	list.remove(c);
+	list.add(c);
+    }
+
+    /**
+     * Tell if the list display only online contacts.
+     *
+     * @return true if only online contacts are shown
+     */
+    public boolean isOnlineOnly() {
+	return showOnlineOnly;
+    }
+
+    /**
+     * Set the list to display only the online contacts.
+     *
+     * @param online true to display only online contacts
+     */
+    public void setOnlineOnly(boolean online) {
+	if (online != showOnlineOnly) {
+	    showOnlineOnly = online;
+	    mCurrentList = showOnlineOnly ? onlineContacts : allContacts;
+	    notifyDataSetChanged();
+	}
+    }
+
+    /**
+     * A Filter which select Contact to display by searching in ther Jid.
+     */
+    private class ContactFilter extends Filter {
+
+	/**
+	 * Create a ContactFilter.
+	 */
+	public ContactFilter() { }
+
+	@Override
+	protected Filter.FilterResults performFiltering(CharSequence constraint) {
+	    Log.d(TAG, "performFiltering");
+	    List<Contact> result = mCurrentList;
+	    if (constraint.length() > 0) {
+		result = new LinkedList<Contact>();
+		for (Contact c : mCurrentList) {
+		    if (c.getJID().contains(constraint))
+			result.add(c);
+		}
+	    }
+	    Filter.FilterResults fr = new Filter.FilterResults();
+	    fr.values = result;
+	    fr.count = result.size();
+	    return fr;
+	}
+
+	@Override
+	protected void publishResults(CharSequence constraint, Filter.FilterResults  results) {
+	    Log.d(TAG, "publishResults");
+	    List<Contact> contacts = (List<Contact>) results.values;
+	    mCurrentList = contacts;
+	    notifyDataSetChanged();
+	}
+    }
+
+    /**
+     * Comparator Contact by status and name.
+     */
+    private static class ComparatorContactListByStatusAndName<T> implements Comparator<T> {
+	/**
+	 * Constructor.
+	 */
+	public ComparatorContactListByStatusAndName() {
+	}
+
+	@Override
+	public int compare(T c1, T c2) {
+	    if (((Contact) c1).getStatus() < ((Contact) c2).getStatus()) {
+		return 1;
+	    } else if (((Contact) c1).getStatus() > ((Contact) c2).getStatus()) {
+		return -1;
+	    } else
+		return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName());
+	}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/ContactListFragment.java	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,182 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+*/
+package com.beem.project.beem.ui;
+
+import java.util.List;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.Contact;
+
+/**
+ * A Fragment which display a list of contacts.
+ */
+public class ContactListFragment extends ListFragment {
+    private String group;
+    private ContactList hostActivity;
+    private Contact mSelectedContact;
+
+    /**
+     * Create a ContactListFragment.
+     * @param group the group name
+     * @return the ContactListFragment
+     */
+    public static ContactListFragment newInstance(String group) {
+	ContactListFragment f = new ContactListFragment();
+	Bundle b = new Bundle();
+	b.putString("group", group);
+	f.setArguments(b);
+	return f;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	parseArguments();
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+	super.onAttach(activity);
+	hostActivity = (ContactList) activity;
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+	super.onActivityCreated(savedInstanceState);
+	ListAdapter adapter = hostActivity.getContactListAdapter(group);
+	setListAdapter(adapter);
+	registerForContextMenu(getListView());
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+	ContactListAdapter a  = (ContactListAdapter) getListAdapter();
+	Contact c = (Contact) a.getItem(position);
+	Intent i = new Intent(getActivity(), Chat.class);
+	i.setData(c.toUri());
+	startActivity(i);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+	super.onCreateContextMenu(menu, v, menuInfo);
+	MenuInflater inflater =  hostActivity.getMenuInflater();
+	inflater.inflate(R.menu.contactlist_context, menu);
+	AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+	mSelectedContact = (Contact) getListAdapter().getItem(info.position);
+	menu.setHeaderTitle(mSelectedContact.getJID());
+    }
+
+    /**
+     * Parse the arguments submit to the Fragment.
+     */
+    private void parseArguments() {
+	Bundle b = getArguments();
+	if (b == null)
+	    return;
+	group = b.getString("group");
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+	Intent in;
+	boolean result = false;
+	if (mSelectedContact != null) {
+	    switch (item.getItemId()) {
+		case R.id.contact_list_context_menu_chat_item:
+		    List<String> res = mSelectedContact.getMRes();
+		    if (res.isEmpty()) {
+			break;
+		    }
+		    for (String resv : res) {
+			in = new Intent(hostActivity, Chat.class);
+			in.setData(mSelectedContact.toUri(resv));
+			item.getSubMenu().add(resv).setIntent(in);
+		    }
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_call_item:
+		    res = mSelectedContact.getMRes();
+		    if (res.isEmpty()) {
+			    break;
+		    }
+		    for (String resv : res) {
+			    in = new Intent(hostActivity, Call.class);
+			    in.setData(mSelectedContact.toUri(resv));
+			    in.putExtra("isCaller", true);
+			    item.getSubMenu().add(resv).setIntent(in);
+		    }
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_user_info:
+		    item.getSubMenu().setHeaderTitle(mSelectedContact.getJID());
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_userinfo_alias:
+		    hostActivity.doContextMenuAction(item.getItemId(), mSelectedContact);
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_userinfo_group:
+		    in = new Intent(hostActivity, GroupList.class);
+		    in.putExtra("contact", mSelectedContact);
+		    startActivity(in);
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_userinfo_subscription:
+		    hostActivity.doContextMenuAction(item.getItemId(), mSelectedContact);
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_userinfo_block:
+		    result = true;
+		    break;
+		case R.id.contact_list_context_menu_userinfo_delete:
+		    hostActivity.doContextMenuAction(item.getItemId(), mSelectedContact);
+		    result = true;
+		    break;
+		default:
+		    result = super.onContextItemSelected(item);
+		    break;
+	    }
+	    return result;
+	}
+	return super.onContextItemSelected(item);
+    }
+
+}
--- a/src/com/beem/project/beem/ui/Login.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/ui/Login.java	Tue Jun 05 16:44:38 2012 +0200
@@ -51,6 +51,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -82,6 +83,7 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
+	PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
 	Application app = getApplication();
 	if (app instanceof BeemApplication) {
 	    mBeemApplication = (BeemApplication) app;
--- a/src/com/beem/project/beem/ui/Settings.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/ui/Settings.java	Tue Jun 05 16:44:38 2012 +0200
@@ -73,7 +73,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
-	addPreferencesFromResource(R.layout.preferences);
+	addPreferencesFromResource(R.xml.preferences);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/views/SectionTextView.java	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,220 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+*/
+package com.beem.project.beem.ui.views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.beem.project.beem.R;
+
+/**
+ * This class implements a custom TextView with an underscore section line.
+ * It can be used to make tabs.
+ *
+ */
+public class SectionTextView extends TextView {
+    private static final int DEFAULT_PRINCIPAL_COLOR = 0xffffffff;
+    private static final int DEFAULT_PRINCIPAL_LINE_SIZE = 8;
+    private static final int DEFAULT_NON_PRINCIPAL_COLOR = 0xff555555;
+    private static final int DEFAULT_NON_PRINCIPAL_LINE_SIZE = 3;
+    private static final int SECTION_SPACE_SIZE = 5;
+    private boolean principal;
+    private int principalColor;
+    private int nonPrincipalColor;
+    private float principalLineSize;
+    private float nonPrincipalLineSize;
+    private float density;
+
+    private Paint sectionPaint;
+
+
+    /**
+     * Create a SectionTextView.
+     *
+     * @param context the android context
+     * @param attrs the android attributes
+     */
+    public SectionTextView(final Context context, final AttributeSet attrs) {
+	super(context, attrs);
+	initSectionTextView();
+
+	TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SectionTextView);
+
+	principalColor = a.getColor(R.styleable.SectionTextView_principalColor, DEFAULT_PRINCIPAL_COLOR);
+	principalLineSize = a.getDimension(R.styleable.SectionTextView_principalLineSize,
+		DEFAULT_PRINCIPAL_LINE_SIZE * density);
+	nonPrincipalColor = a.getColor(R.styleable.SectionTextView_nonPrincipalColor, DEFAULT_NON_PRINCIPAL_COLOR);
+	nonPrincipalLineSize = a.getDimension(R.styleable.SectionTextView_nonPrincipalLineSize,
+		DEFAULT_NON_PRINCIPAL_LINE_SIZE * density);
+
+	a.recycle();
+    }
+
+    /**
+     * Create a SectionTextView.
+     *
+     * @param context the android context
+     */
+    public SectionTextView(final Context context) {
+	super(context);
+	initSectionTextView();
+    }
+
+    /**
+     * Set the textview in principal mode.
+     * It will show up with a distinctive color.
+     *
+     * @param principal the mode
+     */
+    public void setPrincipal(boolean principal) {
+	this.principal = principal;
+    }
+
+    /**
+     * Get the principal mode of the view.
+     *
+     * @return the mode
+     */
+    public boolean isPrincipal() {
+	return principal;
+    }
+
+
+    /**
+     * Get the color used to show the view in principal mode.
+     *
+     * @return the color
+     */
+    public int getPrincipalColor() {
+	return principalColor;
+    }
+
+    /**
+     * Set the color used to show the view in principal mode.
+     *
+     * @param principalColor the color
+     */
+    public void setPrincipalColor(int principalColor) {
+	this.principalColor = principalColor;
+    }
+
+    /**
+     * Get the color used to show the view when not in principal mode.
+     *
+     * @return the color
+     */
+    public int getNonPrincipalColor() {
+	return nonPrincipalColor;
+    }
+
+    /**
+     * Set the color used to show the view when not in principal mode.
+     *
+     * @param nonPrincipalColor the  color
+     */
+    public void setNonPrincipalColor(int nonPrincipalColor) {
+	this.nonPrincipalColor = nonPrincipalColor;
+    }
+
+    /**
+     * Get the size of the line section in principal mode.
+     *
+     * @return the size of the line
+     */
+    public float getPrincipalLineSize() {
+	return principalLineSize;
+    }
+
+    /**
+     * Set the size of the line section in principal mode.
+     *
+     * @param principalLineSize the size of the line
+     */
+    public void setPrincipalLineSize(float principalLineSize) {
+	this.principalLineSize = principalLineSize;
+    }
+
+    /**
+     * Get the size of the line section when not in principal mode.
+     *
+     * @return the size of the line
+     */
+    public float getNonPrincipalLineSize() {
+	return nonPrincipalLineSize;
+    }
+
+    /**
+     * Set the size of the line section when not in principal mode.
+     *
+     * @param nonPrincipalLineSize the size of the line
+     */
+    public void setNonPrincipalLineSize(float nonPrincipalLineSize) {
+	this.nonPrincipalLineSize = nonPrincipalLineSize;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+	super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+	int height = getMeasuredHeight();
+	height += Math.max(principalLineSize, nonPrincipalLineSize)
+	    + SECTION_SPACE_SIZE * density; // line width + space
+	setMeasuredDimension(getMeasuredWidth(), height);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+	super.onDraw(canvas);
+	if (isPrincipal()) {
+	    sectionPaint.setColor(principalColor);
+	    sectionPaint.setStrokeWidth(principalLineSize);
+	    canvas.drawLine(0, getHeight() - principalLineSize / 2,
+		    getWidth(), getHeight() - principalLineSize / 2, sectionPaint);
+	} else {
+	    sectionPaint.setColor(nonPrincipalColor);
+	    sectionPaint.setStrokeWidth(nonPrincipalLineSize);
+	    canvas.drawLine(0, getHeight() - nonPrincipalLineSize / 2, getWidth(),
+		    getHeight() - nonPrincipalLineSize / 2, sectionPaint);
+	}
+    }
+
+    /**
+     * Initialize the SectionTextView with the default value.
+     */
+    private void initSectionTextView() {
+	density = getResources().getDisplayMetrics().density;
+	sectionPaint = new Paint();
+	principalColor = DEFAULT_PRINCIPAL_COLOR;
+	principalLineSize = DEFAULT_PRINCIPAL_LINE_SIZE * density;
+	nonPrincipalColor = DEFAULT_NON_PRINCIPAL_COLOR;
+	nonPrincipalLineSize = DEFAULT_NON_PRINCIPAL_LINE_SIZE * density;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/views/package-info.java	Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,31 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009-2011 by Frederic-Charles Barthelery,
+                               Nikita Kozlov,
+                               Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://www.beem-project.com/
+
+*/
+/**
+ * This package contains the custom View used by Beem to make the user interfaces.
+ */
+package com.beem.project.beem.ui.views;
+
--- a/src/com/beem/project/beem/utils/Status.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/com/beem/project/beem/utils/Status.java	Tue Jun 05 16:44:38 2012 +0200
@@ -43,6 +43,8 @@
 */
 package com.beem.project.beem.utils;
 
+import com.beem.project.beem.R;
+
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.packet.Presence.Mode;
 
@@ -153,4 +155,32 @@
 	return status != Status.CONTACT_STATUS_DISCONNECT;
     }
 
+    /**
+     * Get icon resource from status.
+     * @param status the status
+     * @return the resource icon
+     */
+    public static int getIconBarFromStatus(final int status) {
+	int icon = R.drawable.beem_status_icon;
+	switch (status) {
+	    case Status.CONTACT_STATUS_AVAILABLE:
+		icon = R.drawable.beem_status_icon_available;
+		break;
+	    case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
+		icon = R.drawable.beem_status_icon_available;
+		break;
+	    case Status.CONTACT_STATUS_AWAY:
+		icon = R.drawable.beem_status_icon_away;
+		break;
+	    case Status.CONTACT_STATUS_BUSY:
+		icon = R.drawable.beem_status_icon_busy;
+		break;
+	    case Status.CONTACT_STATUS_UNAVAILABLE:
+		icon = R.drawable.beem_status_icon_gray;
+		break;
+	    default:
+		icon = R.drawable.beem_status_icon;
+	}
+	return icon;
+    }
 }
--- a/src/de/duenndns/ssl/MemorizingTrustManager.java	Tue Jun 05 16:29:25 2012 +0200
+++ b/src/de/duenndns/ssl/MemorizingTrustManager.java	Tue Jun 05 16:44:38 2012 +0200
@@ -31,12 +31,9 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.Service;
-import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.Uri;
@@ -47,7 +44,7 @@
 import java.security.cert.*;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.security.MessageDigest;
 import java.util.HashMap;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
@@ -80,9 +77,10 @@
 	static String KEYSTORE_FILE = "KeyStore.bks";
 
 	Context master;
+	Activity foregroundAct;
 	NotificationManager notificationManager;
 	private static int decisionId = 0;
-	private static HashMap<Integer,MTMDecision> openDecisions = new HashMap();
+	private static HashMap<Integer, MTMDecision> openDecisions = new HashMap<Integer, MTMDecision>();
 
 	Handler masterHandler;
 	private File keyStoreFile;
@@ -92,15 +90,25 @@
 
 	/** Creates an instance of the MemorizingTrustManager class.
 	 *
-	 * @param m Activity or Service to show the Dialog / Notification
+	 * You need to supply the application context. This has to be one of:
+	 *    - Application
+	 *    - Activity
+	 *    - Service
+	 *
+	 * The context is used for file management, to display the dialog /
+	 * notification and for obtaining translated strings.
+	 *
+	 * @param m Context for the application.
 	 */
-	private MemorizingTrustManager(Context m) {
+	public MemorizingTrustManager(Context m) {
 		master = m;
 		masterHandler = new Handler();
 		notificationManager = (NotificationManager)master.getSystemService(Context.NOTIFICATION_SERVICE);
 
 		Application app;
-		if (m instanceof Service) {
+		if (m instanceof Application) {
+			app = (Application)m;
+		} else if (m instanceof Service) {
 			app = ((Service)m).getApplication();
 		} else if (m instanceof Activity) {
 			app = ((Activity)m).getApplication();
@@ -134,6 +142,36 @@
 	}
 
 	/**
+	 * Binds an Activity to the MTM for displaying the query dialog.
+	 *
+	 * This is useful if your connection is run from a service that is
+	 * triggered by user interaction -- in such cases the activity is
+	 * visible and the user tends to ignore the service notification.
+	 *
+	 * You should never have a hidden activity bound to MTM! Use this
+	 * function in onResume() and @see unbindDisplayActivity in onPause().
+	 *
+	 * @param act Activity to be bound
+	 */
+	public void bindDisplayActivity(Activity act) {
+		foregroundAct = act;
+	}
+
+	/**
+	 * Removes an Activity from the MTM display stack.
+	 *
+	 * Always call this function when the Activity added with
+	 * @see bindDisplayActivity is hidden.
+	 *
+	 * @param act Activity to be unbound
+	 */
+	public void unbindDisplayActivity(Activity act) {
+		// do not remove if it was overridden by a different activity
+		if (foregroundAct == act)
+			foregroundAct = null;
+	}
+
+	/**
 	 * Changes the path for the KeyStore file.
 	 *
 	 * The actual filename relative to the app's directory will be
@@ -207,6 +245,15 @@
 		}
 	}
 
+	// if the certificate is stored in the app key store, it is considered "known"
+	private boolean isCertKnown(X509Certificate cert) {
+		try {
+			return appKeyStore.getCertificateAlias(cert) != null;
+		} catch (KeyStoreException e) {
+			return false;
+		}
+	}
+
 	private boolean isExpiredException(Throwable e) {
 		do {
 			if (e instanceof CertificateExpiredException)
@@ -233,6 +280,10 @@
 				Log.i(TAG, "checkCertTrusted: accepting expired certificate from keystore");
 				return;
 			}
+			if (isCertKnown(chain[0])) {
+				Log.i(TAG, "checkCertTrusted: accepting cert already stored in keystore");
+				return;
+			}
 			try {
 				Log.d(TAG, "checkCertTrusted: trying defaultTrustManager");
 				if (isServer)
@@ -274,6 +325,28 @@
 		return myId;
 	}
 
+	private static String hexString(byte[] data) {
+		StringBuffer si = new StringBuffer();
+		for (int i = 0; i < data.length; i++) {
+			si.append(String.format("%02x", data[i]));
+			if (i < data.length - 1)
+				si.append(":");
+		}
+		return si.toString();
+	}
+
+	private static String certHash(final X509Certificate cert, String digest) {
+		try {
+			MessageDigest md = MessageDigest.getInstance(digest);
+			md.update(cert.getEncoded());
+			return hexString(md.digest());
+		} catch (java.security.cert.CertificateEncodingException e) {
+			return e.getMessage();
+		} catch (java.security.NoSuchAlgorithmException e) {
+			return e.getMessage();
+		}
+	}
+
 	private String certChainMessage(final X509Certificate[] chain, CertificateException cause) {
 		Throwable e = cause;
 		Log.d(TAG, "certChainMessage for " + e);
@@ -281,14 +354,17 @@
 		if (e.getCause() != null) {
 			e = e.getCause();
 			si.append(e.getLocalizedMessage());
-			si.append("\n");
+			//si.append("\n");
 		}
 		for (X509Certificate c : chain) {
-			si.append("\n");
+			si.append("\n\n");
 			si.append(c.getSubjectDN().toString());
-			si.append(" (");
+			si.append("\nMD5: ");
+			si.append(certHash(c, "MD5"));
+			si.append("\nSHA1: ");
+			si.append(certHash(c, "SHA-1"));
+			si.append("\nSigned by: ");
 			si.append(c.getIssuerDN().toString());
-			si.append(")");
 		}
 		return si.toString();
 	}
@@ -305,7 +381,16 @@
 		notificationManager.notify(NOTIFICATION_ID, n);
 	}
 
-	void launchServiceMode(Intent activityIntent, final String certMessage) {
+	/**
+	 * Returns the top-most entry of the activity stack.
+	 *
+	 * @return the Context of the currently bound UI or the master context if none is bound
+	 */
+	Context getUI() {
+		return (foregroundAct != null) ? foregroundAct : master;
+	}
+
+	BroadcastReceiver launchServiceMode(Intent activityIntent, final String certMessage) {
 		BroadcastReceiver launchNotifReceiver= new BroadcastReceiver() {
 		    public void onReceive(Context ctx, Intent i) {
 			Log.i(TAG, "Interception not done by the application. Send notification");
@@ -318,7 +403,7 @@
 		Intent ni = new Intent(INTERCEPT_DECISION_INTENT + "/" + master.getPackageName());
 		ni.putExtra(INTERCEPT_DECISION_INTENT_LAUNCH, call);
 		master.sendOrderedBroadcast(ni, null);
-
+		return launchNotifReceiver;
 	}
 
 	void interact(final X509Certificate[] chain, String authType, CertificateException cause)
@@ -327,29 +412,13 @@
 		/* prepare the MTMDecision blocker object */
 		MTMDecision choice = new MTMDecision();
 		final int myId = createDecisionId(choice);
-		final String certTitle = chain[0].getSubjectDN().toString();
 		final String certMessage = certChainMessage(chain, cause);
-
 		BroadcastReceiver decisionReceiver = new BroadcastReceiver() {
 			public void onReceive(Context ctx, Intent i) { interactResult(i); }
 		};
 		master.registerReceiver(decisionReceiver, new IntentFilter(DECISION_INTENT + "/" + master.getPackageName()));
-		masterHandler.post(new Runnable() {
-			public void run() {
-				Intent ni = new Intent(master, MemorizingActivity.class);
-				ni.setData(Uri.parse(MemorizingTrustManager.class.getName() + "/" + myId));
-				ni.putExtra(DECISION_INTENT_APP, master.getPackageName());
-				ni.putExtra(DECISION_INTENT_ID, myId);
-				ni.putExtra(DECISION_INTENT_CERT, certMessage);
-
-				try {
-					master.startActivity(ni);
-				} catch (Exception e) {
-					Log.e(TAG, "startActivity: " + e);
-					launchServiceMode(ni, certMessage);
-				}
-			}
-		});
+		LaunchRunnable lr = new LaunchRunnable(myId, certMessage);
+		masterHandler.post(lr);
 
 		Log.d(TAG, "openDecisions: " + openDecisions);
 		Log.d(TAG, "waiting on " + myId);
@@ -359,6 +428,8 @@
 			e.printStackTrace();
 		}
 		master.unregisterReceiver(decisionReceiver);
+		if (lr.launchNotifReceiver != null)
+			master.unregisterReceiver(lr.launchNotifReceiver);
 		Log.d(TAG, "finished wait on " + myId + ": " + choice.state);
 		switch (choice.state) {
 		case MTMDecision.DECISION_ALWAYS:
@@ -381,10 +452,42 @@
 			 d = openDecisions.get(decisionId);
 			 openDecisions.remove(decisionId);
 		}
+		if (d == null) {
+			Log.e(TAG, "interactResult: aborting due to stale decision reference!");
+			return;
+		}
 		synchronized(d) {
 			d.state = choice;
 			d.notify();
 		}
 	}
 
+	private class LaunchRunnable implements Runnable {
+		private int myId;
+		private String certMessage;
+		BroadcastReceiver launchNotifReceiver;
+		
+		public LaunchRunnable(final int id, final String certMsg) {
+			myId = id;
+			certMessage = certMsg;
+		}
+		
+		public void run() {
+			Intent ni = new Intent(master, MemorizingActivity.class);
+			ni.setData(Uri.parse(MemorizingTrustManager.class.getName() + "/" + myId));
+			ni.putExtra(DECISION_INTENT_APP, master.getPackageName());
+			ni.putExtra(DECISION_INTENT_ID, myId);
+			ni.putExtra(DECISION_INTENT_CERT, certMessage);
+
+			// we try to directly start the activity and fall back to
+			// making a notification
+			try {
+				getUI().startActivity(ni);
+			} catch (Exception e) {
+				Log.e(TAG, "startActivity: " + e);
+				launchNotifReceiver = launchServiceMode(ni, certMessage);
+			}
+		}
+	}
+	
 }