diff --git a/configure.ac b/configure.ac
index d784ba4..6e37384 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,7 @@ MISSION_CONTROL_REQUIRED=4.61
 ENCHANT_REQUIRED=1.2.0
 ISO_CODES_REQUIRED=0.35
 LIBNOTIFY_REQUIRED=0.4.4
+GEOCLUE_REQUIRED=0.11
 
 # Uncomment that to build with deprecated symbols disabled
 #AC_DEFINE(G_DISABLE_DEPRECATED, [], [Disable deprecated GLib symbols])
@@ -178,6 +179,35 @@ fi
 AM_CONDITIONAL(HAVE_ENCHANT, test "x$have_enchant" = "xyes")
 
 # -----------------------------------------------------------
+# location checks: geoclue
+# -----------------------------------------------------------
+AC_ARG_ENABLE(location,
+              AS_HELP_STRING([--enable-location=@<:@no/yes/auto@:>@],
+                             [Enable location awareness]), ,
+                             enable_location=auto)
+
+if test "x$enable_location" != "xno"; then
+   PKG_CHECK_MODULES(GEOCLUE,
+   [
+      geoclue >= $GEOCLUE_REQUIRED
+   ], have_geoclue="yes", have_geoclue="no")
+
+   if test "x$have_geoclue" = "xyes"; then
+      AC_DEFINE(HAVE_GEOCLUE, 1, [Define if you have geoclue])
+   else
+       have_geoclue="no"
+   fi
+else
+   have_geoclue=no
+fi
+
+if test "x$enable_map" = "xyes" -a "x$have_geoclue" != "xyes"; then
+   AC_MSG_ERROR([Couldn't find location dependencies.])
+fi
+
+AM_CONDITIONAL(HAVE_GEOCLUE, test "x$have_geoclue" = "xyes")
+
+# -----------------------------------------------------------
 # Megaphone
 # -----------------------------------------------------------
 AC_ARG_ENABLE(megaphone,
diff --git a/data/empathy.schemas.in b/data/empathy.schemas.in
index 62b462f..c0fff4a 100644
--- a/data/empathy.schemas.in
+++ b/data/empathy.schemas.in
@@ -463,5 +463,91 @@
       </locale>
     </schema>
 
-  </schemalist>  
+    <schema>
+      <key>/schemas/apps/empathy/location/publish</key>
+      <applyto>/apps/empathy/location/publish</applyto>
+      <owner>empathy</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Empathy can publish the user's location</short>
+        <long>
+        Whether or not Empathy can publish the user's location to its contacts. 
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/empathy/location/method</key>
+      <applyto>/apps/empathy/location/method</applyto>
+      <owner>empathy</owner>
+      <type>string</type>
+      <default>automatic</default>
+      <locale name="C">
+        <short>How Empathy should determine the user's location</short>
+        <long>
+        How Empathy determines the user's location.  A value of "automatic" means that 
+        Empathy will try to guess the user's location, a value of "manual" 
+        means that the user has specified a location.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/empathy/location/resource_network</key>
+      <applyto>/apps/empathy/location/resource_network</applyto>
+      <owner>empathy</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+        <short>Empathy can use the network to guess the location</short>
+        <long>
+        Whether or not Empathy can use the network to guess the location.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/empathy/location/resource_cell</key>
+      <applyto>/apps/empathy/location/resource_cell</applyto>
+      <owner>empathy</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+        <short>Empathy can use the cellular network to guess the location</short>
+        <long>
+        Whether or not Empathy can use the cellular network to guess the location.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/empathy/location/resource_gps</key>
+      <applyto>/apps/empathy/location/resource_gps</applyto>
+      <owner>empathy</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Empathy can use the GPS to guess the location</short>
+        <long>
+        Whether or not Empathy can use the GPS to guess the location.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/empathy/location/reduce_accuracy</key>
+      <applyto>/apps/empathy/location/reduce_accuracy</applyto>
+      <owner>empathy</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Empathy should reduce the location's accuracy</short>
+        <long>
+        Whether or not Empathy should reduce the location's accuracy for privacy reasons.
+        </long>
+      </locale>
+    </schema>
+
+  </schemalist>
 </gconfschemafile>
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 46d0316..15b07dc 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -5,6 +5,7 @@ AM_CPPFLAGS =                                           \
 	-DPKGDATADIR=\""$(pkgdatadir)"\"		\
 	$(EMPATHY_CFLAGS)				\
 	$(ENCHANT_CFLAGS)				\
+	$(GEOCLUE_CFLAGS)				\
 	$(WARN_CFLAGS)
 
 BUILT_SOURCES = 					\
@@ -42,6 +43,7 @@ libempathy_gtk_la_SOURCES =             	\
 	empathy-video-src.c			\
 	empathy-video-widget.c			\
 	empathy-irc-network-dialog.c		\
+	empathy-location-manager.c		\
 	empathy-log-window.c			\
 	empathy-new-message-dialog.c		\
 	empathy-presence-chooser.c		\
@@ -62,6 +64,7 @@ nodist_libempathy_gtk_la_SOURCES =\
 libempathy_gtk_la_LIBADD =			\
 	$(EMPATHY_LIBS)				\
 	$(ENCHANT_LIBS)				\
+	$(GEOCLUE_LIBS)				\
 	$(top_builddir)/libempathy/libempathy.la
 
 libempathy_gtk_la_LDFLAGS =                \
@@ -95,6 +98,7 @@ libempathy_gtk_headers =			\
 	empathy-video-widget.h			\
 	empathy-images.h			\
 	empathy-irc-network-dialog.h		\
+	empathy-location-manager.h		\
 	empathy-log-window.h			\
 	empathy-new-message-dialog.h		\
 	empathy-presence-chooser.h		\
diff --git a/libempathy-gtk/empathy-conf.h b/libempathy-gtk/empathy-conf.h
index 2051a7f..6f484fe 100644
--- a/libempathy-gtk/empathy-conf.h
+++ b/libempathy-gtk/empathy-conf.h
@@ -77,6 +77,12 @@ struct _EmpathyConfClass {
 #define EMPATHY_PREFS_AUTOCONNECT                  EMPATHY_PREFS_PATH "/autoconnect"
 #define EMPATHY_PREFS_IMPORT_ASKED                 EMPATHY_PREFS_PATH "/import_asked"
 #define EMPATHY_PREFS_FILE_TRANSFER_DEFAULT_FOLDER EMPATHY_PREFS_PATH "/file_transfer/default_folder"
+#define EMPATHY_PREFS_LOCATION_PUBLISH             EMPATHY_PREFS_PATH "/location/publish"
+#define EMPATHY_PREFS_LOCATION_METHOD              EMPATHY_PREFS_PATH "/location/method"
+#define EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK    EMPATHY_PREFS_PATH "/location/resource_network"
+#define EMPATHY_PREFS_LOCATION_RESOURCE_CELL       EMPATHY_PREFS_PATH "/location/resource_cell"
+#define EMPATHY_PREFS_LOCATION_RESOURCE_GPS        EMPATHY_PREFS_PATH "/location/resource_gps"
+#define EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY     EMPATHY_PREFS_PATH "/location/reduce_accuracy"
 
 typedef void (*EmpathyConfNotifyFunc) (EmpathyConf  *conf, 
 				      const gchar *key,
diff --git a/libempathy-gtk/empathy-location-manager.c b/libempathy-gtk/empathy-location-manager.c
new file mode 100644
index 0000000..9da3964
--- /dev/null
+++ b/libempathy-gtk/empathy-location-manager.c
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <time.h>
+
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/util.h>
+
+#if HAVE_GEOCLUE
+#include <geoclue/geoclue-master.h>
+
+#include <extensions/extensions.h>
+
+#include "empathy-location-manager.h"
+#include "empathy-conf.h"
+
+#include "libempathy/empathy-account-manager.h"
+#include "libempathy/empathy-enum-types.h"
+#include "libempathy/empathy-location.h"
+#include "libempathy/empathy-tp-contact-factory.h"
+#include "libempathy/empathy-utils.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_LOCATION
+#include "libempathy/empathy-debug.h"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLocationManager)
+typedef struct {
+    gboolean is_setup;
+    MissionControl *mc;
+    GHashTable *location;
+    gpointer token;
+
+    GeoclueResourceFlags resources;
+    GeoclueMasterClient *gc_client;
+    GeocluePosition *gc_position;
+    GeoclueAddress *gc_address;
+
+    gboolean reduce_accuracy;
+    gdouble reduce_value;
+    EmpathyAccountManager *account_manager;
+} EmpathyLocationManagerPriv;
+
+static void location_manager_finalize (GObject *object);
+static void location_manager_get_property (GObject *object, guint param_id,
+    GValue *value, GParamSpec *pspec);
+static void location_manager_set_property (GObject *object, guint param_id,
+    const GValue *value, GParamSpec *pspec);
+static void position_changed_cb (GeocluePosition *position,
+    GeocluePositionFields fields, int timestamp, double latitude,
+    double longitude, double altitude, GeoclueAccuracy *accuracy,
+    gpointer user_data);
+static void address_changed_cb (GeoclueAddress *address, int timestamp,
+    GHashTable *details, GeoclueAccuracy *accuracy, gpointer user_data);
+static void setup_geoclue (EmpathyLocationManager *location_manager);
+static void publish_cb (EmpathyConf  *conf, const gchar *key,
+    gpointer user_data);
+static void update_resources (EmpathyLocationManager *location_manager);
+static void resource_cb (EmpathyConf  *conf, const gchar *key,
+    gpointer user_data);
+static void accuracy_cb (EmpathyConf  *conf, const gchar *key,
+    gpointer user_data);
+static void account_connection_changed_cb (EmpathyAccountManager *manager,
+    McAccount *account, TpConnectionStatusReason reason,
+    TpConnectionStatus current, TpConnectionStatus previous,
+    gpointer *location_manager);
+
+G_DEFINE_TYPE (EmpathyLocationManager, empathy_location_manager, G_TYPE_OBJECT);
+
+enum
+{
+  PROP_0,
+};
+
+static void
+empathy_location_manager_class_init (EmpathyLocationManagerClass *class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = location_manager_finalize;
+  object_class->get_property = location_manager_get_property;
+  object_class->set_property = location_manager_set_property;
+
+  g_type_class_add_private (object_class, sizeof (EmpathyLocationManagerPriv));
+}
+
+static void
+publish_location (EmpathyLocationManager *location_manager,
+                  McAccount *account,
+                  gboolean force_publication)
+{
+  EmpathyLocationManagerPriv *priv;
+  guint connection_status = -1;
+  gboolean can_publish;
+  EmpathyConf *conf = empathy_conf_get ();
+  TpConnection *conn;
+  EmpathyTpContactFactory *factory;
+
+  priv = GET_PRIV (location_manager);
+
+  conn = mission_control_get_tpconnection (priv->mc, account, NULL);
+  if (!conn)
+    return;
+
+  factory = empathy_tp_contact_factory_dup_singleton (conn);
+
+  if (force_publication == FALSE)
+    {
+      if (!empathy_conf_get_bool (conf, EMPATHY_PREFS_LOCATION_PUBLISH,
+            &can_publish))
+        return;
+
+      if (can_publish == FALSE)
+        return;
+    }
+
+  connection_status = mission_control_get_connection_status (priv->mc,
+      account, NULL);
+
+  if (connection_status != TP_CONNECTION_STATUS_CONNECTED)
+    return;
+
+  DEBUG ("Publishing location to account %s",
+      mc_account_get_display_name (account));
+
+  empathy_tp_contact_factory_set_location (factory, priv->location);
+  g_object_unref (factory);
+}
+
+static void
+publish_location_to_all_accounts (EmpathyLocationManager *location_manager,
+                                  gboolean force_publication)
+{
+  GList *accounts = NULL, *l;
+
+  accounts = mc_accounts_list_by_enabled (TRUE);
+  for (l = accounts; l; l = l->next)
+    {
+      publish_location (location_manager, l->data, force_publication);
+    }
+
+  mc_accounts_list_free (accounts);
+}
+
+static void
+account_connection_changed_cb (EmpathyAccountManager *manager,
+                               McAccount *account,
+                               TpConnectionStatusReason reason,
+                               TpConnectionStatus current,
+                               TpConnectionStatus previous,
+                               gpointer *location_manager)
+{
+  DEBUG ("Account %s changed status from %d to %d", mc_account_get_display_name (account),
+      previous, current);
+
+  if (account && current == TP_CONNECTION_STATUS_CONNECTED)
+    publish_location (EMPATHY_LOCATION_MANAGER (location_manager), account,
+        FALSE);
+}
+
+static void
+empathy_location_manager_init (EmpathyLocationManager *location_manager)
+{
+  EmpathyConf               *conf;
+  EmpathyLocationManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (location_manager,
+      EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerPriv);
+
+  location_manager->priv = priv;
+  priv->is_setup = FALSE;
+  priv->mc = empathy_mission_control_dup_singleton ();
+  priv->location = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+      g_free, (GDestroyNotify) tp_g_value_slice_free);
+
+  // Setup settings status callbacks
+  conf = empathy_conf_get ();
+  empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_PUBLISH, publish_cb,
+      location_manager);
+  empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK,
+      resource_cb, location_manager);
+  empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_CELL,
+      resource_cb, location_manager);
+  empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_GPS,
+      resource_cb, location_manager);
+  empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY,
+      accuracy_cb, location_manager);
+
+  resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK, location_manager);
+  resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_CELL, location_manager);
+  resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_GPS, location_manager);
+  accuracy_cb (conf, EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY, location_manager);
+  publish_cb (conf, EMPATHY_PREFS_LOCATION_PUBLISH, location_manager);
+
+  // Setup account status callbacks
+  priv->account_manager = empathy_account_manager_dup_singleton ();
+  g_signal_connect (priv->account_manager,
+    "account-connection-changed",
+    G_CALLBACK (account_connection_changed_cb), location_manager);
+}
+
+
+static void
+location_manager_finalize (GObject *object)
+{
+  EmpathyLocationManagerPriv *priv;
+
+  priv = GET_PRIV (object);
+
+  DEBUG ("finalize: %p", object);
+  g_object_unref (priv->account_manager);
+
+  G_OBJECT_CLASS (empathy_location_manager_parent_class)->finalize (object);
+}
+
+
+static void
+location_manager_get_property (GObject *object,
+                      guint param_id,
+                      GValue *value,
+                      GParamSpec *pspec)
+{
+  EmpathyLocationManagerPriv *priv;
+
+  priv = GET_PRIV (object);
+
+  switch (param_id)
+    {
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        break;
+    };
+}
+
+
+static void
+location_manager_set_property (GObject *object,
+                      guint param_id,
+                      const GValue *value,
+                      GParamSpec *pspec)
+{
+  EmpathyLocationManagerPriv *priv;
+
+  priv = GET_PRIV (object);
+
+  switch (param_id)
+    {
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        break;
+    };
+}
+
+
+EmpathyLocationManager *
+empathy_location_manager_get_default (void)
+{
+  static EmpathyLocationManager *singleton = NULL;
+  if (singleton == NULL)
+    singleton = g_object_new (EMPATHY_TYPE_LOCATION_MANAGER, NULL);
+  return singleton;
+}
+
+static void
+update_timestamp (EmpathyLocationManager *location_manager,
+                  int timestamp)
+{
+  EmpathyLocationManagerPriv *priv;
+  priv = GET_PRIV (location_manager);
+  GValue *new_value;
+  gint64 stamp64 = (gint64) timestamp;
+
+  new_value = tp_g_value_slice_new (G_TYPE_INT64);
+  g_value_set_int64 (new_value, stamp64);
+  g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_TIMESTAMP),
+      new_value);
+  DEBUG ("\t - Timestamp: %" G_GINT64_FORMAT, stamp64);
+}
+
+static void
+initial_position_cb (GeocluePosition *position,
+                     GeocluePositionFields fields,
+                     int timestamp,
+                     double latitude,
+                     double longitude,
+                     double altitude,
+                     GeoclueAccuracy *accuracy,
+                     GError *error,
+                     gpointer location_manager)
+{
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      g_error_free (error);
+    }
+  else
+    position_changed_cb (position, fields, timestamp, latitude, longitude,
+      altitude, accuracy, location_manager);
+}
+
+static void
+position_changed_cb (GeocluePosition *position,
+                     GeocluePositionFields fields,
+                     int timestamp,
+                     double latitude,
+                     double longitude,
+                     double altitude,
+                     GeoclueAccuracy *accuracy,
+                     gpointer location_manager)
+{
+  EmpathyLocationManagerPriv *priv;
+  priv = GET_PRIV (location_manager);
+  GeoclueAccuracyLevel level;
+  gdouble mean, horizontal, vertical;
+  GValue *new_value;
+
+  geoclue_accuracy_get_details (accuracy, &level, &horizontal, &vertical);
+  DEBUG ("New position (accuracy level %d)", level);
+  if (level == GEOCLUE_ACCURACY_LEVEL_NONE)
+    return;
+
+  if (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)
+    {
+      longitude += priv->reduce_value;
+      new_value = tp_g_value_slice_new (G_TYPE_DOUBLE);
+      g_value_set_double (new_value, longitude);
+      g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_LON),
+          new_value);
+      DEBUG ("\t - Longitude: %f", longitude);
+    }
+  if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)
+    {
+      latitude += priv->reduce_value;
+      new_value = tp_g_value_slice_new (G_TYPE_DOUBLE);
+      g_value_set_double (new_value, latitude);
+      g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_LAT),
+          new_value);
+      DEBUG ("\t - Latitude: %f", latitude);
+    }
+  if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
+    {
+      new_value = tp_g_value_slice_new (G_TYPE_DOUBLE);
+      g_value_set_double (new_value, altitude);
+      g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_ALT),
+          new_value);
+      DEBUG ("\t - Altitude: %f", altitude);
+    }
+
+  if (level == GEOCLUE_ACCURACY_LEVEL_DETAILED)
+    {
+      mean = (horizontal + vertical) / 2.0;
+      new_value = tp_g_value_slice_new (G_TYPE_DOUBLE);
+      g_value_set_double (new_value, mean);
+      g_hash_table_insert (priv->location,
+          g_strdup (EMPATHY_LOCATION_ACCURACY), new_value);
+      DEBUG ("\t - Accuracy: %f", mean);
+    }
+
+  update_timestamp (location_manager, timestamp);
+  publish_location_to_all_accounts (EMPATHY_LOCATION_MANAGER (location_manager),
+      FALSE);
+}
+
+
+static void
+address_foreach_cb (gpointer key,
+                    gpointer value,
+                    gpointer location_manager)
+{
+  if (location_manager == NULL)
+    return;
+
+  EmpathyLocationManagerPriv *priv;
+  priv = GET_PRIV (location_manager);
+
+  // Discard street information if reduced accuracy is on
+  if (priv->reduce_accuracy && strcmp (key, EMPATHY_LOCATION_STREET) == 0)
+    return;
+
+  GValue *new_value = tp_g_value_slice_new (G_TYPE_STRING);
+  g_value_set_string (new_value, value);
+
+  g_hash_table_insert (priv->location, g_strdup (key), new_value);
+  DEBUG ("\t - %s: %s", (char*) key, (char*) value);
+}
+
+static void
+initial_address_cb (GeoclueAddress *address,
+                    int timestamp,
+                    GHashTable *details,
+                    GeoclueAccuracy *accuracy,
+                    GError *error,
+                    gpointer location_manager)
+{
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      g_error_free (error);
+    }
+  else
+    address_changed_cb (address, timestamp, details, accuracy, location_manager);
+}
+
+static void
+address_changed_cb (GeoclueAddress *address,
+                    int timestamp,
+                    GHashTable *details,
+                    GeoclueAccuracy *accuracy,
+                    gpointer location_manager)
+{
+  GeoclueAccuracyLevel level;
+  geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+  EmpathyLocationManagerPriv *priv;
+
+  DEBUG ("New address (accuracy level %d):", level);
+
+  priv = GET_PRIV (location_manager);
+  g_hash_table_remove_all (priv->location);
+
+  g_hash_table_foreach (details, address_foreach_cb, (gpointer)location_manager);
+
+  update_timestamp (location_manager, timestamp);
+  publish_location_to_all_accounts (EMPATHY_LOCATION_MANAGER (location_manager),
+      FALSE);
+}
+
+
+static void
+update_resources (EmpathyLocationManager *location_manager)
+{
+  EmpathyLocationManagerPriv *priv;
+
+  priv = GET_PRIV (location_manager);
+
+  DEBUG ("Updating resources");
+
+  if (!geoclue_master_client_set_requirements (priv->gc_client,
+          GEOCLUE_ACCURACY_LEVEL_LOCALITY, 0, TRUE, priv->resources,
+          NULL))
+    {
+      g_printerr ("set_requirements failed");
+      return;
+    }
+
+  if (!priv->is_setup)
+    return;
+
+  geoclue_address_get_address_async (priv->gc_address,
+      initial_address_cb, location_manager);
+  geoclue_position_get_position_async (priv->gc_position,
+      initial_position_cb, location_manager);
+
+}
+
+
+static void
+setup_geoclue (EmpathyLocationManager *location_manager)
+{
+  EmpathyLocationManagerPriv *priv;
+
+  priv = GET_PRIV (location_manager);
+
+  GeoclueMaster *master;
+  GError *error = NULL;
+
+  DEBUG ("Setting up Geoclue");
+  master = geoclue_master_get_default ();
+  priv->gc_client = geoclue_master_create_client (master, NULL, NULL);
+  g_object_unref (master);
+
+  update_resources (location_manager);
+
+  /* Get updated when the position is changes */
+  priv->gc_position = geoclue_master_client_create_position (
+      priv->gc_client, &error);
+  if (priv->gc_position == NULL)
+    {
+      g_printerr ("Failed to create GeocluePosition: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_signal_connect (G_OBJECT (priv->gc_position), "position-changed",
+      G_CALLBACK (position_changed_cb), location_manager);
+
+  /* Get updated when the address changes */
+  priv->gc_address = geoclue_master_client_create_address (
+      priv->gc_client, &error);
+  if (priv->gc_address == NULL)
+    {
+      g_printerr ("Failed to create GeoclueAddress: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_signal_connect (G_OBJECT (priv->gc_address), "address-changed",
+      G_CALLBACK (address_changed_cb), location_manager);
+
+  priv->is_setup = TRUE;
+}
+
+static void
+publish_cb (EmpathyConf *conf,
+            const gchar *key,
+            gpointer user_data)
+{
+  EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
+  EmpathyLocationManagerPriv *priv;
+  gboolean can_publish;
+
+  DEBUG ("Publish Conf changed");
+  priv = GET_PRIV (manager);
+  if (!empathy_conf_get_bool (conf, key, &can_publish))
+    return;
+
+  if (can_publish)
+    {
+      if (!priv->is_setup)
+        setup_geoclue (manager);
+      geoclue_address_get_address_async (priv->gc_address,
+          initial_address_cb, manager);
+      geoclue_position_get_position_async (priv->gc_position,
+          initial_position_cb, manager);
+      publish_location_to_all_accounts (manager, FALSE);
+    }
+  else
+    {
+      /* As per XEP-0080: send an empty location to have remove current
+       * location from the servers
+       */
+      g_hash_table_remove_all (priv->location);
+      publish_location_to_all_accounts (manager, TRUE);
+    }
+
+}
+
+
+static void
+accuracy_cb (EmpathyConf  *conf,
+             const gchar *key,
+             gpointer user_data)
+{
+  EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
+  EmpathyLocationManagerPriv *priv;
+
+  gboolean enabled;
+
+  priv = GET_PRIV (manager);
+  DEBUG ("%s changed", key);
+
+  if (!empathy_conf_get_bool (conf, key, &enabled))
+    return;
+  priv->reduce_accuracy = enabled;
+
+  if (enabled)
+    {
+      GRand *rand = g_rand_new_with_seed (time (NULL));
+      priv->reduce_value = g_rand_double_range (rand, -0.25, 0.25);
+      g_rand_free (rand);
+    }
+  else
+    priv->reduce_value = 0.0;
+
+  if (!priv->is_setup)
+    return;
+
+  geoclue_address_get_address_async (priv->gc_address,
+      initial_address_cb, manager);
+  geoclue_position_get_position_async (priv->gc_position,
+      initial_position_cb, manager);
+}
+
+static void
+resource_cb (EmpathyConf  *conf,
+             const gchar *key,
+             gpointer user_data)
+{
+  EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
+  EmpathyLocationManagerPriv *priv;
+  GeoclueResourceFlags resource = 0;
+  gboolean resource_enabled;
+
+  priv = GET_PRIV (manager);
+  DEBUG ("%s changed", key);
+
+  if (!empathy_conf_get_bool (conf, key, &resource_enabled))
+    return;
+
+  if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK) == 0)
+    resource = GEOCLUE_RESOURCE_NETWORK;
+  if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_CELL) == 0)
+    resource = GEOCLUE_RESOURCE_CELL;
+  if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_GPS) == 0)
+    resource = GEOCLUE_RESOURCE_GPS;
+
+  if (resource_enabled)
+    priv->resources |= resource;
+  else
+    priv->resources &= ~resource;
+
+  if (priv->is_setup)
+    update_resources (manager);
+}
+
+#endif
diff --git a/libempathy-gtk/empathy-location-manager.h b/libempathy-gtk/empathy-location-manager.h
new file mode 100644
index 0000000..937e268
--- /dev/null
+++ b/libempathy-gtk/empathy-location-manager.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ */
+
+#ifndef __EMPATHY_LOCATION_MANAGER_H__
+#define __EMPATHY_LOCATION_MANAGER_H__
+
+#include <glib-object.h>
+
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_LOCATION_MANAGER         (empathy_location_manager_get_type ())
+#define EMPATHY_LOCATION_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManager))
+#define EMPATHY_LOCATION_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerClass))
+#define EMPATHY_IS_LOCATION_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_LOCATION_MANAGER))
+#define EMPATHY_IS_LOCATION_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_LOCATION_MANAGER))
+#define EMPATHY_LOCATION_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerClass))
+
+typedef struct _EmpathyLocationManager      EmpathyLocationManager;
+typedef struct _EmpathyLocationManagerClass EmpathyLocationManagerClass;
+
+typedef enum {
+	EMPATHY_LOCATION_MANAGER_METHOD_MANUAL,
+	EMPATHY_LOCATION_MANAGER_METHOD_AUTOMATIC
+} EmpathyLocationManagerMethod;
+
+struct _EmpathyLocationManager
+{
+  GObject parent;
+  gpointer priv;
+};
+
+struct _EmpathyLocationManagerClass
+{
+  GObjectClass parent_class;
+};
+
+GType empathy_location_manager_get_type (void) G_GNUC_CONST;
+EmpathyLocationManager * empathy_location_manager_get_default (void);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_LOCATION_MANAGER_H__ */
diff --git a/libempathy/empathy-location.h b/libempathy/empathy-location.h
index a43e2d3..17b9704 100644
--- a/libempathy/empathy-location.h
+++ b/libempathy/empathy-location.h
@@ -41,6 +41,7 @@ G_BEGIN_DECLS
 #define EMPATHY_LOCATION_LAT "lat"
 #define EMPATHY_LOCATION_LON "lon"
 #define EMPATHY_LOCATION_ALT "alt"
