Squashed commit of the following:

commit ad26faaf4a0b72d378e77204edf4efedfa2a3933
Author: Garrett Regier <alias301@gmail.com>
Date:   Sun May 23 22:29:34 2010 -0700

    More cleanup

commit 558a96f101428587534746593b29b8bd6346aa20
Author: Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
Date:   Sun May 23 12:38:26 2010 +0200

    Add introspection support to build

    Adds -Wno-portability because we don't presume to support
    non-GNU make,
    http://mail.gnome.org/archives/desktop-devel-list/2009-February/msg00111.html.

    https://bugzilla.gnome.org/show_bug.cgi?id=598536

commit e36ce88c75953ba0b8ff7d7967274e4bd08f7e4f
Author: Fran Diéguez <fran.dieguez@mabishu.com>
Date:   Sat May 22 23:54:08 2010 +0200

    Updated Galician translations

commit d4943a4904f644aecb51dacc5a265b91683b0304
Author: Fran Diéguez <fran.dieguez@mabishu.com>
Date:   Thu May 20 18:58:03 2010 +0200

    Updated Galician translations

commit 1a0a4f459c2e938ecc7be6a6acdec6f6de6808b6
Author: Garrett Regier <alias301@gmail.com>
Date:   Wed May 19 23:41:15 2010 -0700

    Bug 132780 - Added gtk_source_view_get_visual_column

    Utility function to get the visual column at an iter and takes into consideration the indent width

commit ac946e69a4bc9df21f072d5bb58adb5e19f6265e
Author: Garrett Regier <alias301@gmail.com>
Date:   Wed May 19 23:39:47 2010 -0700

    Fix make distcheck

commit 8c0e765c50a0541c8a191e8180fc713950e2bfc2
Author: Garrett Regier <alias301@gmail.com>
Date:   Wed May 19 08:40:01 2010 -0700

    Bug 159134 - Relicense as LGPL

commit 5838e663f604cd04dc77a6ebe9292b659ed02480
Author: Jesse van den Kieboom <jessevdk@gnome.org>
Date:   Wed May 19 08:10:35 2010 +0200

    Fix test-widget for new directories (languages, styles)

commit da012bfafc3bb8446a13a15a52a5cc0e0ad9e949
Author: Garrett Regier <alias301@gmail.com>
Date:   Tue May 18 03:51:24 2010 -0700

    Bug 614373 - Made Glade catalog translatable

commit ccf1d1f356dfc9a2d81b0dd8cde882ce562a4823
Author: Garrett Regier <alias301@gmail.com>
Date:   Mon May 17 15:39:02 2010 -0700

    Move glade/ and gtksourceview/language-specs to data/

    This also moves the styles from language-specs/ to styles/

commit 2ad3c34e36a7c2f5e2bc0f929a399b22b9e05ddf
Author: Garrett Regier <alias301@gmail.com>
Date:   Mon May 17 15:39:02 2010 -0700

    Bug 618820 - Add new javascript keywords

commit bfbc34a72ee0a6747bcf17a82710def4d3df3c22
Merge: f2a01ae cde1482
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Tue May 18 11:14:24 2010 +0200

    Merge branch 'master' into new_split_engine

    Conflicts:
    	gtksourceview/Makefile.am
    	gtksourceview/gtksourcebuffer.c
    	gtksourceview/gtksourceview-marshal.list

commit f2a01ae4123bf447ffd2f6ee8661476c60d4435a
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Sun May 16 15:07:27 2010 +0200

    Hide the internals of SubPatterns.

commit f709df605842fd15275bf56e592230c6fe807a80
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Sun May 16 13:43:56 2010 +0200

    Refactor API from GtkHighlightEngine to GtkSourceSyntaxHighlighter

commit c00e57f5895041a1691e4c3c8dcf3ee08a9514ca
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Sun May 16 13:43:26 2010 +0200

    Rename gtkhighlightengine to gtksourcesyntaxhighlighter.

commit 5287f22dbb7327a4f8bc206159c7f6153ae85790
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Sun May 16 13:24:09 2010 +0200

    First try at hidding internals of Syntax Tree

commit 628a0a4df5d4d5b1f39404127dea8dfbc37ce15b
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Fri May 14 13:12:08 2010 +0200

    Finished cleaning

commit e690480c871534aa6e41e4942b6f569324a922a2
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Fri May 14 12:35:34 2010 +0200

    More cleaning

commit d6a6c43724bd9b30c2878b5d39f46513b1c24f87
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Fri May 14 12:17:05 2010 +0200

    Cleaning highlightengine

commit af7ebb063e6f2109acc88d126c8d7d02fbf70403
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Thu May 13 20:53:41 2010 +0200

    Updating other files to the splited engines.

commit a7a6ce3d4985ca6abf80558abc8787e4b96d43b2
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Thu May 13 20:46:08 2010 +0200

    Real split

commit 8986183d594643136ceb35948d1e6524cb56004b
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Thu May 13 20:34:53 2010 +0200

    Split gtksourcecontextengine.c and gtksourcecontextengine.h

commit cf1231326b347ce0203c63adb5f67bada07fa66f
Author: Jose Aliste <jose.aliste@gmail.com>
Date:   Thu May 13 20:02:46 2010 +0200

    Enabling silent_rules compilation.

diff --git a/gtksourceview/Makefile.am b/gtksourceview/Makefile.am
index d9e7c16..5e60e77 100644
@@ -38,9 +38,10 @@ libgtksourceview_headers =			\
 	gtksourcecompletionitem.h		\
 	gtksourcecompletionproposal.h		\
 	gtksourcecompletionprovider.h		\
-	gtksourcecompletioncontext.h
+	gtksourcecompletioncontext.h		
 
 NOINST_H_FILES = \
+	gtksourcebuffer-private.h	\
 	gtksourcecompletionmodel.h	\
 	gtksourcecompletion-private.h	\
 	gtksourcecompletionutils.h	\
@@ -54,7 +55,9 @@ NOINST_H_FILES = \
 	gtksourceview-i18n.h		\
 	gtksourceview-utils.h		\
 	gtktextregion.h			\
-	gseal-gtk-compat.h
+	gseal-gtk-compat.h		\
+	gtksourcesyntaxhighlighter.h	\
+	gtksourcecontextengine-private.h 
 
 libgtksourceview_2_0_la_SOURCES = 	\
 	gtksourcebuffer.c 		\
@@ -85,6 +88,7 @@ libgtksourceview_2_0_la_SOURCES = 	\
 	gtksourcecompletionmodel.c	\
 	gtksourcecompletionutils.c	\
 	gtksourcecompletioncontext.c 	\
+	gtksourcesyntaxhighlighter.c	\
 	$(libgtksourceview_headers)	\
 	$(NOINST_H_FILES)
 
diff --git a/gtksourceview/gtksourcebuffer-private.h b/gtksourceview/gtksourcebuffer-private.h
new file mode 100644
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
+ *  gtksourcebuffer-private.h
+ *
+ *  Copyright (C) 1999,2000,2001,2002 by:
+ *          Mikael Hermansson <tyan@linux.se>
+ *          Chris Phelps <chicane@reninet.com>
+ *          Jeroen Zwartepoorte <jeroen@xs4all.nl>
+ *
+ *  Copyright (C) 2003 - Paolo Maggi, Gustavo Giráldez
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library 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.
+ */
+
+#ifndef __GTK_SOURCE_BUFFER_PRIVATE_H__
+#define __GTK_SOURCE_BUFFER_PRIVATE_H__
+
+#include "gtksourceview/gtksourcebuffer.h"
+#include "gtksourceview/gtksourceengine.h"
+
+G_BEGIN_DECLS
+
+GtkSourceEngine	*_gtk_source_buffer_get_analyzer	(GtkSourceBuffer *buffer);
+
+G_END_DECLS
+
+#endif /* __GTK_SOURCE_BUFFER_PRIVATE_H__ */
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index 0f1c7aa..7c98a76 100644
@@ -41,6 +41,7 @@
 #include "gtksourcestyle-private.h"
 #include "gtksourceundomanagerdefault.h"
 #include "gtksourceview-typebuiltins.h"
+#include "gtksourcesyntaxhighlighter.h"
 
 /**
  * SECTION:buffer
@@ -104,16 +105,12 @@ enum {
 	PROP_MAX_UNDO_LEVELS,
 	PROP_LANGUAGE,
 	PROP_STYLE_SCHEME,
-	PROP_UNDO_MANAGER
+	PROP_UNDO_MANAGER,
+	PROP_ANALYZE_SYNTAX
 };
 
 struct _GtkSourceBufferPrivate
 {
-	gint                   highlight_syntax:1;
-	gint                   highlight_brackets:1;
-
-	gint                   constructed:1;
-
 	GtkTextTag            *bracket_match_tag;
 	GtkTextMark           *bracket_mark_cursor;
 	GtkTextMark           *bracket_mark_match;
@@ -123,13 +120,18 @@ struct _GtkSourceBufferPrivate
 
 	GtkSourceLanguage     *language;
 
-	GtkSourceEngine       *highlight_engine;
+	GtkSourceEngine       *syntax_analyzer;
+	GtkSourceSyntaxHighlighter  *highlighter;
 	GtkSourceStyleScheme  *style_scheme;
 
 	GtkSourceUndoManager  *undo_manager;
 	gint                   max_undo_levels;
 
-	gint                   allow_bracket_match:1;
+	guint                  constructed : 1;
+	guint                  allow_bracket_match : 1;
+	guint                  analyze_syntax : 1;
+	guint                  highlight_syntax : 1;
+	guint                  highlight_brackets : 1;
 };
 
 G_DEFINE_TYPE (GtkSourceBuffer, gtk_source_buffer, GTK_TYPE_TEXT_BUFFER)
@@ -226,6 +228,14 @@ gtk_source_buffer_class_init (GtkSourceBufferClass *klass)
 								 "in the buffer"),
 							       TRUE,
 							       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_ANALYZE_SYNTAX,
+					 g_param_spec_boolean ("analyze-syntax",
+					 		       _("Analyze syntax"),
+					 		       _("Whether the syntax of the "
+					 		         "buffer should be analyzed"),
+					 		       TRUE,
+					 		       G_PARAM_READWRITE));
 
 	/**
 	 * GtkSourceBuffer:highlight-matching-brackets:
@@ -434,6 +444,7 @@ gtk_source_buffer_init (GtkSourceBuffer *buffer)
 
 	buffer->priv = priv;
 
+	priv->analyze_syntax = TRUE;
 	priv->highlight_syntax = TRUE;
 	priv->highlight_brackets = TRUE;
 	priv->bracket_mark_cursor = NULL;
@@ -505,11 +516,11 @@ gtk_source_buffer_dispose (GObject *object)
 		set_undo_manager (buffer, NULL);
 	}
 
-	if (buffer->priv->highlight_engine != NULL)
+	if (buffer->priv->syntax_analyzer != NULL)
 	{
-		_gtk_source_engine_attach_buffer (buffer->priv->highlight_engine, NULL);
-		g_object_unref (buffer->priv->highlight_engine);
-		buffer->priv->highlight_engine = NULL;
+		_gtk_source_engine_attach_buffer (buffer->priv->syntax_analyzer, NULL);
+		g_object_unref (buffer->priv->syntax_analyzer);
+		buffer->priv->syntax_analyzer = NULL;
 	}
 
 	if (buffer->priv->language != NULL)
@@ -571,6 +582,10 @@ gtk_source_buffer_set_property (GObject      *object,
 			                                    g_value_get_object (value));
 			break;
 
+		case PROP_ANALYZE_SYNTAX:
+			gtk_source_buffer_set_analyze_syntax (source_buffer, 
+							      g_value_get_boolean (value));
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 			break;
@@ -626,6 +641,10 @@ gtk_source_buffer_get_property (GObject    *object,
 			g_value_set_object (value, source_buffer->priv->undo_manager);
 			break;
 
+                case PROP_ANALYZE_SYNTAX:
+                        g_value_set_boolean (value, 
+					     source_buffer->priv->analyze_syntax);
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 			break;
@@ -914,8 +933,8 @@ gtk_source_buffer_content_inserted (GtkTextBuffer *buffer,
 	gtk_text_buffer_get_iter_at_mark (buffer, &insert_iter, mark);
 	gtk_source_buffer_move_cursor (buffer, &insert_iter, mark);
 
-	if (source_buffer->priv->highlight_engine != NULL)
-		_gtk_source_engine_text_inserted (source_buffer->priv->highlight_engine,
+	if (source_buffer->priv->syntax_analyzer != NULL)
+		_gtk_source_engine_text_inserted (source_buffer->priv->syntax_analyzer,
 						  start_offset,
 						  end_offset);
 }
@@ -1030,8 +1049,8 @@ gtk_source_buffer_real_delete_range (GtkTextBuffer *buffer,
 	gtk_source_buffer_move_cursor (buffer, &iter, mark);
 
 	/* emit text deleted for engines */
-	if (source_buffer->priv->highlight_engine != NULL)
-		_gtk_source_engine_text_deleted (source_buffer->priv->highlight_engine,
+	if (source_buffer->priv->syntax_analyzer != NULL)
+		_gtk_source_engine_text_deleted (source_buffer->priv->syntax_analyzer,
 						 offset, length);
 }
 
@@ -1451,6 +1470,50 @@ gtk_source_buffer_set_highlight_syntax (GtkSourceBuffer *buffer,
 }
 
 /**
+ * gtk_source_buffer_get_analyze_syntax:
+ * @buffer: a #GtkSourceBuffer.
+ *
+ * Determines whether syntax highlighting is activated in the source
+ * buffer.
+ *
+ * Return value: %TRUE if syntax highlighting is enabled, %FALSE otherwise.
+ **/
+gboolean
+gtk_source_buffer_get_analyze_syntax (GtkSourceBuffer *buffer)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_BUFFER (buffer), FALSE);
+
+	return (buffer->priv->analyze_syntax != FALSE);
+}
+
+/**
+ * gtk_source_buffer_set_analyze_syntax:
+ * @buffer: a #GtkSourceBuffer.
+ * @analyze: %TRUE to enable syntax analysis, %FALSE to disable it.
+ *
+ * Controls whether to analyze the syntax of the buffer. If @analyze
+ * is %TRUE, a syntax text will be highlighted according to the syntax
+ * patterns specified in the language set with
+ * gtk_source_buffer_set_language(). If @highlight is %FALSE, syntax highlighting
+ * is disabled and all the GtkTextTag objects that have been added by the
+ * syntax highlighting engine are removed from the buffer.
+ **/
+void
+gtk_source_buffer_set_analyze_syntax (GtkSourceBuffer *buffer,
+					gboolean         analyze)
+{
+	g_return_if_fail (GTK_IS_SOURCE_BUFFER (buffer));
+
+	analyze = (analyze != FALSE);
+
+	if (buffer->priv->analyze_syntax != analyze)
+	{
+		buffer->priv->analyze_syntax = analyze;
+		g_object_notify (G_OBJECT (buffer), "analyze-syntax");
+	}
+}
+
+/**
  * gtk_source_buffer_set_language:
  * @buffer: a #GtkSourceBuffer.
  * @language: (allow-none): a #GtkSourceLanguage to set, or %NULL.
@@ -1473,12 +1536,12 @@ gtk_source_buffer_set_language (GtkSourceBuffer   *buffer,
 	if (buffer->priv->language == language)
 		return;
 
-	if (buffer->priv->highlight_engine != NULL)
+	if (buffer->priv->syntax_analyzer != NULL)
 	{
 		/* disconnect the old engine */
