diff --git a/ChangeLog b/ChangeLog
index 17b88ed..af86632 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2010-01-29 Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
+	* gladeui/Makefile.am:
+	  Added new files needed for object separation and updated protocol for the preview feature.
+
+	* gladeui/glade-preview-tokens.h:
+	  Stores commom code between glade-preview and glade-previewer.
+
+	* gladeui/glade-preview-tokens.h:
+	  Updated protocol. Added update for the preview feature. Updted license to LGPL.
+
+	* gladeui/glade-project.c, gladeui/glade-preview.[ch]:
+	  Object separation for Glade_preview. Updated license of gladeui/glade-preview.[ch] to LGPL. Updated protocol for glade-previewer. Added auto-update for the preview feature.
+
 2011-01-28  Tristan Van Berkom <tristanvb@openismus.com>
 
 	* gladeui/glade-xml-utils.h, gladeui/glade-widget-adaptor.[ch], gladeui/glade-widget.[ch]:
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index 6210af1..14eb5fd 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -89,7 +89,8 @@ libgladeui_2_la_SOURCES = \
 	glade-name-context.c \
 	glade-displayable-values.c \
 	glade-signal-model.c \
-	glade-cell-renderer-icon.c
+	glade-cell-renderer-icon.c \
+	glade-preview.c
 
 libgladeui_2_la_CPPFLAGS =  \
 	$(common_defines)   \
@@ -142,9 +143,9 @@ libgladeuiinclude_HEADERS = \
 	glade-editable.h \
 	glade-editor-table.h \
 	glade-cell-renderer-icon.h \
-	glade-signal-model.h
-
-
+	glade-signal-model.h \
+	glade-preview.h \
+	glade-preview-tokens.h
 
 if PLATFORM_WIN32
 libgladeui_2_la_LDFLAGS += -no-undefined