+#define EMPATHY_LOCATION_ACCURACY "accuracy"
 #define EMPATHY_LOCATION_ACCURACY_LEVEL "accuracy-level"
 #define EMPATHY_LOCATION_ERROR "error"
 #define EMPATHY_LOCATION_VERTICAL_ERROR_M "vertical-error-m"
diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c
index 0ad8e9b..95a84ff 100644
--- a/src/empathy-preferences.c
+++ b/src/empathy-preferences.c
@@ -65,6 +65,15 @@ typedef struct {
 
 	GtkWidget *treeview_spell_checker;
 
+	GtkWidget *checkbutton_publish_location;
+	GtkWidget *radiobutton_location_method_automatic;
+	GtkWidget *radiobutton_location_method_manual;
+	GtkWidget *checkbutton_location_method_automatic_network;
+	GtkWidget *checkbutton_location_method_automatic_cell;
+	GtkWidget *checkbutton_location_method_automatic_gps;
+	GtkWidget *button_location_method_manual;
+	GtkWidget *checkbutton_location_reduce_accuracy;
+
 	GList     *notify_ids;
 } EmpathyPreferences;
 
@@ -248,6 +257,49 @@ preferences_setup_widgets (EmpathyPreferences *preferences)
 					  EMPATHY_PREFS_AUTOCONNECT,
 					  preferences->checkbutton_autoconnect);
 