-		_gtk_source_engine_attach_buffer (buffer->priv->highlight_engine, NULL);
-		g_object_unref (buffer->priv->highlight_engine);
-		buffer->priv->highlight_engine = NULL;
+		_gtk_source_engine_attach_buffer (buffer->priv->syntax_analyzer, NULL);
+		g_object_unref (buffer->priv->syntax_analyzer);
+		buffer->priv->syntax_analyzer = NULL;
 	}
 
 	if (buffer->priv->language != NULL)
@@ -1491,16 +1554,22 @@ gtk_source_buffer_set_language (GtkSourceBuffer   *buffer,
 		g_object_ref (language);
 
 		/* get a new engine */
-		buffer->priv->highlight_engine = _gtk_source_language_create_engine (language);
+		buffer->priv->syntax_analyzer = _gtk_source_language_create_engine (language);
 
-		if (buffer->priv->highlight_engine)
+		if (buffer->priv->syntax_analyzer)
 		{
-			_gtk_source_engine_attach_buffer (buffer->priv->highlight_engine,
+			_gtk_source_engine_attach_buffer (buffer->priv->syntax_analyzer,
 							  GTK_TEXT_BUFFER (buffer));
 
+			buffer->priv->highlighter = _gtk_source_syntax_highlighter_new (GTK_TEXT_BUFFER (buffer));
+			_gtk_source_syntax_highlighter_set_styles_map (buffer->priv->highlighter,
+								       language->priv->styles);
+
 			if (buffer->priv->style_scheme)
-				_gtk_source_engine_set_style_scheme (buffer->priv->highlight_engine,
-								     buffer->priv->style_scheme);
+			{
+				_gtk_source_syntax_highlighter_set_style_scheme (buffer->priv->highlighter,
+										 buffer->priv->style_scheme);
+			}
 		}
 	}
 
@@ -1542,11 +1611,13 @@ _gtk_source_buffer_update_highlight (GtkSourceBuffer   *buffer,
 {
 	g_return_if_fail (GTK_IS_SOURCE_BUFFER (buffer));
 
-	if (buffer->priv->highlight_engine != NULL)
-		_gtk_source_engine_update_highlight (buffer->priv->highlight_engine,
-						     start,
-						     end,
-						     synchronous);
+	if (buffer->priv->syntax_analyzer != NULL)
+	{
+		_gtk_source_engine_analyze (buffer->priv->syntax_analyzer,
+					    start,
+					    end,
+					    synchronous);
+	}
 }
 
 /**
@@ -1600,9 +1671,9 @@ gtk_source_buffer_set_style_scheme (GtkSourceBuffer      *buffer,
 	buffer->priv->style_scheme = scheme ? g_object_ref (scheme) : NULL;
 	update_bracket_match_style (buffer);
 
-	if (buffer->priv->highlight_engine != NULL)
-		_gtk_source_engine_set_style_scheme (buffer->priv->highlight_engine,
-						     scheme);
+	if (buffer->priv->syntax_analyzer != NULL)
+		_gtk_source_syntax_highlighter_set_style_scheme (buffer->priv->highlighter,
+						        scheme);
 
 	g_object_notify (G_OBJECT (buffer), "style-scheme");
 }
@@ -2238,12 +2309,12 @@ gtk_source_buffer_iter_has_context_class (GtkSourceBuffer   *buffer,
 	g_return_val_if_fail (iter != NULL, FALSE);
 	g_return_val_if_fail (context_class != NULL, FALSE);
 
-	if (buffer->priv->highlight_engine == NULL)
+	if (buffer->priv->syntax_analyzer == NULL)
 	{
 		return FALSE;
 	}
 
-	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->highlight_engine,
+	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->syntax_analyzer,
 							context_class);
 
 	if (tag != NULL)
@@ -2324,12 +2395,12 @@ gtk_source_buffer_iter_forward_to_context_class_toggle (GtkSourceBuffer *buffer,
 	g_return_val_if_fail (iter != NULL, FALSE);
 	g_return_val_if_fail (context_class != NULL, FALSE);
 
-	if (buffer->priv->highlight_engine == NULL)
+	if (buffer->priv->syntax_analyzer == NULL)
 	{
 		return FALSE;
 	}
 
-	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->highlight_engine,
+	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->syntax_analyzer,
 							context_class);
 
 	if (tag == NULL)
@@ -2369,12 +2440,12 @@ gtk_source_buffer_iter_backward_to_context_class_toggle (GtkSourceBuffer *buffer
 	g_return_val_if_fail (iter != NULL, FALSE);
 	g_return_val_if_fail (context_class != NULL, FALSE);
 
-	if (buffer->priv->highlight_engine == NULL)
+	if (buffer->priv->syntax_analyzer == NULL)
 	{
 		return FALSE;
 	}
 
-	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->highlight_engine,
+	tag = _gtk_source_engine_get_context_class_tag (buffer->priv->syntax_analyzer,
 							context_class);
 
 	if (tag == NULL)
@@ -2437,3 +2508,11 @@ gtk_source_buffer_get_undo_manager (GtkSourceBuffer *buffer)
 
 	return buffer->priv->undo_manager;
 }
+
+GtkSourceEngine *
+_gtk_source_buffer_get_analyzer (GtkSourceBuffer *buffer)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_BUFFER (buffer), NULL);
+
+	return buffer->priv->syntax_analyzer;
+}
diff --git a/gtksourceview/gtksourcebuffer.h b/gtksourceview/gtksourcebuffer.h
index d802f64..97d51a4 100644
@@ -119,6 +119,9 @@ GtkSourceStyleScheme    *gtk_source_buffer_get_style_scheme     (GtkSourceBuffer
 void			 gtk_source_buffer_set_style_scheme     (GtkSourceBuffer        *buffer,
 								 GtkSourceStyleScheme   *scheme);
 
+gboolean		 gtk_source_buffer_get_analyze_syntax	(GtkSourceBuffer        *buffer);
+void			 gtk_source_buffer_set_analyze_syntax	(GtkSourceBuffer        *buffer,
+								 gboolean                analyze);
 /* Force highlighting */
 void			 gtk_source_buffer_ensure_highlight     (GtkSourceBuffer        *buffer,
 								 const GtkTextIter      *start,
@@ -128,8 +131,10 @@ void			 gtk_source_buffer_ensure_highlight     (GtkSourceBuffer        *buffer,
 void			 gtk_source_buffer_undo			(GtkSourceBuffer        *buffer);
 void			 gtk_source_buffer_redo			(GtkSourceBuffer        *buffer);
 
-void			 gtk_source_buffer_begin_not_undoable_action (GtkSourceBuffer   *buffer);
-void			 gtk_source_buffer_end_not_undoable_action   (GtkSourceBuffer   *buffer);
+void			 gtk_source_buffer_begin_not_undoable_action
+								(GtkSourceBuffer   *buffer);
+void			 gtk_source_buffer_end_not_undoable_action
+								(GtkSourceBuffer   *buffer);
 
 /* Mark methods */
 GtkSourceMark		*gtk_source_buffer_create_source_mark	(GtkSourceBuffer        *buffer,
@@ -193,7 +198,8 @@ GtkSourceMark		*_gtk_source_buffer_source_mark_prev	(GtkSourceBuffer        *buf
 								 GtkSourceMark          *mark, 
 								 const gchar            *category);
 
-GtkTextTag		*_gtk_source_buffer_get_bracket_match_tag (GtkSourceBuffer        *buffer);
+GtkTextTag		*_gtk_source_buffer_get_bracket_match_tag
+								(GtkSourceBuffer        *buffer);
 
 G_END_DECLS
 
diff --git a/gtksourceview/gtksourcecontextengine-private.h b/gtksourceview/gtksourcecontextengine-private.h
new file mode 100644
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
+ * gtksourcecontextengine-private.h
+ * This file is part of gtksourceview
+ *
+ * Copyright (C) 2010 - Jose Aliste <jose.aliste@gmail.com>
+ *
+ * gtksourceview 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.1 of the License, or (at your option) any later version.
+ *
+ * gtksourceview 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GTK_SOURCE_CONTEXT_ENGINE_PRIVATE_H__
+#define __GTK_SOURCE_CONTEXT_ENGINE_PRIVATE_H__
+
+G_BEGIN_DECLS
+
+typedef struct _BufAndIters		BufAndIters;
+typedef struct _Segment			Segment;
+typedef struct _Annotation		Annotation;
+typedef struct _SubPattern		SubPattern;
+typedef struct _SubPatternAnnotation	SubPatternAnnotation;
+
+struct _BufAndIters
+{
+	GtkTextBuffer     *buffer;
+	const GtkTextIter *start;
+	const GtkTextIter *end;
+};
+
+typedef enum {
+	SUB_PATTERN_WHERE_DEFAULT = 0,
+	SUB_PATTERN_WHERE_START,
+	SUB_PATTERN_WHERE_END
+} SubPatternWhere;
+
+struct _Segment
+{
+	Segment			*parent;
+	Segment			*next;
+	Segment			*prev;
+	Segment			*children;
+	Segment			*last_child;
+
+	/* Subpatterns found in this segment. */
+	SubPattern		*sub_patterns;
+
+	/* Offsets of the segment [start_at; end_at). */
+	gint			 start_at;
+	gint			 end_at;
+
+	/* In case of container contexts, start_len/end_len is length in chars
+	 * of start/end match. */	 
+	gint			 start_len;
+	gint			 end_len;
+	
+	/* Annotation with style and class information.
+	 * Eventually, we may add a GInterface (implemented by Analyzers) 
+	 * so handlers can add custom data to the annotation. */  
+	Annotation		*annot;
+};
+
+struct _Annotation 
+{
+	gchar			*style;
+	GtkTextTag		*style_tag;
+	guint			 style_inside; /* ??? */
+	GSList			*context_classes;
+	/* context information; */
+};
+
+struct _SubPattern
+{
+	Annotation		*annot;
+	gint			 start_at;
+	gint			 end_at;
+	SubPattern		*next;
+};
+
+
+G_END_DECLS
+
+#endif /* __GTK_SOURCE_CONTEXT_ENGINE_PRIVATE_H__ */
diff --git a/gtksourceview/gtksourcecontextengine.c b/gtksourceview/gtksourcecontextengine.c
index 4308254..cb6844b 100644
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2003 - Gustavo Giráldez <gustavo.giraldez@gmx.net>
  *  Copyright (C) 2005, 2006 - Marco Barisione, Emanuele Aina
+ *  Copyright (C) 2010, Jose Aliste <jose.aliste@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU Library General Public License as published by
@@ -21,10 +22,12 @@
 
 #include "gtksourceview-i18n.h"
 #include "gtksourcecontextengine.h"
+#include "gtksourcecontextengine-private.h"
 #include "gtktextregion.h"
 #include "gtksourcelanguage-private.h"
 #include "gtksourcebuffer.h"
 #include "gtksourcestyle-private.h"
+#include "gtksourceview-marshal.h"
 
 #include <glib.h>
 
@@ -83,7 +86,6 @@
 #define LOOKUP_DEFINITION(ctx_data, id) \
 	(g_hash_table_lookup ((ctx_data)->definitions, (id)))
 
-#define HAS_OPTION(def,opt) (((def)->flags & GTK_SOURCE_CONTEXT_##opt) != 0)
 
 /* Can the context be terminated by ancestor? */
 /* Root context can't be terminated; its child may not be terminated by it;
@@ -101,40 +103,30 @@
 #define CONTEXT_ENDS_PARENT(ctx) \
 	((ctx)->parent != NULL && (ctx)->parent->parent != NULL && \
 		HAS_OPTION ((ctx)->definition, END_PARENT))
-#define SEGMENT_ENDS_PARENT(s) CONTEXT_ENDS_PARENT ((s)->context)
+
+#define HAS_OPTION(def,opt) (((def)->flags & GTK_SOURCE_CONTEXT_##opt) != 0)
+#define CONTEXT_IS_SIMPLE(c) ((c)->definition->type == CONTEXT_TYPE_SIMPLE)
+#define CONTEXT_IS_CONTAINER(c) ((c)->definition->type == CONTEXT_TYPE_CONTAINER)
+
+
+/* Segment macros */
+#define SEGMENT_ENDS_PARENT(s) CONTEXT_ENDS_PARENT (SEGMENT_GET_CONTEXT(s))
 
 /* Does the segment terminate at line end? */
 /* Root segment doesn't, children look at the flag */
 #define CONTEXT_END_AT_LINE_END(ctx) \
 	((ctx)->parent != NULL && HAS_OPTION ((ctx)->definition, END_AT_LINE_END))
-#define SEGMENT_END_AT_LINE_END(s) CONTEXT_END_AT_LINE_END((s)->context)
+#define SEGMENT_END_AT_LINE_END(s) CONTEXT_END_AT_LINE_END(SEGMENT_GET_CONTEXT(s))
 
-#define CONTEXT_IS_SIMPLE(c) ((c)->definition->type == CONTEXT_TYPE_SIMPLE)
-#define CONTEXT_IS_CONTAINER(c) ((c)->definition->type == CONTEXT_TYPE_CONTAINER)
-#define SEGMENT_IS_INVALID(s) ((s)->context == NULL)
-#define SEGMENT_IS_SIMPLE(s) CONTEXT_IS_SIMPLE ((s)->context)
-#define SEGMENT_IS_CONTAINER(s) CONTEXT_IS_CONTAINER ((s)->context)
+#define SEGMENT_IS_INVALID(s) (SEGMENT_GET_CONTEXT(s) == NULL)
+#define SEGMENT_IS_SIMPLE(s) CONTEXT_IS_SIMPLE (SEGMENT_GET_CONTEXT(s))
+#define SEGMENT_IS_CONTAINER(s) CONTEXT_IS_CONTAINER (SEGMENT_GET_CONTEXT(s))
 
-#define ENGINE_ID(ce) ((ce)->priv->ctx_data->lang->priv->id)
-#define ENGINE_STYLES_MAP(ce) ((ce)->priv->ctx_data->lang->priv->styles)
 
 #define TAG_CONTEXT_CLASS_NAME "GtkSourceViewTagContextClassName"
 
-typedef struct _RegexInfo RegexInfo;
-typedef struct _RegexAndMatch RegexAndMatch;
-typedef struct _Regex Regex;
-typedef struct _SubPatternDefinition SubPatternDefinition;
-typedef struct _SubPattern SubPattern;
-typedef struct _Segment Segment;
-typedef struct _Context Context;
-typedef struct _ContextPtr ContextPtr;
-typedef struct _ContextDefinition ContextDefinition;
-typedef struct _DefinitionChild DefinitionChild;
-typedef struct _DefinitionsIter DefinitionsIter;
-typedef struct _LineInfo LineInfo;
-typedef struct _InvalidRegion InvalidRegion;
-typedef struct _ContextClassTag ContextClassTag;
-
+#define ENGINE_ID(ce) ((ce)->priv->ctx_data->lang->priv->id)
+#define ENGINE_STYLES_MAP(ce) ((ce)->priv->ctx_data->lang->priv->styles)
 typedef enum {
 	GTK_SOURCE_CONTEXT_ENGINE_ERROR_DUPLICATED_ID = 0,
 	GTK_SOURCE_CONTEXT_ENGINE_ERROR_INVALID_ARGS,
@@ -152,11 +144,62 @@ typedef enum {
 	CONTEXT_TYPE_CONTAINER
 } ContextType;
 
-typedef enum {
-	SUB_PATTERN_WHERE_DEFAULT = 0,
-	SUB_PATTERN_WHERE_START,
-	SUB_PATTERN_WHERE_END
-} SubPatternWhere;
+typedef struct _RegexInfo RegexInfo;
+typedef struct _RegexAndMatch RegexAndMatch;
+typedef struct _Regex Regex;
+typedef struct _ContextPtr ContextPtr;
+typedef struct _Context Context;
+typedef struct _ContextDefinition ContextDefinition;
+typedef struct _DefinitionChild DefinitionChild;
+typedef struct _DefinitionsIter DefinitionsIter;
+typedef struct _LineInfo LineInfo;
+typedef struct _InvalidRegion InvalidRegion;
+typedef struct _ContextClassTag ContextClassTag;
+typedef struct _SubPatternDefinition SubPatternDefinition;
+
+typedef struct _RealSegment RealSegment;
+typedef struct _RealSubPattern RealSubPattern;
+
+struct _RealSegment 
+{
+	Segment			segment;
+	Context			*context;
+	/* Whether this segment is a whole good segment, or it's an
+	 * an end of bigger one left after erase_segments() call. */
+	guint			is_start : 1;
+
+	/* This is NULL if and only if it's a dummy segment which denotes
+	 * inserted or deleted text. */
+};
+
+struct _RealSubPattern
+{
+	SubPattern		sub_pattern;
+	SubPatternDefinition 	*definition;
+};
+
+/* Accessing hidden elements of the Segment structure */
+#define SEGMENT_GET_CONTEXT(s) \
+	(((RealSegment *)(s))->context)
+#define SEGMENT_GET_IS_START(s) \
+	(((RealSegment *)(s))->is_start)
+/* Accessing hidden sub_pattern definition of a SubPattern */
+#define SUBPATTERN_GET_DEFINITION(subpat) \
+	(((RealSubPattern *)(subpat))->definition)
+
+
+struct _GtkSourceContextClass
+{
+	gchar    *name;
+	gboolean  enabled;
+};
+
+struct _ContextClassTag
+{
+	GtkTextTag *tag;
+	gboolean enabled;
+};
+
 
 struct _RegexInfo
 {
@@ -182,63 +225,7 @@ struct _Regex
 	guint			 resolved : 1;
 };
 
-struct _ContextDefinition
-{
-	gchar			*id;
-
-	ContextType		 type;
-	union
-	{
-		Regex		*match;
-		struct {
-			Regex	*start;
-			Regex	*end;
-		}		 start_end;
-	} u;
-
-	/* Name of the style used for contexts of this type. */
-	gchar			*default_style;
-
-	/* This is a list of DefinitionChild pointers. */
-	GSList			*children;
-
-	/* Sub patterns (list of SubPatternDefinition pointers.) */
-	GSList			*sub_patterns;
-	guint			 n_sub_patterns;
-
-	/* List of class definitions */
-	GSList			*context_classes;
-
-	/* Union of every regular expression we can find from this
-	 * context. */
-	Regex			*reg_all;
-
-	guint                    flags : 8;
-	guint                    ref_count : 24;
-};
-
-struct _SubPatternDefinition
-{
-#ifdef NEED_DEBUG_ID
-	/* We need the id only for debugging. */
-	gchar			*id;
-#endif
-	gchar			*style;
-	SubPatternWhere		 where;
 
-	/* List of class definitions */
-	GSList                  *context_classes;
-
-	/* index in the ContextDefinition's list */
-	guint			 index;
-
-	union
-	{
-		gint	 	 num;
-		gchar		*name;
-	} u;
-	guint			 is_named : 1;
-};
 
 struct _DefinitionChild
 {
@@ -267,6 +254,19 @@ struct _DefinitionsIter
 	GSList			*children_stack;
 };
 
+struct _ContextPtr
+{
+	ContextDefinition	*definition;
+
+	ContextPtr		*next;
+
+	union {
+		Context		*context;
+		GHashTable	*hash; /* char* -> Context* */
+	} u;
+	guint			 fixed : 1;
+};
+
 struct _Context
 {
 	/* Definition for the context. */
@@ -283,13 +283,15 @@ struct _Context
 	Regex			*reg_all;
 
 	/* Either definition->default_style or child_def->style, not copied. */
-	const gchar		*style;
-	GtkTextTag		*tag;
-	GtkTextTag	       **subpattern_tags;
-
+	Annotation		annot;
+	//const gchar		*style;
 	/* Cache for generated list of class tags */
-	GSList                  *context_classes;
+	//GSList                  *context_classes;
+
+	GtkTextTag	       **subpattern_tags;
+	GtkTextTag		*tag;
 
+	
 	/* Cache for generated list of subpattern class tags */
 	GSList                 **subpattern_context_classes;
 
@@ -302,62 +304,71 @@ struct _Context
 	guint			 ignore_children_style : 1;
 };
 
-struct _ContextPtr
+struct _ContextDefinition
 {
-	ContextDefinition	*definition;
-
-	ContextPtr		*next;
+	gchar			*id;
 
-	union {
-		Context		*context;
-		GHashTable	*hash; /* char* -> Context* */
+	ContextType		 type;
+	union
+	{
+		Regex		*match;
+		struct {
+			Regex	*start;
+			Regex	*end;
+		}		 start_end;
 	} u;
-	guint			 fixed : 1;
-};
 
-struct _GtkSourceContextReplace
-{
-	gchar			*id;
-	gchar			*replace_with;
-};
+	/* Name of the style used for contexts of this type. */
+	gchar			*default_style;
 
-struct _Segment
-{
-	Segment			*parent;
-	Segment			*next;
-	Segment			*prev;
-	Segment			*children;
-	Segment			*last_child;
+	/* This is a list of DefinitionChild pointers. */
+	GSList			*children;
 
-	/* This is NULL if and only if it's a dummy segment which denotes
-	 * inserted or deleted text. */
-	Context			*context;
+	/* Sub patterns (list of SubPatternDefinition pointers.) */
+	GSList			*sub_patterns;
+	guint			 n_sub_patterns;
 
-	/* Subpatterns found in this segment. */
-	SubPattern		*sub_patterns;
+	/* List of class definitions */
+	GSList			*context_classes;
 
-	/* The context is used in the interval [start_at; end_at). */
-	gint			 start_at;
-	gint			 end_at;
+	/* Union of every regular expression we can find from this
+	 * context. */
+	Regex			*reg_all;
 
-	/* In case of container contexts, start_len/end_len is length in chars
-	 * of start/end match. */
-	gint			 start_len;
-	gint			 end_len;
+	guint                    flags : 8;
+	guint                    ref_count : 24;
+};
 
-	/* Whether this segment is a whole good segment, or it's an
-	 * an end of bigger one left after erase_segments() call. */
-	guint			 is_start : 1;
+
+struct _SubPatternDefinition
+{
+#ifdef NEED_DEBUG_ID
+	/* We need the id only for debugging. */
+	gchar			*id;
+#endif
+	Annotation		annot;
+
+	SubPatternWhere		 where;
+
+	/* index in the ContextDefinition's list */
+	guint			 index;
+
+	union
+	{
+		gint	 	 num;
+		gchar		*name;
+	} u;
+	guint			 is_named : 1;
 };
 
-struct _SubPattern
+struct _GtkSourceContextReplace
 {
-	SubPatternDefinition	*definition;
-	gint			 start_at;
-	gint			 end_at;
-	SubPattern		*next;
+	gchar			*id;
+	gchar			*replace_with;
 };
 
+
+
 /* Line terminator characters (\n, \r, \r\n, or unicode paragraph separator)
  * are removed from the line text. The problem is that pcre does not understand
  * arbitrary line terminators, so $ in pcre means (?=\n) (not quite, it's also
@@ -400,17 +411,6 @@ struct _InvalidRegion
 	gint			 delta;
 };
 
-struct _GtkSourceContextClass
-{
-	gchar    *name;
-	gboolean  enabled;
-};
-
-struct _ContextClassTag
-{
-	GtkTextTag *tag;
-	gboolean enabled;
-};
 
 struct _GtkSourceContextData
 {
@@ -427,23 +427,10 @@ struct _GtkSourceContextEnginePrivate
 	GtkSourceContextData	*ctx_data;
 
 	GtkTextBuffer		*buffer;
-	GtkSourceStyleScheme	*style_scheme;
-
-	/* All tags indexed by style name: values are GSList's of tags, ref()'ed. */
-	GHashTable		*tags;
-	/* Number of all syntax tags created by the engine, needed to set correct
-	 * tag priorities */
-	guint			 n_tags;
 
 	GHashTable		*context_classes;
 
-	/* Whether or not to actually highlight the buffer. */
-	gboolean		 highlight;
-
-	/* Whether highlighting was disabled because of errors. */
-	gboolean		 disabled;
-
-	/* Region covering the unhighlighted text. */
+	/* Region covering the non-analyzed text. */
 	GtkTextRegion		*refresh_region;
 
 	/* Tree of contexts. */
@@ -461,9 +448,17 @@ struct _GtkSourceContextEnginePrivate
 	/* Views highlight requests. */
 	GtkTextRegion		*highlight_requests;
 
+	GHashTable		 *tags;
+	gint			 n_tags;
 #ifdef ENABLE_MEMORY_DEBUG
 	guint			 mem_usage_timeout;
 #endif
+
+	/* Whether or not to actually analyze the syntax of the buffer. */
+	guint		 	 analyze_syntax : 1;
+
+	/* Whether Syntax analysis was disabled because of errors. */
+	guint		 	 disabled : 1;
 };
 
 
@@ -544,142 +539,6 @@ static gboolean		mem_usage_timeout	(GtkSourceContextEngine *ce);
 
 
 /* TAGS AND STUFF -------------------------------------------------------------- */
-
-GtkSourceContextClass *
-gtk_source_context_class_new (gchar const *name,
-                              gboolean     enabled)
-{
-	GtkSourceContextClass *def = g_slice_new (GtkSourceContextClass);
-
-	def->name = g_strdup (name);
-	def->enabled = enabled;
-
-	return def;
-}
-
-static GtkSourceContextClass *
-gtk_source_context_class_copy (GtkSourceContextClass *cclass)
-{
-	return gtk_source_context_class_new (cclass->name, cclass->enabled);
-}
-
-void
-gtk_source_context_class_free (GtkSourceContextClass *cclass)
-{
-	g_free (cclass->name);
-	g_slice_free (GtkSourceContextClass, cclass);
-}
-
-static ContextClassTag *
-context_class_tag_new (GtkTextTag *tag,
-                       gboolean    enabled)
-{
-	ContextClassTag *attrtag = g_slice_new (ContextClassTag);
-
-	attrtag->tag = tag;
-	attrtag->enabled = enabled;
-
-	return attrtag;
-}
-
-static void
-context_class_tag_free (ContextClassTag *attrtag)
-{
-	g_slice_free (ContextClassTag, attrtag);
-}
-
-struct BufAndIters {
-	GtkTextBuffer *buffer;
-	const GtkTextIter *start, *end;
-};
-
-static void
-unhighlight_region_cb (G_GNUC_UNUSED gpointer style,
-		       GSList   *tags,
-		       gpointer  user_data)
-{
-	struct BufAndIters *data = user_data;
-
-	while (tags != NULL)
-	{
-		gtk_text_buffer_remove_tag (data->buffer,
-					    tags->data,
-					    data->start,
-					    data->end);
-		tags = tags->next;
-	}
-}
-
-static void
-unhighlight_region (GtkSourceContextEngine *ce,
-		    const GtkTextIter      *start,
-		    const GtkTextIter      *end)
-{
-	struct BufAndIters data;
-
-	data.buffer = ce->priv->buffer;
-	data.start = start;
-	data.end = end;
-
-	if (gtk_text_iter_equal (start, end))
-		return;
-
-	g_hash_table_foreach (ce->priv->tags, (GHFunc) unhighlight_region_cb, &data);
-}
-
-#define MAX_STYLE_DEPENDENCY_DEPTH	50
-
-static void
-set_tag_style (GtkSourceContextEngine *ce,
-	       GtkTextTag             *tag,
-	       const gchar            *style_id)
-{
-	GtkSourceStyle *style;
-
-	const char *map_to = style_id;
-
-	int guard = 0;
-
-	g_return_if_fail (GTK_IS_TEXT_TAG (tag));
-	g_return_if_fail (style_id != NULL);
-
-	_gtk_source_style_apply (NULL, tag);
-
-	if (ce->priv->style_scheme == NULL)
-		return;
-
-	style = gtk_source_style_scheme_get_style (ce->priv->style_scheme, style_id);
-
-	while (style == NULL)
-	{
-		GtkSourceStyleInfo *info;
-
-		if (guard > MAX_STYLE_DEPENDENCY_DEPTH)
-		{
-			g_warning ("Potential circular dependency between styles detected for style '%s'", style_id);
-			break;
-		}
-
-		++guard;
-
-		/* FIXME Style references really must be fixed, both parser for
-		 * sane use in lang files, and engine for safe use. */
-		info = g_hash_table_lookup (ENGINE_STYLES_MAP(ce), map_to);
-
-		map_to = (info != NULL) ? info->map_to : NULL;
-
-		if (!map_to)
-			break;
-
-		style = gtk_source_style_scheme_get_style (ce->priv->style_scheme, map_to);
-	}
-
-	/* not having style is fine, since parser checks validity of every style reference,
-	 * so we don't need to spit a warning here */
-	if (style != NULL)
-		_gtk_source_style_apply (style, tag);
-}
-
 static GtkTextTag *
 create_tag (GtkSourceContextEngine *ce,
 	    const gchar            *style_id)
@@ -692,19 +551,23 @@ create_tag (GtkSourceContextEngine *ce,
 	tags = g_hash_table_lookup (ce->priv->tags, style_id);
 
 	new_tag = gtk_text_buffer_create_tag (ce->priv->buffer, NULL, NULL);
+
 	/* It must have priority lower than user tags but still
 	 * higher than highlighting tags created before */
 	gtk_text_tag_set_priority (new_tag, ce->priv->n_tags);
-	set_tag_style (ce, new_tag, style_id);
-	ce->priv->n_tags += 1;
 
+	/* set_tag_style (ce, new_tag, style_id); */
+
+	ce->priv->n_tags += 1;
+	DEBUG (g_print ("n tags %d\n", ce->priv->n_tags);)
 	tags = g_slist_prepend (tags, g_object_ref (new_tag));
 	g_hash_table_insert (ce->priv->tags, g_strdup (style_id), tags);
 
 	return new_tag;
 }
 
-/* Find tag which has to be overridden. */
+/* Get the first style of an ancestor of the context that is differnet from @style.
+ * Find tag which has to be overridden. */
 static GtkTextTag *
 get_parent_tag (Context    *context,
 		const char *style)
@@ -713,8 +576,8 @@ get_parent_tag (Context    *context,
 	{
 		/* Lang files may repeat same style for nested contexts,
 		 * ignore them. */
-		if (context->style &&
-		    strcmp (context->style, style) != 0)
+		if (context->annot.style &&
+		    strcmp (context->annot.style, style) != 0)
 		{
 			g_assert (context->tag != NULL);
 			return context->tag;
@@ -727,7 +590,7 @@ get_parent_tag (Context    *context,
 }
 
 static GtkTextTag *
-get_tag_for_parent (GtkSourceContextEngine *ce,
+get_tag_for_parent (GtkSourceContextEngine 	   *ce,
 		    const char             *style,
 		    Context                *parent)
 {
@@ -739,7 +602,8 @@ get_tag_for_parent (GtkSourceContextEngine *ce,
 
 	parent_tag = get_parent_tag (parent, style);
 	tags = g_hash_table_lookup (ce->priv->tags, style);
-
+	// FIXME:  
+	// parent_tag == NULL implies that???
 	if (tags && (!parent_tag ||
 		gtk_text_tag_get_priority (tags->data) > gtk_text_tag_get_priority (parent_tag)))
 	{
@@ -768,11 +632,11 @@ get_tag_for_parent (GtkSourceContextEngine *ce,
 
 			while (parent != NULL)
 			{
-				if (parent->style != NULL)
+				if (parent->annot.style != NULL)
 				{
 					g_string_prepend (style_path, "/");
 					g_string_prepend (style_path,
-							  parent->style);
+							  parent->annot.style);
 				}
 
 				parent = parent->parent;
@@ -794,7 +658,7 @@ get_subpattern_tag (GtkSourceContextEngine *ce,
 		    Context                *context,
 		    SubPatternDefinition   *sp_def)
 {
-	if (sp_def->style == NULL)
+	if (sp_def->annot.style == NULL)
 		return NULL;
 
 	g_assert (sp_def->index < context->definition->n_sub_patterns);
@@ -803,7 +667,7 @@ get_subpattern_tag (GtkSourceContextEngine *ce,
 		context->subpattern_tags = g_new0 (GtkTextTag*, context->definition->n_sub_patterns);
 
 	if (context->subpattern_tags[sp_def->index] == NULL)
-		context->subpattern_tags[sp_def->index] = get_tag_for_parent (ce, sp_def->style, context);
+		context->subpattern_tags[sp_def->index] = get_tag_for_parent (ce, sp_def->annot.style, context);
 
 	g_return_val_if_fail (context->subpattern_tags[sp_def->index] != NULL, NULL);
 	return context->subpattern_tags[sp_def->index];
@@ -813,179 +677,89 @@ static GtkTextTag *
 get_context_tag (GtkSourceContextEngine *ce,
 		 Context                *context)
 {
-	if (context->style != NULL && context->tag == NULL)
+	if (context->annot.style != NULL && context->tag == NULL)
 		context->tag = get_tag_for_parent (ce,
-						   context->style,
+						   context->annot.style,
 						   context->parent);
 	return context->tag;
 }
-
 static void
-apply_tags (GtkSourceContextEngine *ce,
-	    Segment                *segment,
-	    gint                    start_offset,
-	    gint                    end_offset)
+remove_tags_hash_cb (G_GNUC_UNUSED gpointer style,
+		     GSList          *tags,
+		     GtkTextTagTable *table)
 {
-	GtkTextTag *tag;
-	GtkTextIter start_iter, end_iter;
-	GtkTextBuffer *buffer = ce->priv->buffer;
-	SubPattern *sp;
-	Segment *child;
-
-	g_assert (segment != NULL);
-
-	if (SEGMENT_IS_INVALID (segment))
-		return;
-
-	if (segment->start_at >= end_offset || segment->end_at <= start_offset)
-		return;
-
-	start_offset = MAX (start_offset, segment->start_at);
-	end_offset = MIN (end_offset, segment->end_at);
-
-	tag = get_context_tag (ce, segment->context);
-
-	if (tag != NULL)
-	{
-		gint style_start_at, style_end_at;
-
-		style_start_at = start_offset;
-		style_end_at = end_offset;
-
-		if (HAS_OPTION (segment->context->definition, STYLE_INSIDE))
-		{
-			style_start_at = MAX (segment->start_at + segment->start_len, start_offset);
-			style_end_at = MIN (segment->end_at - segment->end_len, end_offset);
-		}
-
-		if (style_start_at > style_end_at)
-		{
-			g_critical ("%s: oops", G_STRLOC);
-		}
-		else
-		{
-			gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, style_start_at);
-			end_iter = start_iter;
-			gtk_text_iter_forward_chars (&end_iter, style_end_at - style_start_at);
-			gtk_text_buffer_apply_tag (ce->priv->buffer, tag, &start_iter, &end_iter);
-		}
-	}
+	GSList *l = tags;
 
-	for (sp = segment->sub_patterns; sp != NULL; sp = sp->next)
+	while (l != NULL)
 	{
-		if (sp->start_at >= start_offset && sp->end_at <= end_offset)
-		{
-			gint start = MAX (start_offset, sp->start_at);
-			gint end = MIN (end_offset, sp->end_at);
-
-			tag = get_subpattern_tag (ce, segment->context, sp->definition);
-
-			if (tag != NULL)
-			{
-				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
-				end_iter = start_iter;
-				gtk_text_iter_forward_chars (&end_iter, end - start);
-				gtk_text_buffer_apply_tag (ce->priv->buffer, tag, &start_iter, &end_iter);
-			}
-		}
+		gtk_text_tag_table_remove (table, l->data);
+		g_object_unref (l->data);
+		l = l->next;
 	}
 
-	for (child = segment->children;
-	     child != NULL && child->start_at < end_offset;
-	     child = child->next)
-	{
-		if (child->end_at > start_offset)
-			apply_tags (ce, child, start_offset, end_offset);
-	}
+	g_slist_free (tags);
 }
-
 /**
- * highlight_region:
+ * destroy_tags_hash:
  *
- * @ce: a #GtkSourceContextEngine.
- * @start: the beginning of the region to highlight.
- * @end: the end of the region to highlight.
+ * @ce: #GtkHighlightEngine.
  *
- * Highlights the specified region.
+ * Destroys syntax tags cache.
  */
 static void
-highlight_region (GtkSourceContextEngine *ce,
-		  GtkTextIter            *start,
-		  GtkTextIter            *end)
+destroy_tags_hash (GtkSourceContextEngine *ce)
 {
-#ifdef ENABLE_PROFILE
-	GTimer *timer;
-#endif
-
-	if (gtk_text_iter_starts_line (end))
-		gtk_text_iter_backward_char (end);
-	if (gtk_text_iter_compare (start, end) >= 0)
-		return;
+	g_hash_table_foreach (ce->priv->tags, (GHFunc) remove_tags_hash_cb,
+                              gtk_text_buffer_get_tag_table (ce->priv->buffer));
+	g_hash_table_destroy (ce->priv->tags);
+	ce->priv->tags = NULL;
+}
 
-#ifdef ENABLE_PROFILE
-	timer = g_timer_new ();
-#endif
+GtkSourceContextClass *
+gtk_source_context_class_new (gchar const *name,
+                              gboolean     enabled)
+{
+	GtkSourceContextClass *def = g_slice_new (GtkSourceContextClass);
 
-	/* First we need to delete tags in the regions. */
-	unhighlight_region (ce, start, end);
+	def->name = g_strdup (name);
+	def->enabled = enabled;
 
-	apply_tags (ce, ce->priv->root_segment,
-		    gtk_text_iter_get_offset (start),
-		    gtk_text_iter_get_offset (end));
+	return def;
+}
 
-#ifdef ENABLE_PROFILE
-	g_print ("highlight (from %d to %d), %g ms elapsed\n",
-		 gtk_text_iter_get_offset (start),
-		 gtk_text_iter_get_offset (end),
-		 g_timer_elapsed (timer, NULL) * 1000);
-	g_timer_destroy (timer);
-#endif
+static GtkSourceContextClass *
+gtk_source_context_class_copy (GtkSourceContextClass *cclass)
+{
+	return gtk_source_context_class_new (cclass->name, cclass->enabled);
 }
 
-/**
- * ensure_highlighted:
- *
- * @ce: a #GtkSourceContextEngine.
- * @start: the beginning of the region to highlight.
- * @end: the end of the region to highlight.
- *
- * Updates text tags in reanalyzed parts of given area.
- * It applies tags according to whatever is in the syntax
- * tree currently, so highlighting may not be correct
- * (gtk_source_context_engine_update_highlight is the method
- * that actually ensures correct highlighting).
- */
-static void
-ensure_highlighted (GtkSourceContextEngine *ce,
-		    const GtkTextIter      *start,
-		    const GtkTextIter      *end)
+void
+gtk_source_context_class_free (GtkSourceContextClass *cclass)
 {
-	GtkTextRegion *region;
-	GtkTextRegionIterator reg_iter;
+	g_free (cclass->name);
+	g_slice_free (GtkSourceContextClass, cclass);
+}
 
-	/* Get the subregions not yet highlighted. */
-	region = gtk_text_region_intersect (ce->priv->refresh_region, start, end);
+static ContextClassTag *
+context_class_tag_new (GtkTextTag *tag,
+                       gboolean    enabled)
+{
+	ContextClassTag *attrtag = g_slice_new (ContextClassTag);
 
-	if (region == NULL)
-		return;
+	attrtag->tag = tag;
+	attrtag->enabled = enabled;
 
-	gtk_text_region_get_iterator (region, &reg_iter, 0);
+	return attrtag;
+}
 
-	/* Highlight all subregions from the intersection.
-	 * hopefully this will only be one subregion. */
-	while (!gtk_text_region_iterator_is_end (&reg_iter))
-	{
-		GtkTextIter s, e;
-		gtk_text_region_iterator_get_subregion (&reg_iter, &s, &e);
-		highlight_region (ce, &s, &e);
-		gtk_text_region_iterator_next (&reg_iter);
-	}
+static void
+context_class_tag_free (ContextClassTag *attrtag)
+{
+	g_slice_free (ContextClassTag, attrtag);
+}
 
-	gtk_text_region_destroy (region, TRUE);
 
-	/* Remove the just highlighted region. */
-	gtk_text_region_subtract (ce->priv->refresh_region, start, end);
-}
+#define MAX_STYLE_DEPENDENCY_DEPTH	50
 
 static GtkTextTag *
 get_context_class_tag (GtkSourceContextEngine *ce,
@@ -1044,7 +818,7 @@ get_subpattern_context_classes (GtkSourceContextEngine *ce,
 	{
 		context->subpattern_context_classes[sp_def->index] =
 				extend_context_classes (ce,
-		                                        sp_def->context_classes);
+		                                        sp_def->annot.context_classes);
 	}
 
 	return context->subpattern_context_classes[sp_def->index];
@@ -1054,14 +828,14 @@ static GSList *
 get_context_classes (GtkSourceContextEngine *ce,
                      Context                *context)
 {
-	if (context->context_classes == NULL)
+	if (context->annot.context_classes == NULL)
 	{
-		context->context_classes =
+		context->annot.context_classes =
 				extend_context_classes (ce,
 		                                        context->definition->context_classes);
 	}
 
-	return context->context_classes;
+	return context->annot.context_classes;
 }
 
 static void
@@ -1124,8 +898,7 @@ add_region_context_classes (GtkSourceContextEngine *ce,
 	start_offset = MAX (start_offset, segment->start_at);
 	end_offset = MIN (end_offset, segment->end_at);
 
-	context_classes = get_context_classes (ce,
-	                                       segment->context);
+	context_classes = get_context_classes (ce, SEGMENT_GET_CONTEXT(segment));
 
 	if (context_classes != NULL)
 	{
@@ -1143,8 +916,8 @@ add_region_context_classes (GtkSourceContextEngine *ce,
 			gint end = MIN (end_offset, sp->end_at);
 
 			context_classes = get_subpattern_context_classes (ce,
-			                                                  segment->context,
-			                                                  sp->definition);
+			                                                  SEGMENT_GET_CONTEXT(segment),
+			                                                  SUBPATTERN_GET_DEFINITION (sp));
 
 			if (context_classes != NULL)
 			{
@@ -1172,7 +945,8 @@ remove_region_context_class_cb (G_GNUC_UNUSED gpointer class,
                                 GtkTextTag             *tag,
                                 gpointer                user_data)
 {
-	struct BufAndIters *data = user_data;
+	BufAndIters *data = user_data;
+
 	gtk_text_buffer_remove_tag (data->buffer,
 	                            tag,
 	                            data->start,
@@ -1184,7 +958,7 @@ remove_region_context_classes (GtkSourceContextEngine *ce,
                                const GtkTextIter      *start,
                                const GtkTextIter      *end)
 {
-	struct BufAndIters data;
+	BufAndIters data;
 
 	data.buffer = ce->priv->buffer;
 	data.start = start;
@@ -1277,11 +1051,12 @@ refresh_range (GtkSourceContextEngine *ce,
 		/* I don't quite like this here, but at least it won't jump into
 		 * the middle of \r\n  */
 		gtk_text_iter_backward_cursor_position (&real_end);
-
+		
 	g_signal_emit_by_name (ce->priv->buffer,
 			       "highlight_updated",
 			       start,
 			       &real_end);
+			      // ce->priv->refresh_region);
 }
 
 
@@ -1671,13 +1446,13 @@ sub_pattern_new (Segment              *segment,
 {
 	SubPattern *sp;
 
-	sp = g_slice_new0 (SubPattern);
+	sp = (SubPattern *) g_slice_new0 (RealSubPattern);
 	sp->start_at = start_at;
 	sp->end_at = end_at;
-	sp->definition = sp_def;
+	SUBPATTERN_GET_DEFINITION (sp) = sp_def;
+	sp->annot = &(sp_def->annot);
 
 	segment_add_subpattern (segment, sp);
-
 	return sp;
 }
 
@@ -1725,9 +1500,9 @@ segment_make_invalid_ (GtkSourceContextEngine *ce,
 		sp = next;
 	}
 
-	ctx = segment->context;
-	segment->context = NULL;
-	segment->is_start = FALSE;
+	ctx = SEGMENT_GET_CONTEXT(segment);
+	SEGMENT_GET_CONTEXT(segment) = NULL;
+	SEGMENT_GET_IS_START(segment) = FALSE;
 	segment->start_len = 0;
 	segment->end_len = 0;
 	add_invalid (ce, segment);
@@ -1764,7 +1539,7 @@ simple_segment_split_ (GtkSourceContextEngine *ce,
 	segment->end_at = offset;
 
 	invalid = create_segment (ce, segment->parent, NULL, offset, offset, FALSE, segment);
-	new_segment = create_segment (ce, segment->parent, segment->context, offset, end_at, FALSE, invalid);
+	new_segment = create_segment (ce, segment->parent, SEGMENT_GET_CONTEXT(segment), offset, end_at, FALSE, invalid);
 
 	while (sp != NULL)
 	{
@@ -1784,7 +1559,14 @@ simple_segment_split_ (GtkSourceContextEngine *ce,
 			sub_pattern_new (new_segment,
 					 offset,
 					 sp->end_at,
-					 sp->definition);
+					 SUBPATTERN_GET_DEFINITION (sp));
+			if (SEGMENT_GET_CONTEXT (new_segment))
+			{
+				sp->annot->style_tag = 
+					get_subpattern_tag (ce, SEGMENT_GET_CONTEXT(new_segment),
+							  SUBPATTERN_GET_DEFINITION (sp));
+			}
+
 			sp->end_at = offset;
 			append_to = segment;
 		}
@@ -2271,7 +2053,7 @@ update_tree (GtkSourceContextEngine *ce)
 }
 
 /**
- * gtk_source_context_engine_update_highlight:
+ * gtk_source_context_engine_analyze:
  *
  * @ce: a #GtkSourceContextEngine.
  * @start: start of area to update.
@@ -2279,22 +2061,22 @@ update_tree (GtkSourceContextEngine *ce)
  * @synchronous: whether it should block until everything
  * is analyzed/highlighted.
  *
- * GtkSourceEngine::update_highlight method.
+ * GtkSourceEngine::analyze method.
  *
- * Makes sure the area is analyzed and highlighted. If @asynchronous
+ * Makes sure the area is analyzed. If @synchronous
  * is %FALSE, then it queues idle worker.
  */
 static void
-gtk_source_context_engine_update_highlight (GtkSourceEngine   *engine,
-					    const GtkTextIter *start,
-					    const GtkTextIter *end,
-					    gboolean           synchronous)
+gtk_source_context_engine_analyze (GtkSourceEngine   *engine,
+				   const GtkTextIter *start,
+				   const GtkTextIter *end,
+				   gboolean           synchronous)
 {
 	gint invalid_line;
 	gint end_line;
 	GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (engine);
 
-	if (!ce->priv->highlight || ce->priv->disabled)
+	if (!ce->priv->analyze_syntax || ce->priv->disabled)
 		return;
 
 	invalid_line = get_invalid_line (ce);
@@ -2305,13 +2087,13 @@ gtk_source_context_engine_update_highlight (GtkSourceEngine   *engine,
 
 	if (invalid_line < 0 || invalid_line > end_line)
 	{
-		ensure_highlighted (ce, start, end);
+		/* The region is already analyzed */
+		return;
 	}
 	else if (synchronous)
 	{
 		/* analyze whole region */
 		update_syntax (ce, end, 0);
-		ensure_highlighted (ce, start, end);
 	}
 	else
 	{
@@ -2323,7 +2105,6 @@ gtk_source_context_engine_update_highlight (GtkSourceEngine   *engine,
 		{
 			GtkTextIter valid_end = *start;
 			gtk_text_iter_set_line (&valid_end, invalid_line);
-			ensure_highlighted (ce, start, &valid_end);
 			gtk_text_region_add (ce->priv->highlight_requests, &valid_end, end);
 		}
 
@@ -2331,43 +2112,6 @@ gtk_source_context_engine_update_highlight (GtkSourceEngine   *engine,
 	}
 }
 
-/**
- * enable_highlight:
- *
- * @ce: a #GtkSourceContextEngine.
- * @enable: whether to enable highlighting.
- *
- * Whether to highlight (i.e. apply tags) analyzed area.
- * Note that this does not turn on/off the analyzis stuff,
- * it affects only text tags.
- */
-static void
-enable_highlight (GtkSourceContextEngine *ce,
-		  gboolean                enable)
-{
-	GtkTextIter start, end;
-
-	if (!enable == !ce->priv->highlight)
-		return;
-
-	ce->priv->highlight = enable != 0;
-	gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (ce->priv->buffer),
-				    &start, &end);
-
-	if (enable)
-		refresh_range (ce, &start, &end, TRUE);
-	else
-		unhighlight_region (ce, &start, &end);
-}
-
-static void
-buffer_notify_highlight_syntax_cb (GtkSourceContextEngine *ce)
-{
-	gboolean highlight;
-	g_object_get (ce->priv->buffer, "highlight-syntax", &highlight, NULL);
-	enable_highlight (ce, highlight);
-}
-
 
 /* IDLE WORKER CODE ------------------------------------------------------- */
 
@@ -2502,23 +2246,6 @@ gtk_source_context_engine_error_quark (void)
 }
 
 static void
-remove_tags_hash_cb (G_GNUC_UNUSED gpointer style,
-		     GSList          *tags,
-		     GtkTextTagTable *table)
-{
-	GSList *l = tags;
-
-	while (l != NULL)
-	{
-		gtk_text_tag_table_remove (table, l->data);
-		g_object_unref (l->data);
-		l = l->next;
-	}
-
-	g_slist_free (tags);
-}
-
-static void
 remove_context_classes_hash_cb (G_GNUC_UNUSED gpointer class,
                                 GtkTextTag             *tag,
                                 GtkTextTagTable        *table)
@@ -2526,22 +2253,6 @@ remove_context_classes_hash_cb (G_GNUC_UNUSED gpointer class,
 	gtk_text_tag_table_remove (table, tag);
 }
 
-/**
- * destroy_tags_hash:
- *
- * @ce: #GtkSourceContextEngine.
- *
- * Destroys syntax tags cache.
- */
-static void
-destroy_tags_hash (GtkSourceContextEngine *ce)
-{
-	g_hash_table_foreach (ce->priv->tags, (GHFunc) remove_tags_hash_cb,
-                              gtk_text_buffer_get_tag_table (ce->priv->buffer));
-	g_hash_table_destroy (ce->priv->tags);
-	ce->priv->tags = NULL;
-}
-
 static void
 destroy_context_classes_hash (GtkSourceContextEngine *ce)
 {
@@ -2574,9 +2285,6 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine,
 	/* Detach previous buffer if there is one. */
 	if (ce->priv->buffer != NULL)
 	{
-		g_signal_handlers_disconnect_by_func (ce->priv->buffer,
-						      (gpointer) buffer_notify_highlight_syntax_cb,
-						      ce);
 
 		if (ce->priv->first_update != 0)
 			g_source_remove (ce->priv->first_update);
@@ -2627,6 +2335,7 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine,
 
 	if (buffer != NULL)
 	{
+		gboolean analyze_syntax;
 		gchar *root_id;
 		ContextDefinition *main_definition;
 		GtkTextIter start, end;
@@ -2639,11 +2348,10 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine,
 		/* If we don't abort here, we will crash later (#485661). But it should
 		 * never happen, _gtk_source_context_data_finish_parse checks main context. */
 		g_assert (main_definition != NULL);
-
+		ce->priv->tags = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 		ce->priv->root_context = context_new (NULL, main_definition, NULL, NULL, FALSE);
 		ce->priv->root_segment = create_segment (ce, NULL, ce->priv->root_context, 0, 0, TRUE, NULL);
 
-		ce->priv->tags = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 		ce->priv->context_classes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
 		gtk_text_buffer_get_bounds (buffer, &start, &end);
@@ -2663,30 +2371,29 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine,
 			ce->priv->invalid_region.delta = 0;
 		}
 
-		g_object_get (ce->priv->buffer, "highlight-syntax", &ce->priv->highlight, NULL);
+		g_object_get (ce->priv->buffer,
+			      "analyze-syntax", &analyze_syntax,
+			      NULL);
+		ce->priv->analyze_syntax = analyze_syntax;
+
 		ce->priv->refresh_region = gtk_text_region_new (buffer);
 		ce->priv->highlight_requests = gtk_text_region_new (buffer);
 
-		g_signal_connect_swapped (buffer,
-					  "notify::highlight-syntax",
-					  G_CALLBACK (buffer_notify_highlight_syntax_cb),
-					  ce);
-
 		install_first_update (ce);
 	}
 }
 
 /**
- * disable_highlighting:
+ * disable_syntax_analysis:
  *
  * @ce: #GtkSourceContextEngine.
  *
- * Dsiables highlighting in case of errors (currently if highlighting
- * a single line took too long, so that highlighting doesn't freeze
+ * Disables analyzing in case of errors (currently if analyzing
+ * a single line took too long, so that analyzing doesn't freeze
  * text editor).
  */
 static void
-disable_highlighting (GtkSourceContextEngine *ce)
+disable_syntax_analysis (GtkSourceContextEngine *ce)
 {
 	if (!ce->priv->disabled)
 	{
@@ -2697,48 +2404,6 @@ disable_highlighting (GtkSourceContextEngine *ce)
 }
 
 static void
-set_tag_style_hash_cb (const char             *style,
-		       GSList                 *tags,
-		       GtkSourceContextEngine *ce)
-{
-	while (tags != NULL)
-	{
-		set_tag_style (ce, tags->data, style);
-		tags = tags->next;
-	}
-}
-
-/**
- * gtk_source_context_engine_set_style_scheme:
- *
- * @engine: #GtkSourceContextEngine.
- * @scheme: #GtkSourceStyleScheme to set.
- *
- * GtkSourceEngine::set_style_scheme method.
- * Sets current style scheme, updates tag styles and everything.
- */
-static void
-gtk_source_context_engine_set_style_scheme (GtkSourceEngine      *engine,
-					    GtkSourceStyleScheme *scheme)
-{
-	GtkSourceContextEngine *ce;
-
-	g_return_if_fail (GTK_IS_SOURCE_CONTEXT_ENGINE (engine));
-	g_return_if_fail (GTK_IS_SOURCE_STYLE_SCHEME (scheme) || scheme == NULL);
-
-	ce = GTK_SOURCE_CONTEXT_ENGINE (engine);
-
-	if (scheme == ce->priv->style_scheme)
-		return;
-
-	if (ce->priv->style_scheme != NULL)
-		g_object_unref (ce->priv->style_scheme);
-
-	ce->priv->style_scheme = scheme ? g_object_ref (scheme) : NULL;
-	g_hash_table_foreach (ce->priv->tags, (GHFunc) set_tag_style_hash_cb, ce);
-}
-
-static void
 gtk_source_context_engine_finalize (GObject *object)
 {
 	GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (object);
@@ -2756,7 +2421,6 @@ gtk_source_context_engine_finalize (GObject *object)
 		g_source_remove (ce->priv->mem_usage_timeout);
 #endif
 
-	g_assert (!ce->priv->tags);
 	g_assert (!ce->priv->root_context);
 	g_assert (!ce->priv->root_segment);
 	g_assert (!ce->priv->first_update);
@@ -2764,9 +2428,6 @@ gtk_source_context_engine_finalize (GObject *object)
 
 	_gtk_source_context_data_unref (ce->priv->ctx_data);
 
-	if (ce->priv->style_scheme != NULL)
-		g_object_unref (ce->priv->style_scheme);
-
 	G_OBJECT_CLASS (_gtk_source_context_engine_parent_class)->finalize (object);
 }
 
@@ -2797,8 +2458,7 @@ _gtk_source_context_engine_class_init (GtkSourceContextEngineClass *klass)
 	engine_class->attach_buffer = gtk_source_context_engine_attach_buffer;
 	engine_class->text_inserted = gtk_source_context_engine_text_inserted;
 	engine_class->text_deleted = gtk_source_context_engine_text_deleted;
-	engine_class->update_highlight = gtk_source_context_engine_update_highlight;
-	engine_class->set_style_scheme = gtk_source_context_engine_set_style_scheme;
+	engine_class->analyze = gtk_source_context_engine_analyze;
 	engine_class->get_context_class_tag = gtk_source_context_engine_get_context_class_tag;
 
 	g_type_class_add_private (object_class, sizeof (GtkSourceContextEnginePrivate));
@@ -2811,6 +2471,22 @@ _gtk_source_context_engine_init (GtkSourceContextEngine *ce)
 						GtkSourceContextEnginePrivate);
 }
 
+Segment *
+_gtk_source_context_engine_get_tree (GtkSourceContextEngine *ce)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_CONTEXT_ENGINE (ce), NULL);
+
+	return ce->priv->root_segment;
+}
+
+GHashTable *
+_gtk_source_context_engine_get_style_tags (GtkSourceContextEngine *ce)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_CONTEXT_ENGINE (ce), NULL);
+
+	return ce->priv->tags;
+}
+
 GtkSourceContextEngine *
 _gtk_source_context_engine_new (GtkSourceContextData *ctx_data)
 {
@@ -3281,7 +2957,7 @@ apply_sub_patterns (Segment         *state,
 		    Regex           *regex,
 		    SubPatternWhere  where)
 {
-	GSList *sub_pattern_list = state->context->definition->sub_patterns;
+	GSList *sub_pattern_list = SEGMENT_GET_CONTEXT(state)->definition->sub_patterns;
 
 	if (SEGMENT_IS_CONTAINER (state))
 	{
@@ -3456,7 +3132,7 @@ apply_match (Segment         *state,
 {
 	gint match_end;
 
-	if (!can_apply_match (state->context, line, *line_pos, &match_end, regex))
+	if (!can_apply_match (SEGMENT_GET_CONTEXT(state), line, *line_pos, &match_end, regex))
 		return FALSE;
 
 	segment_extend (state, line_pos_to_offset (line, match_end));
@@ -3635,13 +3311,13 @@ context_new (Context           *parent,
 	context->definition = definition;
 	context->parent = parent;
 
-	context->style = style;
+	context->annot.style = g_strdup (style);
 	context->ignore_children_style = ignore_children_style;
 
 	if (parent != NULL && parent->ignore_children_style)
 	{
 		context->ignore_children_style = TRUE;
-		context->style = NULL;
+		context->annot.style = NULL;
 	}
 
 	if (!parent || (parent->all_ancestors_extend && CONTEXT_EXTENDS_PARENT (parent)))
@@ -3820,8 +3496,8 @@ context_unref (Context *context)
 		}
 	}
 
-	g_slist_foreach (context->context_classes, (GFunc)context_class_tag_free, NULL);
-	g_slist_free (context->context_classes);
+	g_slist_foreach (context->annot.context_classes, (GFunc)context_class_tag_free, NULL);
+	g_slist_free (context->annot.context_classes);
 
 	g_free (context->subpattern_context_classes);
 	g_free (context->subpattern_tags);
@@ -4020,18 +3696,21 @@ segment_new (GtkSourceContextEngine *ce,
 	     gboolean                is_start)
 {
 	Segment *segment;
-
 #ifdef ENABLE_CHECK_TREE
 	g_assert (!is_start || context != NULL);
 #endif
 
-	segment = g_slice_new0 (Segment);
+	segment = (Segment *) g_slice_new0 (RealSegment);
 	segment->parent = parent;
-	segment->context = context_ref (context);
 	segment->start_at = start_at;
 	segment->end_at = end_at;
-	segment->is_start = is_start;
-
+	segment->annot = &(context->annot);
+	
+	SEGMENT_GET_IS_START(segment) = is_start;
+	SEGMENT_GET_CONTEXT(segment) = context_ref (context);
+	if (context)
+		context->annot.style_tag = get_context_tag (ce, context);
+	
 	if (context == NULL)
 		add_invalid (ce, segment);
 
@@ -4307,7 +3986,7 @@ segment_destroy (GtkSourceContextEngine *ce,
 	if (SEGMENT_IS_INVALID (segment))
 		remove_invalid (ce, segment);
 
-	context_unref (segment->context);
+	context_unref (SEGMENT_GET_CONTEXT(segment));
 
 #ifdef ENABLE_DEBUG
 	g_assert (!g_slist_find (ce->priv->invalid, segment));
@@ -4348,7 +4027,7 @@ container_context_starts_here (GtkSourceContextEngine  *ce,
 		return FALSE;
 	}
 
-	new_context = create_child_context (state->context, child_def, line->text);
+	new_context = create_child_context (SEGMENT_GET_CONTEXT(state), child_def, line->text);
 	g_return_val_if_fail (new_context != NULL, FALSE);
 
 	if (!can_apply_match (new_context, line, *line_pos, &match_end,
@@ -4375,7 +4054,7 @@ container_context_starts_here (GtkSourceContextEngine  *ce,
 	 * checking before creating the segment because it's more convenient. */
 	if (*line_pos == match_end &&
 	    new_segment->prev != NULL &&
-	    new_segment->prev->context == new_segment->context &&
+	    SEGMENT_GET_CONTEXT(new_segment->prev) == SEGMENT_GET_CONTEXT(new_segment) &&
 	    new_segment->prev->start_at == new_segment->prev->end_at &&
 	    new_segment->prev->start_at == line_pos_to_offset (line, *line_pos))
 	{
@@ -4417,7 +4096,7 @@ simple_context_starts_here (GtkSourceContextEngine *ce,
 	if (!regex_match (definition->u.match, line->text, line->byte_length, *line_pos))
 		return FALSE;
 
-	new_context = create_child_context (state->context, child_def, line->text);
+	new_context = create_child_context (SEGMENT_GET_CONTEXT(state), child_def, line->text);
 	g_return_val_if_fail (new_context != NULL, FALSE);
 
 	if (!can_apply_match (new_context, line, *line_pos, &match_end, definition->u.match))
@@ -4538,8 +4217,8 @@ segment_ends_here (Segment  *state,
 {
 	g_assert (SEGMENT_IS_CONTAINER (state));
 
-	return state->context->definition->u.start_end.end &&
-		regex_match (state->context->end,
+	return SEGMENT_GET_CONTEXT(state)->definition->u.start_end.end &&
+		regex_match (SEGMENT_GET_CONTEXT(state)->end,
 			     line->text,
 			     line->byte_length,
 			     pos);
@@ -4630,7 +4309,7 @@ ancestor_ends_here (Segment                *state,
 {
 	Context *terminating_context;
 
-	terminating_context = ancestor_context_ends_here (state->context, line, line_pos);
+	terminating_context = ancestor_context_ends_here (SEGMENT_GET_CONTEXT(state), line, line_pos);
 
 	if (new_state != NULL && terminating_context != NULL)
 	{
@@ -4639,7 +4318,7 @@ ancestor_ends_here (Segment                *state,
 		 * closed by next next_segment() call from analyze_line. */
 		Segment *current_segment = state;
 
-		while (current_segment->context != terminating_context)
+		while (SEGMENT_GET_CONTEXT(current_segment) != terminating_context)
 			current_segment = current_segment->parent;
 
 		*new_state = current_segment;
@@ -4682,9 +4361,9 @@ next_segment (GtkSourceContextEngine  *ce,
 		gboolean context_end_found;
 		DefinitionChild *child_def;
 
-		if (state->context->reg_all)
+		if (SEGMENT_GET_CONTEXT(state)->reg_all)
 		{
-			if (!regex_match (state->context->reg_all,
+			if (!regex_match (SEGMENT_GET_CONTEXT(state)->reg_all,
 					  line->text,
 					  line->byte_length,
 					  pos))
@@ -4692,12 +4371,12 @@ next_segment (GtkSourceContextEngine  *ce,
 				return FALSE;
 			}
 
-			regex_fetch_pos_bytes (state->context->reg_all,
+			regex_fetch_pos_bytes (SEGMENT_GET_CONTEXT(state)->reg_all,
 					       0, &pos, NULL);
 		}
 
 		/* Does an ancestor end here? */
-		if (ANCESTOR_CAN_END_CONTEXT (state->context) &&
+		if (ANCESTOR_CAN_END_CONTEXT (SEGMENT_GET_CONTEXT(state)) &&
 		    ancestor_ends_here (state, line, pos, new_state))
 		{
 			g_assert (pos <= line->byte_length);
@@ -4711,7 +4390,7 @@ next_segment (GtkSourceContextEngine  *ce,
 
 		/* Iter over the definitions we can find in the current
 		 * context. */
-		definition_iter_init (&def_iter, state->context->definition);
+		definition_iter_init (&def_iter, SEGMENT_GET_CONTEXT(state)->definition);
 		while ((child_def = definition_iter_next (&def_iter)) != NULL)
 		{
 			gboolean try_this = TRUE;
@@ -4733,8 +4412,8 @@ next_segment (GtkSourceContextEngine  *ce,
 
 				for (prev = state->children; prev != NULL; prev = prev->next)
 				{
-					if (prev->context != NULL &&
-					    prev->context->definition == child_def->u.definition)
+					if (SEGMENT_GET_CONTEXT(prev) != NULL &&
+					    SEGMENT_GET_CONTEXT(prev)->definition == child_def->u.definition)
 					{
 						try_this = FALSE;
 						break;
@@ -4768,7 +4447,7 @@ next_segment (GtkSourceContextEngine  *ce,
 			 * Still, it may happen that parent context ends in
 			 * the middle of the end regex match, apply_match()
 			 * checks this. */
-			if (apply_match (state, line, &pos, state->context->end, SUB_PATTERN_WHERE_END))
+			if (apply_match (state, line, &pos, SEGMENT_GET_CONTEXT(state)->end, SUB_PATTERN_WHERE_END))
 			{
 				g_assert (pos <= line->byte_length);
 
@@ -4819,7 +4498,7 @@ check_line_end (GtkSourceContextEngine *ce,
 	{
 		if (SEGMENT_END_AT_LINE_END (current_segment))
 			terminating_segment = current_segment;
-		else if (!ANCESTOR_CAN_END_CONTEXT(current_segment->context))
+		else if (!ANCESTOR_CAN_END_CONTEXT(SEGMENT_GET_CONTEXT(current_segment)))
 			break;
 		current_segment = current_segment->parent;
 	}
@@ -4939,7 +4618,7 @@ analyze_line (GtkSourceContextEngine *ce,
 			g_critical ("%s",
 			            _("Highlighting a single line took too much time, "
 				      "syntax highlighting will be disabled"));
-			disable_highlighting (ce);
+			disable_syntax_analysis (ce);
 			break;
 		}
 
@@ -4971,7 +4650,7 @@ analyze_line (GtkSourceContextEngine *ce,
 
 	/* Verify if we need to close the context because we are at
 	 * the end of the line. */
-	if (ANCESTOR_CAN_END_CONTEXT (state->context) ||
+	if (ANCESTOR_CAN_END_CONTEXT (SEGMENT_GET_CONTEXT(state)) ||
 	    SEGMENT_END_AT_LINE_END (state))
 	{
 		state = check_line_end (ce, state);
@@ -5390,7 +5069,7 @@ segment_erase_middle_ (GtkSourceContextEngine *ce,
 
 	new_segment = segment_new (ce,
 				   segment->parent,
-				   segment->context,
+				   SEGMENT_GET_CONTEXT(segment),
 				   end,
 				   segment->end_at,
 				   FALSE);
@@ -5587,7 +5266,7 @@ segment_erase_range_ (GtkSourceContextEngine *ce,
 				/* If we erase the beginning, we need to clear
 				 * is_start flag. */
 				segment->start_at = end;
-				segment->is_start = FALSE;
+				SEGMENT_GET_IS_START(segment) = FALSE;
 			}
 			else
 			{
@@ -5618,7 +5297,7 @@ segment_merge (GtkSourceContextEngine *ce,
 		return;
 
 	g_assert (!SEGMENT_IS_INVALID (first));
-	g_assert (first->context == second->context);
+	g_assert (SEGMENT_GET_CONTEXT(first) == SEGMENT_GET_CONTEXT(second));
 	g_assert (first->end_at == second->start_at);
 
 	if (first->parent != second->parent)
@@ -5899,7 +5578,7 @@ update_syntax (GtkSourceContextEngine *ce,
 			state = get_segment_at_offset (ce,
 						       ce->priv->hint ? ce->priv->hint : state,
 						       line_start_offset - 1);
-		g_assert (state->context != NULL);
+		g_assert (SEGMENT_GET_CONTEXT(state) != NULL);
 
 		ce->priv->hint2 = ce->priv->hint;
 
@@ -5955,7 +5634,8 @@ update_syntax (GtkSourceContextEngine *ce,
 			 * and the segment on the next line is continuation of the
 			 * segment from previous line. */
 			if (old_state != state &&
-			    (old_state->context != state->context || state->is_start))
+			    (SEGMENT_GET_CONTEXT(old_state) != SEGMENT_GET_CONTEXT(state) || 
+			    	SEGMENT_GET_IS_START(state) ))
 			{
 				need_invalidate_next = TRUE;
 				next_line_invalid = TRUE;
@@ -6018,6 +5698,7 @@ update_syntax (GtkSourceContextEngine *ce,
 
 	g_timer_destroy (timer);
 
+
 out:
 	/* must call context_thaw, so this is the only return point */
 	context_thaw (ce->priv->root_context);
@@ -6221,12 +5902,12 @@ context_definition_unref (ContextDefinition *definition)
 #ifdef NEED_DEBUG_ID
 		g_free (sp_def->id);
 #endif
-		g_free (sp_def->style);
+		g_free (sp_def->annot.style);
 		if (sp_def->is_named)
 			g_free (sp_def->u.name);
 
-		g_slist_foreach (sp_def->context_classes, (GFunc) gtk_source_context_class_free, NULL);
-		g_slist_free (sp_def->context_classes);
+		g_slist_foreach (sp_def->annot.context_classes, (GFunc) gtk_source_context_class_free, NULL);
+		g_slist_free (sp_def->annot.context_classes);
 
 		g_slice_free (SubPatternDefinition, sp_def);
 		sub_pattern_list = sub_pattern_list->next;
@@ -6450,7 +6131,7 @@ _gtk_source_context_data_add_sub_pattern (GtkSourceContextData *ctx_data,
 #ifdef NEED_DEBUG_ID
 	sp_def->id = g_strdup (id);
 #endif
-	sp_def->style = g_strdup (style);
+	sp_def->annot.style = g_strdup (style);
 	sp_def->where = where_num;
 	number = sub_pattern_to_int (name);
 
@@ -6468,7 +6149,7 @@ _gtk_source_context_data_add_sub_pattern (GtkSourceContextData *ctx_data,
 	parent->sub_patterns = g_slist_append (parent->sub_patterns, sp_def);
 	sp_def->index = parent->n_sub_patterns++;
 
-	sp_def->context_classes = copy_context_classes (context_classes);
+	sp_def->annot.context_classes = copy_context_classes (context_classes);
 
 	return TRUE;
 }
diff --git a/gtksourceview/gtksourcecontextengine.h b/gtksourceview/gtksourcecontextengine.h
index 5074000..f21f2ce 100644
@@ -24,6 +24,7 @@
 
 #include <gtksourceview/gtksourceengine.h>
 #include <gtksourceview/gtksourcelanguage.h>
+#include <gtksourcecontextengine-private.h>
 
 G_BEGIN_DECLS
 
@@ -81,7 +82,13 @@ GtkSourceContextClass *
 
 void		gtk_source_context_class_free		(GtkSourceContextClass *cclass);
 
-GtkSourceContextEngine *_gtk_source_context_engine_new  (GtkSourceContextData	*data);
+GtkSourceContextEngine *
+		_gtk_source_context_engine_new		(GtkSourceContextData	*data);
+
+Segment *	_gtk_source_context_engine_get_tree	(GtkSourceContextEngine *ce);
+
+GHashTable *	_gtk_source_context_engine_get_style_tags
+							(GtkSourceContextEngine *ce);
 
 gboolean	 _gtk_source_context_data_define_context
 							(GtkSourceContextData	 *data,
diff --git a/gtksourceview/gtksourceengine.c b/gtksourceview/gtksourceengine.c
index e89dfe2..60ae509 100644
@@ -44,7 +44,7 @@ _gtk_source_engine_init (G_GNUC_UNUSED GtkSourceEngine *engine)
 
 void
 _gtk_source_engine_attach_buffer (GtkSourceEngine *engine,
-				 GtkTextBuffer   *buffer)
+				 GtkTextBuffer    *buffer)
 {
 	g_return_if_fail (GTK_IS_SOURCE_ENGINE (engine));
 	g_return_if_fail (GTK_SOURCE_ENGINE_GET_CLASS (engine)->attach_buffer != NULL);
@@ -79,30 +79,19 @@ _gtk_source_engine_text_deleted (GtkSourceEngine *engine,
 }
 
 void
-_gtk_source_engine_update_highlight (GtkSourceEngine   *engine,
-				     const GtkTextIter *start,
-				     const GtkTextIter *end,
-				     gboolean           synchronous)
+_gtk_source_engine_analyze (GtkSourceEngine   *engine,
+			    const GtkTextIter *start,
+			    const GtkTextIter *end,
+			    gboolean           synchronous)
 {
 	g_return_if_fail (GTK_IS_SOURCE_ENGINE (engine));
 	g_return_if_fail (start != NULL && end != NULL);
-	g_return_if_fail (GTK_SOURCE_ENGINE_GET_CLASS (engine)->update_highlight != NULL);
+	g_return_if_fail (GTK_SOURCE_ENGINE_GET_CLASS (engine)->analyze != NULL);
 
-	GTK_SOURCE_ENGINE_GET_CLASS (engine)->update_highlight (engine,
-								start,
-								end,
-								synchronous);
-}
-
-void
-_gtk_source_engine_set_style_scheme (GtkSourceEngine      *engine,
-				     GtkSourceStyleScheme *scheme)
-{
-	g_return_if_fail (GTK_IS_SOURCE_ENGINE (engine));
-	g_return_if_fail (GTK_IS_SOURCE_STYLE_SCHEME (scheme) || scheme == NULL);
-	g_return_if_fail (GTK_SOURCE_ENGINE_GET_CLASS (engine)->set_style_scheme != NULL);
-
-	GTK_SOURCE_ENGINE_GET_CLASS (engine)->set_style_scheme (engine, scheme);
+	GTK_SOURCE_ENGINE_GET_CLASS (engine)->analyze (engine,
+						       start,
+						       end,
+						       synchronous);
 }
 
 GtkTextTag *
diff --git a/gtksourceview/gtksourceengine.h b/gtksourceview/gtksourceengine.h
index 2768ffa..ccf21d6 100644
@@ -56,14 +56,11 @@ struct _GtkSourceEngineClass
 				       gint                  offset,
 				       gint                  length);
 
-	void     (* update_highlight) (GtkSourceEngine      *engine,
+	void     (* analyze) 	      (GtkSourceEngine      *engine,
 				       const GtkTextIter    *start,
 				       const GtkTextIter    *end,
 				       gboolean              synchronous);
 
-	void     (* set_style_scheme) (GtkSourceEngine      *engine,
-				       GtkSourceStyleScheme *scheme);
-
 	GtkTextTag *(* get_context_class_tag)
 				      (GtkSourceEngine      *engine,
 				       const gchar          *context_class);
@@ -79,13 +76,10 @@ void        _gtk_source_engine_text_inserted	(GtkSourceEngine      *engine,
 void        _gtk_source_engine_text_deleted	(GtkSourceEngine      *engine,
 						 gint                  offset,
 						 gint                  length);
-void        _gtk_source_engine_update_highlight	(GtkSourceEngine      *engine,
+void        _gtk_source_engine_analyze		(GtkSourceEngine      *engine,
 						 const GtkTextIter    *start,
 						 const GtkTextIter    *end,
 						 gboolean              synchronous);
-void        _gtk_source_engine_set_style_scheme	(GtkSourceEngine      *engine,
-						 GtkSourceStyleScheme *scheme);
-
 GtkTextTag *_gtk_source_engine_get_context_class_tag
 						 (GtkSourceEngine     *engine,
 						  const gchar         *context_class);
diff --git a/gtksourceview/gtksourcesyntaxhighlighter.c b/gtksourceview/gtksourcesyntaxhighlighter.c
new file mode 100644
@@ -0,0 +1,577 @@
+/* -*- mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
+ *  gtkhighlightengine.c
+ *
+ *  Copyright (C) 2003 - Gustavo Giráldez <gustavo.giraldez@gmx.net>
+ *  Copyright (C) 2005, 2006 - Marco Barisione, Emanuele Aina
+ *  Copyright (C) 2010 Jose Aliste <jose.aliste@gmail.com>
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library 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.
+ */
+
+#include "gtksourceview-i18n.h"
+#include "gtksourcesyntaxhighlighter.h"
+#include "gtktextregion.h"
+#include "gtksourcelanguage-private.h"
+#include "gtksourcebuffer.h"
+#include "gtksourcebuffer-private.h"
+#include "gtksourcestyle-private.h"
+#include "gtksourcecontextengine-private.h"
+
+#include <glib.h>
+
+#include <errno.h>
+#include <string.h>
+
+#undef ENABLE_DEBUG
+#undef ENABLE_PROFILE
+#undef ENABLE_CHECK_TREE
+#undef ENABLE_MEMORY_DEBUG /* define it to make it print memory usage information */
+			   /* it won't work with GRegex */
+
+#ifdef ENABLE_DEBUG
+#define DEBUG(x) (x)
+#else
+#define DEBUG(x)
+#endif
+
+#ifdef ENABLE_PROFILE
+#define PROFILE(x) (x)
+#else
+#define PROFILE(x)
+#endif
+
+#if defined (ENABLE_DEBUG) || defined (ENABLE_PROFILE) || \
+    defined (ENABLE_CHECK_TREE)
+#define NEED_DEBUG_ID
+#endif
+
+#define MAX_STYLE_DEPENDENCY_DEPTH	50
+
+struct _GtkSourceSyntaxHighlighterPrivate
+{
+	GtkTextBuffer		*buffer;
+	GtkSourceStyleScheme	*style_scheme;
+
+	/* All tags indexed by style name: values are GSList's of tags, ref()'ed. */
+	GHashTable		*tags;
+
+	/* pointer to the styles_map of Language. */ 
+	GHashTable		*styles_map;
+
+	/* Region covering the unhighlighted text. */
+	GtkTextRegion           *refresh_region;
+
+	/* Pointer to the segment tree created by the syntax analyzer */
+	Segment			*segment_tree;
+
+#ifdef ENABLE_MEMORY_DEBUG
+	guint			 mem_usage_timeout;
+#endif
+
+	/* Whether or not to actually highlight the buffer. */
+	guint			 highlight : 1;
+};
+
+G_DEFINE_TYPE (GtkSourceSyntaxHighlighter, _gtk_source_syntax_highlighter, G_TYPE_OBJECT)
+
+static void
+set_tag_style_hash_cb (const gchar                *style,
+		       GSList                     *tags,
+		       GtkSourceSyntaxHighlighter *highlighter);
+
+static void
+unhighlight_region_cb (gpointer  style G_GNUC_UNUSED,
+		       GSList   *tags,
+		       gpointer  user_data)
+{
+	BufAndIters *data = user_data;
+
+	while (tags != NULL)
+	{
+		gtk_text_buffer_remove_tag (data->buffer,
+					    tags->data,
+					    data->start,
+					    data->end);
+		tags = tags->next;
+	}
+}
+
+static void
+unhighlight_region (GtkSourceSyntaxHighlighter *highlighter,
+		    const GtkTextIter          *start,
+		    const GtkTextIter          *end)
+{
+	BufAndIters data;
+
+	data.buffer = highlighter->priv->buffer;
+	data.start = start;
+	data.end = end;
+
+	if (gtk_text_iter_equal (start, end))
+		return;
+
+	g_hash_table_foreach (highlighter->priv->tags,
+			      (GHFunc) unhighlight_region_cb,
+			      &data);
+}
+
+static void
+set_tag_style (GtkSourceSyntaxHighlighter *highlighter,
+	       GtkTextTag                 *tag,
+	       const gchar                *style_id)
+{
+	GtkSourceStyle *style;
+	const gchar *map_to;
+	gint guard = 0;
+
+	DEBUG (g_print ("Set Tag style\n"));
+
+	g_return_if_fail (GTK_IS_TEXT_TAG (tag));
+	g_return_if_fail (style_id != NULL);
+
+	_gtk_source_style_apply (NULL, tag);
+
+	if (highlighter->priv->style_scheme == NULL)
+		return;
+
+	map_to = style_id;
+	style = gtk_source_style_scheme_get_style (highlighter->priv->style_scheme,
+						   style_id);
+
+	while (style == NULL)
+	{
+		GtkSourceStyleInfo *info;
+
+		if (guard > MAX_STYLE_DEPENDENCY_DEPTH)
+		{
+			g_warning ("Potential circular dependency between styles detected for style '%s'", style_id);
+			break;
+		}
+
+		++guard;
+
+		/* FIXME Style references really must be fixed, both parser for
+		 * sane use in lang files, and engine for safe use. */
+		info = g_hash_table_lookup (highlighter->priv->styles_map, map_to);
+
+		map_to = (info != NULL) ? info->map_to : NULL;
+
+		if (!map_to)
+			break;
+
+		style = gtk_source_style_scheme_get_style (highlighter->priv->style_scheme, map_to);
+	}
+
+	/* not having style is fine, since parser checks validity of every style reference,
+	 * so we don't need to spit a warning here */
+	if (style != NULL)
+		_gtk_source_style_apply (style, tag);
+}
+
+
+
+static void
+apply_tags (GtkSourceSyntaxHighlighter  *highlighter,
+	    Segment                     *segment,
+	    gint                         start_offset,
+	    gint                         end_offset)
+{
+	GtkTextTag *tag;
+	GtkTextIter start_iter, end_iter;
+	GtkTextBuffer *buffer = highlighter->priv->buffer;
+	SubPattern *sp;
+	Segment *child;
+
+	g_assert (segment != NULL);
+
+	/* Non-annotated segments are invalid.*/
+	if (!segment->annot)
+		return;
+
+	if (segment->start_at >= end_offset || segment->end_at <= start_offset)
+		return;
+
+	start_offset = MAX (start_offset, segment->start_at);
+	end_offset = MIN (end_offset, segment->end_at);
+
+	tag = segment->annot->style_tag; /* get_context_tag */
+
+	if (tag != NULL)
+	{
+		/* printf("tag is not null\n"); */
+		gint style_start_at, style_end_at;
+
+		style_start_at = start_offset;
+		style_end_at = end_offset;
+
+		if (segment->annot->style_inside)
+		{
+			style_start_at = MAX (segment->start_at + segment->start_len, start_offset);
+			style_end_at = MIN (segment->end_at - segment->end_len, end_offset);
+		}
+
+		if (style_start_at > style_end_at)
+		{
+			g_critical ("%s: oops", G_STRLOC);
+		}
+		else
+		{	/* FIXME: We should cache the start_at and end_at so we only apply the tag
+			   where is needed, instead of erasing all the highlighting */
+			gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, style_start_at);
+			end_iter = start_iter;
+			gtk_text_iter_forward_chars (&end_iter, style_end_at - style_start_at);
+			gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+		}
+	}
+
+	for (sp = segment->sub_patterns; sp != NULL; sp = sp->next)
+	{
+		if (sp->start_at >= start_offset && sp->end_at <= end_offset)
+		{
+			gint start = MAX (start_offset, sp->start_at);
+			gint end = MIN (end_offset, sp->end_at);
+
+			tag = sp->annot->style_tag;
+
+			if (tag != NULL)
+			{
+				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+				end_iter = start_iter;
+				gtk_text_iter_forward_chars (&end_iter, end - start);
+				gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+			}
+		}
+	}
+
+	for (child = segment->children;
+	     child != NULL && child->start_at < end_offset;
+	     child = child->next)
+	{
+		if (child->end_at > start_offset)
+			apply_tags (highlighter, child, start_offset, end_offset);
+	}
+}
+
+/**
+ * highlight_region:
+ *
+ * @highlighter: a #GtkSourceSyntaxHighlighter.
+ * @start: the beginning of the region to highlight.
+ * @end: the end of the region to highlight.
+ *
+ * Highlights the specified region.
+ */
+static void
+highlight_region (GtkSourceSyntaxHighlighter *highlighter,
+		  const GtkTextIter          *start,
+		  const GtkTextIter          *end)
+{
+#ifdef ENABLE_PROFILE
+	GTimer *timer;
+#endif
+	GtkTextIter real_end;
+
+	real_end = *end;
+	if (gtk_text_iter_starts_line (&real_end))
+		gtk_text_iter_backward_char (&real_end);
+	if (gtk_text_iter_compare (start, &real_end) >= 0)
+		return;
+
+#ifdef ENABLE_PROFILE
+	timer = g_timer_new ();
+#endif
+
+	/* First we need to delete tags in the region. */
+	unhighlight_region (highlighter, start, &real_end);
+
+	apply_tags (highlighter,
+		    highlighter->priv->segment_tree,
+		    gtk_text_iter_get_offset (start),
+		    gtk_text_iter_get_offset (&real_end));
+	g_hash_table_foreach (highlighter->priv->tags,
+			      (GHFunc) set_tag_style_hash_cb,
+			      highlighter);
+
+#ifdef ENABLE_PROFILE
+	g_print ("highlight (from %d to %d), %g ms elapsed\n",
+		 gtk_text_iter_get_offset (start),
+		 gtk_text_iter_get_offset (&real_end),
+		 g_timer_elapsed (timer, NULL) * 1000);
+	g_timer_destroy (timer);
+#endif
+}
+
+
+/* FIXME: ensure_highlighted was used before to highlight regions. 
+   Since we no longer have refresh_region in the highlightengine, 
+   we use highlight_region directly for the moment. I need to investigate more
+   before I can add this method back */
+/**
+ * ensure_highlighted:
+ *
+ * @highlighter: a #GtkSourceSyntaxHighlighter.
+ * @start: the beginning of the region to highlight.
+ * @end: the end of the region to highlight.
+ *
+ * Updates text tags in reanalyzed parts of given area.
+ * It applies tags according to whatever is in the syntax
+ * tree currently, so highlighting may not be correct
+ * (gtk_source_syntax_highlighter_update_highlight is the method
+ * that actually ensures correct highlighting).
+ */
+#if 0 
+static void
+ensure_highlighted (GtkSourceSyntaxHighlighter *highlighter,
+		    const GtkTextIter          *start,
+		    const GtkTextIter          *end,
+		    GtkTextRegion	       *refresh_region)
+{
+	GtkTextRegion *region;
+	GtkTextRegionIterator reg_iter;
+
+	/* Get the subregions not yet highlighted. */
+	region = gtk_text_region_intersect (refresh_region, start, end);
+
+	if (region == NULL)
+		return;
+
+	gtk_text_region_get_iterator (region, &reg_iter, 0);
+
+	/* Highlight all subregions from the intersection.
+	 * hopefully this will only be one subregion. */
+	while (!gtk_text_region_iterator_is_end (&reg_iter))
+	{
+		GtkTextIter s, e;
+		gtk_text_region_iterator_get_subregion (&reg_iter, &s, &e);
+		highlight_region (highlighter, &s, &e);
+		gtk_text_region_iterator_next (&reg_iter);
+	}
+
+	gtk_text_region_destroy (region, TRUE);
+
+	/* Remove the just highlighted region. */
+	gtk_text_region_subtract (highlighter->priv->refresh_region, start, end);
+}
+#endif
+
+/**
+ * update_highlight_cb:
+ *
+ * @highlighter: a #GtkSourceSyntaxHighlighter.
+ * @start: start of area to update.
+ * @end: start of area to update.
+ *
+ * GtkSourceEngine::update_highlight method.
+ *
+ * Makes sure the area is analyzed and highlighted. If @synchronous
+ * is %FALSE, then it queues idle worker.
+ */
+static void
+update_highlight_cb (GtkSourceSyntaxHighlighter *highlighter,
+		     const GtkTextIter          *start,
+		     const GtkTextIter          *end,
+		     GtkSourceBuffer            *buffer)
+{
+	if (!highlighter->priv->highlight)
+		return;
+
+	highlight_region (highlighter, start, end);
+}
+
+/**
+ * enable_highlight:
+ *
+ * @highlighter: a #GtkSourceSyntaxHighlighter.
+ * @enable: whether to enable highlighting.
+ *
+ * Whether to highlight (i.e. apply tags) analyzed area.
+ * Note that this does not turn on/off the analyzis stuff,
+ * it affects only text tags.
+ */
+static void
+enable_highlight (GtkSourceSyntaxHighlighter *highlighter,
+		  gboolean                    enable)
+{
+	GtkTextIter start, end;
+
+	enable = (enable != FALSE);
+
+	if (enable == highlighter->priv->highlight)
+		return;
+
+	highlighter->priv->highlight = enable;
+	gtk_text_buffer_get_bounds (highlighter->priv->buffer,
+				    &start, &end);
+
+	if (enable)
+	{
+		/* FIXME: here we used to call refresh_range (highlighter, &start, &end, TRUE);
+		   but that is in the SyntaxAnalyzer now. */
+		highlight_region (highlighter, &start, &end);
+	}
+	else
+	{
+		unhighlight_region (highlighter, &start, &end);
+	}
+}
+
+static void
+buffer_notify_highlight_syntax_cb (GtkSourceSyntaxHighlighter *highlighter)
+{
+	gboolean highlight;
+
+	g_object_get (highlighter->priv->buffer,
+		      "highlight-syntax", &highlight,
+		      NULL);
+
+	enable_highlight (highlighter, highlight);
+}
+
+static void
+set_tag_style_hash_cb (const gchar                *style,
+		       GSList                     *tags,
+		       GtkSourceSyntaxHighlighter *highlighter)
+{
+	while (tags != NULL)
+	{
+		set_tag_style (highlighter, tags->data, style);
+		tags = tags->next;
+	}
+}
+
+static void
+gtk_source_syntax_highlighter_finalize (GObject *object)
+{
+	GtkSourceSyntaxHighlighter *highlighter = GTK_SOURCE_SYNTAX_HIGHLIGHTER (object);
+
+	g_signal_handlers_disconnect_by_func (highlighter->priv->buffer,
+					      (gpointer) buffer_notify_highlight_syntax_cb,
+					      highlighter);
+
+	/* TODO: Should I clean the root_segment? */
+	/*if (highlighter->priv->root_segment != NULL)
+		segment_destroy (highlighter, highlighter->priv->root_segment);
+	highlighter->priv->segment_tree = NULL; */
+
+	/* FIXME:
+	if (highlighter->priv->refresh_region != NULL)
+		gtk_text_region_destroy (highlighter->priv->refresh_region, FALSE);
+	highlighter->priv->refresh_region = NULL; */
+
+	g_object_unref (highlighter->priv->buffer);
+
+	if (highlighter->priv->style_scheme != NULL)
+		g_object_unref (highlighter->priv->style_scheme);
+
+	G_OBJECT_CLASS (_gtk_source_syntax_highlighter_parent_class)->finalize (object);
+}
+
+static void
+_gtk_source_syntax_highlighter_class_init (GtkSourceSyntaxHighlighterClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gtk_source_syntax_highlighter_finalize;
+
+	g_type_class_add_private (object_class, sizeof (GtkSourceSyntaxHighlighterPrivate));
+}
+
+static void
+_gtk_source_syntax_highlighter_init (GtkSourceSyntaxHighlighter *highlighter)
+{
+	highlighter->priv = G_TYPE_INSTANCE_GET_PRIVATE (highlighter,
+							 GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER,
+							 GtkSourceSyntaxHighlighterPrivate);
+
+	highlighter->priv->buffer = NULL;
+	highlighter->priv->segment_tree = NULL;
+	highlighter->priv->tags = NULL;
+	highlighter->priv->styles_map = NULL;
+	highlighter->priv->refresh_region = NULL;
+	highlighter->priv->segment_tree = NULL;
+	highlighter->priv->highlight = FALSE;
+}
+
+GtkSourceSyntaxHighlighter *
+_gtk_source_syntax_highlighter_new (GtkSourceBuffer *buffer)
+{
+	GtkSourceSyntaxHighlighter *highlighter;
+	GtkSourceContextEngine *analyzer;
+	gboolean highlight;
+
+	g_return_val_if_fail (GTK_IS_SOURCE_BUFFER (buffer), NULL);
+
+	highlighter = g_object_new (GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER, NULL);
+
+	highlighter->priv->buffer = g_object_ref (buffer);
+
+	analyzer = GTK_SOURCE_CONTEXT_ENGINE (_gtk_source_buffer_get_analyzer (buffer));
+	highlighter->priv->segment_tree = _gtk_source_context_engine_get_tree (analyzer);
+	highlighter->priv->tags = _gtk_source_context_engine_get_style_tags (analyzer);
+
+	g_object_get (highlighter->priv->buffer,
+		      "highlight-syntax", &highlight,
+		      NULL);
+	highlighter->priv->highlight = highlight;
+
+	g_signal_connect_swapped (buffer,
+				  "notify::highlight-syntax",
+				  G_CALLBACK (buffer_notify_highlight_syntax_cb),
+				  highlighter);
+	g_signal_connect_swapped (buffer,
+				  "highlight_updated", 
+				  G_CALLBACK (update_highlight_cb),
+				  highlighter);
+
+	return highlighter;
+}
+
+/**
+ * gtk_source_syntax_highlighter_set_style_scheme:
+ *
+ * @engine: #GtkSourceSyntaxHighlighter.
+ * @scheme: #GtkSourceStyleScheme to set.
+ *
+ * GtkSourceEngine::set_style_scheme method.
+ * Sets current style scheme, updates tag styles and everything.
+ */
+void
+_gtk_source_syntax_highlighter_set_style_scheme (GtkSourceSyntaxHighlighter *highlighter,
+						 GtkSourceStyleScheme       *scheme)
+{
+	g_return_if_fail (GTK_IS_SOURCE_SYNTAX_HIGHLIGHTER (highlighter));
+	g_return_if_fail (GTK_IS_SOURCE_STYLE_SCHEME (scheme) || scheme == NULL);
+
+	if (scheme != highlighter->priv->style_scheme)
+	{
+		if (highlighter->priv->style_scheme != NULL)
+			g_object_unref (highlighter->priv->style_scheme);
+
+		highlighter->priv->style_scheme = (scheme == NULL) ? NULL : g_object_ref (scheme);
+
+		g_hash_table_foreach (highlighter->priv->tags,
+				      (GHFunc) set_tag_style_hash_cb,
+				      highlighter);
+	}
+}
+
+void
+_gtk_source_syntax_highlighter_set_styles_map (GtkSourceSyntaxHighlighter *highlighter,
+					       GHashTable                 *styles)
+{
+	g_return_if_fail (GTK_IS_SOURCE_SYNTAX_HIGHLIGHTER (highlighter));
+
+	if (highlighter->priv->styles_map != styles)
+		highlighter->priv->styles_map = styles;
+}
diff --git a/gtksourceview/gtksourcesyntaxhighlighter.h b/gtksourceview/gtksourcesyntaxhighlighter.h
new file mode 100644
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
+ *  gtkhighlightengine.h
+ *
+ *  Copyright (C) 2003 - Gustavo Giráldez
+ *  Copyright (C) 2005 - Marco Barisione, Emanuele Aina
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library 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.
+ */
+
+#ifndef __GTK_SOURCE_SYNTAX_HIGHLIGHTER_H__
+#define __GTK_SOURCE_SYNTAX_HIGHLIGHTER_H__
+
+#include <gtksourceview/gtksourcebuffer.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER            (_gtk_source_syntax_highlighter_get_type ())
+#define GTK_SOURCE_SYNTAX_HIGHLIGHTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER, GtkSourceSyntaxHighlighter))
+#define GTK_SOURCE_SYNTAX_HIGHLIGHTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER, GtkSourceSyntaxHighlighterClass))
+#define GTK_IS_SOURCE_SYNTAX_HIGHLIGHTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER))
+#define GTK_IS_SOURCE_SYNTAX_HIGHLIGHTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER))
+#define GTK_SOURCE_SYNTAX_HIGHLIGHTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SOURCE_SYNTAX_HIGHLIGHTER, GtkSourceSyntaxHighlighterClass))
+
+typedef struct _GtkSourceSyntaxHighlighter        GtkSourceSyntaxHighlighter;
+typedef struct _GtkSourceSyntaxHighlighterClass   GtkSourceSyntaxHighlighterClass;
+typedef struct _GtkSourceSyntaxHighlighterPrivate GtkSourceSyntaxHighlighterPrivate;
+
+struct _GtkSourceSyntaxHighlighter
+{
+	GObject parent_instance;
+
+	/*< private >*/
+	GtkSourceSyntaxHighlighterPrivate *priv;
+};
+
+struct _GtkSourceSyntaxHighlighterClass
+{
+	GObjectClass parent_class;
+};
+
+GType				 _gtk_source_syntax_highlighter_get_type	(void) G_GNUC_CONST;
+
+GtkSourceSyntaxHighlighter	*_gtk_source_syntax_highlighter_new		(GtkSourceBuffer            *buffer);
+void				 _gtk_source_syntax_highlighter_set_style_scheme(GtkSourceSyntaxHighlighter *highlighter,
+										 GtkSourceStyleScheme 	    *scheme);
+void				 _gtk_source_syntax_highlighter_set_styles_map	(GtkSourceSyntaxHighlighter *highlighter,
+										 GHashTable                 *styles);
+
+G_END_DECLS
+
+#endif /* __GTK_SOURCE_SYNTAX_HIGHLIGHTER_H__ */
diff --git a/gtksourceview/gtksourceview-marshal.list b/gtksourceview/gtksourceview-marshal.list
index ee06a8a..90f9227 100644
@@ -16,3 +16,4 @@ BOOL:OBJECT,BOXED,OBJECT
 VOID:BOXED,POINTER
 VOID:INT
 VOID:BOXED,INT
+VOID:BOXED,BOXED,POINTER
diff --git a/tests/test-widget.c b/tests/test-widget.c
index f1154b6..633f594 100644
@@ -75,6 +75,8 @@ static void       marks_toggled_cb               (GtkAction       *action,
 						  gpointer         user_data);
 static void       margin_toggled_cb              (GtkAction       *action,
 						  gpointer         user_data);
+static void	  syntax_highlight_toggled_cb	 (GtkAction 	  *action,
+						  gpointer	   user_data);
 static void       hl_bracket_toggled_cb          (GtkAction       *action,
 						  gpointer         user_data);
 static void       hl_line_toggled_cb             (GtkAction       *action,
@@ -135,6 +137,9 @@ static GtkActionEntry view_action_entries[] = {
 };
 
 static GtkToggleActionEntry toggle_entries[] = {
+	{ "SyntaxHighlight", NULL, "Synta_x Highlighting", NULL, 
+	  "Toggle syntax highlighting",
+	  G_CALLBACK (syntax_highlight_toggled_cb), TRUE },
 	{ "HlBracket", NULL, "Highlight Matching _Bracket", NULL,
 	  "Toggle highlighting of matching bracket",
 	  G_CALLBACK (hl_bracket_toggled_cb), FALSE },
@@ -203,6 +208,7 @@ static const gchar *view_ui_description =
 "    <menu action=\"ViewMenu\">"
 "      <menuitem action=\"NewView\"/>"
 "      <separator/>"
+"      <menuitem action=\"SyntaxHighlight\"/>"
 "      <menuitem action=\"HlBracket\"/>"
 "      <menuitem action=\"ShowNumbers\"/>"
 "      <menuitem action=\"ShowMarks\"/>"
@@ -530,6 +536,18 @@ hl_bracket_toggled_cb (GtkAction *action, gpointer user_data)
 		GTK_SOURCE_BUFFER (buffer),
 		gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
 }
+static void
+syntax_highlight_toggled_cb (GtkAction *action, gpointer user_data)
+{
+        GtkTextBuffer *buffer;
+        g_return_if_fail (GTK_IS_TOGGLE_ACTION (action) && GTK_IS_SOURCE_VIEW (user_data));
+        buffer = gtk_text_view_get_buffer (user_data);
+        gtk_source_buffer_set_highlight_syntax (
+                GTK_SOURCE_BUFFER (buffer),
+                gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+}
+
+
 
 static void
 hl_line_toggled_cb (GtkAction *action, gpointer user_data)

