diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 542607d..3468581 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -178,6 +178,8 @@ struct _EvView {
 	GtkWidget *goto_entry;
 
 	EvTransitionAnimation *animation;
+	
+	gchar *uri;
 };
 
 struct _EvViewClass {
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 8e7fc4a..940f2c3 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -287,7 +287,10 @@ static void       jump_to_find_result                        (EvView
 static void       jump_to_find_page                          (EvView             *view, 
 							      EvViewFindDirection direction,
 							      gint                shift);
-
+static void       synctex_open_editor                        (EvView             *view,
+							      gint page,
+							      gint doc_point_x,
+							      gint doc_point_y);
 /*** Selection ***/
 static void       compute_selections                         (EvView             *view,
 							      EvSelectionStyle    style,
@@ -1316,7 +1319,7 @@ goto_dest (EvView *view, EvLinkDest *dest)
 						view->current_page);
 }
 
-static void
+void
 ev_view_goto_dest (EvView *view, EvLinkDest *dest)
 {
 	EvLinkDestType type;
@@ -2626,6 +2629,25 @@ ev_view_button_press_event (GtkWidget      *widget,
 	view->pressed_button = event->button;
 	view->selection_info.in_drag = FALSE;
 
+	/* Doubleclick in document: open editor via synctex */
+	if( event->button==1 && event->type==GDK_2BUTTON_PRESS ){
+		/* First: get pagenumber and doc_point where doubleclick happened */
+		gint page=0;
+		gint offset_x=0, offset_y=0;
+		gint doc_point_x=0, doc_point_y=0;
+		
+		find_page_at_location(view, event->x+view->scroll_x, event->y+view->scroll_y,
+			&page, &offset_x, &offset_y);
+			
+		get_doc_point_from_offset(view, page, offset_x, offset_y,
+			&doc_point_x, &doc_point_y);
+
+		if ( page > -1 ){ /* Clicked inside a page: open editor and return */
+			synctex_open_editor(view, page, doc_point_x, doc_point_y);
+			return TRUE;
+		}
+	}
+
 	if (view->scroll_info.autoscrolling)
 		return TRUE;
 	
@@ -4420,6 +4442,13 @@ ev_view_reload (EvView *view)
 	view_update_range_and_current_page (view);
 }
 
+void
+ev_view_set_uri (EvView *view, gchar *uri)
+{
+	view->uri = uri;
+	return;
+}
+
 /*** Zoom and sizing mode ***/
 
 #define EPSILON 0.0000001
@@ -5153,6 +5182,75 @@ ev_view_find_cancel (EvView *view)
 	view->find_pages = NULL;
 }
 
+void
+ev_view_highlight_rect (EvView *view, EvRectangle *rect)
+{
+		gint i, page, n_pages;
+		gdouble width, height;
+		EvPoint point;
+
+		page = ev_page_cache_get_current_page (view->page_cache);
+		n_pages = ev_page_cache_get_n_pages (view->page_cache);
+
+		view->find_pages = (GList**)g_malloc( sizeof(gpointer) * n_pages );
+		for( i=0; i<n_pages; i++){
+			view->find_pages[i] = NULL;
+		}
+		view->find_pages[page] = g_list_append ( view->find_pages[page], rect );
+		view->highlight_find_results=TRUE;
+		
+		width = (gdouble)ev_view_get_width(view) / ev_view_get_zoom(view);
+		height = (gdouble)ev_view_get_height(view) / ev_view_get_zoom(view);
+		
+		point.x = (rect->x1+rect->x2)/2.0 - width/2.0;
+		if (point.x<0){
+			point.x=0;
+		}
+		point.y = (rect->y1+rect->y2)/2.0 - height/2.0;
+		if (point.y<0){
+			point.y=0;
+		}
+		view->pending_point = point;
+		view->pending_scroll = SCROLL_TO_PAGE_POSITION;
+		return;
+}
+
+#define MAX_SYNCTEX_ARG    2048
+
+static void 
+synctex_open_editor(EvView *view, gint page, gint doc_point_x, gint doc_point_y)
+{
+	GFile  *f = g_file_new_for_uri(view->uri);
+	GFile  *dir = g_file_get_parent(f);
+	gchar  *filename = g_file_get_path(f);
+	gchar  *dirname = g_file_get_path(dir);
+	gchar   synctex_arg[MAX_SYNCTEX_ARG];
+	gchar **argv;
+	gint    len;
+
+	g_object_unref(f);
+	g_object_unref(dir);
+
+	/* Build synctex argument with location information */
+	page += 1;  /* Page should be 1-based */
+	len = g_snprintf(synctex_arg, MAX_SYNCTEX_ARG, "%d:%d:%d:%s", page, doc_point_x, doc_point_y, filename);
+	g_free(filename);
+	if (len <= 0 || len > MAX_SYNCTEX_ARG) {
+		g_warning("synctex_open_editor: g_snprintf returned %d\n", len);
+		return;
+	}
+
+	/* Execute synctex command */
+	argv = g_new(gchar*, 6);
+	argv[0] = "synctex";
+	argv[1] = "edit";
+	argv[2] = "-o";
+	argv[3] = synctex_arg;
+	argv[4] = "-x";
+	argv[5] = NULL;
+	g_spawn_async(dirname, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
+}
+
 /*** Selections ***/
 
 /* compute_new_selection_rect/text calculates the area currently selected by
diff --git a/libview/ev-view.h b/libview/ev-view.h
index 2ff3aef..15787ca 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -57,6 +57,8 @@ void		ev_view_set_document	  (EvView         *view,
 void 		ev_view_set_loading       (EvView 	  *view,
 				           gboolean        loading);
 void            ev_view_reload            (EvView         *view);
+void			ev_view_set_uri			  (EvView		  *view,
+							gchar *uri);
 
 /* Clipboard */
 void		ev_view_copy		  (EvView         *view);
@@ -118,6 +120,8 @@ void            ev_view_find_changed              (EvView         *view,
 						   GList         **results,
 						   gint            page);
 void            ev_view_find_cancel               (EvView         *view);
+void            ev_view_highlight_rect            (EvView *view,
+						   EvRectangle *rect);
 
 /* Cursor */
 void           ev_view_hide_cursor        (EvView         *view);
@@ -129,6 +133,8 @@ void	       ev_view_scroll             (EvView         *view,
 					   gboolean        horizontal);
 void	       ev_view_handle_link        (EvView         *view,
 					   EvLink         *link);
+void           ev_view_goto_dest           (EvView         *view,
+                       EvLinkDest *dest);
 gboolean       ev_view_next_page	  (EvView         *view);
 gboolean       ev_view_previous_page	  (EvView         *view);
 gchar*         ev_view_page_label_from_dest (EvView *view, EvLinkDest *dest);
diff --git a/shell/ev-application.c b/shell/ev-application.c
index 56824e8..58316c2 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -24,6 +24,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -358,16 +359,22 @@ static EvLinkDest *
 get_destination_from_args (GHashTable *args)
 {
 	EvLinkDest *dest = NULL;
-	GValue     *value = NULL;
+	GValue     *page_value = NULL;
+	GValue     *absolute_value = NULL;
 	
 	g_assert (args != NULL);
 	
-	value = g_hash_table_lookup (args, "page-label");
-	if (value) {
+	page_value = g_hash_table_lookup (args, "page-label");
+	absolute_value= g_hash_table_lookup (args, "use-absolute-page");
+	
+	if (page_value) {
 		const gchar *page_label;
-
-		page_label = g_value_get_string (value);
-		dest = ev_link_dest_new_page_label (page_label);
+		page_label = g_value_get_string(page_value);
+		if ( g_value_get_boolean( absolute_value ) ){
+			dest = ev_link_dest_new_page( atol(page_label)-1 );
+		} else{
+			dest = ev_link_dest_new_page_label(page_label);
+		}
 	}
 
 	return dest;
@@ -385,6 +392,34 @@ get_find_string_from_args (GHashTable *args)
 	return value ? g_value_get_string (value) : NULL;
 }
 
+static EvRectangle *
+get_highlight_rect_from_args (GHashTable *args)
+{
+	GValue      *value = NULL;
+	EvRectangle *rect = NULL;
+	
+	g_assert (args != NULL);
+	rect = g_new(EvRectangle, 1);
+	
+	value = g_hash_table_lookup (args, "highlight-rect-x1");
+	if (!value) {	return NULL;	}
+	rect->x1 = g_value_get_double (value);
+
+	value = g_hash_table_lookup (args, "highlight-rect-x2");
+	if (!value) {	return NULL;	}
+	rect->x2 = g_value_get_double (value);
+
+	value = g_hash_table_lookup (args, "highlight-rect-y1");
+	if (!value) {	return NULL;	}
+	rect->y1 = g_value_get_double (value);
+
+	value = g_hash_table_lookup (args, "highlight-rect-y2");
+	if (!value) {	return NULL;	}
+	rect->y2 = g_value_get_double (value);
+
+	return rect;
+}
+
 /**
  * ev_application_open_window:
  * @application: The instance of the application.
@@ -519,6 +554,7 @@ ev_application_open_uri_at_dest (EvApplication  *application,
 				 EvLinkDest     *dest,
 				 EvWindowRunMode mode,
 				 const gchar    *search_string,
+				 EvRectangle    *highlight_rect,
 				 guint           timestamp)
 {
 	EvWindow *new_window;
@@ -542,7 +578,8 @@ ev_application_open_uri_at_dest (EvApplication  *application,
 
 	/* We need to load uri before showing the window, so
 	   we can restore window size without flickering */	
-	ev_window_open_uri (new_window, uri, dest, mode, search_string);
+	ev_window_open_uri (new_window, uri, dest, mode, search_string,
+	                    highlight_rect);
 
 	if (!GTK_WIDGET_REALIZED (GTK_WIDGET (new_window)))
 		gtk_widget_realize (GTK_WIDGET (new_window));
@@ -581,17 +618,19 @@ ev_application_open_uri (EvApplication  *application,
 	EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
 	const gchar     *search_string = NULL;
 	GdkScreen       *screen = NULL;
+	EvRectangle		*highlight_rect = NULL;
 
 	if (args) {
 		screen = get_screen_from_args (args);
 		dest = get_destination_from_args (args);
 		mode = get_window_run_mode_from_args (args);
 		search_string = get_find_string_from_args (args);
+		highlight_rect = get_highlight_rect_from_args (args);
 	}
-	
+
 	ev_application_open_uri_at_dest (application, uri, screen,
 					 dest, mode, search_string,
-					 timestamp);
+					 highlight_rect, timestamp);
 
 	if (dest)
 		g_object_unref (dest);
@@ -610,7 +649,7 @@ ev_application_open_uri_list (EvApplication *application,
 	for (l = uri_list; l != NULL; l = l->next) {
 		ev_application_open_uri_at_dest (application, (char *)l->data,
 						 screen, NULL, 0, NULL,
-						 timestamp);
+						 NULL, timestamp);
 	}
 }
 
diff --git a/shell/ev-application.h b/shell/ev-application.h
index ee38aea..8913e1f 100644
--- a/shell/ev-application.h
+++ b/shell/ev-application.h
@@ -69,6 +69,7 @@ void              ev_application_open_uri_at_dest    (EvApplication   *applicati
 						      EvLinkDest      *dest,
 						      EvWindowRunMode  mode,
 						      const gchar     *search_string,
+						      EvRectangle     *highlight_rect, 
 						      guint32          timestamp);
 void	          ev_application_open_uri_list       (EvApplication   *application,
 		  			              GSList          *uri_list,
diff --git a/shell/ev-window.c b/shell/ev-window.c
index f61e350..48c3c0e 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -190,6 +190,7 @@ struct _EvWindowPrivate {
 	EvLinkDest       *dest;
 	gchar            *search_string;
 	EvWindowRunMode   window_mode;
+	EvRectangle		 *highlight_rect;
 
 	EvJob            *load_job;
 	EvJob            *reload_job;
@@ -1360,6 +1361,7 @@ ev_window_load_job_cb (EvJob *job,
 
 	g_assert (job_load->uri);
 
+	ev_view_set_uri(EV_VIEW (ev_window->priv->view), g_strdup (job_load->uri));
 	ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
 
 	/* Success! */
@@ -1391,6 +1393,11 @@ ev_window_load_job_cb (EvJob *job,
 			link = ev_link_new (NULL, link_action);
 			ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
 		    	g_object_unref (link);
+			
+			if (ev_window->priv->highlight_rect) {
+				ev_view_highlight_rect ( EV_VIEW (ev_window->priv->view),
+					ev_window->priv->highlight_rect );
+			}
 
 			/* Already unrefed by ev_link_action
 			 * FIXME: link action should inc dest ref counting
@@ -1777,7 +1784,8 @@ ev_window_open_uri (EvWindow       *ev_window,
 		    const char     *uri,
 		    EvLinkDest     *dest,
 		    EvWindowRunMode mode,
-		    const gchar    *search_string)
+		    const gchar    *search_string, 
+		    EvRectangle     *highlight_rect)
 {
 	GFile *source_file;
 
@@ -1786,6 +1794,19 @@ ev_window_open_uri (EvWindow       *ev_window,
 	if (ev_window->priv->uri &&
 	    g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
 		ev_window_reload_document (ev_window);
+
+		if (dest){
+			if (ev_window->priv->dest){
+				g_object_unref (ev_window->priv->dest);
+			}
+			ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
+			ev_view_goto_dest(EV_VIEW (ev_window->priv->view), dest);
+
+			if (highlight_rect){
+				ev_window->priv->highlight_rect = highlight_rect;
+				ev_view_highlight_rect( EV_VIEW (ev_window->priv->view), highlight_rect );
+			}
+		}
 		return;
 	}
 
@@ -1814,6 +1835,8 @@ ev_window_open_uri (EvWindow       *ev_window,
 		g_object_unref (ev_window->priv->dest);
 	ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
 
+	ev_window->priv->highlight_rect = highlight_rect;
+
 	setup_size_from_metadata (ev_window);
 
 	ev_window->priv->load_job = ev_job_load_new (uri);
@@ -2147,6 +2170,7 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest)
 					 dest,
 					 0,
 					 NULL, 
+					 NULL,
 					 GDK_CURRENT_TIME);
 	g_free (symlink_uri);
 }
@@ -2180,7 +2204,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action,
 	
 	ev_application_open_uri_at_dest (EV_APP, uri,
 					 gtk_window_get_screen (GTK_WINDOW (window)),
-					 NULL, 0, NULL, GDK_CURRENT_TIME);
+					 NULL, 0, NULL, NULL, GDK_CURRENT_TIME);
 }
 
 static void
@@ -2190,7 +2214,7 @@ ev_window_open_recent_action_item_activated (EvOpenRecentAction *action,
 {
 	ev_application_open_uri_at_dest (EV_APP, uri,
 					 gtk_window_get_screen (GTK_WINDOW (window)),
-					 NULL, 0, NULL, GDK_CURRENT_TIME);
+					 NULL, 0, NULL, NULL, GDK_CURRENT_TIME);
 }
 
 static void
@@ -5300,6 +5324,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action)
 					 ev_link_action_get_dest (action),
 					 0,
 					 NULL, 
+					 NULL,
 					 GDK_CURRENT_TIME);
 
 	g_free (uri);
diff --git a/shell/ev-window.h b/shell/ev-window.h
index 1df15ec..89378ab 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -76,7 +76,8 @@ void		ev_window_open_uri	  (EvWindow       *ev_window,
 					   const char     *uri,
 					   EvLinkDest     *dest,
 					   EvWindowRunMode mode,
-					   const gchar    *search_string);
+					   const gchar    *search_string,
+					   EvRectangle     *highlight_rect);
 gboolean	ev_window_is_empty	  (const EvWindow *ev_window);
 void		ev_window_print_range     (EvWindow       *ev_window,
 					   int             first_page,
diff --git a/shell/main.c b/shell/main.c
index 22d42af..db4a793 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -43,6 +43,8 @@
 #endif
 
 static gchar   *ev_page_label;
+static gboolean use_absolute_page = FALSE;
+static gchar   *ev_highlight_rect;
 static gchar   *ev_find_string;
 static gboolean preview_mode = FALSE;
 static gboolean fullscreen_mode = FALSE;
@@ -66,6 +68,8 @@ option_version_cb (const gchar *option_name,
 static const GOptionEntry goption_options[] =
 {
 	{ "page-label", 'p', 0, G_OPTION_ARG_STRING, &ev_page_label, N_("The page of the document to display."), N_("PAGE")},
+	{ "use-absolute-page", 'a', 0, G_OPTION_ARG_NONE, &use_absolute_page, N_("PAGE is absolute page number (first page is 1). Use with -p"), NULL},
+	{ "highlight-rect", 'h', 0, G_OPTION_ARG_STRING, &ev_highlight_rect, N_("Highlight a rectangle in the document. Two possible formats: \"x:y\" ( x and y center of box) or \"x:y:w:h\" (x and y top-left corner of box, w and h width and height."), N_("COORDS")},
 	{ "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullscreen_mode, N_("Run evince in fullscreen mode"), NULL },
 	{ "presentation", 's', 0, G_OPTION_ARG_NONE, &presentation_mode, N_("Run evince in presentation mode"), NULL },
 	{ "preview", 'w', 0, G_OPTION_ARG_NONE, &preview_mode, N_("Run evince as a previewer"), NULL },
@@ -189,6 +193,7 @@ arguments_parse (void)
 	g_hash_table_insert (args, g_strdup ("screen"), value);
 
 	if (ev_page_label) {
+		/* ev_page_label */
 		value = g_new0 (GValue, 1);
 		g_value_init (value, G_TYPE_STRING);
 		g_value_set_string (value, ev_page_label);
@@ -197,6 +202,64 @@ arguments_parse (void)
 
 		g_free (ev_page_label);
 		ev_page_label = NULL;
+
+		/* use_absolute_page */
+		value = g_new0 (GValue, 1);
+		g_value_init (value, G_TYPE_BOOLEAN);
+		g_value_set_boolean (value, use_absolute_page);
+
+		g_hash_table_insert (args, g_strdup ("use-absolute-page"), value);
+	}
+	
+	if (ev_highlight_rect) {
+		int i;
+		gdouble x1, x2, y1, y2;
+		gchar **strings;
+		
+		strings = g_strsplit( ev_highlight_rect, ":", 5);		
+		for (i=0; strings[i]!=NULL; i++);
+		
+		if ( i==2 ) {
+			x1 = atof(strings[0]) - 10;
+			x2 = atof(strings[0]) + 10;
+			y1 = atof(strings[1]) - 10;
+			y2 = atof(strings[1]) + 10;
+		} else if ( i==4 ) {
+			x1 = atof(strings[0]);
+			x2 = atof(strings[0]) + atof(strings[2]);
+			y1 = atof(strings[1]);
+			y2 = atof(strings[1]) + atof(strings[3]);
+		}
+
+		if ( (i==2||i==4) && (x2-x1)>0 && (y2-y1)>0 ){
+			value = g_new0 (GValue, 1);
+			g_value_init (value, G_TYPE_DOUBLE);
+			g_value_set_double (value, x1);
+			g_hash_table_insert (args, g_strdup ("highlight-rect-x1"), value);
+			
+			value = g_new0 (GValue, 1);
+			g_value_init (value, G_TYPE_DOUBLE);
+			g_value_set_double (value, x2);
+			g_hash_table_insert (args, g_strdup ("highlight-rect-x2"), value);
+			
+			value = g_new0 (GValue, 1);
+			g_value_init (value, G_TYPE_DOUBLE);
+			g_value_set_double (value, y1);
+			g_hash_table_insert (args, g_strdup ("highlight-rect-y1"), value);
+			
+			value = g_new0 (GValue, 1);
+			g_value_init (value, G_TYPE_DOUBLE);
+			g_value_set_double (value, y2);
+			g_hash_table_insert (args, g_strdup ("highlight-rect-y2"), value);
+		} else {
+			/* FIXME: Should GError or something else be used for error handling?
+			 * 		  It would be best to quit after printing the error */
+			printf("Evince: Invalid argument for -h (or --highlight). Ignoring\n");
+		}
+
+		g_strfreev(strings);
+		g_free (ev_highlight_rect);
+		ev_highlight_rect = NULL;
 	}
 
 	if (ev_find_string) {