+	preferences_hookup_toggle_button (preferences,
+					  EMPATHY_PREFS_LOCATION_PUBLISH,
+					  preferences->checkbutton_publish_location);
+
+	preferences_hookup_radio_button (preferences,
+					 EMPATHY_PREFS_LOCATION_METHOD,
+					 preferences->radiobutton_location_method_automatic);
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->radiobutton_location_method_automatic);
+
+	preferences_hookup_toggle_button (preferences,
+					  EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK,
+					  preferences->checkbutton_location_method_automatic_network);
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->checkbutton_location_method_automatic_network);
+
+	preferences_hookup_toggle_button (preferences,
+					  EMPATHY_PREFS_LOCATION_RESOURCE_CELL,
+					  preferences->checkbutton_location_method_automatic_cell);
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->checkbutton_location_method_automatic_cell);
+
+	preferences_hookup_toggle_button (preferences,
+					  EMPATHY_PREFS_LOCATION_RESOURCE_GPS,
+					  preferences->checkbutton_location_method_automatic_gps);
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->checkbutton_location_method_automatic_gps);
+
+	preferences_hookup_toggle_button (preferences,
+					  EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY,
+					  preferences->checkbutton_location_reduce_accuracy);
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->checkbutton_location_reduce_accuracy);
+
+	preferences_hookup_sensitivity (preferences,
+					EMPATHY_PREFS_LOCATION_PUBLISH,
+					preferences->radiobutton_location_method_manual);
+	
 	id = empathy_conf_notify_add (empathy_conf_get (),
 				      EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
 				      preferences_compact_contact_list_changed_cb,
@@ -646,25 +698,33 @@ preferences_widget_sync_string (const gchar *key, GtkWidget *widget)
 		if (GTK_IS_ENTRY (widget)) {
 			gtk_entry_set_text (GTK_ENTRY (widget), value);
 		} else if (GTK_IS_RADIO_BUTTON (widget)) {
-			if (strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) {
-				GType        type;
-				GEnumClass  *enum_class;
-				GEnumValue  *enum_value;
-				GSList      *list;
-				GtkWidget   *toggle_widget;
-				
-				/* Get index from new string */
+			GType        type;
+			GTypeClass  *type_class;
+			GEnumClass  *enum_class;
+			GEnumValue  *enum_value;
+			GSList      *list;
+			GtkWidget   *toggle_widget;
+
+			if (strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0)
 				type = empathy_contact_list_store_sort_get_type ();
-				enum_class = G_ENUM_CLASS (g_type_class_peek (type));
-				enum_value = g_enum_get_value_by_nick (enum_class, value);
-				
-				if (enum_value) { 
-					list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
-					toggle_widget = g_slist_nth_data (list, enum_value->value);
-					gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE);
-				}
-			} else {
+			else if (strcmp (key, EMPATHY_PREFS_LOCATION_METHOD) == 0)
+				type = EMPATHY_TYPE_LOCATION_MANAGER_METHOD;
+			else {
 				g_warning ("Unhandled key:'%s' just had string change", key);
+				g_free (value);
+				return;
+			}
+
+			/* Get index from new string */
+			type_class = g_type_class_ref (type);
+			enum_class = G_ENUM_CLASS (type_class);
+			enum_value = g_enum_get_value_by_nick (enum_class, value);
+			g_type_class_unref (type_class);
+
+			if (enum_value) {
+				list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+				toggle_widget = g_slist_nth_data (list, enum_value->value);
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE);
 			}
 		}
 