diff --git a/gladeui/glade-preview-tokens.h b/gladeui/glade-preview-tokens.h
new file mode 100644
index 0000000..f131a8e
--- /dev/null
+++ b/gladeui/glade-preview-tokens.h
@@ -0,0 +1,11 @@
+#ifndef __GLADE_PREVIEW_TOKENS_H__
+#define __GLADE_PREVIEW_TOKENS_H__
+
+#define UPDATE_TOKEN "<update>\n"
+#define UPDATE_TOKEN_SIZE strlen (UPDATE_TOKEN)
+
+#define QUIT_TOKEN "<quit>\n"
+#define QUIT_TOKEN_SIZE strlen (QUIT_TOKEN)
+
+#endif /* __GLADE_PREVIEW_TOKENS_H__ */
+
diff --git a/gladeui/glade-preview.c b/gladeui/glade-preview.c
new file mode 100644
index 0000000..10c14f6
--- /dev/null
+++ b/gladeui/glade-preview.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2010 Marco Diego Aurélio Mesquita
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
+ */
+
+#include <config.h>
+
+/**
+ * SECTION:glade-preview
+ * @Short_Description: The glade preview launch/kill interface.
+ *
+ * This object owns all data that is needed to keep a preview. It stores
+ * the GIOChannel used for comunnication between glade and glade-previewer,
+ * the event source id for a watch  (in the case a watch is used to monitor
+ * the communication channel), the previewed widget and the pid of the
+ * corresponding glade-previewer.
+ * 
+ */
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+
+#include "glade.h"
+#include "glade-preview.h"
+#include "glade-project.h"
+#include "glade-app.h"
+
+#include "glade-preview-tokens.h"
+
+/* Private data for glade-preview */
+struct _GladePreviewPrivate
+{
+  GIOChannel *channel;          /* Channel user for communication between glade and glade-previewer */
+  guint watch;                  /* Event source id used to monitor the channel */
+  GladeWidget *previewed_widget;
+  GPid pid;                     /* Pid of the corresponding glade-previewer process */
+};
+
+G_DEFINE_TYPE (GladePreview, glade_preview, G_TYPE_OBJECT);
+
+#define GLADE_PREVIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GLADE_TYPE_PREVIEW, GladePreviewPrivate))
+
+enum
+{
+  PREVIEW_EXITS,
+  LAST_SIGNAL
+};
+
+static guint glade_preview_signals[LAST_SIGNAL] = { 0 };
+
+/**
+ * glade_preview_kill
+ * @preview: a #GladePreview that will be killed.
+ *
+ * Uses the communication channel and protocol to send the "<quit>" token to the
+ * glade-previewer telling it to commit suicide.
+ *
+ */
+static void
+glade_preview_kill (GladePreview * preview)
+{
+  const gchar *quit = QUIT_TOKEN;
+  GIOChannel *channel;
+  GError *error = NULL;
+  gsize size;
+
+  channel = preview->priv->channel;
+  g_io_channel_write_chars (channel, quit, strlen (quit), &size, &error);
+
+  if (size != strlen (quit) && error != NULL)
+    {
+      g_printerr ("Error passing quit signal trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_flush (channel, &error);
+  if (error != NULL)
+    {
+      g_printerr ("Error flushing channel: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_shutdown (channel, TRUE, &error);
+  if (error != NULL)
+    {
+      g_printerr ("Error shutting down channel: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_unref (channel);
+  preview->priv->channel = NULL;
+}
+
+static void
+glade_preview_dispose (GObject * gobject)
+{
+  GladePreview *self = GLADE_PREVIEW (gobject);
+
+  if (self->priv->channel)
+    {
+      g_source_remove (self->priv->watch);
+      glade_preview_kill (self);
+      g_signal_emit (self, glade_preview_signals[PREVIEW_EXITS], 0);
+    }
+
+  G_OBJECT_CLASS (glade_preview_parent_class)->dispose (gobject);
+}
+
+/* We have to use finalize because of the signal that is sent in dispose */
+static void
+glade_preview_finalize (GObject * gobject)
+{
+  G_OBJECT_CLASS (glade_preview_parent_class)->finalize (gobject);
+}
+
+static void
+glade_preview_class_init (GladePreviewClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = glade_preview_dispose;
+  gobject_class->finalize = glade_preview_finalize;
+
+        /**
+	* GladePreview::exits:
+	* @gladepreview: the #GladePreview which received the signal.
+	* @gladeproject: the #GladeProject associated with the preview.
+	*
+	* Emitted when @preview exits.
+	*/
+  glade_preview_signals[PREVIEW_EXITS] =
+      g_signal_new ("exits",
+                    G_TYPE_FROM_CLASS (gobject_class),
+                    G_SIGNAL_RUN_FIRST,
+                    0, NULL, NULL,
+                    g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+
+  g_type_class_add_private (klass, sizeof (GladePreviewPrivate));
+}
+
+static void
+glade_preview_init (GladePreview * self)
+{
+  GladePreviewPrivate *priv;
+
+  self->priv = priv = GLADE_PREVIEW_GET_PRIVATE (self);
+  priv->channel = NULL;
+}
+
+static void
+glade_preview_internal_watch (GPid pid, gint status, gpointer data)
+{
+  /* This means a preview exited. We'll now signal it */
+  g_signal_emit (data, glade_preview_signals[PREVIEW_EXITS], 0);
+}
+
+/**
+ * glade_preview_launch_preview:
+ * @buffer: Contents of an xml definition of the interface which will be previewed
+ * @widget: Pointer to a local instance of the widget that will be previewed.
+ *
+ * Creates a new #GladePreview and launches glade-previewer to preview it.
+ *
+ * Returns: a new #GladePreview or NULL if launch fails.
+ * 
+ */
+GladePreview *
+glade_preview_launch (gchar * buffer, GladeWidget * widget)
+{
+  GPid pid;
+  GError *error = NULL;
+  gchar *argv[4];
+  gint child_stdin;
+  GIOChannel *output;
+  GladePreview *preview = NULL;
+
+#ifdef WINDOWS
+  argv[0] =
+      g_build_filename (glade_app_get_bin_dir (), "glade-previewer.exe", NULL);
+#else
+  argv[0] =
+      g_build_filename (glade_app_get_bin_dir (), "glade-previewer", NULL);
+#endif
+
+  argv[1] = "--listen";
+
+  if (widget != NULL)
+    {
+      argv[2] =
+          g_strdup_printf ("--toplevel=%s", glade_widget_get_name (widget));
+      argv[3] = NULL;
+    }
+
+  if (g_spawn_async_with_pipes (NULL,
+                                argv,
+                                NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
+                                &pid, &child_stdin, NULL, NULL,
+                                &error) == FALSE)
+    {
+      g_printerr (_("Error launching previewer: %s\n"), error->message);
+      glade_util_ui_message (glade_app_get_window (),
+                             GLADE_UI_ERROR, NULL,
+                             _("Failed to launch preview: %s.\n"),
+                             error->message);
+      g_error_free (error);
+      goto end;
+    }
+
+#ifdef WINDOWS
+  output = g_io_channel_win32_new_fd (child_stdin);
+#else
+  output = g_io_channel_unix_new (child_stdin);
+#endif
+
+  gsize bytes_written;
+  g_io_channel_write_chars (output, buffer, strlen (buffer), &bytes_written,
+                            &error);
+
+  if (bytes_written != strlen (buffer) && error != NULL)
+    {
+      g_printerr ("Error passing UI trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_flush (output, &error);
+  if (error != NULL)
+    {
+      g_printerr ("Error flushing UI trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  if (widget != NULL)
+    g_free (argv[2]);
+
+  /* Setting up preview data */
+  preview = g_object_new (GLADE_TYPE_PREVIEW, NULL);
+  preview->priv->channel = output;
+  preview->priv->previewed_widget = widget;
+  preview->priv->pid = pid;
+
+end:
+  g_free (argv[0]);
+
+  preview->priv->watch = g_child_watch_add (preview->priv->pid,
+                                            glade_preview_internal_watch,
+                                            preview);
+
+  return preview;
+}
+
+void
+glade_preview_update (gchar * buffer, GladePreview * preview)
+{
+  const gchar *update_token = UPDATE_TOKEN;
+  gchar *update;
+  GIOChannel *channel;
+  GError *error = NULL;
+  gsize size;
+
+  GladeWidget *gwidget = glade_preview_get_widget (preview);
+
+  update = g_strdup_printf ("%s%s\n", update_token,
+                            glade_widget_get_name (gwidget));
+
+  channel = preview->priv->channel;
+  g_io_channel_write_chars (channel, update, strlen (update), &size, &error);
+
+  if (size != strlen (update) && error != NULL)
+    {
+      g_printerr ("Error passing quit signal trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_flush (channel, &error);
+  if (error != NULL)
+    {
+      g_printerr ("Error flushing channel: %s", error->message);
+      g_error_free (error);
+    }
+
+  /* We'll now send the interface: */
+  gsize bytes_written;
+  g_io_channel_write_chars (channel, buffer, strlen (buffer), &bytes_written,
+                            &error);
+
+  if (bytes_written != strlen (buffer) && error != NULL)
+    {
+      g_printerr ("Error passing UI trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_io_channel_flush (channel, &error);
+  if (error != NULL)
+    {
+      g_printerr ("Error flushing UI trough pipe: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_free (update);
+}
+
+GladeWidget *
+glade_preview_get_widget (GladePreview * preview)
+{
+  return preview->priv->previewed_widget;
+}
+
+GPid
+glade_preview_get_pid (GladePreview * preview)
+{
+  return preview->priv->pid;
+}
diff --git a/gladeui/glade-preview.h b/gladeui/glade-preview.h
new file mode 100644
index 0000000..b4ca874
--- /dev/null
+++ b/gladeui/glade-preview.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Marco Diego Aurélio Mesquita
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
+ */
+
+#ifndef _GLADE_PREVIEW_H_
+#define _GLADE_PREVIEW_H_
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+G_BEGIN_DECLS
+#define GLADE_TYPE_PREVIEW             (glade_preview_get_type ())
+#define GLADE_PREVIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_PREVIEW, GladePreview))
+#define GLADE_PREVIEW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_PREVIEW, GladePreviewClass))
+#define GLADE_IS_PREVIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_PREVIEW))
+#define GLADE_IS_PREVIEW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_PREVIEW))
+#define GLADE_PREVIEW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_PREVIEW, GladePreviewClass))
+typedef struct _GladePreviewClass GladePreviewClass;
+typedef struct _GladePreview GladePreview;
+
+struct _GladePreviewClass
+{
+  GObjectClass parent_class;
+};
+
+typedef struct _GladePreviewPrivate GladePreviewPrivate;
+
+struct _GladePreview
+{
+  GObject parent_instance;
+
+  GladePreviewPrivate *priv;
+};
+
+GType         glade_preview_get_type    (void) G_GNUC_CONST;
+GladePreview *glade_preview_launch      (gchar * buffer, GladeWidget * widget);
+void          glade_preview_update      (gchar * buffer, GladePreview * preview);
+GladeWidget  *glade_preview_get_widget  (GladePreview * preview);
+GPid          glade_preview_get_pid     (GladePreview * preview);
+
+G_END_DECLS
+#endif /* _GLADE_PREVIEW_H_ */
diff --git a/gladeui/glade-previewer.c b/gladeui/glade-previewer.c
index 295950b..e175afd 100644
--- a/gladeui/glade-previewer.c
+++ b/gladeui/glade-previewer.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2010 Marco Diego Aurélio Mesquita
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as
+ * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
@@ -11,7 +11,7 @@
  * 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
+ * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
@@ -19,7 +19,6 @@
  *   Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
  */
 
-
 #include <config.h>
 
 #include <stdlib.h>
@@ -32,6 +31,8 @@
 #include <locale.h>
 #include <glib/gi18n-lib.h>
 
+#include "glade-preview-tokens.h"
+
 static void
 display_help_and_quit (const GOptionEntry * entries)
 {
@@ -168,10 +169,11 @@ get_toplevel (gchar * name, gchar * string, gsize length)
     }
 
   g_object_unref (builder);
+
   return toplevel;
 }
 
-static void
+static GtkWidget *
 preview_widget (gchar * name, gchar * buffer, gsize length)
 {
   GtkWidget *widget;
@@ -200,6 +202,8 @@ preview_widget (gchar * name, gchar * buffer, gsize length)
 
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
   gtk_widget_show_all (window);
+
+  return widget;
 }
 
 static GIOChannel *
@@ -259,7 +263,7 @@ read_buffer (GIOChannel * source)
     }
 
   /* Check for quit token */
-  if (g_strcmp0 ("<quit>", token) == 0)
+  if (g_strcmp0 (QUIT_TOKEN, token) == 0)
     {
       g_free (token);
       return NULL;
@@ -287,11 +291,115 @@ read_buffer (GIOChannel * source)
   return buffer;
 }
 
+static void
+copy_window_properties (GtkWindow *old_window, GtkWindow *new_window)
+{
+	GParamSpec **properties_list;
+	guint i, n_properties;
+	gint width, height;
+	GValue copy_value = { 0,};
+
+	if (!old_window || !new_window) return;
+
+	properties_list = g_object_class_list_properties
+			  (G_OBJECT_GET_CLASS (G_OBJECT (new_window)),
+			  &n_properties);
+
+	for (i = 0; i < n_properties; i++)
+	{
+		if (!((properties_list[i]->flags & G_PARAM_READABLE) &&
+		      (properties_list[i]->flags & G_PARAM_WRITABLE) &&
+		      (!(properties_list[i]->flags & G_PARAM_CONSTRUCT_ONLY))
+		    )) continue;
+
+		/* We won't set some properties */
+		if (g_strcmp0 ("parent", properties_list[i]->name) == 0) continue;
+		if (g_strcmp0 ("visible", properties_list[i]->name) == 0) continue;
+
+		g_value_init (&copy_value, properties_list[i]->value_type);
+		g_object_get_property (G_OBJECT (new_window),
+				       properties_list[i]->name,
+				       &copy_value);
+
+		g_object_set_property (G_OBJECT (old_window),
+				       properties_list[i]->name,
+				       &copy_value);
+
+		g_value_unset (&copy_value);
+	}
+
+	/* Special code to copy default size */
+	if (gtk_window_get_resizable (old_window))
+	{
+		gtk_window_get_default_size (new_window, &width, &height);
+		if ((width > 0) && (height > 0))
+			gtk_window_resize (old_window, width, height);
+	}
+
+	if (properties_list) g_free (properties_list);
+}
+
+static void
+update_window (GtkWindow *old_window, GtkWindow *new_window)
+{
+	GtkWidget *window_child;
+	GtkWidget *old_window_child;
+
+	if (!old_window || !new_window) return;
+
+	/* ref the new window child */
+	window_child = gtk_bin_get_child (GTK_BIN (new_window));
+	if (window_child)
+	{
+		g_object_ref (window_child);
+
+		/* remove window child */
+		gtk_container_remove (GTK_CONTAINER (new_window), window_child);
+	}
+
+	/* gtk_widget_destroy the *running preview's* window child */
+	old_window_child = gtk_bin_get_child (GTK_BIN (old_window));
+	if (old_window_child)
+		gtk_widget_destroy (old_window_child);
+
+	/* apply properties from the new window to the
+	 * old window (using GObjectapis)*/
+	copy_window_properties (old_window, new_window);
+
+	/* add new preview's window child to the old preview's window */
+	if (window_child)
+	{
+		gtk_container_add (GTK_CONTAINER (old_window), window_child);
+		/* unref the newly added child (which we added a ref to before) */
+		g_object_unref (window_child);
+	}
+}
+
+static void
+update_window_child (GtkWindow *old_window, GtkWidget *new_widget)
+{
+	GtkWidget *old_window_child;
+
+	if (!old_window) return;
+
+	/* gtk_widget_destroy the *running preview's* window child */
+	old_window_child = gtk_bin_get_child (GTK_BIN (old_window));
+	if (old_window_child)
+		gtk_widget_destroy (old_window_child);
+
+	/* add new widget as child to the old preview's window */
+	if (new_widget)
+		gtk_container_add (GTK_CONTAINER (old_window), new_widget);
+}
+
 static gboolean
 on_data_incoming (GIOChannel * source, GIOCondition condition, gpointer data)
 {
   gchar *buffer;
   gsize length;
+	static GtkWidget *preview_window = NULL;
+  GtkWidget *new_widget;
+  gchar **split_buffer = NULL;
 
   gchar *toplevel_name = (gchar *) data;
 
@@ -310,8 +418,43 @@ on_data_incoming (GIOChannel * source, GIOCondition condition, gpointer data)
 
   length = strlen (buffer);
 
-  preview_widget (toplevel_name, buffer, length);
-  g_free (buffer);
+  /* if it is the first time this is called */
+  if (!preview_window)
+  {
+    preview_window = preview_widget (toplevel_name, buffer, length);
+  }
+  else
+  {
+    /* We have an update */
+    split_buffer = g_strsplit_set (buffer + UPDATE_TOKEN_SIZE, "\n", 2);
+
+    g_free (buffer);
+    if (!split_buffer) return FALSE;
+
+    toplevel_name = split_buffer[0];
+    buffer = split_buffer[1];
+    length = strlen (buffer);
+
+    new_widget = get_toplevel (toplevel_name, buffer, length);
+
+		if (GTK_IS_WINDOW (new_widget))
+			update_window (GTK_WINDOW (preview_window),
+				       GTK_WINDOW (new_widget));
+		else update_window_child (GTK_WINDOW (preview_window), new_widget);
+  }
+
+  if (!split_buffer)
+  {
+    /* This means we're not in an update, we should free the buffer. */
+    g_free (buffer);
+  }
+  else
+  {
+    /* This means we've had an update, buffer was already freed. */
+    g_free (split_buffer[0]);
+    g_free (split_buffer[1]);
+    g_free (split_buffer);
+  }
 
   return TRUE;
 }
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 5a36957..f053be4 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -45,6 +45,8 @@
 #include "glade-marshallers.h"
 #include "glade-catalog.h"
 
+#include "glade-preview.h"
+
 #include "glade-project.h"
 #include "glade-command.h"
 #include "glade-name-context.h"
@@ -138,8 +140,8 @@ struct _GladeProjectPrivate
   GtkWidget *relative_path_entry;
   GtkWidget *full_path_button;
 
-  /* Store preview processes, so we can kill them on close */
-  GHashTable *preview_channels;
+ 	/* Store previews, so we can kill them on close */
+ 	GHashTable *previews;
 
   /* For the loading progress bars ("load-progress" signal) */
   gint progress_step;
@@ -165,13 +167,6 @@ typedef struct
   gchar *filename;
 } StockFilePair;
 
-typedef struct
-{
-  GIOChannel *channel;
-  guint watch;
-} ChannelWatchPair;
-
-
 GType
 glade_pointer_mode_get_type (void)
 {
@@ -642,66 +637,36 @@ glade_project_push_undo_impl (GladeProject * project, GladeCommand * cmd)
 }
 
 static void
-glade_project_preview_exits (GPid pid, gint status, gpointer data)
+glade_project_preview_exits (GladePreview *preview, GladeProject *project)
 {
-  GladeProject *project = (GladeProject *) data;
-  ChannelWatchPair *channel_watch;
-  GIOChannel *channel;
-  gchar *pidstr = g_strdup_printf ("%d", pid);
+  gchar *pidstr = g_strdup_printf ("%d", glade_preview_get_pid (preview));
 
-  channel_watch = g_hash_table_lookup (project->priv->preview_channels, pidstr);
-  channel = channel_watch->channel;
-  g_io_channel_unref (channel);
-  g_hash_table_remove (project->priv->preview_channels, pidstr);
+  preview = g_hash_table_lookup (project->priv->previews, pidstr);
+  g_hash_table_remove (project->priv->previews, pidstr);
 
   g_free (pidstr);
-  g_free (channel_watch);
 }
 
 static void
 glade_project_kill_previews (gpointer key, gpointer value, gpointer user_data)
 {
-  const gchar *quit = "<quit>";
-  GIOChannel *channel;
-  ChannelWatchPair *channel_watch = (ChannelWatchPair *) value;
-  GError *error = NULL;
-  gsize size;
-
-  channel = channel_watch->channel;
-  /* Removing watch, since the child will commit suicide */
-  g_source_remove (channel_watch->watch);
-  g_io_channel_write_chars (channel, quit, strlen (quit), &size, &error);
-
-  if (size != strlen (quit) && error != NULL)
-    {
-      g_printerr ("Error passing quit signal trough pipe: %s", error->message);
-      g_error_free (error);
-    }
-
-  g_io_channel_flush (channel, &error);
-  if (error != NULL)
-    {
-      g_printerr ("Error flushing channel: %s", error->message);
-      g_error_free (error);
-    }
+  GladePreview *preview = GLADE_PREVIEW (value);
+  /*  handler, since the child will commit suicide */
+  g_signal_handlers_disconnect_by_func (preview,
+                                        G_CALLBACK (glade_project_preview_exits),
+                                        user_data);
 
-  g_io_channel_shutdown (channel, TRUE, &error);
-  if (error != NULL)
-    {
-      g_printerr ("Error shutting down channel: %s", error->message);
-      g_error_free (error);
-    }
-
-  g_io_channel_unref (channel);
-  g_free (channel_watch);
+  g_object_unref (preview);
 }
 
 static void
 glade_project_close_impl (GladeProject * project)
 {
-  g_hash_table_foreach (project->priv->preview_channels,
+  if (!project->priv->previews) return;
+  g_hash_table_foreach (project->priv->previews,
                         glade_project_kill_previews, project);
-  g_hash_table_unref (project->priv->preview_channels);
+  g_hash_table_unref (project->priv->previews);
+  project->priv->previews = NULL;
 }
 
 static void
@@ -745,8 +710,9 @@ glade_project_init (GladeProject * project)
   priv->first_modification = NULL;
   priv->first_modification_is_na = FALSE;
 
-  priv->preview_channels =
-      g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  priv->previews = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                          g_free, NULL);
+
   priv->widget_names = glade_name_context_new ();
 
   priv->accel_group = NULL;
@@ -1877,93 +1843,23 @@ glade_project_save (GladeProject * project, const gchar * path, GError ** error)
   return ret > 0;
 }
 
-static GPid
-glade_project_launch_preview (GladeProject * project, gchar * buffer,
-                              GtkWidget * widget)
+static gboolean
+glade_project_check_previewed_widget (gpointer key, gpointer value,
+                                      gpointer user_data)
 {
-  GPid pid;
-  GError *error = NULL;
-  gchar *argv[4];
-  gint child_stdin;
-  GIOChannel *output;
-  guint watch;
-  ChannelWatchPair *channel_watch;
-  GladeWidget *glade_widget;
-
-
-#ifdef WINDOWS
-  argv[0] =
-      g_build_filename (glade_app_get_bin_dir (), "glade-previewer.exe", NULL);
-#else
-  argv[0] =
-      g_build_filename (glade_app_get_bin_dir (), "glade-previewer", NULL);
-#endif
-
-
-  argv[1] = "--listen";
-
-  if (widget != NULL)
-    {
-      glade_widget = glade_widget_get_from_gobject (G_OBJECT (widget));
-      argv[2] = g_strdup_printf ("--toplevel=%s", glade_widget_get_name (glade_widget));
-      argv[3] = NULL;
-    }
-
-  if (g_spawn_async_with_pipes (NULL,
-                                argv,
-                                NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
-                                &pid, &child_stdin, NULL, NULL,
-                                &error) == FALSE)
-    {
-      g_printerr (_("Error launching previewer: %s\n"), error->message);
-      glade_util_ui_message (glade_app_get_window (),
-                             GLADE_UI_ERROR, NULL,
-                             _("Failed to launch preview: %s.\n"),
-                             error->message);
-      g_error_free (error);
-      pid = 0;
-      goto end;
-    }
-
-  /* Store watch so we can remove it later */
-  watch = g_child_watch_add (pid, glade_project_preview_exits, project);
-
-#ifdef WINDOWS
-  output = g_io_channel_win32_new_fd (child_stdin);
-#else
-  output = g_io_channel_unix_new (child_stdin);
-#endif
-
-  gsize bytes_written;
-  g_io_channel_write_chars (output, buffer, strlen (buffer), &bytes_written,
-                            &error);
-
-  if (bytes_written != strlen (buffer) && error != NULL)
-    {
-      g_printerr ("Error passing UI trough pipe: %s", error->message);
-      g_error_free (error);
-    }
-
-  g_io_channel_flush (output, &error);
-  if (error != NULL)
-    {
-      g_printerr ("Error flushing UI trough pipe: %s", error->message);
-      g_error_free (error);
-    }
-
-  if (widget != NULL)
-    g_free (argv[2]);
-
-  /* Adding channel to list of channels */
-  channel_watch = g_new (ChannelWatchPair, 1);
-  channel_watch->channel = output;
-  channel_watch->watch = watch;
-  g_hash_table_insert (project->priv->preview_channels,
-                       g_strdup_printf ("%d", pid), channel_watch);
+  if (!key || !value || !user_data) return FALSE;
+  GladePreview *preview = GLADE_PREVIEW (value);
+  GladeWidget *gwidget = (GladeWidget *)user_data;
+  return glade_preview_get_widget (preview) == gwidget;
+}
 
-end:
-  g_free (argv[0]);
-  return pid;
+static GladePreview*
+glade_project_has_preview (GladeProject *project, GladeWidget *gwidget)
+{
+  if (!project->priv->previews) return FALSE;
+  return g_hash_table_find(project->priv->previews,
+                           glade_project_check_previewed_widget,
+                           gwidget);
 }
 
 /**
@@ -1981,7 +1877,7 @@ glade_project_preview (GladeProject * project, GladeWidget * gwidget)
 {
   GladeXmlContext *context;
   gchar *text;
-  GtkWidget *widget;
+  GladePreview *preview;
 
   g_return_if_fail (GLADE_IS_PROJECT (project));
 
@@ -1992,9 +1888,25 @@ glade_project_preview (GladeProject * project, GladeWidget * gwidget)
   gwidget = glade_widget_get_toplevel (gwidget);
   if (!GTK_IS_WIDGET (glade_widget_get_object (gwidget)))
     return;
-  widget = GTK_WIDGET (glade_widget_get_object (gwidget));
 
-  glade_project_launch_preview (project, text, widget);
+  preview = glade_project_has_preview (project, gwidget);
+  if(!preview)
+  {
+    preview = glade_preview_launch (text, gwidget);
+    g_signal_connect (preview, "exits",
+                      G_CALLBACK (glade_project_preview_exits),
+                      project);
+
+    /* Add preview to list of previews */
+    g_hash_table_insert (project->priv->previews,
+                         g_strdup_printf("%d", glade_preview_get_pid (preview)),
+                         preview);
+
+  }
+  else
+  {
+    glade_preview_update (text, preview);
+  }
 
   g_free (text);
 }
@@ -2810,6 +2722,7 @@ glade_project_remove_object (GladeProject * project, GObject * object)
 {
   GladeWidget *gwidget;
   GList *list, *children;
+  GladePreview *preview = NULL;
 
   g_return_if_fail (GLADE_IS_PROJECT (project));
   g_return_if_fail (G_IS_OBJECT (object));
@@ -2846,10 +2759,21 @@ glade_project_remove_object (GladeProject * project, GObject * object)
   project->priv->tree = g_list_remove (project->priv->tree, object);
   project->priv->objects = g_list_remove (project->priv->objects, object);
 
+  /* Check if there is a preview of such object */
+  if (project->priv->previews)
+  preview = g_hash_table_find (project->priv->previews,
+                               glade_project_check_previewed_widget,
+                               GLADE_WIDGET(gwidget));
+
   /* Unset the project pointer on the GladeWidget */
   glade_widget_set_project (gwidget, NULL);
   glade_widget_set_in_project (gwidget, FALSE);
   g_object_unref (gwidget);
+
+  if (preview)
+  {
+    g_object_unref (preview);
+  }
 }
 
 /*******************************************************************
@@ -3638,7 +3562,6 @@ resource_full_path_set (GtkFileChooserButton * button, GladeProject * project)
   glade_project_set_resource_path (project, text);
 }
 
-
 static void
 update_prefs_for_resource_path (GladeProject * project)
 {
