Index: gnome-session/gsm-manager.c
===================================================================
--- gnome-session/gsm-manager.c	(revision 5330)
+++ gnome-session/gsm-manager.c	(working copy)
@@ -1681,6 +1681,18 @@
 }
 
 static void
+on_xsmp_client_save_request (GsmXSMPClient *client,
+			     gboolean       show_dialog,
+			     GsmManager    *manager)
+{
+	GError *error;
+
+	g_debug ("GsmManager: save_request");
+	error = NULL;
+	gsm_session_save (manager->priv->clients, &error);
+}
+
+static void
 on_store_client_added (GsmStore   *store,
                        const char *id,
                        GsmManager *manager)
@@ -1701,6 +1713,10 @@
                                   "logout-request",
                                   G_CALLBACK (on_xsmp_client_logout_request),
                                   manager);
+		g_signal_connect (client,
+				  "save-request",
+				  G_CALLBACK (on_xsmp_client_save_request),
+				  manager);
         }
 
         g_signal_connect (client,
@@ -2574,6 +2590,27 @@
 }
 
 gboolean
+gsm_manager_save_session (GsmManager *manager,
+			  GError	**error)
+{
+	g_debug ("GsmManager: SaveSession called");
+
+	g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
+
+	if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
+		g_set_error (error,
+                             GSM_MANAGER_ERROR,
+                             GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+                             "SaveSession interface is only available during the Running phase");
+		return FALSE;
+	}
+
+	maybe_save_session (manager);
+
+	return TRUE;
+}
+
+gboolean
 gsm_manager_can_shutdown (GsmManager *manager,
                           gboolean   *shutdown_available,
                           GError    **error)
Index: gnome-session/gsm-manager.h
===================================================================
--- gnome-session/gsm-manager.h	(revision 5330)
+++ gnome-session/gsm-manager.h	(working copy)
@@ -152,6 +152,9 @@
 gboolean            gsm_manager_shutdown                       (GsmManager     *manager,
                                                                 GError        **error);
 
+gboolean            gsm_manager_save_session                   (GsmManager     *manager,
+                                                                GError        **error);
+
 gboolean            gsm_manager_can_shutdown                   (GsmManager     *manager,
                                                                 gboolean       *shutdown_available,
                                                                 GError        **error);
Index: gnome-session/org.gnome.SessionManager.xml
===================================================================
--- gnome-session/org.gnome.SessionManager.xml	(revision 5330)
+++ gnome-session/org.gnome.SessionManager.xml	(working copy)
@@ -256,6 +256,14 @@
       </doc:doc>
     </method>
 
+    <method name="SaveSession">
+      <doc:doc>
+	<doc:description>
+	  <doc:para>Request to save session</doc:para>
+	</doc:description>
+      </doc:doc>
+    </method>
+
     <method name="CanShutdown">
       <arg name="is_available" direction="out" type="b">
         <doc:doc>
Index: gnome-session/gsm-xsmp-client.c
===================================================================
--- gnome-session/gsm-xsmp-client.c	(revision 5330)
+++ gnome-session/gsm-xsmp-client.c	(working copy)
@@ -66,6 +66,7 @@
 enum {
         REGISTER_REQUEST,
         LOGOUT_REQUEST,
+	SAVE_REQUEST,
         LAST_SIGNAL
 };
 
@@ -960,6 +961,17 @@
                               G_TYPE_NONE,
                               1, G_TYPE_BOOLEAN);
 