@@ -975,35 +1035,42 @@ preferences_radio_button_toggled_cb (GtkWidget *button,
 {
 	const gchar *key;
 	const gchar *value = NULL;
+	GSList      *group;
+	GType        type;
+	GTypeClass  *type_class;
+	GEnumClass  *enum_class;
+	GEnumValue  *enum_value;
 
-	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
 		return;
-	}
 
 	key = g_object_get_data (G_OBJECT (button), "key");
 
-	if (key && strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) {
-		GSList      *group;
-		GType        type;
-		GEnumClass  *enum_class;
-		GEnumValue  *enum_value;
-		
-		group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-		
-		/* Get string from index */
+	if (key && strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0)
 		type = empathy_contact_list_store_sort_get_type ();
-		enum_class = G_ENUM_CLASS (g_type_class_peek (type));
-		enum_value = g_enum_get_value (enum_class, g_slist_index (group, button));
-		
-		if (!enum_value) {
-			g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioButton index:%d", 
-				   g_slist_index (group, button));
-			return;
-		}
+	else if (key && strcmp (key, EMPATHY_PREFS_LOCATION_METHOD) == 0)
+		type = EMPATHY_TYPE_LOCATION_MANAGER_METHOD;
+	else {
+		g_warning ("Unsupported type");
+		return;
+	}
 
-		value = enum_value->value_nick;
+	group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+
+	/* Get string from index */
+	type_class = g_type_class_ref (type);
+	enum_class = G_ENUM_CLASS (type_class);
+	enum_value = g_enum_get_value (enum_class, g_slist_index (group, button));
+	g_type_class_unref (type_class);
+	
+	if (!enum_value) {
+		g_warning ("No GEnumValue with index:%d",
+			   g_slist_index (group, button));
+		return;
 	}
 
+	value = enum_value->value_nick;
+
 	empathy_conf_set_string (empathy_conf_get (), key, value);
 }
 
