diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c
index 2dcd538..6bd3af9 100644
--- a/lib/widgets/ephy-location-entry.c
+++ b/lib/widgets/ephy-location-entry.c
@@ -73,6 +73,7 @@ struct _EphyLocationEntryPrivate
 	GtkCellRenderer *extracell;
 
 	char *before_completion;
+	char *saved_text;
 
 	guint text_col;
 	guint action_col;
@@ -85,6 +86,8 @@ struct _EphyLocationEntryPrivate
 	guint hash;
 
 	guint user_changed : 1;
+	guint can_redo : 1;
+	guint block_update : 1;
 	guint original_address : 1;
 	guint secure : 1;
 	guint apply_colours : 1;
@@ -221,6 +224,8 @@ ephy_location_entry_finalize (GObject *object)
 {
 	EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
 	EphyLocationEntryPrivate *priv = entry->priv;
+	
+	g_free (priv->saved_text);
 
 	if (priv->favicon != NULL)
 	{
@@ -343,7 +348,13 @@ editable_changed_cb (GtkEditable *editable,
 
 	update_address_state (entry);
 
-	if (priv->user_changed == FALSE) return;
+	if (priv->block_update == TRUE) 
+		return;
+	else
+	{
+		priv->user_changed = TRUE;
+		priv->can_redo = FALSE;
+	}	
 
 	update_favicon (entry);
 
@@ -424,6 +435,8 @@ entry_activate_after_cb (GtkEntry *entry,
 			 EphyLocationEntry *lentry)
 {
 	EphyLocationEntryPrivate *priv = lentry->priv;
+	
+	priv->user_changed = FALSE;
 
 	if (priv->needs_reset)
 	{
@@ -528,19 +541,34 @@ entry_clear_activate_cb (GtkMenuItem *item,
 {
 	EphyLocationEntryPrivate *priv = entry->priv;
 
-	priv->user_changed = FALSE;
+	priv->block_update = TRUE;
 	gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), "");
+	priv->block_update = FALSE;
 	priv->user_changed = TRUE;
 }
 
 static void
+entry_redo_activate_cb (GtkMenuItem *item,
+			EphyLocationEntry *entry)
+{
+	ephy_location_entry_undo_reset (entry);
+}
+
+static void
+entry_undo_activate_cb (GtkMenuItem *item,
+			EphyLocationEntry *entry)
+{
+	ephy_location_entry_reset_internal (entry, FALSE);
+}
+
+static void
 entry_populate_popup_cb (GtkEntry *entry,
 			 GtkMenu *menu,
 			 EphyLocationEntry *lentry)
 {
 	EphyLocationEntryPrivate *priv = lentry->priv;
 	GtkWidget *image;
-	GtkWidget *menuitem;
+	GtkWidget *clear_menuitem, *undo_menuitem, *redo_menuitem, *separator;
 	GList *children, *item;
 	int pos = 0, sep = 0;
 	gboolean is_editable;
@@ -553,13 +581,13 @@ entry_populate_popup_cb (GtkEntry *entry,
 	 * standard items in the GtkEntry context menu (Cut, Copy, Paste, Delete,
 	 * Select All, Input Methods and Insert Unicode control character.)
 	 */
-	menuitem = gtk_image_menu_item_new_with_mnemonic (_("Cl_ear"));
-	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(menuitem), image);
-	g_signal_connect (menuitem , "activate",
+	clear_menuitem = gtk_image_menu_item_new_with_mnemonic (_("Cl_ear"));
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear_menuitem), image);
+	g_signal_connect (clear_menuitem , "activate",
 			  G_CALLBACK (entry_clear_activate_cb), lentry);
 	is_editable = gtk_editable_get_editable (GTK_EDITABLE (priv->icon_entry->entry));
-	gtk_widget_set_sensitive (menuitem, is_editable);
-	gtk_widget_show (menuitem);
+	gtk_widget_set_sensitive (clear_menuitem, is_editable);
+	gtk_widget_show (clear_menuitem);
 
 	/* search for the 2nd separator (the one after Select All) in the context
 	 * menu, and insert this menu item before it.
@@ -571,7 +599,25 @@ entry_populate_popup_cb (GtkEntry *entry,
 		if (GTK_IS_SEPARATOR_MENU_ITEM (item->data)) sep++;
 	}
 
-	gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, pos - 1);
+	gtk_menu_shell_insert (GTK_MENU_SHELL (menu), clear_menuitem, pos - 1);
+	
+	undo_menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_UNDO, NULL);
+	gtk_widget_set_sensitive (undo_menuitem, priv->user_changed);
+	g_signal_connect (undo_menuitem, "activate",
+			  G_CALLBACK (entry_undo_activate_cb), lentry);
+	gtk_widget_show (undo_menuitem);
+	gtk_menu_shell_insert (GTK_MENU_SHELL (menu), undo_menuitem, 0);
+	
+	redo_menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_REDO, NULL);
+	gtk_widget_set_sensitive (redo_menuitem, priv->can_redo);
+	g_signal_connect (redo_menuitem, "activate",
+			  G_CALLBACK (entry_redo_activate_cb), lentry);
+	gtk_widget_show (redo_menuitem);
+	gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1);
+	
+	separator = gtk_separator_menu_item_new ();
+	gtk_widget_show (separator);
+	gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2);
 }
 
 static void
@@ -876,7 +922,9 @@ ephy_location_entry_init (EphyLocationEntry *le)
 	p = EPHY_LOCATION_ENTRY_GET_PRIVATE (le);
 	le->priv = p;
 
-	p->user_changed = TRUE;
+	p->user_changed = FALSE;
+	p->block_update = FALSE;
+	p->saved_text = NULL;
 
 	ephy_location_entry_construct_contents (le);
 
@@ -1095,9 +1143,9 @@ ephy_location_entry_set_location (EphyLocationEntry *entry,
 	/* First record the new hash, then update the entry text */
 	priv->hash = g_str_hash (address);
 
-	priv->user_changed = FALSE;
+	priv->block_update = TRUE;
 	gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), text);
-	priv->user_changed = TRUE;
+	priv->block_update = FALSE;
 
 	/* We need to call update_address_state() here, as the 'changed' signal
 	 * may not get called if the user has typed in the exact correct url */
@@ -1115,6 +1163,22 @@ ephy_location_entry_set_location (EphyLocationEntry *entry,
 	}
 }
 
+gboolean
+ephy_location_entry_get_can_undo (EphyLocationEntry *entry)
+{
+	EphyLocationEntryPrivate *priv = entry->priv;
+	
+	return priv->user_changed;
+}
+
+gboolean
+ephy_location_entry_get_can_redo (EphyLocationEntry *entry)
+{
+	EphyLocationEntryPrivate *priv = entry->priv;
+	
+	return priv->can_redo;
+}
+
 const char *
 ephy_location_entry_get_location (EphyLocationEntry *entry)
 {
@@ -1137,6 +1201,10 @@ ephy_location_entry_reset_internal (EphyLocationEntry *entry,
 	old_text = gtk_entry_get_text (GTK_ENTRY (priv->icon_entry->entry));
 	old_text = old_text != NULL ? old_text : "";
 
+	g_free (priv->saved_text);
+	priv->saved_text = g_strdup (old_text);
+	priv->can_redo = TRUE;
+
 	retval = g_str_hash (text) != g_str_hash (old_text);
 
 	ephy_location_entry_set_location (entry, text, NULL);
@@ -1146,10 +1214,22 @@ ephy_location_entry_reset_internal (EphyLocationEntry *entry,
 	{
 		g_signal_emit (entry, signals[USER_CHANGED], 0);
 	}
+	
+	priv->user_changed = FALSE;
 
 	return retval;
 }
 
+void
+ephy_location_entry_undo_reset (EphyLocationEntry *entry)
+{
+	EphyLocationEntryPrivate *priv = entry->priv;
+	
+	gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), priv->saved_text);
+	priv->can_redo = FALSE;
+	priv->user_changed = TRUE;
+}
+
 gboolean
 ephy_location_entry_reset (EphyLocationEntry *entry)
 {
diff --git a/lib/widgets/ephy-location-entry.h b/lib/widgets/ephy-location-entry.h
index 0833bed..de6d35e 100644
--- a/lib/widgets/ephy-location-entry.h
+++ b/lib/widgets/ephy-location-entry.h
@@ -87,8 +87,14 @@ void		ephy_location_entry_set_completion_func (EphyLocationEntry *le,
 					
 const char     *ephy_location_entry_get_location	(EphyLocationEntry *le);
 
+gboolean	ephy_location_entry_get_can_undo	(EphyLocationEntry *le);
+
+gboolean	ephy_location_entry_get_can_redo	(EphyLocationEntry *entry);
+
 gboolean	ephy_location_entry_reset		(EphyLocationEntry *entry);
 
+void		ephy_location_entry_undo_reset		(EphyLocationEntry *entry);
+
 void		ephy_location_entry_activate		(EphyLocationEntry *le);
 
 GtkWidget      *ephy_location_entry_get_entry		(EphyLocationEntry *entry);
diff --git a/src/ephy-window.c b/src/ephy-window.c
index a8c696d..3ffe173 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -57,6 +57,7 @@
 #include "ephy-find-toolbar.h"
 #include "ephy-embed-persist.h"
 #include "ephy-embed-factory.h"
+#include "ephy-location-entry.h"
 
 #include <string.h>
 #include <glib/gi18n.h>
@@ -1128,15 +1129,35 @@ update_edit_actions_sensitivity (EphyWindow *window, gboolean hide)
 	if (GTK_IS_EDITABLE (widget))
 	{
 		gboolean has_selection;
-
+		GtkActionGroup *action_group;
+		GtkAction *location_action;
+		GSList *proxies;
+		GtkWidget *proxy;
+		
+		action_group = ephy_toolbar_get_action_group (window->priv->toolbar);
+		location_action = gtk_action_group_get_action (action_group,
+							       "Location");
+		proxies = gtk_action_get_proxies (location_action);
+		proxy = GTK_WIDGET (proxies->data);
+		
 		has_selection = gtk_editable_get_selection_bounds
 			(GTK_EDITABLE (widget), NULL, NULL);
 
 		can_copy = has_selection;
 		can_cut = has_selection;
 		can_paste = TRUE;
-		can_undo = FALSE;
-		can_redo = FALSE;
+		if (proxy != NULL &&
+		    EPHY_IS_LOCATION_ENTRY (proxy) &&
+		    widget == ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy)))
+		{
+			can_undo = ephy_location_entry_get_can_undo (EPHY_LOCATION_ENTRY (proxy));
+			can_redo = ephy_location_entry_get_can_redo (EPHY_LOCATION_ENTRY (proxy));
+		}
+		else
+		{
+			can_undo = FALSE;
+			can_redo = FALSE;
+		}
 	}
 	else
 	{
diff --git a/src/window-commands.c b/src/window-commands.c
index 9bc698a..dd5bd63 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -355,14 +355,24 @@ window_cmd_edit_undo (GtkAction *action,
 {
 	GtkWidget *widget;
 	GtkWidget *embed;
+	GtkWidget *location_entry;
 
 	widget = gtk_window_get_focus (GTK_WINDOW (window));
-	embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED);
-
-	if (embed)
+	location_entry = gtk_widget_get_ancestor (widget, EPHY_TYPE_LOCATION_ENTRY);
+	
+	if (location_entry)
+	{
+		ephy_location_entry_reset (EPHY_LOCATION_ENTRY (location_entry));
+	}
+	else 
 	{
-		ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), 
-						 "cmd_undo");
+		embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED);
+
+		if (embed)
+		{
+			ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), 
+							 "cmd_undo");
+		}
 	}
 }
 
@@ -372,17 +382,25 @@ window_cmd_edit_redo (GtkAction *action,
 {
 	GtkWidget *widget;
 	GtkWidget *embed;
+	GtkWidget *location_entry;
 
 	widget = gtk_window_get_focus (GTK_WINDOW (window));
-	embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED);
-
-	if (embed)
+	location_entry = gtk_widget_get_ancestor (widget, EPHY_TYPE_LOCATION_ENTRY);
+	
+	if (location_entry)
 	{
-		ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), 
-						 "cmd_redo");
+		ephy_location_entry_undo_reset (EPHY_LOCATION_ENTRY (location_entry));
+	}
+	else
+	{
+		embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED);
+		if (embed)
+		{
+			ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), 
+							 "cmd_redo");
+		}
 	}
 }
-
 void
 window_cmd_edit_cut (GtkAction *action,
 		     EphyWindow *window)