+	signals[SAVE_REQUEST] =
+		g_signal_new ("save-request",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmXSMPClientClass, save_request),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__BOOLEAN,
+                              G_TYPE_NONE,
+                              1, G_TYPE_BOOLEAN);
+
         g_object_class_install_property (object_class,
                                          PROP_ICE_CONNECTION,
                                          g_param_spec_pointer ("ice-connection",
Index: gnome-session/gsm-xsmp-client.h
===================================================================
--- gnome-session/gsm-xsmp-client.h	(revision 5330)
+++ gnome-session/gsm-xsmp-client.h	(working copy)
@@ -54,8 +54,9 @@
                                           char          **client_id);
         gboolean (*logout_request)       (GsmXSMPClient  *client,
                                           gboolean        prompt);
+	gboolean (*save_request)	 (GsmXSMPClient  *client,
+                                          gboolean        prompt);
 
-
         void     (*saved_state)          (GsmXSMPClient  *client);
 
         void     (*request_phase2)       (GsmXSMPClient  *client);
Index: capplet/gsm-properties-dialog.c
===================================================================
--- capplet/gsm-properties-dialog.c	(revision 5330)
+++ capplet/gsm-properties-dialog.c	(working copy)
@@ -41,7 +41,13 @@
 #include "gsm-app-dialog.h"
 #include "eggdesktopfile.h"
 #include "gsm-util.h"
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
+#define GSM_SERVICE_DBUS   "org.gnome.SessionManager"
+#define GSM_PATH_DBUS	    "/org/gnome/SessionManager"
+#define GSM_INTERFACE_DBUS "org.gnome.SessionManager"
+
 #define GSM_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PROPERTIES_DIALOG, GsmPropertiesDialogPrivate))
 
 #define IS_STRING_EMPTY(x) ((x)==NULL||(x)[0]=='\0')
@@ -1246,12 +1252,116 @@
 }
 
 static void
+display_error (const char *message)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
+					 GTK_BUTTONS_CLOSE, "%s", message);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+static DBusGConnection *
+get_session_bus (void)
+{
+	DBusGConnection *bus;
+	GError *error = NULL;
+
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+	if (bus == NULL) {
+		g_warning ("Couldn't connect to session bus: %s", error->message);
+		g_error_free (error);
+	}
+
+	return bus;
+}
+
+static DBusGProxy *
+get_sm_proxy (void)
+{
+	DBusGConnection *connection;
+	DBusGProxy      *sm_proxy;
+
+	connection = get_session_bus ();
+	if (connection == NULL) {
+		display_error (_("Could not connect to the session manager"));
+		return NULL;
+	}
+
+	sm_proxy = dbus_g_proxy_new_for_name (connection,
+					      GSM_SERVICE_DBUS,
+					      GSM_PATH_DBUS,
+					      GSM_INTERFACE_DBUS);
+
+	if (sm_proxy == NULL) {
+		display_error (_("Could not connect to the session manager"));
+		return NULL;
+	}
+
+	return sm_proxy;
+}
+
+static char*
+save_session (void)
+{
+	DBusGProxy *sm_proxy;
+	GError	   *error;
+	gboolean    res = FALSE;
+
+	sm_proxy = get_sm_proxy ();
+	if (sm_proxy == NULL) {
+		return NULL;
+	}
+
+	error = NULL;
+	res = dbus_g_proxy_call (sm_proxy,
+				 "SaveSession",
+				 &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+
+	if (!res) {
+		if (error != NULL) {
+			g_warning ("Failed to call save session: %s",
+				   error->message);
+			g_error_free (error);
+		} else {
+			g_warning ("Failed to call save session");
+		}
+	}
+
+	if (sm_proxy != NULL) {
+		g_object_unref (sm_proxy);
+	}
+
+	if (res)
+		return "Session saved successfully!";
+}
+
+static void
 on_save_session_clicked (GtkWidget           *widget,
                          GsmPropertiesDialog *dialog)
 {
-        g_debug ("Session saving is not implemented yet!");
+	GtkWidget *message;
+	char *status=NULL;
+
+	status = save_session ();
+
+	if (status) {
+		message = gtk_message_dialog_new (GTK_WINDOW (dialog),
+						  GTK_DIALOG_MODAL | 
+						  GTK_DIALOG_DESTROY_WITH_PARENT,
+						  GTK_MESSAGE_INFO,
+						  GTK_BUTTONS_OK,
+						  status);
+		gtk_dialog_run (GTK_DIALOG (message));
+		gtk_widget_destroy (message);
+	}
 }
-
+ 
 static void
 setup_dialog (GsmPropertiesDialog *dialog)
 {
Index: data/session-properties.glade
===================================================================
--- data/session-properties.glade	(revision 5330)
+++ data/session-properties.glade	(working copy)
@@ -306,7 +306,7 @@
                     <property name="visible">True</property>
                     <child>
                       <widget class="GtkButton" id="session_properties_save_button">
-                        <property name="visible">False</property>
+                        <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
                         <child>