@@ -1089,6 +1156,14 @@ empathy_preferences_show (GtkWindow *parent)
 		"checkbutton_sounds_disabled_away", &preferences->checkbutton_sounds_disabled_away,
 		"treeview_sounds", &preferences->treeview_sounds,
 		"treeview_spell_checker", &preferences->treeview_spell_checker,
+		"checkbutton_publish_location", &preferences->checkbutton_publish_location,
+		"radiobutton_location_method_automatic", &preferences->radiobutton_location_method_automatic,
+		"radiobutton_location_method_manual", &preferences->radiobutton_location_method_manual,
+		"checkbutton_location_method_automatic_network", &preferences->checkbutton_location_method_automatic_network,
+		"checkbutton_location_method_automatic_cell", &preferences->checkbutton_location_method_automatic_cell,
+		"checkbutton_location_method_automatic_gps", &preferences->checkbutton_location_method_automatic_gps,
+		"button_location_method_manual", &preferences->button_location_method_manual,
+		"checkbutton_location_reduce_accuracy", &preferences->checkbutton_location_reduce_accuracy,
 		NULL);
 	g_free (filename);
 
@@ -1120,6 +1195,15 @@ empathy_preferences_show (GtkWindow *parent)
 		gtk_widget_show (page);
 	}
 
+#if HAVE_GEOCLUE
+	{
+		GtkWidget *page;
+
+		page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 5);
+		gtk_widget_show (page);
+	}
+#endif
+
 	if (parent) {
 		gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog),
 					      GTK_WINDOW (parent));
diff --git a/src/empathy-preferences.glade b/src/empathy-preferences.glade
index c7c5ace..fe483a7 100644
--- a/src/empathy-preferences.glade
+++ b/src/empathy-preferences.glade
@@ -621,6 +621,258 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkVBox" id="vbox1">
+                <property name="border_width">12</property>
+                <property name="spacing">18</property>
+                <child>
+                  <widget class="GtkFrame" id="frame1">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment1">
+                        <property name="visible">True</property>
+                        <property name="top_padding">6</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <widget class="GtkCheckButton" id="checkbutton_publish_location">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="label" translatable="yes">_Publish location to contacts</property>
+                            <property name="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Location&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkFrame" id="frame8">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment3">
+                        <property name="visible">True</property>
+                        <property name="top_padding">6</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <widget class="GtkVBox" id="vbox4">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton_location_method_automatic">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="label" translatable="yes">_Automatic</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkAlignment" id="alignment4">
+                                <property name="visible">True</property>
+                                <property name="left_padding">18</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox5">
+                                    <property name="visible">True</property>
+                                    <child>
+                                      <widget class="GtkCheckButton" id="checkbutton_location_method_automatic_network">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="label" translatable="yes">Use network</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkCheckButton" id="checkbutton_location_method_automatic_cell">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="label" translatable="yes">Use cellphone (if available)</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkCheckButton" id="checkbutton_location_method_automatic_gps">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="label" translatable="yes">Use GPS (if available)</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">2</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkHBox" id="hbox1">
+                                <property name="spacing">12</property>
+                                <child>
+                                  <widget class="GtkRadioButton" id="radiobutton_location_method_manual">
+                                    <property name="visible">True</property>
+                                    <property name="sensitive">False</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="label" translatable="yes">_Manual</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="response_id">0</property>
+                                    <property name="draw_indicator">True</property>
+                                    <property name="group">radiobutton_location_method_automatic</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkButton" id="button_location_method_manual">
+                                    <property name="visible">True</property>
+                                    <property name="sensitive">False</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="label" translatable="yes">gtk-edit</property>
+                                    <property name="use_stock">True</property>
+                                    <property name="response_id">0</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Location Determination Method&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkFrame" id="frame2">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment2">
+                        <property name="visible">True</property>
+                        <property name="top_padding">6</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <widget class="GtkVBox" id="vbox3">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkCheckButton" id="checkbutton_location_reduce_accuracy">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="label" translatable="yes">Reduce location accuracy</property>
+                                <property name="use_underline">True</property>
+                                <property name="response_id">0</property>
+                                <property name="draw_indicator">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Privacy&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Location</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">4</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </widget>
           <packing>
             <property name="position">1</property>
diff --git a/src/empathy.c b/src/empathy.c
index 817b9bc..8cc899f 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -51,6 +51,7 @@
 
 #include <libempathy-gtk/empathy-conf.h>
 #include <libempathy-gtk/empathy-ui-utils.h>
+#include <libempathy-gtk/empathy-location-manager.h>
 
 #include "empathy-accounts-dialog.h"
 #include "empathy-main-window.h"
@@ -417,6 +418,9 @@ int
 main (int argc, char *argv[])
 {
 	guint32            startup_timestamp;
+#if HAVE_GEOCLUE
+	EmpathyLocationManager *location_manager = NULL;
+#endif
 	EmpathyStatusIcon *icon;
 	EmpathyDispatcher *dispatcher;
 	EmpathyLogManager *log_manager;
@@ -573,6 +577,11 @@ main (int argc, char *argv[])
 	g_signal_connect (G_OBJECT (call_factory), "new-call-handler",
 		G_CALLBACK (new_call_handler_cb), NULL);
 
+	/* Location mananger */
+#if HAVE_GEOCLUE
+	location_manager = empathy_location_manager_get_default ();
+#endif
+
 	gtk_main ();
 
 	empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
@@ -584,6 +593,9 @@ main (int argc, char *argv[])
 	g_object_unref (dispatcher);
 	g_object_unref (chatroom_manager);
 	g_object_unref (ft_manager);
+#if HAVE_GEOCLUE
+	g_object_unref (location_manager);
+#endif
 
 	notify_uninit ();
 
