[anjuta/newproject: 120/120] Improve AnjutaToken object and update all parsers



commit 6ed85240256fd892e9009b6fe9215697a623213f
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sat Dec 19 15:44:32 2009 +0100

    Improve AnjutaToken object and update all parsers

 libanjuta/Makefile.am                       |   10 +-
 libanjuta/anjuta-project.c                  |  108 ++-
 libanjuta/anjuta-project.h                  |   11 +-
 libanjuta/anjuta-token-file.c               |  403 ++++++---
 libanjuta/anjuta-token-file.h               |   22 +-
 libanjuta/anjuta-token-list.c               |  756 +++++++++++++++++
 libanjuta/anjuta-token-stream.c             |  317 +++++++
 libanjuta/anjuta-token-stream.h             |   44 +
 libanjuta/anjuta-token-style.c              |  491 -----------
 libanjuta/anjuta-token.c                    | 1220 ++++++++++++++++++++-------
 libanjuta/anjuta-token.h                    |  103 +--
 plugins/am-project/Makefile.am              |    2 +
 plugins/am-project/ac-parser.y              |  342 +++++----
 plugins/am-project/ac-scanner.h             |   19 +-
 plugins/am-project/ac-scanner.l             |  327 ++------
 plugins/am-project/ac-writer.c              |  156 +++--
 plugins/am-project/am-parser.y              |  270 +++----
 plugins/am-project/am-project-private.h     |   17 +-
 plugins/am-project/am-project.c             | 1134 +++++++++++++------------
 plugins/am-project/am-project.h             |   13 +-
 plugins/am-project/am-scanner.h             |   14 +-
 plugins/am-project/am-scanner.l             |  404 ++++------
 plugins/am-project/am-writer.c              |  219 +++++
 plugins/am-project/am-writer.h              |   39 +
 plugins/mk-project/mk-parser.y              |  398 +++++-----
 plugins/mk-project/mk-project.c             |  316 +++-----
 plugins/mk-project/mk-project.h             |   12 +-
 plugins/mk-project/mk-rule.c                |   80 +-
 plugins/mk-project/mk-rule.h                |    4 +-
 plugins/mk-project/mk-scanner.h             |   18 +-
 plugins/mk-project/mk-scanner.l             |  222 +++---
 plugins/project-manager/gbf-project-model.c |    6 +-
 plugins/project-manager/gbf-project-util.c  |   46 +
 plugins/project-manager/gbf-project-util.h  |    8 +-
 plugins/project-manager/plugin.c            |    4 +-
 35 files changed, 4513 insertions(+), 3042 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index f7363bf..43d1801 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -82,12 +82,14 @@ libanjuta_la_SOURCES= \
 	anjuta-command-queue.h \
 	anjuta-token.c \
 	anjuta-token.h \
-	anjuta-token-style.c \
-	anjuta-token-style.h \
-	anjuta-token-file.c \
+	anjuta-token-list.h \
+	anjuta-token-list.c \
 	anjuta-token-file.h \
+	anjuta-token-file.c \
+	anjuta-project.c \
 	anjuta-project.h \
-	anjuta-project.c
+	anjuta-token-stream.c \
+	anjuta-token-stream.h
 
 if HAVE_PLUGIN_GLADE
 
diff --git a/libanjuta/anjuta-project.c b/libanjuta/anjuta-project.c
index 75ea98b..4938665 100644
--- a/libanjuta/anjuta-project.c
+++ b/libanjuta/anjuta-project.c
@@ -21,6 +21,31 @@
 
 #include "anjuta-debug.h"
 
+/**
+ * SECTION:anjuta-project
+ * @title: Anjuta project
+ * @short_description: Anjuta project
+ * @see_also: 
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-project.h
+ * 
+ * A project in Anjuta is represented by a tree. There are three kinds of node.
+ * 
+ * A source node represents a source file. These are lead of the tree, a source
+ * node cannot have children.
+ *
+ * A target node represents an object file defined explicitely.
+ * There are different kinds of target: program, library...
+ * A target have as children all source needed to build it.
+ *
+ * A group node is used to group several target or source, it can represent
+ * a directory by example. The root node of the project is a group node
+ * representing the project directory.
+ *
+ * All these nodes are base objects. They have derived in each project backend
+ * to provide more specific information.
+ */ 
+
 /* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
 #define NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
 #define GROUP_DATA(node)  ((node) != NULL ? (AnjutaProjectGroupData *)((node)->data) : NULL)
@@ -66,58 +91,63 @@ AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint
 	return g_node_nth_child (node, n);
 }
 
-GList *
-anjuta_project_node_all_child (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+typedef struct
 {
-	AnjutaProjectNode *node;
-	GList *list = NULL;
-	
-	for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
-	{
-		if (anjuta_project_node_get_type (node) == type)
-		{
-			list = g_list_prepend (list, node);
-		}
-	}
+	AnjutaProjectNodeFunc func;
+	gpointer data;
+} AnjutaProjectNodePacket;
 
-	list = g_list_reverse (list);
+static gboolean
+anjuta_project_node_traverse_func (GNode *node, gpointer data)
+{
+	AnjutaProjectNodePacket *pack = (AnjutaProjectNodePacket *)data;
+	
+	pack->func ((AnjutaProjectNode *)node, pack->data);
 
-	return list;
+	return FALSE;
 }
 
-GList *
-anjuta_project_node_all (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+void
+anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
 {
-	AnjutaProjectNode *node;
-	GList *list = NULL;
+    AnjutaProjectNodePacket pack = {func, data};
 	
-	for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
-	{
-		if (anjuta_project_node_get_type (node) == type)
-		{
-			list = g_list_prepend (list, node);
-		}
-		if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_GROUP)
-		{
-			GList *child_list;
+	/* POST_ORDER is important when deleting the node, children has to be
+	 * deleted first */
+	g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, anjuta_project_node_traverse_func, &pack);
+}
 
-			child_list = anjuta_project_node_all (node, type);
-			child_list = g_list_reverse (child_list);
-			list = g_list_concat (child_list, list);
-		}
-	}
+void
+anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
+{
+	g_node_children_foreach (node, G_TRAVERSE_ALL, func, data);
+}
 
-	list = g_list_reverse (list);
+AnjutaProjectNode *
+anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node)
+{
+	return g_node_append (parent, node);
+}
 
-	return list;
+AnjutaProjectNode *
+anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
+{
+	return g_node_insert_before (parent, sibling, node);
 }
 
-void
-anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
+AnjutaProjectNode *
+anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
+{
+	return g_node_insert_after (parent, sibling, node);
+}
+
+AnjutaProjectNode *
+anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node)
 {
-	g_node_traverse (node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, func, data);
+	return g_node_prepend (parent, node);
 }
 
+
 AnjutaProjectNodeType
 anjuta_project_node_get_type (const AnjutaProjectNode *node)
 {
diff --git a/libanjuta/anjuta-project.h b/libanjuta/anjuta-project.h
index 31fbed1..8eec3a2 100644
--- a/libanjuta/anjuta-project.h
+++ b/libanjuta/anjuta-project.h
@@ -83,7 +83,7 @@ typedef GNode AnjutaProjectGroup;
 typedef GNode AnjutaProjectTarget;
 typedef GNode AnjutaProjectSource;
 
-typedef GNodeTraverseFunc AnjutaProjectNodeFunc;
+typedef void (*AnjutaProjectNodeFunc) (AnjutaProjectNode *node, gpointer data);
 
 AnjutaProjectNode *anjuta_project_node_parent (AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_first_child (AnjutaProjectNode *node);
@@ -91,9 +91,14 @@ AnjutaProjectNode *anjuta_project_node_last_child (AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_next_sibling (AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_prev_sibling (AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint n);
-GList *anjuta_project_node_all_child (AnjutaProjectNode *node, AnjutaProjectNodeType type);
-GList *anjuta_project_node_all (AnjutaProjectNode *node, AnjutaProjectNodeType type);
+
+AnjutaProjectNode *anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
+
 void anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
+void anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
 
 AnjutaProjectNodeType anjuta_project_node_get_type (const AnjutaProjectNode *node);
 
diff --git a/libanjuta/anjuta-token-file.c b/libanjuta/anjuta-token-file.c
index 9fb09a8..7964cff 100644
--- a/libanjuta/anjuta-token-file.c
+++ b/libanjuta/anjuta-token-file.c
@@ -33,15 +33,11 @@ struct _AnjutaTokenFile
 {
 	GObject parent;
 	
-	GFile* file;
-	
-	gsize length;
-	gchar *content;
-	
-	AnjutaToken *first;
-	AnjutaToken *last;
+	GFile* file;				/* Corresponding GFile */
 
-	guint line_width;
+	AnjutaToken *content;		/* Current file content */
+
+	AnjutaToken *save;			/* List of memory block used */
 };
 
 struct _AnjutaTokenFileClass
@@ -54,118 +50,100 @@ static GObjectClass *parent_class = NULL;
 /* Helpers functions
  *---------------------------------------------------------------------------*/
 
-/* Create a directories, including parents if necessary. This function
- * exists in GLIB 2.18, but we need only 2.16 currently.
- * */
+/* Private functions
+ *---------------------------------------------------------------------------*/
 
-static gboolean
-make_directory_with_parents (GFile *file,
-							   GCancellable *cancellable,
-							   GError **error)
+static AnjutaToken*
+anjuta_token_file_find_position (AnjutaTokenFile *file, AnjutaToken *token)
 {
-	GError *path_error = NULL;
-	GList *children = NULL;
+	AnjutaToken *start;
+	const gchar *pos;
+	const gchar *ptr;
+	const gchar *end;
+	
+	if (token == NULL) return NULL;
 
-	for (;;)
+	if (anjuta_token_get_length (token) == 0)
 	{
-		if (g_file_make_directory (file, cancellable, &path_error))
-		{
-			/* Making child directory succeed */
-			if (children == NULL)
-			{
-				/* All directories have been created */
-				return TRUE;
-			}
-			else
-			{
-				/* Get next child directory */
-				g_object_unref (file);
-				file = (GFile *)children->data;
-				children = g_list_delete_link (children, children);
-			}
-		}
-		else if (g_error_matches (path_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+		AnjutaToken *last = anjuta_token_last (token);
+
+		for (; (token != NULL) && (token != last); token = anjuta_token_next (token))
 		{
-			g_clear_error (&path_error);
-			children = g_list_prepend (children, file);
-			file = g_file_get_parent (file);
+			if (anjuta_token_get_length (token) != 0) break;
 		}
-		else
-		{
-			g_object_unref (file);
-			g_list_foreach (children, (GFunc)g_object_unref, NULL);
-			g_list_free (children);
-			g_propagate_error (error, path_error);
+
+		if (anjuta_token_get_length (token) == 0) return NULL;
+	}
+
+	pos = anjuta_token_get_string (token);
+	for (start = file->content; start != NULL; start = anjuta_token_next (start))
+	{
+		guint len = anjuta_token_get_length (start);
 			
-			return FALSE;
+		if (len)
+		{
+			ptr = anjuta_token_get_string (start);
+			end = ptr + len;
+
+			if ((pos >= ptr) && (pos < end)) break;
 		}
-	}				
+	}
+	if ((start != NULL) && (ptr != pos))
+	{
+		start = anjuta_token_split (start, pos - ptr);
+		start = anjuta_token_next (start);
+	}
+
+	return start;
 }
 
 /* Public functions
  *---------------------------------------------------------------------------*/
 
-const gchar *
-anjuta_token_file_get_content (AnjutaTokenFile *file, GError **error)
+AnjutaToken*
+anjuta_token_file_load (AnjutaTokenFile *file, GError **error)
 {
-	if (file->content == NULL)
-	{
-		gchar *content;
-		gsize length;
+	gchar *content;
+	gsize length;
+
+	anjuta_token_file_unload (file);
 	
-		if (g_file_load_contents (file->file, NULL, &content, &length, NULL, error))
-		{
-			file->content = content;
-			file->length = length;
-		}
+	file->save = anjuta_token_new_static (ANJUTA_TOKEN_FILE,  NULL);
+	file->content = anjuta_token_new_static (ANJUTA_TOKEN_FILE,  NULL);
+	
+	if (g_file_load_contents (file->file, NULL, &content, &length, NULL, error))
+	{
+		AnjutaToken *token;
+			
+		token =	anjuta_token_new_with_string (ANJUTA_TOKEN_FILE, content, length);
+		anjuta_token_prepend_child (file->save, token);
+		
+		token =	anjuta_token_new_static (ANJUTA_TOKEN_FILE, content);
+		anjuta_token_prepend_child (file->content, token);
 	}
 	
 	return file->content;
 }
 
-gsize
-anjuta_token_file_get_length (AnjutaTokenFile *file, GError **error)
-{
-	anjuta_token_file_get_content (file, error);
-
-	return file->length;
-}
-
-typedef struct _AnjutaTokenFileSaveData AnjutaTokenFileSaveData;
-
-struct _AnjutaTokenFileSaveData
-{
-	GError **error;
-	GFileOutputStream *stream;
-	gboolean fail;
-};
-
-static gboolean
-save_node (AnjutaToken *token, AnjutaTokenFileSaveData *data)
+gboolean
+anjuta_token_file_unload (AnjutaTokenFile *file)
 {
-	if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED))
-	{
-		if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (token)))
-		{
-			if (g_output_stream_write (G_OUTPUT_STREAM (data->stream), anjuta_token_get_string (token), anjuta_token_get_length (token) * sizeof (char), NULL, data->error) < 0)
-			{
-				data->fail = TRUE;
-
-				return TRUE;
-			}
-		}
-	}
+	if (file->content != NULL) anjuta_token_free (file->content);
+	file->content = NULL;
 	
-	return FALSE;
+	if (file->save != NULL) anjuta_token_free (file->save);
+	file->save = NULL;
+
+	return TRUE;
 }
 
 gboolean
 anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
 {
 	GFileOutputStream *stream;
-	gboolean ok;
+	gboolean ok = TRUE;
 	GError *err = NULL;
-	AnjutaTokenFileSaveData data;
+	AnjutaToken *token;
 	
 	stream = g_file_replace (file->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &err);
 	if (stream == NULL)
@@ -175,7 +153,7 @@ anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
 			/* Perhaps parent directory is missing, try to create it */
 			GFile *parent = g_file_get_parent (file->file);
 			
-			if (make_directory_with_parents (parent, NULL, NULL))
+			if (g_file_make_directory_with_parents (parent, NULL, NULL))
 			{
 				g_object_unref (parent);
 				g_clear_error (&err);
@@ -197,14 +175,22 @@ anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
 		}
 	}
 
-	data.error = error;
-	data.stream = stream;
-	data.fail = FALSE;
-	g_node_traverse ((GNode *)file->first, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)save_node, &data);
-	ok = g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
+	for (token = file->content; token != NULL; token = anjuta_token_next (token))
+	{
+		if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (token)))
+		{
+			if (g_output_stream_write (G_OUTPUT_STREAM (stream), anjuta_token_get_string (token), anjuta_token_get_length (token) * sizeof (char), NULL, error) < 0)
+			{
+				ok = FALSE;
+				break;
+			}
+		}
+	}
+		
+	ok = ok && g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
 	g_object_unref (stream);
 	
-	return !data.fail;
+	return ok;
 }
 
 void
@@ -214,44 +200,192 @@ anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file)
 	file->file = new_file != NULL ? g_object_ref (new_file) : NULL;
 }
 
-void
-anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token)
+/**
+ * anjuta_token_file_update:
+ * @file: a #AnjutaTokenFile derived class object.
+ * @token: Token to update.
+ * 
+ * Update the file with all changed token starting from @token. The function can
+ * return an error if the token is not in the file.
+ * 
+ * Return value: TRUE is the update is done without error.
+ */
+gboolean
+anjuta_token_file_update (AnjutaTokenFile *file, AnjutaToken *token)
 {
-	if (file->last == NULL)
+	AnjutaToken *prev;
+	AnjutaToken *next;
+	AnjutaToken *last;
+	guint added;
+
+	/* Find all token needing an update */
+	
+	/* Find following tokens */
+	for (last = token; last != NULL; last = anjuta_token_next (last))
+	{
+		/* Get all tokens in group */
+		last = anjuta_token_last (last);
+
+		gint flags = anjuta_token_get_flags (last);
+		if (!(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+	}
+
+	/* Find first modified token */
+	for (;;)
 	{
-		file->first = token;
+		gint flags = anjuta_token_get_flags (token);
+		if (flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED)) break;
+		if (token == last)
+		{
+			/* No changed */
+			return TRUE;
+		}
+		token = anjuta_token_next (token);
 	}
-	else if (file->last == file->first)
+	
+	/* Find previous token */
+	for (prev = token; prev != NULL; prev = anjuta_token_previous (prev))
 	{
-		g_node_insert_after ((GNode *)file->first, NULL, (GNode *)token);
+		gint flags = anjuta_token_get_flags (prev);
+		if ((anjuta_token_get_length (prev) != 0) && !(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+		token = prev;    
 	}
-	else
+	
+	/* Delete removed token and compute length of added token */
+	added = 0;
+	for (next = token; (next != NULL) && (next != last);)
 	{
-		while (((GNode *)file->last)->parent != (GNode *)file->first)
+		gint flags = anjuta_token_get_flags (next);
+		
+		if ((flags & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (next) > 0))
 		{
-			file->last = (AnjutaToken *)((GNode *)file->last)->parent;
+			AnjutaToken *pos = anjuta_token_file_find_position (file, next);
+			guint len = anjuta_token_get_length (next);
+
+			if (pos != NULL)
+			{
+				while (len != 0)
+				{
+					guint flen = anjuta_token_get_length (pos);
+					if (len < flen)
+					{
+						pos = anjuta_token_split (pos, len);
+						flen = len;
+					}
+					pos = anjuta_token_free (pos);
+					len -= flen;
+				}
+				next = anjuta_token_free (next);
+				continue;
+			}
+		}
+		else if (flags & ANJUTA_TOKEN_ADDED)
+		{
+			added += anjuta_token_get_length (next);
 		}
-		g_node_insert_after ((GNode *)file->first, (GNode *)file->last, (GNode *)token);
+		next = anjuta_token_next (next);
 	}
-	file->last = token;
-}
 
-void
-anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width)
-{
-	if (width > file->line_width) file->line_width = width;
-}
+	/* Add new token */
+	if (added != 0)
+	{
+		gchar *value;
+		AnjutaToken *add;
+		AnjutaToken *start = NULL;
+		
+		value = g_new (gchar, added);
+		anjuta_token_prepend_child (file->save, anjuta_token_new_with_string (ANJUTA_TOKEN_NAME, value, added));
+		
+		/* Find token position */
+		if (prev != NULL)
+		{
+			start = anjuta_token_file_find_position (file, prev);
+			if (start != NULL) start = anjuta_token_split (start, anjuta_token_get_length (prev));
+		}
 
-AnjutaToken*
-anjuta_token_file_first (AnjutaTokenFile *file)
-{
-	return file->first;
+		/* Insert token */
+		add = anjuta_token_new_fragment (ANJUTA_TOKEN_NAME, value, added);
+		if (start == NULL)
+		{
+			anjuta_token_prepend_child (file->content, add);
+		}
+		else
+		{
+			anjuta_token_insert_after (start, add);
+		}
+
+		for (next = token; (next != NULL) && (next != last); next = anjuta_token_next (next))
+		{
+			gint flags = anjuta_token_get_flags (next);
+
+
+			if (flags & ANJUTA_TOKEN_ADDED)
+			{
+				guint len = anjuta_token_get_length (next);
+
+				if (len > 0)
+				{
+					memcpy(value, anjuta_token_get_string (next), len);
+					anjuta_token_set_string (next, value, len);
+					value += len;
+				}
+			}
+		}
+	}
+
+	fprintf (stdout, "Dump config list from file:\n");
+	anjuta_token_dump (file->content);
+
+	
+	return TRUE;
 }
 
-AnjutaToken*
-anjuta_token_file_last (AnjutaTokenFile *file)
+gboolean
+anjuta_token_file_get_token_location (AnjutaTokenFile *file, AnjutaTokenFileLocation *location, AnjutaToken *token)
 {
-	return file->last;
+	AnjutaTokenFileLocation loc = {NULL, 1, 1};
+	AnjutaToken *pos;
+	const gchar *target = anjuta_token_get_string (token);
+	
+	for (pos = file->content; pos != NULL; pos = anjuta_token_next (pos))
+	{
+		if (!(anjuta_token_get_flags (pos) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (pos)))
+		{
+			const gchar *ptr;
+			const gchar *end;
+
+			ptr = anjuta_token_get_string (pos);
+			end = ptr + anjuta_token_get_length (pos);
+			
+			for (; ptr != end; ptr++)
+			{
+				if (*ptr == '\n')
+				{
+					/* New line */
+					loc.line++;
+					loc.column = 1;
+				}
+				else
+				{
+					loc.column++;
+				}
+					
+				if (ptr == target)
+				{
+					if (location != NULL)
+					{
+						location->filename = file->file == NULL ? NULL : g_file_get_parse_name (file->file);
+						location->line = loc.line;
+						location->column = loc.column;
+					}
+
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
 }
 
 GFile*
@@ -260,10 +394,15 @@ anjuta_token_file_get_file (AnjutaTokenFile *file)
 	return file->file;
 }
 
-guint
-anjuta_token_file_get_line_width (AnjutaTokenFile *file)
+AnjutaToken*
+anjuta_token_file_get_content (AnjutaTokenFile *file)
 {
-	return file->line_width;
+	if (file->content == NULL)
+	{
+		anjuta_token_file_load (file, NULL);
+	}
+	
+	return file->content;
 }
 
 /* GObject functions
@@ -279,10 +418,7 @@ anjuta_token_file_dispose (GObject *object)
 {
 	AnjutaTokenFile *file = ANJUTA_TOKEN_FILE (object);
 
-	anjuta_token_free (file->first);
-
-	if (file->content) g_free (file->content);
-	file->content = NULL;
+	anjuta_token_file_unload (file);
 	
 	if (file->file) g_object_unref (file->file);
 	file->file = NULL;
@@ -297,6 +433,8 @@ static void
 anjuta_token_file_instance_init (AnjutaTokenFile *file)
 {
 	file->file = NULL;
+	file->content = NULL;
+	file->save = NULL;
 }
 
 /* class_init intialize the class itself not the instance */
@@ -351,12 +489,7 @@ anjuta_token_file_new (GFile *gfile)
 {
 	AnjutaTokenFile *file = g_object_new (ANJUTA_TOKEN_FILE_TYPE, NULL);
 
-	if (gfile)
-	{
-		file->file =  g_object_ref (gfile);
-		file->first = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
-		file->last = file->first;
-	}
+	if (gfile) file->file =  g_object_ref (gfile);
 	
 	return file;
 };
diff --git a/libanjuta/anjuta-token-file.h b/libanjuta/anjuta-token-file.h
index d1053f1..1061d86 100644
--- a/libanjuta/anjuta-token-file.h
+++ b/libanjuta/anjuta-token-file.h
@@ -37,23 +37,29 @@ G_BEGIN_DECLS
 typedef struct _AnjutaTokenFile AnjutaTokenFile;
 typedef struct _AnjutaTokenFileClass AnjutaTokenFileClass;
 
+typedef struct
+{
+	gchar *filename;
+	guint line;
+	guint column;
+} AnjutaTokenFileLocation;
+
 GType anjuta_token_file_get_type (void);
 
 AnjutaTokenFile *anjuta_token_file_new (GFile *file);
 void anjuta_token_file_free (AnjutaTokenFile *file);
 
-const gchar* anjuta_token_file_get_content (AnjutaTokenFile *file, GError **error);
-gsize anjuta_token_file_get_length (AnjutaTokenFile *file, GError **error);
-void anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file);
+AnjutaToken* anjuta_token_file_load (AnjutaTokenFile *file, GError **error);
+gboolean anjuta_token_file_unload (AnjutaTokenFile *file);
 gboolean anjuta_token_file_save (AnjutaTokenFile *file, GError **error);
+void anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file);
 
-void anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token);
-void anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width);
+gboolean anjuta_token_file_update (AnjutaTokenFile *file, AnjutaToken *token);
 
-AnjutaToken* anjuta_token_file_first (AnjutaTokenFile *file);
-AnjutaToken* anjuta_token_file_last (AnjutaTokenFile *file);
+gboolean anjuta_token_file_get_token_location (AnjutaTokenFile *file, AnjutaTokenFileLocation *location, AnjutaToken *token);
 GFile *anjuta_token_file_get_file (AnjutaTokenFile *file);
-guint anjuta_token_file_get_line_width (AnjutaTokenFile *file);
+AnjutaToken *anjuta_token_file_get_content (AnjutaTokenFile *file);
+
 
 G_END_DECLS
 
diff --git a/libanjuta/anjuta-token-list.c b/libanjuta/anjuta-token-list.c
new file mode 100644
index 0000000..ba89ea3
--- /dev/null
+++ b/libanjuta/anjuta-token-list.c
@@ -0,0 +1,756 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-list.c
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anjuta-token-list.h"
+
+#include "libanjuta/anjuta-debug.h"
+
+#include <string.h>
+
+/* Type definition
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaTokenStyleSeparator AnjutaTokenStyleSeparator;
+
+struct _AnjutaTokenStyleSeparator
+{
+	guint count;
+	gchar *value;
+	gboolean eol;
+};
+
+struct _AnjutaTokenStyle
+{
+	guint max_width;
+	GHashTable *separator;
+};
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+void free_separator (AnjutaTokenStyleSeparator *sep, gpointer user_data)
+{
+	g_free (sep->value);
+	g_slice_free (AnjutaTokenStyleSeparator, sep);
+}
+
+void free_separator_list (guint key, GList *value, gpointer user_data)
+{
+	/* Free list elements */
+	g_list_foreach (value, (GFunc)free_separator, NULL);
+	g_list_free (value);
+}
+
+AnjutaTokenStyleSeparator*
+anjuta_token_style_insert_separator (AnjutaTokenStyle *style, guint key, const gchar *value)
+{
+	GList *list;
+	GList *last = NULL;
+	GList *sibling = NULL;
+	AnjutaTokenStyleSeparator *sep;
+
+
+	/* Look the separator is already registered */
+	list = (GList *)g_hash_table_lookup (style->separator, GINT_TO_POINTER (key));
+	if (list != NULL)
+	{
+		for (sibling = list; sibling != NULL; sibling = g_list_next(sibling))
+		{
+			sep = (AnjutaTokenStyleSeparator *)sibling->data;
+
+			/* Keep the first separator with count = 1, to insert the new one if
+			 * not found */
+			if ((last == NULL) && (sep->count == 1)) last = sibling;
+
+			if (value == NULL)
+			{
+				if (sep->value == NULL)
+				{
+					sep->count++;
+					break;
+				}
+			}
+			else if ((sep->value != NULL) && (strcmp (sep->value, value) == 0))
+			{
+				sep->count++;
+				break;
+			}
+		}
+	}
+
+	if (sibling != NULL)
+	{
+		/* Increment the separator count, Move it if needed */
+		for (last = g_list_previous (sibling); last != NULL; last = g_list_previous (sibling))
+		{
+			if (((AnjutaTokenStyleSeparator *)sibling->data)->count >= ((AnjutaTokenStyleSeparator *)last->data)->count)
+			{
+				last->next = sibling->next;
+				sibling->next = last;
+				sibling->prev = last->prev;
+				last->prev = sibling;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		if (last == NULL)
+		{
+			/* Update the list head */
+			list = sibling;
+			g_hash_table_replace (style->separator, GINT_TO_POINTER (key), list);
+		}
+
+		return (AnjutaTokenStyleSeparator *)sibling->data;
+	}
+	else
+	{
+		/* Create a new separator */
+		sep = g_slice_new0 (AnjutaTokenStyleSeparator);
+		sep->count = 1;
+		sep->value = g_strdup (value);
+		sep->eol = value == NULL ? FALSE : strchr (value, '\n') != NULL;
+		list = g_list_insert_before (list, last, sep);
+		g_hash_table_replace (style->separator, GINT_TO_POINTER (key), list);
+
+		return sep;
+	}
+}
+
+AnjutaTokenStyleSeparator*
+anjuta_token_style_insert_separator_between (AnjutaTokenStyle *style, gint next, gint prev, const gchar *value)
+{
+	return anjuta_token_style_insert_separator (style, ((guint)prev & 0xFFFF) | (((guint)next & 0xFFFF) << 16), value);
+}
+
+static AnjutaToken*
+anjuta_token_style_lookup (AnjutaTokenStyle *style, AnjutaTokenType type, gboolean eol)
+{
+	GList *list;
+	
+	list = g_hash_table_lookup (style->separator, GINT_TO_POINTER (type));
+
+	return anjuta_token_new_string (ANJUTA_TOKEN_NAME, ((AnjutaTokenStyleSeparator *)list->data)->value);
+}
+
+/* Public style functions
+ *---------------------------------------------------------------------------*/
+
+void
+anjuta_token_style_update (AnjutaTokenStyle *style, AnjutaToken *list)
+{
+	AnjutaToken *token;
+	AnjutaToken *next_token;
+	guint prev = 0;
+	guint next = 0;
+	guint line_width = 0;
+	guint sep_count = 0;
+
+	/* Initialize first line width */
+	for (token = list; token != NULL; token = anjuta_token_previous (token))
+	{
+		gchar *value = anjuta_token_evaluate (token);
+		const gchar *eol = strrchr (value, '\n');
+		gsize len = strlen (value);
+
+		g_free (value);
+
+
+		if (eol != NULL)
+		{
+			line_width = value + len - eol;
+			break;
+		}
+
+		line_width += len;
+	}
+	
+	for (token = anjuta_token_first_item (list); token != NULL; token = next_token)
+	{
+		gchar *value = NULL;
+		const gchar *eol;
+		gsize len;
+		gint type;
+		
+		next_token = anjuta_token_next_item (token);
+		type = anjuta_token_get_type (token);
+		next = next_token == NULL ? 0 : anjuta_token_get_type (next_token);
+
+		value = anjuta_token_evaluate (token);
+		if (value == NULL) continue;
+
+		len = strlen (value);
+		eol = strrchr (value, '\n');
+		if (eol != NULL) len -= (eol - value);
+		g_free (value);
+
+		line_width += len;
+		
+		switch (type)
+		{
+			case ANJUTA_TOKEN_START:
+			case ANJUTA_TOKEN_LAST:
+			case ANJUTA_TOKEN_NEXT:
+				break;
+			default:
+				if (eol != NULL)
+				{
+					line_width = len;
+					sep_count = 0;
+				}
+				continue;
+		}
+		
+		value = anjuta_token_evaluate (token);
+		anjuta_token_style_insert_separator_between (style, 0, type, value);
+		if (type == ANJUTA_TOKEN_NEXT)
+		{
+			anjuta_token_style_insert_separator_between (style, next, prev, value);
+			anjuta_token_style_insert_separator_between (style, next, ANJUTA_TOKEN_ANY, value);
+			anjuta_token_style_insert_separator_between (style, ANJUTA_TOKEN_ANY, prev, value);
+		}
+		g_free (value);
+
+		if (eol == NULL)
+		{
+			sep_count++;
+		}
+		else
+		{
+			if ((sep_count > 1) && (line_width > style->max_width))
+			{
+				style->max_width = line_width;
+			}
+			sep_count = 0;
+			line_width = len;
+		}
+	}
+}	
+
+void
+anjuta_token_style_format (AnjutaTokenStyle *style, AnjutaToken *list)
+{
+	AnjutaToken *item;
+	AnjutaToken *last;
+	AnjutaToken *text;
+	AnjutaToken *prev;
+
+	/* Find following tokens */
+	for (last = list; last != NULL; last = anjuta_token_next (last))
+	{
+		/* Get all tokens in group */
+		last = anjuta_token_last (last);
+
+		gint flags = anjuta_token_get_flags (last);
+		if (!(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+	}
+	
+	/* Find previous token */
+	for (prev = list; prev != NULL; prev = anjuta_token_previous (prev))
+	{
+		gint flags = anjuta_token_get_flags (prev);
+		if ((anjuta_token_get_length (prev) != 0) && !(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+		list = prev;    
+	}
+
+	for (item = list; (item != NULL) && (item != last); item = anjuta_token_next (item))
+	{
+		if (anjuta_token_get_flags (item) & ANJUTA_TOKEN_ADDED)
+		{
+			switch (anjuta_token_get_type (item))
+			{
+			case ANJUTA_TOKEN_START:
+				text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_START, FALSE);
+				anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+				anjuta_token_insert_after (item, text);
+				anjuta_token_merge (item, text);
+				item = text;
+				break;
+			case ANJUTA_TOKEN_NEXT:
+				text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_NEXT, FALSE);
+				anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+				anjuta_token_insert_after (item, text);
+				anjuta_token_merge (item, text);
+				item = text;
+				break;
+			case ANJUTA_TOKEN_LAST:
+				text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_LAST, FALSE);
+				anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+				anjuta_token_insert_after (item, text);
+				anjuta_token_merge (item, text);
+				item = text;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
+/* Word functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_first_word:
+ * @list: a #AnjutaToken object being a list
+ *
+ * Get the first word of the list. A word is an item in the list which is not
+ * a space or a separator.
+ *
+ * Return value: A #AnjutaToken representing the first word or NULL.
+ */
+AnjutaToken *
+anjuta_token_first_word (AnjutaToken *list)
+{
+	AnjutaToken *item;
+
+	for (item = anjuta_token_first_item (list); item != NULL; item = anjuta_token_next_item (item))
+	{
+		switch (anjuta_token_get_type (item))
+		{
+		case ANJUTA_TOKEN_START:
+		case ANJUTA_TOKEN_NEXT:
+			continue;
+		case ANJUTA_TOKEN_LAST:
+			item = NULL;
+			break;
+		default:
+			break;
+		}
+		break;
+	}
+
+	return item;
+}
+
+AnjutaToken *
+anjuta_token_next_word (AnjutaToken *item)
+{
+	for (item = anjuta_token_next_item (item); item != NULL; item = anjuta_token_next_item (item))
+	{
+		switch (anjuta_token_get_type (item))
+		{
+		case ANJUTA_TOKEN_START:
+		case ANJUTA_TOKEN_NEXT:
+			continue;
+		case ANJUTA_TOKEN_LAST:
+			item = NULL;
+			break;	
+		default:
+			break;
+		}
+		break;
+	}
+
+	return item;
+}
+
+AnjutaToken *
+anjuta_token_nth_word (AnjutaToken *list, guint n)
+{
+	AnjutaToken *item;
+	gboolean no_item = TRUE;
+
+	for (item = anjuta_token_first_item (list); item != NULL; item = anjuta_token_next_item (item))
+	{
+		switch (anjuta_token_get_type (item))
+		{
+		case ANJUTA_TOKEN_START:
+			break;
+		case ANJUTA_TOKEN_NEXT:
+			if (no_item)	
+			{
+				if (n == 0) return NULL;
+				n--;
+			}
+			no_item = TRUE;
+			break;
+		case ANJUTA_TOKEN_LAST:
+			return NULL;
+		default:
+			if (n == 0) return item;
+			n--;
+			no_item = FALSE;
+			break;
+		}
+	}
+
+	return NULL;
+}
+
+AnjutaToken *
+anjuta_token_replace_nth_word (AnjutaToken *list, guint n, AnjutaToken *item)
+{
+	AnjutaToken *token;
+	gboolean no_item = TRUE;
+
+	token = anjuta_token_first_item (list); 
+	if (token == NULL)
+	{
+		token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+		anjuta_token_merge (list, token);
+	}
+
+	for (n++;;)
+	{
+		AnjutaToken *next;
+
+		switch (anjuta_token_get_type (token))
+		{
+		case ANJUTA_TOKEN_LAST:
+			if (no_item)
+			{
+				n--;
+				if (n == 0)
+				{
+					token = anjuta_token_insert_before (token, item);
+					return token;
+				}
+			}
+			token = anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+			no_item = TRUE;
+			break;
+		case ANJUTA_TOKEN_NEXT:
+			if (no_item)	
+			{
+				n--;
+				if (n == 0)
+				{
+					token = anjuta_token_insert_before (token, item);
+					return token;
+				}
+			}
+			no_item = TRUE;
+			break;
+		case ANJUTA_TOKEN_ITEM:
+			n--;
+			if (n == 0)
+			{
+				anjuta_token_set_flags (token, ANJUTA_TOKEN_REMOVED);
+				token = anjuta_token_insert_before (token, item);
+				return token;
+			}
+			no_item = FALSE;
+			break;
+		default:
+			break;
+		}
+
+		next = anjuta_token_next_item (token);
+		if (next == NULL)
+		{
+			token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+			anjuta_token_merge (list, token);
+		}
+		else
+		{
+			token = next;
+		}
+	}
+}
+
+AnjutaToken *
+anjuta_token_insert_word_before (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *item)
+{
+	AnjutaToken *token;
+
+	if (list == NULL) list = anjuta_token_list (sibling);
+
+	for (token = anjuta_token_first_item (list); token != NULL;)
+	{
+		AnjutaToken *next;
+
+		switch (anjuta_token_get_type (token))
+		{
+		case ANJUTA_TOKEN_LAST:
+			anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+			anjuta_token_insert_before (token, item);
+			return item;
+		case ANJUTA_TOKEN_START:		
+			if (token == sibling)
+			{
+				anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				anjuta_token_insert_after (token, item);
+				return item;
+			}
+			break;	
+		case ANJUTA_TOKEN_NEXT:
+			if (token == sibling)
+			{
+				token = anjuta_token_insert_before (token, item);
+				anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				return item;
+			}
+			break;
+		default:
+			if (token == sibling)
+			{
+				anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				anjuta_token_insert_before (token, item);
+				return item;
+			}
+			break;
+		}
+
+		next = anjuta_token_next_item (token);
+		if (next == NULL)
+		{
+			token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+			anjuta_token_insert_after (token, item);
+			return item;
+		}
+		token = next;
+	}
+	
+	anjuta_token_prepend_items (list, item);
+
+	return item;
+}
+
+AnjutaToken *
+anjuta_token_insert_word_after (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *item)
+{
+	AnjutaToken *token;
+
+	if (list == NULL) list = anjuta_token_list (sibling);
+
+	for (token = anjuta_token_first_item (list); token != NULL;)
+	{
+		AnjutaToken *next;
+
+		switch (anjuta_token_get_type (token))
+		{
+		case ANJUTA_TOKEN_LAST:
+			anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+			anjuta_token_insert_before (token, item);
+			return item;
+		case ANJUTA_TOKEN_START:		
+			if (token == sibling)
+			{
+				anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				anjuta_token_insert_after (token, item);
+				return item;
+			}
+			break;	
+		case ANJUTA_TOKEN_NEXT:
+			if (token == sibling)
+			{
+				token = anjuta_token_insert_after (token, item);
+				anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				return item;
+			}
+			break;
+		default:
+			if (token == sibling)
+			{
+				token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				anjuta_token_insert_after (token, item);
+				return item;
+			}
+			break;
+		}
+
+		next = anjuta_token_next_item (token);
+		if (next == NULL)
+		{
+			token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+			anjuta_token_insert_after (token, item);
+			return item;
+		}
+		token = next;
+	}
+	
+	anjuta_token_prepend_items (list, item);
+
+	return item;
+}
+
+AnjutaToken*
+anjuta_token_remove_word (AnjutaToken *token, AnjutaTokenStyle *user_style)
+{
+	AnjutaTokenStyle *style;
+	AnjutaToken *space;
+
+	style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\n",NULL,0);
+	anjuta_token_style_update (style, anjuta_token_parent (token));
+	
+	anjuta_token_set_flags (token, ANJUTA_TOKEN_REMOVED);
+	space = anjuta_token_next_item (token);
+	if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
+	{
+		/* Remove following space */
+		anjuta_token_set_flags (space, ANJUTA_TOKEN_REMOVED);
+	}
+	else
+	{
+		space = anjuta_token_previous_item (token);
+		if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
+		{
+			anjuta_token_set_flags (space, ANJUTA_TOKEN_REMOVED);
+		}
+	}
+	
+	anjuta_token_style_format (style, anjuta_token_parent (token));
+	if (user_style == NULL) anjuta_token_style_free (style);
+	
+	return NULL;
+}
+
+AnjutaToken *
+anjuta_token_insert_token_list (gboolean after, AnjutaToken *pos,...)
+{
+	AnjutaToken *first = NULL;
+	GList *group = NULL;
+	va_list args;
+	gint type;
+
+	va_start (args, pos);
+
+	for (type = va_arg (args, gint); type != 0; type = va_arg (args, gint))
+	{
+		gchar *string = va_arg (args, gchar *);
+		AnjutaToken *token;
+
+		if (after)
+		{
+			pos = token = anjuta_token_insert_after (pos, anjuta_token_new_string (type | ANJUTA_TOKEN_ADDED, string));
+		}
+		else
+		{
+			token = anjuta_token_insert_before (pos, anjuta_token_new_string (type | ANJUTA_TOKEN_ADDED, string));
+		}
+		if (first == NULL) first = token;
+
+		if (group != NULL)
+		{
+			anjuta_token_merge ((AnjutaToken *)group->data, token);
+		}
+
+		if (string == NULL)
+		{
+			switch (type)
+			{
+			case ANJUTA_TOKEN_LIST:
+				break;
+			default:
+				group = g_list_delete_link (group, group);
+				break;
+			}
+			group = g_list_prepend (group, token);
+		}
+	}
+	g_list_free (group);
+	
+	va_end (args);
+	
+	return first;
+}
+
+AnjutaToken *
+anjuta_token_find_type (AnjutaToken *list, gint flags, AnjutaTokenType* types)
+{
+	AnjutaToken *tok;
+	AnjutaToken *last = NULL;
+	
+	for (tok = list; tok != NULL; tok = anjuta_token_next (tok))
+	{
+		AnjutaTokenType *type;
+		for (type = types; *type != 0; type++)
+		{
+			if (anjuta_token_get_type (tok) == *type)
+			{
+				last = tok;
+				if (flags & ANJUTA_TOKEN_SEARCH_NOT) break;
+				if (!(flags & ANJUTA_TOKEN_SEARCH_LAST)) break;
+			}
+		}
+		if ((flags & ANJUTA_TOKEN_SEARCH_NOT) && (*type == 0)) break;
+	}
+
+	return last;
+}
+
+AnjutaToken *
+anjuta_token_skip_comment (AnjutaToken *token)
+{
+	if (token == NULL) return NULL;
+	
+	for (;;)
+	{
+		for (;;)
+		{
+			AnjutaToken *next = anjuta_token_next (token);
+
+			if (next == NULL) return token;
+			
+			switch (anjuta_token_get_type (token))
+			{
+			case ANJUTA_TOKEN_FILE:
+			case ANJUTA_TOKEN_SPACE:
+				token = next;
+				continue;
+			case ANJUTA_TOKEN_COMMENT:
+				token = next;
+				break;
+			default:
+				return token;
+			}
+			break;
+		}
+		
+		for (;;)
+		{
+			AnjutaToken *next = anjuta_token_next (token);
+
+			if (next == NULL) return token;
+			token = next;
+			if (anjuta_token_get_type (token) == ANJUTA_TOKEN_EOL) break;
+		}
+	}
+}
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+AnjutaTokenStyle *
+anjuta_token_style_new (const gchar *start, const gchar *next, const gchar *eol, const gchar *last, guint max_width)
+{
+	AnjutaTokenStyle *style;
+	
+	style = g_slice_new0 (AnjutaTokenStyle);
+	style->max_width = max_width;
+	
+	style->separator = g_hash_table_new (g_direct_hash, NULL);
+	anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_START, start);
+	anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_NEXT, next);
+	anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_NEXT, eol);
+	anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_LAST, last);
+	
+	return style;	
+}
+
+void
+anjuta_token_style_free (AnjutaTokenStyle *style)
+{
+	g_hash_table_foreach (style->separator, (GHFunc)free_separator_list, NULL);
+	g_hash_table_destroy (style->separator);
+	g_slice_free (AnjutaTokenStyle, style);
+}
diff --git a/libanjuta/anjuta-token-stream.c b/libanjuta/anjuta-token-stream.c
new file mode 100644
index 0000000..7b10f8e
--- /dev/null
+++ b/libanjuta/anjuta-token-stream.c
@@ -0,0 +1,317 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-stream.c
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anjuta-token-stream.h"
+
+#include "anjuta-debug.h"
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * SECTION:anjuta-token-stream
+ * @title: Anjuta token stream
+ * @short_description: Anjuta token stream
+ * @see_also: 
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-token-stream.h
+ *  
+ * A #AnjutaTokenStream object reads and writes a list of tokens. It uses two
+ * list. The first list is assigned when the object is created. Each token is
+ * read as characters discarding the separation between tokens. The second list
+ * is written using the data of the first list, so no new memory is allocated,
+ * in order to recreate a new list of tokens.
+ *
+ * This is used when the lexer needs several passes. At the beginning the file
+ * is read as a single token containing the whole file content. The first pass
+ * split this content into tokens. Additional passes are done on some parts of
+ * the token list to get a more precise splitting.
+ *
+ * It is important to not allocate new memory and keep the same character
+ * pointers in the additional passes because the token list does not own the
+ * memory. The address of each character is used to find the position of the
+ * changed data in the file.
+ *
+ * Several objects can be linked together to create a stack. It is used for
+ * included file or variable expansion.
+ */ 
+
+/* Types declarations
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaTokenStream
+{
+	/* Input stream */
+    AnjutaToken *first;
+    AnjutaToken *last;
+
+    /* Read position in input stream */
+    AnjutaToken *next;
+    gsize pos;
+
+    /* Write position in input stream */
+    AnjutaToken *start;
+    gsize begin;
+	
+    /* Output stream */
+    AnjutaToken *root;
+	
+	/* Parent stream */
+    AnjutaTokenStream *parent;    
+};
+
+/* Helpers functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_stream_append_token:
+ * @stream: a #AnjutaTokenStream object.
+ * @token: a #AnjutaToken object.
+ *
+ * Append an already existing token in the output stream. 
+ */
+void
+anjuta_token_stream_append_token (AnjutaTokenStream *stream, AnjutaToken *token)
+{
+	anjuta_token_append_child (stream->root, token);
+}
+
+/**
+ * anjuta_token_stream_tokenize:
+ * @stream: a #AnjutaTokenStream object.
+ * @type: a token type.
+ * @length: the token length in character.
+ *
+ * Create a token of type from the last length characters previously read and
+ * append it in the output stream. The characters are not copied in the output
+ * stream, the new token uses the same characters.
+ *
+ * Return value: The created token.
+ */
+AnjutaToken* 
+anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length)
+{
+    AnjutaToken *frag;
+    AnjutaToken *end;
+
+    frag = anjuta_token_new_fragment (type, NULL, 0);
+
+    for (end = stream->start; end != NULL;)
+    {
+        if (anjuta_token_get_type (end) < ANJUTA_TOKEN_PARSED)
+        {
+            gint toklen = anjuta_token_get_length (end);
+            AnjutaToken *copy = anjuta_token_cut (end, stream->begin, length);
+    
+            if (toklen >= (length + stream->begin))
+            {
+
+                if (end == stream->start)
+                {
+                    /* Get whole token */
+                    anjuta_token_free (frag);
+                    anjuta_token_set_type (copy, type);
+                    frag = copy;
+                }
+                else
+                {
+                    /* Get several token */
+                    anjuta_token_append_child (frag, copy);
+                }
+
+                if (toklen == (length + stream->begin))
+                {
+                    stream->start = anjuta_token_next (end);
+                    stream->begin = 0;
+                }
+                else
+                {
+                    stream->start = end;
+                    stream->begin += length;
+                }
+                break;
+            }
+            else
+            {
+                anjuta_token_append_child (frag, copy);
+                length -= toklen;
+                end = anjuta_token_next (end);
+                stream->begin = 0;
+            }
+        }
+        else
+        {
+            end = anjuta_token_next (end);
+            stream->begin = 0;
+        }
+    }
+    
+    anjuta_token_stream_append_token (stream, frag);
+
+    return frag;
+}
+
+/**
+ * anjuta_token_stream_read:
+ * @stream: a #AnjutaTokenStream object.
+ * @buffer: a character buffer to fill with token data.
+ * @max_size: the size of the buffer.
+ *
+ * Read token from the input stream and write the content as a C string in the
+ * buffer passed as argument.
+ *
+ * Return value: The number of characters written in the buffer.
+ */
+gint 
+anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_size)
+{
+    gint result = 0;
+
+    if (stream->next != NULL)
+    {
+        gsize length = anjuta_token_get_length (stream->next);
+
+        if ((anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED) || (stream->pos >= length))
+        {
+            for (;;)
+            {
+                /* Last token */
+                if (stream->next == stream->last) return 0;
+
+                if (anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED)
+                {
+                    stream->next = anjuta_token_next (stream->next);
+                }
+                else
+                {
+                    stream->next = anjuta_token_next (stream->next);
+                }
+
+                if ((stream->next == NULL) || (anjuta_token_get_type (stream->next) == ANJUTA_TOKEN_EOV))
+                {
+                    /* Last token */
+                    return 0;
+                }
+                else if ((anjuta_token_get_length (stream->next) != 0) && (anjuta_token_get_type (stream->next) < ANJUTA_TOKEN_PARSED))
+                {
+                    /* Find some data */
+                    stream->pos = 0;
+                    length = anjuta_token_get_length (stream->next);
+                    break;  
+                }
+            }
+        }
+
+        if (stream->pos < length)
+        {
+            const gchar *start = anjuta_token_get_string (stream->next);
+
+            length -= stream->pos;
+            
+            if (length > max_size) length = max_size;
+            memcpy (buffer, start + stream->pos, length);
+            stream->pos += length;
+            result = length;
+        }
+    }
+
+    return result;
+}
+
+/**
+ * anjuta_token_stream_get_root:
+ * @stream: a #AnjutaTokenStream object.
+ *
+ * Return the root token for the output stream.
+ *
+ * Return value: The output root token.
+ */
+AnjutaToken* 
+anjuta_token_stream_get_root (AnjutaTokenStream *stream)
+{
+	g_return_val_if_fail (stream != NULL, NULL);
+	
+	return stream->root;
+}
+
+
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_stream_push:
+ * @parent: a parent #AnjutaTokenStream object or NULL.
+ * @token: a token list.
+ *
+ * Create a new stream from a list of tokens. If a parent stream is passed,
+ * the new stream keep a link on it, so we can return it when the new stream
+ * will be destroyed.
+ *
+ * Return value: The newly created stream.
+ */
+AnjutaTokenStream *
+anjuta_token_stream_push (AnjutaTokenStream *parent, AnjutaToken *token)
+{
+	AnjutaTokenStream *child;
+
+    child = g_new (AnjutaTokenStream, 1);
+    child->first = token;
+    child->pos = 0;
+    child->begin = 0;
+    child->parent = parent;
+
+    child->next = anjuta_token_next (token);
+    child->start = child->next;
+    child->last = anjuta_token_last (token);
+    if (child->last == token) child->last = NULL;
+
+	child->root = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
+	
+	return child;
+}
+
+/**
+ * anjuta_token_stream_pop:
+ * @parent: a #AnjutaTokenStream object.
+ *
+ * Destroy the stream object and return the parent stream if it exists.
+ *
+ * Return value: The parent stream or NULL if there is no parent.
+ */
+AnjutaTokenStream *
+anjuta_token_stream_pop (AnjutaTokenStream *stream)
+{
+	AnjutaTokenStream *parent;
+
+	g_return_val_if_fail (stream != NULL, NULL);
+	
+	parent = stream->parent;
+    g_free (stream);
+
+	return parent;
+}
diff --git a/libanjuta/anjuta-token-stream.h b/libanjuta/anjuta-token-stream.h
new file mode 100644
index 0000000..c1d4557
--- /dev/null
+++ b/libanjuta/anjuta-token-stream.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-stream.h
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ANJUTA_TOKEN_STREAM_H_
+#define _ANJUTA_TOKEN_STREAM_H_
+
+#include <glib.h>
+
+#include <libanjuta/anjuta-token.h>
+
+G_BEGIN_DECLS
+
+typedef struct _AnjutaTokenStream AnjutaTokenStream;
+
+AnjutaTokenStream *anjuta_token_stream_push (AnjutaTokenStream *stream, AnjutaToken *token);
+AnjutaTokenStream *anjuta_token_stream_pop (AnjutaTokenStream *stream);
+
+AnjutaToken* anjuta_token_stream_get_root (AnjutaTokenStream *stream);
+
+AnjutaToken* anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length);
+gint anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_size);
+
+void anjuta_token_stream_append_token (AnjutaTokenStream *stream, AnjutaToken *token);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/anjuta-token.c b/libanjuta/anjuta-token.c
index 088e9f8..7657906 100644
--- a/libanjuta/anjuta-token.c
+++ b/libanjuta/anjuta-token.c
@@ -26,10 +26,52 @@
 #include <stdio.h>
 #include <string.h>
 
+/**
+ * SECTION:anjuta-token
+ * @title: Anjuta token
+ * @short_description: Anjuta token
+ * @see_also: 
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-token.h
+ *  
+ * A #AnjutaToken represents a token. It is a sequence of characters associated
+ * with a type representing its meaning. By example, a token can represent
+ * a keyword, a comment, a variable...
+ *
+ * The token can own the string or has only a pointer on some data allocated
+ * somewhere else with a length.
+ *
+ * A token is linked with other tokens using three double linked lists.
+ *
+ * The first list using next and prev fields is used to keep the token in the
+ * order where there are in the file. The first character of the first token is
+ * the first character in the file.
+ *
+ * A second list is used to represent included
+ * files. Such file is represented by a special token in the first list which
+ * has a pointer, named children to a token list. Each token in this secondary
+ * list has a pointer to its parent, it means the token representing the file
+ * where is the token. It looks like a tree. In fact, every file is represented
+ * by a special token, so the root node is normally a file token and has as
+ * children all the token representing the file content. This parent/child list
+ * is used for expanded variable too.
+ *
+ * A third list is used to group several tokens. A token can have a pointer to
+ * another last token. It means that this token is a group starting from this
+ * token to the one indicated by the last field. In addition each token in this
+ * group has a pointer on the first token of the group. This grouping is
+ * independent of the parent/child list. So a group can start in one file and
+ * end in another included file. The grouping can be nested too. Typically
+ * we can have a group representing a command, a sub group representing the 
+ * arguments and then one sub group for each argument.
+ */ 
+
+
 typedef struct _AnjutaTokenData AnjutaTokenData;
 
 struct _AnjutaTokenData
 {
+	AnjutaTokenData *data;
 	AnjutaTokenType type;	
 	gint flags;
 	gchar *pos;
@@ -38,126 +80,300 @@ struct _AnjutaTokenData
 
 struct _AnjutaToken
 {
-	AnjutaTokenData	*data;
 	AnjutaToken	*next;
 	AnjutaToken	*prev;
 	AnjutaToken	*parent;
+	AnjutaToken *last;
+	AnjutaToken *group;
 	AnjutaToken	*children;
+	AnjutaTokenData data;
 };
-		
-#define ANJUTA_TOKEN_DATA(node)  ((node) != NULL ? (AnjutaTokenData *)((node)->data) : NULL)
-
 
 /* Helpers functions
  *---------------------------------------------------------------------------*/
 
-/* Return true and update end if the token is found.
- * If a close token is found, return FALSE but still update end */
-gboolean
-anjuta_token_match (AnjutaToken *token, gint flags, AnjutaToken *sequence, AnjutaToken **end)
-{
+/* Private functions
+ *---------------------------------------------------------------------------*/
 
-	for (; sequence != NULL; /*sequence = flags & ANJUTA_SEARCH_BACKWARD ? anjuta_token_previous (sequence) : anjuta_token_next (sequence)*/)
+static AnjutaToken *
+anjuta_token_next_child (AnjutaToken *child, AnjutaToken **last)
+{
+	if (child == NULL) return child;
+	
+	if (child->children != NULL)
 	{
-		AnjutaToken *toka;
-		AnjutaToken *tokb = token;
-
-		for (toka = sequence; toka != NULL; toka = anjuta_token_next_sibling (toka))
+		child = child->children;
+	}
+	else
+	{
+		for (;;)
 		{
-			if (anjuta_token_compare (toka, tokb))
+			if ((*last == NULL) || (child == *last))
 			{
-				tokb = anjuta_token_next (tokb);
-				if (tokb == NULL)
+				if (child->last == NULL)
 				{
-					if (end) *end = sequence;
-					return TRUE;
+					child = NULL;
+					break;
 				}
+				*last = child->last;
 			}
-			else
+			if (child->next != NULL)
 			{
+				child = child->next;
 				break;
 			}
+			child = child->parent;
 		}
+	}
+
+	return child;
+}
+
+static AnjutaToken *
+anjuta_token_next_after_children (AnjutaToken *token)
+{
+	if (token->next != NULL)
+	{
+		return token->next;
+	}
+	else if (token->parent != NULL)
+	{
+		return anjuta_token_next_after_children (token->parent);
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+AnjutaToken *
+anjuta_token_copy (AnjutaToken *token)
+{
+	AnjutaToken *copy = NULL;
 
-		if (flags & ANJUTA_SEARCH_BACKWARD)
+	if (token != NULL)
+	{
+		copy = g_slice_new0 (AnjutaToken);
+		copy->data.type = token->data.type;
+		copy->data.flags = token->data.flags;
+		if ((copy->data.flags & ANJUTA_TOKEN_STATIC) || (token->data.pos == NULL))
 		{
-			sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_previous (sequence) : anjuta_token_previous_sibling (sequence);
+			copy->data.pos = token->data.pos;
 		}
 		else
 		{
-			sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_next (sequence) : anjuta_token_next_sibling (sequence);
+			copy->data.pos = g_strdup (token->data.pos);
 		}
+		copy->data.length = token->data.length;
 	}
-	/*g_message ("matched %p %d", sequence, level);*/
-	
-	if (end) *end = sequence;
-	
-	return FALSE;
-}
 
+	return copy;
+}
 
-gboolean
-anjuta_token_remove (AnjutaToken *token)
+static AnjutaToken *
+anjuta_token_unlink (AnjutaToken *token)
 {
-	ANJUTA_TOKEN_DATA (token)->flags |= ANJUTA_TOKEN_REMOVED;
 
-	return TRUE;
+	if (token->prev != NULL)
+	{
+		token->prev->next = token->next;
+	}
+	else if ((token->parent != NULL) && (token->parent->children == token))
+	{
+		token->parent->children = token->next;
+	}
+	token->parent = NULL;
+
+	if (token->next != NULL)
+	{
+		token->next->prev = token->prev;
+		token->next = NULL;
+	}
+	token->prev = NULL;
+
+	return token;
 }
 
-gboolean
-anjuta_token_compare (AnjutaToken *toka, AnjutaToken *tokb)
+static void
+anjuta_token_evaluate_token (AnjutaToken *token, GString *value, gboolean raw)
 {
-	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (toka);
-	AnjutaTokenData *datb = ANJUTA_TOKEN_DATA (tokb);
-
-	if (datb->type)
+	if ((token != NULL) && (token->data.length != 0))
 	{
-		if (datb->type != data->type) return FALSE;
+		if (!raw)
+		{
+			switch (anjuta_token_get_type (token))
+			{
+			case ANJUTA_TOKEN_COMMENT:
+			case ANJUTA_TOKEN_OPEN_QUOTE:
+			case ANJUTA_TOKEN_CLOSE_QUOTE:
+			case ANJUTA_TOKEN_ESCAPE:
+			case ANJUTA_TOKEN_MACRO:
+			case ANJUTA_TOKEN_EOV:
+				return;
+			default:
+				break;
+			}
+		}
+		g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
 	}
+}	
+
+static void
+anjuta_token_show (AnjutaToken *token, gint indent)
+{
+	fprintf (stdout, "%*s%p", indent, "", token);
+	fprintf (stdout, ": %d \"%.*s\" %p/%p %s\n",
+	    anjuta_token_get_type (token),
+	    anjuta_token_get_length (token),
+	    anjuta_token_get_string (token),
+	    token->last, token->children,
+	    anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED ? " (removed)" : "");
+}
+
+static AnjutaToken*
+anjuta_token_dump_child (AnjutaToken *token, gint indent)
+{
+
+	anjuta_token_show (token, indent);
 	
-	if (datb != ANJUTA_TOKEN_NONE)
+	if (token->children != NULL)
 	{
-		if (datb->length != 0)
-		{
-			if (data->length != datb->length) return FALSE;
+		AnjutaToken *child;
+		AnjutaToken *next = NULL;
+		AnjutaToken *last = anjuta_token_next_after_children (token);
 		
-			if ((data->flags & ANJUTA_TOKEN_CASE_INSENSITIVE)  && (datb->flags & ANJUTA_TOKEN_CASE_INSENSITIVE))
+		for (child = token->children; child != NULL;)
+		{
+			if (child == last)
 			{
-				if (g_ascii_strncasecmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+				return child;
 			}
-			else
+			if (next == NULL)
+			{
+				next = anjuta_token_dump_child (child, indent + 4);
+			}
+			if (child == next)
 			{
-				if (strncmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+				next = NULL;
+				
+#if 0
+				/* Look for previous children */
+				for (child = anjuta_token_next (child); child != NULL; child = child->parent)
+				{
+					if (child->parent == token) break;
+				};
+				continue;
+#endif
 			}
+			child = anjuta_token_next (child);
 		}
 	}
-		
-	if (datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS)
+	
+	if (token->last != NULL)
 	{
-		if ((data->flags & datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS) == 0)
-			return FALSE;
+		AnjutaToken *child;
+		AnjutaToken *next = NULL;
+		
+		for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (child))
+		{
+			if (next == NULL)
+			{
+				next = anjuta_token_dump_child (child, indent + 4);
+				if (child == token->last)
+				{
+					return child;
+				}
+			}
+			if (child == next) next = NULL;
+			if (child == token->last)
+			{
+				return child;
+			}
+		}
 	}
 
-	return TRUE;
+	return token;
 }
 
-AnjutaToken *
-anjuta_token_next_after_children (AnjutaToken *token)
+static gboolean
+anjuta_token_check_child (AnjutaToken *token, AnjutaToken *parent)
 {
-	if (token->next != NULL)
+	if (token->parent != parent)
 	{
-		return token->next;
+		anjuta_token_show (token, 0);
+		fprintf(stderr, "Error: Children has %p as parent instead of %p\n", token->parent, parent);
+		return FALSE;
 	}
-	else if (token->parent != NULL)
+
+	return anjuta_token_check (token);
+}
+
+/* Get and set functions
+ *---------------------------------------------------------------------------*/
+
+void
+anjuta_token_set_type (AnjutaToken *token, gint type)
+{
+	token->data.type = type;
+}
+
+gint
+anjuta_token_get_type (AnjutaToken *token)
+{
+	return token->data.type;
+}
+
+void
+anjuta_token_set_flags (AnjutaToken *token, gint flags)
+{
+	AnjutaToken *child;
+	AnjutaToken *last = token->last;
+	
+	for (child = token; child != NULL; child = anjuta_token_next_child (child, &last))
 	{
-		return anjuta_token_next_after_children (token->parent);
+		child->data.flags |= flags;
 	}
-	else
+}
+
+void
+anjuta_token_clear_flags (AnjutaToken *token, gint flags)
+{
+	token->data.flags &= ~flags;
+}
+
+gint
+anjuta_token_get_flags (AnjutaToken *token)
+{
+	return token->data.flags;
+}
+
+void
+anjuta_token_set_string (AnjutaToken *token, const gchar *data, guint length)
+{
+	if (!(token->data.flags & ANJUTA_TOKEN_STATIC))
 	{
-		return NULL;
+		g_free (token->data.pos);
+		token->data.flags |= ANJUTA_TOKEN_STATIC;
 	}
+	token->data.pos = (gchar *)data;
+	token->data.length = length;
+}
+
+const gchar *
+anjuta_token_get_string (AnjutaToken *token)
+{
+	return token->data.pos;
+}
+
+guint
+anjuta_token_get_length (AnjutaToken *token)
+{
+	return token->data.length;
 }
 
+/* Basic move functions
+ *---------------------------------------------------------------------------*/
+
 AnjutaToken *
 anjuta_token_next (AnjutaToken *token)
 {
@@ -193,31 +409,14 @@ anjuta_token_previous (AnjutaToken *token)
 }
 
 AnjutaToken *
-anjuta_token_next_sibling (AnjutaToken *token)
-{
-	return token ? token->next : NULL;
-}
-
-AnjutaToken *
-anjuta_token_next_child (AnjutaToken *token)
-{
-	return token ? token->children : NULL;
-}
-
-AnjutaToken *
-anjuta_token_previous_sibling (AnjutaToken *token)
-{
-	return token->prev;
-}
-
-AnjutaToken *
-anjuta_token_last_child (AnjutaToken *token)
+anjuta_token_last (AnjutaToken *token)
 {
-	AnjutaToken *last = NULL;
-
-	for (; token != NULL; token = (AnjutaToken *)g_node_last_child ((GNode *)last))
+	AnjutaToken *last;
+	
+	for (last = token; last->last != NULL; last = last->last);
+	if (last->children != NULL)
 	{
-		last = token;
+		for (last = last->children; last->next != NULL; last = last->next);
 	}
 
 	return last;
@@ -229,401 +428,748 @@ anjuta_token_parent (AnjutaToken *token)
 	return token->parent;
 }
 
-void
-anjuta_token_set_type (AnjutaToken *token, gint type)
+AnjutaToken *
+anjuta_token_list (AnjutaToken *token)
 {
-	ANJUTA_TOKEN_DATA (token)->type = type;
+	return token->group;
 }
 
-void
-anjuta_token_set_flags (AnjutaToken *token, gint flags)
+AnjutaToken *
+anjuta_token_parent_group (AnjutaToken *token)
 {
-	ANJUTA_TOKEN_DATA (token)->flags |= flags;
+	return token->group;
 }
 
-void
-anjuta_token_clear_flags (AnjutaToken *token, gint flags)
-{
-	ANJUTA_TOKEN_DATA (token)->flags &= ~flags;
-}
+/* Item move functions
+ *---------------------------------------------------------------------------*/
 
-gint
-anjuta_token_get_type (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_last_item (AnjutaToken *list)
 {
-	return ANJUTA_TOKEN_DATA (token)->type;
+	return list->last;
 }
 
-gint
-anjuta_token_get_flags (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_first_item (AnjutaToken *list)
 {
-	return ANJUTA_TOKEN_DATA (token)->flags;
+	if (list == NULL) return NULL;
+	if (list->children != NULL) return list->children;
+	if (list->last != NULL) return list->next;
+
+	return NULL;
 }
 
-gchar *
-anjuta_token_get_value (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_next_item (AnjutaToken *item)
 {
-	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
+	AnjutaToken *last;
 
-	return data && (data->pos != NULL) ? g_strndup (data->pos, data->length) : NULL;
-}
+	if (item == NULL) return NULL;
 
-const gchar *
-anjuta_token_get_string (AnjutaToken *token)
-{
-	return ANJUTA_TOKEN_DATA (token)->pos;
+	if ((item->group != NULL) && (item == item->group->last)) return NULL;
+	for (last = item; last->last != NULL; last = last->last);
+
+	return last->next;
 }
 
-guint
-anjuta_token_get_length (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_previous_item (AnjutaToken *item)
 {
-	return ANJUTA_TOKEN_DATA (token)->length;
+	AnjutaToken *first;
+
+	if (item == NULL) return NULL;
+
+	for (first = item->prev; (first != NULL) && (first->group != item->group); first = first->group);
+
+	return first;
 }
 
-static void
-anjuta_token_evaluate_token (AnjutaToken *token, GString *value, gboolean raw)
+/* Add/Insert/Remove tokens
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_append_child:
+ * @parent: a #AnjutaToken object used as parent.
+ * @children: a #AnjutaToken object.
+ *
+ * Insert all tokens in children as the last children of the given parent.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_append_child (AnjutaToken *parent, AnjutaToken *children)
 {
-	if ((token != NULL) && (ANJUTA_TOKEN_DATA (token)->length != 0))
+	AnjutaToken *token;
+	AnjutaToken *last;
+	AnjutaToken *old_group;
+	AnjutaToken *old_parent;
+
+	g_return_val_if_fail (parent != NULL, NULL);
+	g_return_val_if_fail (children != NULL, NULL);
+
+	old_group = children->group;
+	old_parent = children->parent;
+	
+	if (parent->children == NULL)
 	{
-		if (!raw)
+		parent->children = children;
+		
+		children->prev = NULL;
+	}
+	else
+	{
+		/* Find last children */
+		for (last = parent->children; last->next != NULL;)
 		{
-			gint type = anjuta_token_get_type (token);
-			if ((type == ANJUTA_TOKEN_COMMENT) || (type == ANJUTA_TOKEN_OPEN_QUOTE) || (type == ANJUTA_TOKEN_CLOSE_QUOTE) || (type == ANJUTA_TOKEN_ESCAPE))
+			if ((last->last != NULL) && (last->last->parent == last->parent))
 			{
-				return;
+				last = last->last;
+			}
+			else
+			{
+				last = last->next;
 			}
 		}
-		g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
-	}
-}	
 
-gchar *
-anjuta_token_evaluate_range (AnjutaToken *start, AnjutaToken *end)
-{
-	GString *value = g_string_new (NULL);
+		last->next = children;
+		children->prev = last;
+	}
 
-	for (;;)
+	/* Update each token */	
+	for (token = children;;)
 	{
-		if (start == NULL) break;
-		anjuta_token_evaluate_token (start, value, FALSE);
-		if (start == end) break;
-		
-		start = anjuta_token_next (start);
+		if (token->parent == old_parent) token->parent = parent;
+		if (token->group == old_group) token->group = parent->group;
+
+		if (token->children != NULL)
+		{
+			token = token->children;
+		}
+		else if (token->next != NULL)
+		{
+			token = token->next;
+		}
+		else
+		{
+			while (token->parent != parent)
+			{
+				token = token->parent;
+				if (token->next != NULL) break;
+			}
+			if (token->next == NULL) break;
+			token = token->next;
+		}
 	}
-	
 
-	return g_string_free (value, FALSE);
+	return children;
 }
 
-static  void
-anjuta_token_evaluate_child (AnjutaToken *token, GString *value, gboolean raw)
+/**
+ * anjuta_token_prepend_child:
+ * @parent: a #AnjutaToken object used as parent.
+ * @children: a #AnjutaToken object.
+ *
+ * Insert all tokens in children as the first children of the given parent.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_prepend_child (AnjutaToken *parent, AnjutaToken *children)
 {
-	anjuta_token_evaluate_token (token, value, raw);
+	AnjutaToken *child;
+	AnjutaToken *last = NULL;
 
-	if (token->children) anjuta_token_evaluate_child (token->children, value, raw);
+	g_return_val_if_fail (parent != NULL, NULL);
+	g_return_val_if_fail (children != NULL, NULL);
 
-	if (token->next) anjuta_token_evaluate_child (token->next, value, raw);
+	/* Update each token */	
+	for (child = children;;)
+	{
+		AnjutaToken *next;
+		
+		if (child->parent == children->parent) child->parent = parent;
+		if (child->group == children->group) child->group = parent->group;
+
+		next = anjuta_token_next_child (child, &last);
+		if (next == NULL) break;
+		child = next;
+	}
+
+	child->next = parent->children;
+	if (child->next) child->next->prev = child;
+	parent->children = children;
+
+	return children;
 }
 
-gchar *
-anjuta_token_evaluate (AnjutaToken *token)
+/**
+ * anjuta_token_prepend_items:
+ * @list: a #AnjutaToken object used as list.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens in item as item of the given list.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_prepend_items (AnjutaToken *list, AnjutaToken *item)
 {
-	GString *value = g_string_new (NULL);
-	gchar *str;
+	AnjutaToken *token;
+	AnjutaToken *old_group;
+	AnjutaToken *old_parent;
 
-	if (token != NULL)
+	g_return_val_if_fail (list != NULL, NULL);
+	g_return_val_if_fail (item != NULL, NULL);
+
+	old_group = item->group;
+	old_parent = item->parent;
+
+	/* Update each token */	
+	for (token = item;;)
 	{
-		anjuta_token_evaluate_token (token, value, FALSE);
-		if (token->children) anjuta_token_evaluate_child (token->children, value, FALSE);
+		if (token->parent == old_parent) token->parent = list->parent;
+		if (token->group == old_group) token->group = list;
+
+		if (token->children != NULL)
+		{
+			token = token->children;
+		}
+		else if (token->next != NULL)
+		{
+			token = token->next;
+		}
+		else
+		{
+			while (token->parent != list->parent)
+			{
+				token = token->parent;
+				if (token->next != NULL) break;
+			}
+			if (token->next == NULL) break;
+			token = token->next;
+		}
 	}
 
-	str = g_string_free (value, FALSE);
-	return *str == '\0' ? NULL : str; 	
-}
+	token->next = list->next;
+	if (token->next) token->next->prev = token;
 
-gchar *
-anjuta_token_value (AnjutaToken *token)
-{
-	GString *value = g_string_new (NULL);
-	gchar *str;
+	list->next = item;
+	item->prev = list;
 
-	if (token != NULL)
+	if (list->last == NULL)
 	{
-		anjuta_token_evaluate_token (token, value, TRUE);
-		if (token->children) anjuta_token_evaluate_child (token->children, value, TRUE);
+		while (token->group != list) token = token->group;
+		list->last = token;
 	}
 
-	str = g_string_free (value, FALSE);
-	return *str == '\0' ? NULL : str; 	
+	return item;
 }
 
+/**
+ * anjuta_token_insert_after:
+ * @sibling: a #AnjutaToken object.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens after sibling.
+ *
+ * Return value: The first token inserted.
+ */
 AnjutaToken *
-anjuta_token_merge (AnjutaToken *first, AnjutaToken *end)
+anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *list)
 {
-	AnjutaToken *child;
-	AnjutaToken *tok;
+	AnjutaToken *last;
+	AnjutaToken *token;
+	AnjutaToken *old_group;
+	AnjutaToken *old_parent;
+
+	g_return_val_if_fail (sibling != NULL, NULL);
+	g_return_val_if_fail (list != NULL, NULL);
 
-	if (first == end) return first;
+	old_group = list->group;
+	old_parent = list->parent;
 
-	child = (AnjutaToken *)g_node_last_child ((GNode *)first);
-	do
+	/* Update each token */	
+	for (token = list;;)
 	{
-		tok = (AnjutaToken *)g_node_next_sibling ((GNode *)first);
-		if (tok == NULL) break;
-		
-		g_node_unlink ((GNode *)tok);
-		child = (AnjutaToken *)g_node_insert_after ((GNode *)first, (GNode *)child, (GNode *)tok);
+		if (token->parent == old_parent) token->parent = sibling->parent;
+		if (token->group == old_group) token->group = sibling->group;
+
+		if (token->children != NULL)
+		{
+			token = token->children;
+		}
+		else if (token->next != NULL)
+		{
+			token = token->next;
+		}
+		else
+		{
+			while (token->parent != sibling->parent)
+			{
+				token = token->parent;
+				if (token->next != NULL) break;
+			}
+			if (token->next == NULL) break;
+			token = token->next;
+		}
+	}
 
+	for (last = sibling; last->last != NULL; last = last->last);
+
+	token->next = last->next;
+	if (token->next) token->next->prev = token;
+	
+	last->next = list;
+	list->prev = last;
+
+	if ((sibling->group != NULL) && (sibling->group->last == sibling))
+	{
+		while (token->group != sibling->group) token = token->group;
+		sibling->group->last = token;
 	}
-	while (tok != end);
 
-	return first;
+	return list;
 }
 
+/**
+ * anjuta_token_insert_before:
+ * @sibling: a #AnjutaToken object.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens before sibling.
+ *
+ * Return value: The first token inserted.
+ */
 AnjutaToken *
-anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end)
+anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *list)
 {
-	AnjutaToken *child;
-	AnjutaToken *tok;
+	AnjutaToken *last;
+	AnjutaToken *token;
+	AnjutaToken *old_group;
+	AnjutaToken *old_parent;
 
-	if (first == end) return first;
+	g_return_val_if_fail (sibling != NULL, NULL);
+	g_return_val_if_fail (list != NULL, NULL);
 
-	child = (AnjutaToken *)g_node_first_child ((GNode *)first);
-	do
+	old_group = list->group;
+	old_parent = list->parent;
+
+	/* Update each token */	
+	for (token = list;;)
 	{
-		tok = (AnjutaToken *)g_node_prev_sibling ((GNode *)first);
-		if (tok == NULL) break;
-		
-		g_node_unlink ((GNode *)tok);
-		child = (AnjutaToken *)g_node_insert_before ((GNode *)first, (GNode *)child, (GNode *)tok);
+		if (token->parent == old_parent) token->parent = sibling->parent;
+		if (token->group == old_group) token->group = sibling->group;
 
+		if (token->children != NULL)
+		{
+			token = token->children;
+		}
+		else if (token->next != NULL)
+		{
+			token = token->next;
+		}
+		else
+		{
+			while (token->parent != sibling->parent)
+			{
+				token = token->parent;
+				if (token->next != NULL) break;
+			}
+			if (token->next == NULL) break;
+			token = token->next;
+		}
 	}
-	while (tok != end);
 
-	return first;
+	for (last = sibling; last->last != NULL; last = last->last);
+
+	token->next = sibling;
+	list->prev = sibling->prev;
+	sibling->prev = token;
+
+	if (list->prev) list->prev->next = list;
+
+	if ((list->parent != NULL) && (list->parent->children == sibling)) list->parent->children = list;
+	
+	return list;
 }
 
+/**
+ * anjuta_token_delete_parent:
+ * @parent: a #AnjutaToken object used as parent.
+ *
+ * Delete only the parent token.
+ *
+ * Return value: the first children
+ */
 AnjutaToken *
-anjuta_token_copy (const AnjutaToken *token)
+anjuta_token_delete_parent (AnjutaToken *parent)
 {
-	AnjutaToken *copy = NULL;
+	AnjutaToken *token;
 
-	if (token != NULL)
+	g_return_val_if_fail (parent != NULL, NULL);
+
+	if (parent->children == NULL) return NULL;
+	
+	/* Update each token */	
+	for (token = parent->children;;)
 	{
-		AnjutaTokenData *org = ANJUTA_TOKEN_DATA (token);
-		AnjutaTokenData *data = NULL;
-		AnjutaToken *child;
-		AnjutaToken *last;
+		if (token->parent == parent) token->parent = parent->parent;
 
-		data = g_slice_new0 (AnjutaTokenData);
-		data->type =org->type;
-		data->flags = org->type;
-		if ((data->flags & ANJUTA_TOKEN_STATIC) || (org->pos == NULL))
+		if (token->children != NULL)
 		{
-			data->pos = org->pos;
+			token = token->children;
 		}
-		else
+		else if (token->next != NULL)
 		{
-			data->pos = g_strdup (ANJUTA_TOKEN_DATA (token)->pos);
+			token = token->next;
 		}
-		data->length = org->length;
-
-		copy = (AnjutaToken *)g_node_new (data);
-
-		last = NULL;
-		for (child = anjuta_token_next_child (token); child != NULL; child = anjuta_token_next_sibling (child))
+		else
 		{
-			AnjutaToken *new_child = anjuta_token_copy (child);
-			last =  last == NULL ? anjuta_token_insert_child (copy, new_child) : anjuta_token_insert_after (last, new_child);
+			while (token->parent != parent->parent)
+			{
+				token = token->parent;
+				if (token->next != NULL) break;
+			}
+			if (token->next == NULL) break;
+			token = token->next;
 		}
 	}
 
-	return copy;
+	token->next = parent->next;
+	if (token->next) token->next->prev = token;
+
+	parent->next = parent->children;
+	parent->children->prev = parent;
+	parent->children = NULL;
+
+	return anjuta_token_free (parent);
 }
 
+/* Merge function
+ *---------------------------------------------------------------------------*/
+
 AnjutaToken *
-anjuta_token_clear (AnjutaToken *token)
+anjuta_token_merge (AnjutaToken *first, AnjutaToken *end)
 {
-	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
-
-	if (!(data->flags & ANJUTA_TOKEN_STATIC))
+	if ((first == end) || (end == NULL)) return first;
+	
+	if (first->parent == NULL)
 	{
-		g_free (data->pos);
+		first->parent = end->parent;
 	}
-	data->length = 0;
-	data->pos = NULL;
+	if (first->next == NULL)
+	{
+		anjuta_token_insert_before (end, first);
+	}
+	first->last = end;
+	end->group = first;
 
-	return token;
+	return first;
 }
 
 AnjutaToken *
-anjuta_token_delete (AnjutaToken *token)
+anjuta_token_merge_own_children (AnjutaToken *group)
 {
-	GNode *last;
-	GNode *child;
-	AnjutaToken *next;
+	AnjutaToken *token;
+	AnjutaToken *next = NULL;
 	
-	for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+	if (group->last != NULL) return group;
+
+	if (group->last->last != NULL) group->last = group->last->last;
+
+	for (token = anjuta_token_next (group); (token != NULL) && (token != group->last); token = anjuta_token_next (token))
 	{
-		g_node_unlink (child);
-		last = g_node_insert_after (((GNode *)token)->parent, last, child);
+		if (next == NULL)
+		{
+			if (token->last != NULL)
+			{
+				next = token->last;
+				//token->last = NULL;
+			}
+			token->group = group;
+		}
+		else if (next == token)
+		{
+			next = NULL;
+		}
 	}
 
-	next = (AnjutaToken *)g_node_next_sibling (token);
-	anjuta_token_clear (token);
-	g_node_destroy ((GNode *)token);
-
-	return next;
+	return group;
 }
 
 AnjutaToken *
-anjuta_token_insert_child (AnjutaToken *parent, AnjutaToken *child)
+anjuta_token_merge_children (AnjutaToken *first, AnjutaToken *end)
 {
-	return (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)NULL, (GNode *)child);
+	if ((first == end) || (end == NULL))
+	{
+		return first;
+	}
+
+	if (first->parent == NULL)
+	{
+		first->parent = end->parent;
+	}
+	if (first->next == NULL)
+	{
+		anjuta_token_insert_before (end, first);
+	}
+	anjuta_token_unlink (end);
+	if (end->last != NULL)
+	{
+		first->last = end->last;
+		end->last->group = first;
+	}
+	end->group = first;
+	anjuta_token_free (end);
+
+	return first;
 }
 
 AnjutaToken *
-anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *token)
+anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end)
 {
-	return (AnjutaToken *)g_node_insert_after ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)token);
+	if ((end == NULL) || (first == end)) return first;
+
+	anjuta_token_unlink (first);
+	anjuta_token_insert_before (end, first);
+	end->group = first;
+
+	return first;
 }
 
-AnjutaToken *
-anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *baby)
+AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
 {
-	return (AnjutaToken *)g_node_insert_before ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)baby);
-}	
+	if (token->data.length > size)
+	{
+		AnjutaToken *copy;
+
+		copy = anjuta_token_copy (token);
+		anjuta_token_insert_before (token, copy);
+
+		copy->data.length = size;
+		if (token->data.flags & ANJUTA_TOKEN_STATIC)
+		{
+			token->data.pos += size;
+			token->data.length -= size;
+		}
+		else
+		{
+			memcpy(token->data.pos, token->data.pos + size, token->data.length - size);
+		}
+
+		return copy;
+	}
+	else
+	{
+		return token;
+	}
+}
 
-AnjutaToken *anjuta_token_group (AnjutaToken *parent, AnjutaToken *last)
+AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size)
 {
-	AnjutaToken *child;
-	AnjutaToken *tok;
+	AnjutaToken *copy;
 
-	if (parent == last) return parent; 
-	if (parent->children == last) return parent;
+	copy = anjuta_token_copy (token);
 
-	child = (AnjutaToken *)g_node_last_child ((GNode *)parent);
-	do
+	if (pos >= token->data.length)
+	{
+		if (!(copy->data.flags & ANJUTA_TOKEN_STATIC))
+		{
+			g_free (copy->data.pos);
+		}
+		copy->data.pos = NULL;
+		copy->data.length = 0;
+	}
+	if ((pos + size) > token->data.length)
 	{
-		tok = (AnjutaToken *)g_node_next_sibling ((GNode *)parent);
-		if (tok == NULL) break;
+		size = token->data.length - pos;
+	}
 		
-		g_node_unlink ((GNode *)tok);
-		child = (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)child, (GNode *)tok);
-
+	if (copy->data.flags & ANJUTA_TOKEN_STATIC)
+	{
+		copy->data.pos += pos;
 	}
-	while (tok != last);
+	else
+	{
+		memcpy(copy->data.pos, copy->data.pos + pos, size);
+	}
+	copy->data.length = size;
 
-	return parent;
-	
+	return copy;
 }
 
-AnjutaToken *anjuta_token_group_new (AnjutaTokenType type, AnjutaToken* first)
+/* Token evaluation
+ *---------------------------------------------------------------------------*/
+
+gchar *
+anjuta_token_evaluate (AnjutaToken *token)
 {
-	AnjutaToken *parent = anjuta_token_new_static (type, NULL);
+	GString *value = g_string_new (NULL);
+
+	if (token != NULL)
+	{
+		AnjutaToken *last = token->last;
+		AnjutaToken *child;
+		
+		for (child = token; child != NULL; child = anjuta_token_next_child (child, &last))
+		{
+			anjuta_token_evaluate_token (child, value, TRUE);
+		}
+	}
 
-	g_node_insert_before ((GNode *)first->parent, (GNode *)first, (GNode *)parent);
-	return anjuta_token_group (parent, first);
+	/* Return NULL and free data for an empty string */
+	return g_string_free (value, *(value->str) == '\0');
 }
 
-AnjutaToken *anjuta_token_ungroup (AnjutaToken *token)
+/* Other functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+anjuta_token_compare (AnjutaToken *toka, AnjutaToken *tokb)
 {
-	GNode *last = (GNode *)token;
-	GNode *child;
+	if (tokb->data.type)
+	{
+		if (tokb->data.type != toka->data.type) return FALSE;
+	}
 	
-	for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+	if (tokb->data.type != ANJUTA_TOKEN_NONE)
+	{
+		if (tokb->data.length != 0)
+		{
+			if (toka->data.length != tokb->data.length) return FALSE;
+		
+			if ((toka->data.flags & ANJUTA_TOKEN_CASE_INSENSITIVE)  && (tokb->data.flags & ANJUTA_TOKEN_CASE_INSENSITIVE))
+			{
+				if (g_ascii_strncasecmp (toka->data.pos, tokb->data.pos, toka->data.length) != 0) return FALSE;
+			}
+			else
+			{
+				if (strncmp (toka->data.pos, tokb->data.pos, toka->data.length) != 0) return FALSE;
+			}
+		}
+	}
+		
+	if (tokb->data.flags & ANJUTA_TOKEN_PUBLIC_FLAGS)
 	{
-		g_node_unlink (child);
-		last = g_node_insert_after (((GNode *)token)->parent, last, child);
+		if ((toka->data.flags & tokb->data.flags & ANJUTA_TOKEN_PUBLIC_FLAGS) == 0)
+			return FALSE;
 	}
 
-	return token;
+	return TRUE;
 }
 
-AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
+void
+anjuta_token_dump (AnjutaToken *token)
 {
-	if (ANJUTA_TOKEN_DATA (token)->length > size)
-	{
-		AnjutaToken *copy;
+	if (token == NULL) return;
+	
+	anjuta_token_dump_child (token, 0);
+}
 
-		copy = anjuta_token_copy (token);
-		g_node_insert_before ((GNode *)token->parent, (GNode *)token, (GNode *)copy);
+void
+anjuta_token_dump_link (AnjutaToken *token)
+{
+	AnjutaToken *last = token;
 
-		ANJUTA_TOKEN_DATA (copy)->length = size;
-		if (ANJUTA_TOKEN_DATA (token)->flags & ANJUTA_TOKEN_STATIC)
-		{
-			ANJUTA_TOKEN_DATA (token)->pos += size;
-			ANJUTA_TOKEN_DATA (token)->length -= size;
-		}
-		else
-		{
-			memcpy(ANJUTA_TOKEN_DATA (token)->pos, ANJUTA_TOKEN_DATA (token)->pos + size, ANJUTA_TOKEN_DATA (token)->length - size);
-		}
+	while (last->last != NULL) last = last->last;
 
-		return copy;
-	}
-	else
+	for (; token != last; token = anjuta_token_next (token))
 	{
-		return token;
+		anjuta_token_show (token, 0);
 	}
 }
 
-AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value)
+gboolean
+anjuta_token_check (AnjutaToken *token)
 {
-	for (;arg != NULL;)
+	if ((token->children != NULL) && (token->last != NULL))
+	{
+		anjuta_token_show (token, 0);
+		fprintf(stderr, "Error: Previous token has both non NULL children and last\n");
+
+		return FALSE;
+	}
+
+	if (token->children != NULL)
 	{
-		switch (anjuta_token_get_type (arg))
+		AnjutaToken *child;
+		
+		for (child = token->children; child != NULL; child = child->next)
 		{
-			case ANJUTA_TOKEN_START:
-			case ANJUTA_TOKEN_NEXT:
-			case ANJUTA_TOKEN_LAST:
-				arg = anjuta_token_next_sibling (arg);
-				continue;
-			default:
-				*value = anjuta_token_evaluate (arg);
-				arg = anjuta_token_next_sibling (arg);
-				break;
+			if (!anjuta_token_check_child (child, token)) return FALSE;
+		}
+	}
+
+	if (token->last != NULL)
+	{
+		AnjutaToken *child;
+		
+		for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (child))
+		{
+			if (!anjuta_token_check (child)) return FALSE;
+			if (child == token->last) break;
 		}
-		break;
 	}
 	
-	return arg;
+	return TRUE;
 }
 
 /* Constructor & Destructor
  *---------------------------------------------------------------------------*/
 
-AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const char *value)
+AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const gchar *value)
 {
+	AnjutaToken *token;
+	
 	if (value == NULL)
 	{
-		return anjuta_token_new_static (type, NULL);
+		token = anjuta_token_new_static (type, NULL);
 	}
 	else
 	{
-		AnjutaTokenData *data;
+		token = g_slice_new0 (AnjutaToken);
+		token->data.type = type  & ANJUTA_TOKEN_TYPE;
+		token->data.flags = type & ANJUTA_TOKEN_FLAGS;
+		token->data.pos = g_strdup (value);
+		token->data.length = strlen (value);
+	}
 
-		data = g_slice_new0 (AnjutaTokenData);
-		data->type = type  & ANJUTA_TOKEN_TYPE;
-		data->flags = type & ANJUTA_TOKEN_FLAGS;
-		data->pos = g_strdup (value);
-		data->length = strlen (value);
+	return token;
+}
 
-		return (AnjutaToken *)g_node_new (data);
+AnjutaToken*
+anjuta_token_new_with_string (AnjutaTokenType type, gchar *value, gsize length)
+{
+	AnjutaToken *token;
+	
+	if (value == NULL)
+	{
+		token = anjuta_token_new_static (type, NULL);
 	}
+	else
+	{
+		token = g_slice_new0 (AnjutaToken);
+		token->data.type = type  & ANJUTA_TOKEN_TYPE;
+		token->data.flags = type & ANJUTA_TOKEN_FLAGS;
+		token->data.pos = value;
+		token->data.length = length;
+	}
+
+	return token;
 }
-	
+
 AnjutaToken *
 anjuta_token_new_fragment (gint type, const gchar *pos, gsize length)
 {
-	AnjutaTokenData *data;
+	AnjutaToken *token;
 
-	data = g_slice_new0 (AnjutaTokenData);
-	data->type = type  & ANJUTA_TOKEN_TYPE;
-	data->flags = (type & ANJUTA_TOKEN_FLAGS) | ANJUTA_TOKEN_STATIC;
-	data->pos = (gchar *)pos;
-	data->length = length;
+	token = g_slice_new0 (AnjutaToken);
+	token->data.type = type  & ANJUTA_TOKEN_TYPE;
+	token->data.flags = (type & ANJUTA_TOKEN_FLAGS) | ANJUTA_TOKEN_STATIC;
+	token->data.pos = (gchar *)pos;
+	token->data.length = length;
 
-	return (AnjutaToken *)g_node_new (data);
+	return token;
 };
 
 AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const char *value)
@@ -631,18 +1177,48 @@ AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const char *value)
 	return anjuta_token_new_fragment (type, value, value == NULL ? 0 : strlen (value));	
 }
 
-
-static void
-free_token_data (GNode *node, gpointer data)
+AnjutaToken*
+anjuta_token_free_children (AnjutaToken *token)
 {
-	g_slice_free (AnjutaTokenData, node->data);
+	AnjutaToken *child;
+	
+	if (token == NULL) return NULL;
+
+	for (child = token->children; child != NULL; child = token->children)
+	{
+		anjuta_token_free (child);
+	}
+	token->children = NULL;
+	
+	if (token->last != NULL)
+	{
+		for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (token))
+		{
+			anjuta_token_free (child);
+			if (child == token->last) break;
+		}
+	}
+	token->last = NULL;
+
+	return token;	
 }
 
-void
+AnjutaToken*
 anjuta_token_free (AnjutaToken *token)
 {
-	if (token == NULL) return;
+	AnjutaToken *next;
+	
+	if (token == NULL) return NULL;
 
-	g_node_children_foreach ((GNode *)token, G_TRAVERSE_ALL, free_token_data, NULL);
-	g_node_destroy ((GNode *)token);
+	anjuta_token_free_children (token);
+
+	next = anjuta_token_next (token);
+	anjuta_token_unlink (token);
+	if ((token->data.pos != NULL) && !(token->data.flags & ANJUTA_TOKEN_STATIC))
+	{
+		g_free (token->data.pos);
+	}
+	g_slice_free (AnjutaToken, token);
+
+	return next;
 }
diff --git a/libanjuta/anjuta-token.h b/libanjuta/anjuta-token.h
index ed6c319..44a0e14 100644
--- a/libanjuta/anjuta-token.h
+++ b/libanjuta/anjuta-token.h
@@ -34,12 +34,16 @@ typedef enum
 	ANJUTA_TOKEN_TYPE 							= 0xFFFF,
 
 	ANJUTA_TOKEN_FIRST								= 16384,	
-	ANJUTA_TOKEN_FILE 								= 16384,
+	ANJUTA_TOKEN_FILE,
+	ANJUTA_TOKEN_MACRO,
+	ANJUTA_TOKEN_CONTENT,
+	ANJUTA_TOKEN_ARGUMENT,
+	ANJUTA_TOKEN_VALUE,
+	ANJUTA_TOKEN_EOV,
+	ANJUTA_TOKEN_PARSED,
 	ANJUTA_TOKEN_KEYWORD,
 	ANJUTA_TOKEN_OPERATOR,
 	ANJUTA_TOKEN_NAME,
-	ANJUTA_TOKEN_VALUE,
-	ANJUTA_TOKEN_MACRO,
 	ANJUTA_TOKEN_VARIABLE,
 	ANJUTA_TOKEN_DEFINITION,
 	ANJUTA_TOKEN_STATEMENT,
@@ -54,7 +58,6 @@ typedef enum
 	ANJUTA_TOKEN_START,
 	ANJUTA_TOKEN_NEXT,
 	ANJUTA_TOKEN_LAST,
-	ANJUTA_TOKEN_ARGUMENT,
 	ANJUTA_TOKEN_ITEM,
 	ANJUTA_TOKEN_STRING,
 	ANJUTA_TOKEN_ERROR,
@@ -81,81 +84,57 @@ typedef enum
 	
 } AnjutaTokenType;
 
-//typedef GNode AnjutaToken;
 typedef struct _AnjutaToken AnjutaToken;
 
-typedef struct _AnjutaTokenRange
-{
-	AnjutaToken *first;
-	AnjutaToken *last;
-} AnjutaTokenRange;
-
-enum AnjutaTokenSearchFlag
-{
-	ANJUTA_SEARCH_OVER	  = 0,
-	ANJUTA_SEARCH_INTO		= 1 << 0,
-	ANJUTA_SEARCH_ALL	   = 1 << 1,
-	ANJUTA_SEARCH_BACKWARD = 1 << 2
-};
-
 AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const gchar *value);
+AnjutaToken *anjuta_token_new_with_string (AnjutaTokenType type, gchar *value, gsize length);
 AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const gchar *value);
 AnjutaToken *anjuta_token_new_fragment (gint type, const gchar *pos, gsize length);
 
-void anjuta_token_free (AnjutaToken *token);
-
-AnjutaToken *anjuta_token_merge (AnjutaToken *first, AnjutaToken *end);
-AnjutaToken *anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end);
-AnjutaToken *anjuta_token_copy (const AnjutaToken *token);
-AnjutaToken *anjuta_token_clear (AnjutaToken *token);
-AnjutaToken *anjuta_token_delete (AnjutaToken *token);
-
-AnjutaToken *anjuta_token_group_new (AnjutaTokenType type, AnjutaToken *first);
-AnjutaToken *anjuta_token_group (AnjutaToken *parent, AnjutaToken *last);
-AnjutaToken *anjuta_token_ungroup (AnjutaToken *parent);
-
-AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size);
-
-AnjutaToken * anjuta_token_insert_child (AnjutaToken *parent, AnjutaToken *child);
-AnjutaToken *anjuta_token_insert_after (AnjutaToken *token, AnjutaToken *sibling);
-AnjutaToken *anjuta_token_insert_before (AnjutaToken *token, AnjutaToken *sibling);
-gboolean anjuta_token_match (AnjutaToken *token, gint flags, AnjutaToken *sequence, AnjutaToken **end);
-
-//AnjutaToken *anjuta_token_copy (AnjutaToken *token);
-//AnjutaToken *anjuta_token_copy_include_range (AnjutaToken *token, AnjutaToken *end);
-//AnjutaToken *anjuta_token_copy_exclude_range (AnjutaToken *token, AnjutaToken *end);
-//void anjuta_token_foreach (AnjutaToken *token, GFunc func, gpointer user_data);
-gboolean anjuta_token_remove (AnjutaToken *token);
-//gboolean anjuta_token_free_range (AnjutaToken *token, AnjutaToken *end);
-//GList *anjuta_token_split_list (AnjutaToken *token);
+AnjutaToken* anjuta_token_free_children (AnjutaToken *token);
+AnjutaToken* anjuta_token_free (AnjutaToken *token);
 
 void anjuta_token_set_type (AnjutaToken *token, gint type);
+gint anjuta_token_get_type (AnjutaToken *token);
 void anjuta_token_set_flags (AnjutaToken *token, gint flags);
 void anjuta_token_clear_flags (AnjutaToken *token, gint flags);
-
-gchar *anjuta_token_evaluate_range (AnjutaToken *start, AnjutaToken *end);
-gchar *anjuta_token_evaluate (AnjutaToken *token);
-gchar *anjuta_token_value (AnjutaToken *token);
+gint anjuta_token_get_flags (AnjutaToken *token);
+const gchar *anjuta_token_get_string (AnjutaToken *token);
+void anjuta_token_set_string (AnjutaToken *token, const char *value, guint length);
+guint anjuta_token_get_length (AnjutaToken *token);
 
 AnjutaToken *anjuta_token_next (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_after_children (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_sibling (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_child (AnjutaToken *token);
 AnjutaToken *anjuta_token_previous (AnjutaToken *token);
-AnjutaToken *anjuta_token_previous_sibling (AnjutaToken *token);
-AnjutaToken *anjuta_token_last_child (AnjutaToken *token);
+AnjutaToken *anjuta_token_last (AnjutaToken *token);
 AnjutaToken *anjuta_token_parent (AnjutaToken *token);
-gboolean anjuta_token_compare (AnjutaToken *tokena, AnjutaToken *tokenb);
+AnjutaToken *anjuta_token_list (AnjutaToken *token);
 
-AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value);
+AnjutaToken *anjuta_token_first_item (AnjutaToken *list);
+AnjutaToken *anjuta_token_next_item (AnjutaToken *item);
+AnjutaToken *anjuta_token_previous_item (AnjutaToken *item);
+AnjutaToken *anjuta_token_last_item (AnjutaToken *list);
 
+AnjutaToken *anjuta_token_append_child (AnjutaToken *parent, AnjutaToken *child);
+AnjutaToken *anjuta_token_prepend_child (AnjutaToken *parent, AnjutaToken *child);
+AnjutaToken *anjuta_token_prepend_items (AnjutaToken *list, AnjutaToken *item);
+AnjutaToken *anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *token);
+AnjutaToken *anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *token);
+AnjutaToken *anjuta_token_delete_parent (AnjutaToken *parent);
 
-gint anjuta_token_get_type (AnjutaToken *token);
-gint anjuta_token_get_flags (AnjutaToken *token);
-gchar *anjuta_token_get_value (AnjutaToken *token);
-gchar *anjuta_token_get_value_range (AnjutaToken *token, AnjutaToken *end);
-const gchar *anjuta_token_get_string (AnjutaToken *token);
-guint anjuta_token_get_length (AnjutaToken *token);
+AnjutaToken *anjuta_token_merge (AnjutaToken *first, AnjutaToken *end);
+AnjutaToken *anjuta_token_merge_own_children (AnjutaToken *first);
+AnjutaToken *anjuta_token_merge_children (AnjutaToken *first, AnjutaToken *end);
+AnjutaToken *anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end);
+AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size);
+AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size);
+
+gchar *anjuta_token_evaluate (AnjutaToken *token);
+
+void anjuta_token_dump (AnjutaToken *token);
+gboolean anjuta_token_check (AnjutaToken *token);
+void anjuta_token_dump_link (AnjutaToken *token);
+
+gboolean anjuta_token_compare (AnjutaToken *tokena, AnjutaToken *tokenb);
 
 G_END_DECLS
 
diff --git a/plugins/am-project/Makefile.am b/plugins/am-project/Makefile.am
index 29ee16d..f2a678b 100644
--- a/plugins/am-project/Makefile.am
+++ b/plugins/am-project/Makefile.am
@@ -40,6 +40,8 @@ libam_project_la_SOURCES = \
 	ac-scanner.h \
 	ac-writer.h \
 	ac-writer.c \
+	am-writer.h \
+	am-writer.c \
 	am-project-private.h \
 	am-dialogs.h \
 	am-dialogs.c
diff --git a/plugins/am-project/ac-parser.y b/plugins/am-project/ac-parser.y
index 959675e..b581a2a 100644
--- a/plugins/am-project/ac-parser.y
+++ b/plugins/am-project/ac-parser.y
@@ -18,24 +18,21 @@
  */
 %{
 
-#include <stdlib.h>
 #include "ac-scanner.h"
 #include "ac-parser.h"
 
+#include <stdlib.h>
+
 //#define YYDEBUG 1
 
 #include "libanjuta/anjuta-debug.h"
 
-//static void amp_ac_yyerror (YYLTYPE *loc, void *scanner, char const *s);
-
-//amp_ac_yydebug = 1;
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N)	((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
 
 %}
 
-/*%union {
-	AnjutaToken *token;
-}*/
-
 %token  EOL '\n'
 
 %token  SPACE ' '
@@ -51,7 +48,8 @@
 %token  COMMA             ','
 %token  LOWER           '<'
 %token  GREATER         '>'
-    
+
+%token  COMMENT         256
 %token  NAME
 %token  VARIABLE
 %token  MACRO
@@ -61,9 +59,6 @@
 
 %token  START_SPACE_LIST
 
-%left   ARG
-%left   EMPTY
-
 /* M4 macros */
 
 %token  DNL
@@ -81,21 +76,11 @@
 %token	AC_SUBST
 %token  AC_INIT
 
-/*%type pkg_check_modules obsolete_ac_output ac_output ac_config_files
-%type dnl
-%type ac_macro_with_arg ac_macro_without_arg
-%type spaces
-%type separator
-%type arg_string arg arg_list arg_list_body shell_string_body raw_string_body
-
-%type expression comment macro
-%type arg_string_body arg_body expression_body
-
-%type any_space*/
 
 %defines
 
-%pure_parser
+%define api.pure
+%define api.push_pull "push"
 
 %parse-param {AmpAcScanner* scanner}
 %lex-param   {AmpAcScanner* scanner}
@@ -108,23 +93,16 @@
 
 %debug
 
-
-%{
-static void amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s);
-
-%}
-
-
 %%
 
 input:
-    START_SPACE_LIST space_list
-    | file
+    file
+    | START_SPACE_LIST space_list
     ;
 
 file:
     /* empty */
-	| file statement
+	| file  statement
 	;
    
 statement:
@@ -187,16 +165,12 @@ operator:
     ;
 
 name:
-    not_operator_token
-    | name  word_token {
-        anjuta_token_group ($1, $2);
+    not_operator_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+        anjuta_token_merge ($$, $1);
     }
-    ;
-
-junks:
-    JUNK
-    | junks JUNK {
-        anjuta_token_group ($1, $2);
+    | name  word_token {
+        anjuta_token_merge ($1, $2);
     }
     ;
 
@@ -204,17 +178,13 @@ junks:
  *----------------------------------------------------------------------------*/
 
 dnl:
-    DNL  not_eol_list  EOL {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
-        anjuta_token_group ($1, $3);
-    }
+    DNL  not_eol_list  EOL
     ;
     
 
 pkg_check_modules:
     PKG_CHECK_MODULES arg_list {
-        anjuta_token_set_type ($1, AC_TOKEN_PKG_CHECK_MODULES);
-        $$ = anjuta_token_group ($1, $2);
+        amp_ac_scanner_load_module (scanner, $2);
     }
 	;
 
@@ -228,15 +198,12 @@ optional_arg:
     ;
 
 ac_macro_with_arg:
-	AC_MACRO_WITH_ARG optional_arg RIGHT_PAREN {
-        anjuta_token_group ($1, $1);
-    }
+	AC_MACRO_WITH_ARG optional_arg RIGHT_PAREN
 	;
 
 ac_init:
     AC_INIT arg_list {
-        anjuta_token_set_type ($1, AC_TOKEN_AC_INIT);
-        $$ = anjuta_token_group ($1, $2);
+        amp_ac_scanner_load_properties (scanner, $1, $2);
     }
 
 ac_output:
@@ -247,15 +214,13 @@ ac_output:
 
 obsolete_ac_output:
     OBSOLETE_AC_OUTPUT  arg_list {
-        anjuta_token_set_type ($1, AC_TOKEN_OBSOLETE_AC_OUTPUT);
-        $$ = anjuta_token_group ($1, $2);
+        amp_ac_scanner_load_config (scanner, $2);
     }
 	;
 	
 ac_config_files:
     AC_CONFIG_FILES  arg_list {
-        anjuta_token_set_type ($1, AC_TOKEN_AC_CONFIG_FILES);
-        $$ = anjuta_token_group ($1, $2);
+        amp_ac_scanner_load_config (scanner, $2);
     }
 	;
 
@@ -264,26 +229,41 @@ ac_config_files:
 
 arg_list:
     arg_list_body  RIGHT_PAREN {
-        anjuta_token_set_type ($2, ANJUTA_TOKEN_LAST);
-        $$ = $2;
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_LAST, NULL);
+        anjuta_token_merge ($$, $2);
+        anjuta_token_merge ($1, $$);
+        $$ = $1;
     }
     | spaces  arg_list_body  RIGHT_PAREN {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
-        anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        $$ = $3;
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_LAST, NULL);
+        anjuta_token_merge ($$, $3);
+        anjuta_token_merge ($1, $$);
+        $$ = $1;
     }
     ;
 
 arg_list_body:
-    arg
-    | arg_list_body  separator  arg
+    arg {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+        anjuta_token_merge ($$, $1);
+        fprintf(stdout, "arg_list_body arg\n");
+        anjuta_token_dump ($1);
+    }
+    | arg_list_body  separator  arg {
+        fprintf(stdout, "arg_list_body body\n");
+        anjuta_token_dump ($1);
+        fprintf(stdout, "arg_list_body separator\n");
+        anjuta_token_dump ($2);
+        fprintf(stdout, "arg_list_body arg\n");
+        anjuta_token_dump ($3);
+        anjuta_token_merge ($1, $3);
+        fprintf(stdout, "arg_list_body merge\n");
+        anjuta_token_dump ($1);
+    }
     ;
-    
+
 comment:
-    HASH not_eol_list EOL {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
-        anjuta_token_group ($1, $3);
-    }
+    HASH not_eol_list EOL
     ;
 
 not_eol_list:
@@ -294,56 +274,96 @@ not_eol_list:
 
 shell_string:
     LEFT_BRACE shell_string_body RIGHT_BRACE {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
-        anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        $$ = anjuta_token_group ($1, $3);
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+        anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+        $$ = anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($2, $3);
     }
     ;
 
 shell_string_body:
-    /* empty */
-    | shell_string_body not_brace_token
-    | shell_string_body shell_string
+    /* empty */ {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+    }
+    | shell_string_body not_brace_token {
+        anjuta_token_merge ($1, $2);
+    }
+    | shell_string_body shell_string {
+        anjuta_token_merge ($1, $2);
+    }
     ;
 
 raw_string:
     LEFT_BRACE raw_string_body RIGHT_BRACE {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
-        anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        $$ = anjuta_token_group ($1, $3);
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+        anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+        $$ = anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($2, $3);
     }
     ;
 
 raw_string_body:
-    /* empty */
-    | raw_string_body not_brace_token
-    | raw_string_body raw_string
+    /* empty */ {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+    }
+    | raw_string_body not_brace_token {
+        anjuta_token_merge ($1, $2);
+    }
+    | raw_string_body raw_string {
+        anjuta_token_merge ($1, $2);
+    }
     ;
 
 arg_string:
     LEFT_BRACE arg_string_body RIGHT_BRACE  {
-        $$ = anjuta_token_group_new (NAME, $1);
         anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
         anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
-        anjuta_token_group ($$, $3);
+        $$ = anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($2, $3);
     }
     ;
 
 arg_string_body:
-    /* empty */
-    | arg_string_body space_token
-    | arg_string_body HASH
-    | arg_string_body LEFT_PAREN
-    | arg_string_body RIGHT_PAREN
-    | arg_string_body COMMA
-    | arg_string_body EQUAL
-    | arg_string_body GREATER
-    | arg_string_body LOWER
-    | arg_string_body NAME
-    | arg_string_body VARIABLE
-    | arg_string_body WORD
+    /* empty */ {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+    }
+    | arg_string_body space_token {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body HASH {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body LEFT_PAREN {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body RIGHT_PAREN {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body COMMA {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body EQUAL {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body GREATER {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body LOWER {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body NAME {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body VARIABLE {
+        anjuta_token_merge ($1, $2);
+    }
+    | arg_string_body WORD {
+        anjuta_token_merge ($1, $2);
+    }
     | arg_string_body macro
-    | arg_string_body raw_string
+    | arg_string_body raw_string {
+        anjuta_token_merge ($1, $2);
+    }
     ;
 
 /* Items
@@ -351,33 +371,48 @@ arg_string_body:
 
 arg:
     /* empty */ {
-        $$ = NULL;
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
     }
     | arg_part arg_body {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_ARGUMENT, $1);
-        if ($2 != NULL) anjuta_token_group ($$, $2);
+        fprintf(stdout, "arg part\n");
+        anjuta_token_dump ($1);
+        fprintf(stdout, "arg body\n");
+        anjuta_token_dump ($2);
+        anjuta_token_merge_children ($1, $2);
+        fprintf(stdout, "arg merge\n");
+        anjuta_token_dump ($1);
     }        
     ;
 
 arg_body:
     /* empty */ {
-        $$ = NULL;
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
     }
     | arg_body arg_part_or_space {
-        $$ = $2;
+        anjuta_token_merge_children ($1, $2);
     }
     ;
 
 arg_part_or_space:
-    space_token
+    space_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
+        anjuta_token_merge ($$, $1);
+    }
     | arg_part
     ;
 
 arg_part:
     arg_string
-    | expression
-    | macro
-    | HASH
+    | expression { $$ = NULL;}
+    | dnl
+    | arg_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+    ;
+
+arg_token:
+    HASH
     | EQUAL
     | LOWER
     | GREATER
@@ -388,46 +423,75 @@ arg_part:
 
 separator:
     COMMA {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_NEXT, NULL);
+        anjuta_token_merge ($$, $1);
     }
     | COMMA spaces {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
-        anjuta_token_group ($$, $2);
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_NEXT, NULL);
+        fprintf(stdout, "separator spaces\n");
+        anjuta_token_dump ($2);
+        fprintf(stdout, "separator comma\n");
+        anjuta_token_dump ($1);
+        fprintf(stdout, "separator next\n");
+        anjuta_token_dump ($$);
+        anjuta_token_merge ($$, $1);
+        anjuta_token_merge_children ($$, $2);
+        fprintf(stdout, "separator merge\n");
+        anjuta_token_dump ($$);
     }
     ;
 
 expression:
     LEFT_PAREN  expression_body  RIGHT_PAREN {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
-        anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        $$ = anjuta_token_group ($1, $3);
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+        anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+        $$ = anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($2, $3);
     }
     ;
 
 expression_body:
-    /* empty */ {
-        $$ = NULL;
+    /* empty */  {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+    }
+    | expression_body space_token {
+        anjuta_token_merge ($1, $2);
     }
-    | expression_body space_token
     | expression_body comment
-    | expression_body COMMA
-    | expression_body EQUAL
-    | expression_body LOWER
-    | expression_body GREATER
-    | expression_body NAME
-    | expression_body VARIABLE
-    | expression_body WORD
+    | expression_body COMMA {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body EQUAL {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body LOWER {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body GREATER {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body NAME {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body VARIABLE {
+        anjuta_token_merge ($1, $2);
+    }
+    | expression_body WORD {
+        anjuta_token_merge ($1, $2);
+    }
     | expression_body macro
-    | expression_body expression
+    | expression_body expression {
+        anjuta_token_merge ($1, $2);
+    }
     ;
 
 spaces:
-	space_token
+	space_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+        anjuta_token_merge ($$, $1);
+    }
 	| spaces space_token {
-        anjuta_token_group ($$, $2);
-	}
-	| spaces JUNK {
-        anjuta_token_group ($$, $2);
+        anjuta_token_merge ($1, $2);
 	}
 	;
 
@@ -464,12 +528,6 @@ args_token:
     | COMMA
     ;
 
-operator_token:
-    EQUAL
-    | LOWER
-    | GREATER
-    ;
-
 not_operator_token:
     HASH
     | LEFT_BRACE
@@ -508,21 +566,7 @@ any_macro:
     | DNL
     | OBSOLETE_AC_OUTPUT
     | PKG_CHECK_MODULES
+    | AC_INIT
     ;
 
 %%
-    
-static void
-amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s)
-{
-    gchar *filename;
-
-	g_message ("scanner %p", scanner);
-    filename = amp_ac_scanner_get_filename ((AmpAcScanner *)scanner);
-    if (filename == NULL) filename = "?";
-    g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/am-project/ac-scanner.h b/plugins/am-project/ac-scanner.h
index f3d03a6..48b5f75 100644
--- a/plugins/am-project/ac-scanner.h
+++ b/plugins/am-project/ac-scanner.h
@@ -20,27 +20,31 @@
 #ifndef _AC_SCANNER_H_
 #define _AC_SCANNER_H_
 
-#include "libanjuta/anjuta-token.h"
-#include "libanjuta/anjuta-token-file.h"
-
+#include "am-project.h"
 
 #include <glib.h>
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
+/* Token location is found directly from token value. We don't maintain a 
+ * independent position. */
+#define YYLTYPE AnjutaToken*
 #define YYSTYPE AnjutaToken*
 
 typedef struct _AmpAcScanner AmpAcScanner;
 
-AmpAcScanner *amp_ac_scanner_new (void);
+AmpAcScanner *amp_ac_scanner_new (AmpProject *project);
 void amp_ac_scanner_free (AmpAcScanner *scanner);
 
 gboolean amp_ac_scanner_parse (AmpAcScanner *scanner, AnjutaTokenFile *file, GError **error);
-gboolean amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error);
+AnjutaToken* amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error);
 
+void amp_ac_scanner_load_module (AmpAcScanner *scanner, AnjutaToken *module);
+void amp_ac_scanner_load_config (AmpAcScanner *scanner, AnjutaToken *list);
+void amp_ac_scanner_load_properties (AmpAcScanner *scanner, AnjutaToken *macro, AnjutaToken *args);
 
-const gchar* amp_ac_scanner_get_filename (AmpAcScanner *scanner);
+void amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s);
 
 enum 
 {
@@ -51,7 +55,8 @@ enum
 	AC_TOKEN_AC_OUTPUT,
 	AC_TOKEN_SPACE_LIST,
 	AC_TOKEN_OPEN_STRING,
-	AC_TOKEN_CLOSE_STRING
+	AC_TOKEN_CLOSE_STRING,
+	AC_TOKEN_AC_PREREQ,
 };
 
 enum
diff --git a/plugins/am-project/ac-scanner.l b/plugins/am-project/ac-scanner.l
index b1868a2..87afc6c 100644
--- a/plugins/am-project/ac-scanner.l
+++ b/plugins/am-project/ac-scanner.l
@@ -19,20 +19,16 @@
  
 %{
 
-#include <stdlib.h>
-#include <string.h>
-
 #include "ac-scanner.h"
 #include "ac-parser.h"
 
 #include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
 
-/* Eliminate warning */
-#define YY_NO_UNPUT 1 
-
-#define YY_INPUT(buf, result, max_size) result = amp_ac_scanner_input (yyextra, buf, max_size)
+#include <stdlib.h>
+#include <string.h>
 
-#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
 
 #define YY_EXTRA_TYPE  AmpAcScanner*
 
@@ -40,40 +36,30 @@
 
 //#define YY_USER_INIT {yy_flex_debug = 1;}
  
-static AnjutaToken* amp_ac_scanner_append_token (AmpAcScanner *scanner, gint token);
-static void amp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static gint amp_ac_scanner_input (AmpAcScanner *scanner, gchar *buffer, gsize max_size);
-
-gboolean amp_ac_yyparse (AmpAcScanner *scanner);
-
+static gint amp_ac_scanner_parse_end (AmpAcScanner *scanner);
 
-#define RETURN(tok) *yylval = amp_ac_scanner_append_token (yyextra, tok); \
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
                     return tok
-                    
 
 struct _AmpAcScanner
 {
     yyscan_t scanner;
 
-    AnjutaTokenFile *file;
-    gchar *filename;
+    AnjutaTokenStream *stream;
 
-    AnjutaToken *token;
-    gint first;
+    AmpProject *project;
 
-    /* Beginning of current token */
-    AnjutaToken *start;
-    gsize begin;
-
-    /* Position in buffer */
-    AnjutaToken *next;
-    gsize pos;
+    AnjutaToken *parsed;
 };
 
+             
 %}
 
 %option reentrant stack noyywrap yylineno
 
+/* Remove some warnings */
+%option nounput noinput noyy_pop_state noyy_top_state
+
 %option prefix="amp_ac_yy"
 
 /* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
@@ -150,6 +136,7 @@ AC_CONFIG_FILES\(       { RETURN (AC_CONFIG_FILES); }
 
 {OTHER}|\$|\\           { RETURN (WORD); }
 
+<<EOF>>                     { if (amp_ac_scanner_parse_end (yyextra) == YY_NULL) return YY_NULL; }
 
 <SPACE_LIST>{
 
@@ -167,264 +154,132 @@ AC_CONFIG_FILES\(       { RETURN (AC_CONFIG_FILES); }
 /* Private functions
  *---------------------------------------------------------------------------*/
 
-static AnjutaToken*
-amp_ac_scanner_append_token (AmpAcScanner *scanner, gint token)
+
+static gint
+amp_ac_scanner_parse_end (AmpAcScanner *scanner)
 {
-    AnjutaToken *frag;
+    scanner->parsed = anjuta_token_stream_get_root (scanner->stream);
+    yypop_buffer_state(scanner->scanner);
+    scanner->stream = anjuta_token_stream_pop (scanner->stream);
 
-    if (scanner->file != NULL)
+    if (scanner->stream == NULL)
     {
-        const gchar *start = anjuta_token_file_get_content (scanner->file, NULL);
-            
-        frag = anjuta_token_new_fragment (token, start + scanner->begin, yyget_leng (scanner->scanner));
-        anjuta_token_file_append (scanner->file, frag);
-        scanner->begin += yyget_leng (scanner->scanner);
+        yyterminate();
     }
-    else if (scanner->token != NULL)
+    else
     {
-        gsize length = yyget_leng (scanner->scanner);
-        AnjutaToken *end;
-
-        for (end = scanner->start; end != NULL; end = anjuta_token_next_sibling (end))
-        {
-            if (anjuta_token_get_type (end) < ANJUTA_TOKEN_FIRST)
-            {
-                gint toklen = anjuta_token_get_length (end);
-    
-                if (toklen >= length)
-                {
-                    if (toklen > length)
-                    {
-                        AnjutaToken *start = end;
-
-                        end = anjuta_token_split (end, length);
-                        if (start == scanner->start)
-                        {
-                            scanner->start = end;
-                        }
-                    }
-
-                    if (end == scanner->start)
-                    {
-                        /* Get whole token */
-                        frag = end;
-                        anjuta_token_set_type (frag, token);
-                        scanner->start = anjuta_token_next_sibling (end);
-                    }
-                    else
-                    {
-                        frag = anjuta_token_new_fragment (token, NULL, 0);
-                        anjuta_token_insert_before (scanner->start, frag);
-                        scanner->start = anjuta_token_next_sibling (end);
-                        anjuta_token_group (frag, end);
-                    }
-                    break;
-                }
-                else
-                {
-                    length -= toklen;
-                }
-            }
-        }
+        return 1;
     }
-    
-    return frag;
 }
 
-static void
-amp_update_location (YYLTYPE *loc, const gchar *text, gint length)
-{
-	const gchar *ptr;
-	const gchar *end = text + length;
-
-    loc->first_line = loc->last_line;
-    loc->first_column = loc->last_column + 1;
-
-	for (ptr = text; ptr != end; ptr++)
-	{
-		if (*ptr == '\n')
-		{
-			loc->last_column = 0;
-			loc->last_line++;
-			length -= (ptr + 1 - text);
-		}
-	}
-
-	loc->last_column += length;
-}
+/* Parser functions
+ *---------------------------------------------------------------------------*/
 
-static gint
-amp_ac_scanner_input (AmpAcScanner *scanner, gchar *buffer, gsize max_size)
+void
+amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s)
 {
-    gint result = YY_NULL;
+    AnjutaTokenFileLocation location;
 
-    if (scanner->file != NULL)
+    if (amp_project_get_token_location (scanner->project, &location, *loc))
     {
-        gsize length = anjuta_token_file_get_length (scanner->file, NULL);
-        if (scanner->pos < length)
-        {
-            const gchar *start = anjuta_token_file_get_content (scanner->file, NULL);
-
-            length -= scanner->pos;
-
-            if (length > max_size) length = max_size;
-            memcpy (buffer, start + scanner->pos, length);
-            scanner->pos += length;
-            result = length;
-        }
+        g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+        g_free (location.filename);
     }
-    else if (scanner->token != NULL)
+    else
     {
-        if (scanner->next)
-        {
-            gsize length = anjuta_token_get_length (scanner->next);
-
-            if ((anjuta_token_get_type (scanner->next) >= ANJUTA_TOKEN_FIRST) || (scanner->pos >= length))
-            {
-                for (;;)
-                {
-                    scanner->next = anjuta_token_next_sibling (scanner->next);
-                    if (scanner->next == NULL)
-                    {
-                        /* Last token */
-                        break;
-                    }
-                    else if ((anjuta_token_get_length (scanner->next) != 0) && (anjuta_token_get_type (scanner->next) < ANJUTA_TOKEN_FIRST))
-                    {
-                        /* Find some data */
-                        scanner->pos = 0;
-                        length = anjuta_token_get_length (scanner->next);
-                        break;  
-                    }
-                }
-            }
-
-            if (scanner->pos < length)
-            {
-                const gchar *start = anjuta_token_get_string (scanner->next);
-
-                length -= scanner->pos;
-            
-                if (length > max_size) length = max_size;
-                memcpy (buffer, start + scanner->pos, length);
-                scanner->pos += length;
-                result = length;
-            }
-        }
-
+        g_message ("%s \n", s);
     }
-
-    return result;
 }
 
-/* Public functions
- *---------------------------------------------------------------------------*/
-
-int
-amp_ac_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,AmpAcScanner *scanner)
+void
+amp_ac_scanner_load_module (AmpAcScanner *scanner, AnjutaToken *module)
 {
-    /* Return a special start token for bison */
-    switch (scanner->first)
-    {
-    case AC_SPACE_LIST_STATE:
-        scanner->first = 0;
-        yy_push_state (SPACE_LIST, scanner->scanner);
-        return START_SPACE_LIST;
-    default:
-        break;
-    }
+    amp_project_load_module (scanner->project, module);
+}
 
-	/* Parse unknown data */
-    return ac_yylex (yylval_param, yylloc_param, scanner->scanner);
+void
+amp_ac_scanner_load_config (AmpAcScanner *scanner, AnjutaToken *list)
+{
+    amp_project_load_config (scanner->project, list);
 }
 
-gboolean
-amp_ac_scanner_parse (AmpAcScanner *scanner, AnjutaTokenFile *file, GError **error)
+void
+amp_ac_scanner_load_properties (AmpAcScanner *scanner, AnjutaToken *macro, AnjutaToken *list)
 {
+    amp_project_load_properties (scanner->project, macro, list);
+}
 
-    g_return_val_if_fail (file != NULL, FALSE);
 
-	scanner->file = file;
-    scanner->pos = 0;
-    scanner->begin = 0;
-    scanner->token = NULL;
-    scanner->first = 0;
-	
-	return amp_ac_yyparse (scanner) == 0;
-}
+/* Public functions
+ *---------------------------------------------------------------------------*/
 
-gboolean
+AnjutaToken *
 amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error)
 {
-    AnjutaToken *child;
+    AnjutaToken *first;
+    AnjutaTokenStream *stream;
 
-    scanner->token = token;
-    scanner->pos = 0;
-    scanner->begin = 0;
-    scanner->file = NULL;
-    scanner->first = start;
+    stream = anjuta_token_stream_push (scanner->stream, token);
+    first = anjuta_token_stream_get_root (stream);
 
-    if (anjuta_token_get_length (token) != 0)
+    if (scanner->stream != NULL)
     {
-        AnjutaToken *copy = anjuta_token_copy (token);
-        
-        anjuta_token_insert_child (token, copy);
-        anjuta_token_clear (token);
-    }
+        /* Parse an included file or a expanded variable */
 
-    /* Move all know data in a list */
-    for (child = anjuta_token_next_child (token); child != NULL;)
+        scanner->stream = stream;
+        yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+    }
+    else
     {
-        if (anjuta_token_get_type (child) < ANJUTA_TOKEN_FIRST)
+        amp_ac_yypstate *ps;
+        gint status;
+	    YYSTYPE yylval_param;
+        YYLTYPE yylloc_param;
+
+        scanner->stream = stream;
+        ps = amp_ac_yypstate_new ();
+
+        yylval_param = NULL;
+        yylloc_param = NULL;
+        switch (start)
         {
-            child = anjuta_token_ungroup (child);
-            if (anjuta_token_get_length (child) == 0)
-            {
-                child = anjuta_token_delete (child);
-                continue;
-            }
+        case AC_SPACE_LIST_STATE:
+            amp_ac_yypush_parse (ps, START_SPACE_LIST, &yylval_param, &yylloc_param, scanner);
+            yy_push_state (SPACE_LIST, scanner->scanner);
+            break;
+        default:
+            break;
         }
-        child = anjuta_token_next_sibling (child);
-    }
-
-    scanner->next = anjuta_token_next_child (token);
-    scanner->start = scanner->next;
 
-	return amp_ac_yyparse (scanner) == 0;
-}
+        do
+        {
+            gint yychar = ac_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+        
+            yylloc_param = yylval_param;
+            status = amp_ac_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
 
-const gchar*
-amp_ac_scanner_get_filename (AmpAcScanner *scanner)
-{
-	g_free (scanner->filename);
-    scanner->filename = NULL;
-    if (scanner->file != NULL)
-    {
-        scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
-    }
-    else if (scanner->token != NULL)
-    {
-        scanner->filename = anjuta_token_value (scanner->token);
+        } while (status == YYPUSH_MORE);
+        amp_ac_yypstate_delete (ps);
     }
-	
-	return scanner->filename;
-}
 
+	return first;
+}
 
 /* Constructor & Destructor
  *---------------------------------------------------------------------------*/
 
 AmpAcScanner *
-amp_ac_scanner_new (void)
+amp_ac_scanner_new (AmpProject *project)
 {
 	AmpAcScanner *scanner;
 
 	scanner = g_new0 (AmpAcScanner, 1);
 
     yylex_init(&scanner->scanner);
-
     yyset_extra (scanner, scanner->scanner);
 
+    scanner->project = project;
+
 	return scanner;
 };
 
@@ -433,11 +288,7 @@ amp_ac_scanner_free (AmpAcScanner *scanner)
 {
 	g_return_if_fail (scanner != NULL);
 
-    //if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
     yylex_destroy(scanner->scanner);
 
-	g_free (scanner->filename);
-	scanner->filename = NULL;
-	
 	g_free (scanner);
 }
diff --git a/plugins/am-project/ac-writer.c b/plugins/am-project/ac-writer.c
index 71d2bfc..2aa583a 100644
--- a/plugins/am-project/ac-writer.c
+++ b/plugins/am-project/ac-writer.c
@@ -25,6 +25,8 @@
 #endif
 
 #include "ac-writer.h"
+#include "ac-scanner.h"
+#include "ac-parser.h"
 
 #include "am-project-private.h"
 
@@ -41,56 +43,78 @@
 /* Private functions
  *---------------------------------------------------------------------------*/
 
-static gboolean
-remove_list_item (AnjutaToken *token, AnjutaTokenStyle *user_style)
+static AnjutaToken*
+find_tokens (AnjutaToken *list, AnjutaTokenType* types)
 {
-	AnjutaTokenStyle *style;
-	AnjutaToken *space;
-
-	DEBUG_PRINT ("remove list item");
-
-	style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
-	anjuta_token_style_update (style, anjuta_token_parent (token));
+	AnjutaToken *tok;
 	
-	anjuta_token_remove (token);
-	space = anjuta_token_next_sibling (token);
-	if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
-	{
-		/* Remove following space */
-		anjuta_token_remove (space);
-	}
-	else
+	for (tok = list; tok != NULL; tok = anjuta_token_next (tok))
 	{
-		space = anjuta_token_previous_sibling (token);
-		if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
+		AnjutaTokenType *type;
+		for (type = types; *type != 0; type++)
 		{
-			anjuta_token_remove (space);
+			if (anjuta_token_get_type (tok) == *type)
+			{
+				return tok;
+			}
 		}
 	}
-	
-	anjuta_token_style_format (style, anjuta_token_parent (token));
-	if (user_style == NULL) anjuta_token_style_free (style);
-	
-	return TRUE;
+
+	return NULL;
 }
 
-static gboolean
-add_list_item (AnjutaToken *list, AnjutaToken *token, AnjutaTokenStyle *user_style)
+static AnjutaToken *
+find_next_eol (AnjutaToken *token)
 {
-	AnjutaTokenStyle *style;
-	AnjutaToken *space;
-
-	style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
-	anjuta_token_style_update (style, anjuta_token_parent (list));
+	if (token == NULL) return NULL;
 	
-	space = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
-	space = anjuta_token_insert_after (list, space);
-	anjuta_token_insert_after (space, token);
+	for (;;)
+	{
+		AnjutaToken *next = anjuta_token_next (token);
+
+		if (next == NULL) return token;
+		token = next;
+		if (anjuta_token_get_type (token) == EOL) return token;
+	}
+}
 
-	anjuta_token_style_format (style, anjuta_token_parent (list));
-	if (user_style == NULL) anjuta_token_style_free (style);
+static AnjutaToken *
+skip_comment (AnjutaToken *token)
+{
+	if (token == NULL) return NULL;
 	
-	return TRUE;
+	for (;;)
+	{
+		for (;;)
+		{
+			AnjutaToken *next = anjuta_token_next (token);
+
+			if (next == NULL) return token;
+			
+			switch (anjuta_token_get_type (token))
+			{
+			case ANJUTA_TOKEN_FILE:
+			case SPACE:
+				token = next;
+				continue;
+			case COMMENT:
+				token = next;
+				break;
+			default:
+				return token;
+			}
+			break;
+		}
+		
+		for (;;)
+		{
+			AnjutaToken *next = anjuta_token_next (token);
+
+			if (next == NULL) return token;
+			token = next;
+			if (anjuta_token_get_type (token) == EOL) break;
+		}
+	}
 }
 
 /* Public functions
@@ -100,18 +124,11 @@ gboolean
 amp_project_update_property (AmpProject *project, AmpPropertyType type)
 {
 	AnjutaToken *token;
+	AnjutaToken *arg;
 	guint pos;
 	const gchar *value;
-	
-	if (project->property == NULL)
-	{
-		return FALSE;
-	}
-	gchar *name;
-	gchar *version;
-	gchar *bug_report;
-	gchar *tarname;
-	gchar *url;
+
+	g_return_val_if_fail (project->property != NULL, FALSE);
 
 	switch (type)
 	{
@@ -137,9 +154,48 @@ amp_project_update_property (AmpProject *project, AmpPropertyType type)
 			break;
 	}
 	
+	if (project->property->ac_init == NULL)
+	{
+		gint types[] = {AC_TOKEN_AC_PREREQ, 0};
+		AnjutaToken *group;
+
+		token = find_tokens (project->configure_token, types);
+		if (token == NULL)
+		{
+			token = skip_comment (project->configure_token);
+			if (token == NULL)
+			{
+				token = anjuta_token_append_child (project->configure_token, anjuta_token_new_string (COMMENT | ANJUTA_TOKEN_ADDED, "#"));
+				token = anjuta_token_insert_after (token, anjuta_token_new_string (SPACE | ANJUTA_TOKEN_ADDED, " Created by Anjuta project manager"));
+				token = anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+				token = anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+			}
+		}
+		
+		token = anjuta_token_insert_before (token, anjuta_token_new_string (AC_TOKEN_AC_INIT | ANJUTA_TOKEN_ADDED, "AC_INIT("));
+		project->property->ac_init = token;
+		group = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LIST | ANJUTA_TOKEN_ADDED, NULL));
+		project->property->args = group;
+		token = anjuta_token_insert_after (group, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+		anjuta_token_merge (group, token);
+		anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+		fprintf(stdout, "whole file\n");
+		anjuta_token_dump (project->configure_token);
+	}
+	fprintf(stdout, "ac_init before replace\n");
+	anjuta_token_dump (project->property->args);
 	token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, value);
-	anjuta_token_list_replace_nth (project->property->ac_init, pos, token);
-	anjuta_token_style_format (project->arg_list, project->property->ac_init);
+	arg = anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_ITEM | ANJUTA_TOKEN_ADDED, NULL));
+	anjuta_token_merge (arg, token);
+	anjuta_token_replace_nth_word (project->property->args, pos, arg);
+	fprintf(stdout, "ac_init after replace\n");
+	anjuta_token_dump (project->property->args);
+	fprintf(stdout, "ac_init after replace link\n");
+	anjuta_token_dump_link (project->property->args);
+	anjuta_token_style_format (project->arg_list, project->property->args);
+	fprintf(stdout, "ac_init after update link\n");
+	anjuta_token_dump (project->property->args);
+	anjuta_token_file_update (project->configure_file, token);
 	
 	return TRUE;
 }
diff --git a/plugins/am-project/am-parser.y b/plugins/am-project/am-parser.y
index a6fbcd7..bb8b37e 100644
--- a/plugins/am-project/am-parser.y
+++ b/plugins/am-project/am-parser.y
@@ -18,56 +18,58 @@
  */
 %{
 
-#include <am-scanner.h>
+#include "am-scanner.h"
+#include "am-parser.h"
 
 #include <stdlib.h>
 
 #define YYDEBUG 1
 
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N)	((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
 %}
 
-/* Defining an union allow to use 2 protocol blocks (enclosed by %{ %}) which
- * is useful when redefining YYSTYPE. */
-%union {
-	AnjutaToken *token;
-	AnjutaTokenRange range;
-}
-
-%token	<token> EOL	'\n'
-%token	<token> SPACE
-%token	<token> TAB '\t'
-%token	<token> MACRO
-%token	<token> VARIABLE
-%token	<token> COLON ':'
-%token	<token> DOUBLE_COLON "::"
-%token	<token> ORDER '|'
-%token	<token> SEMI_COLON ';'
-%token	<token> EQUAL '='
-%token	<token> IMMEDIATE_EQUAL ":="
-%token	<token> CONDITIONAL_EQUAL "?="
-%token	<token> APPEND "+="
-%token	<token> CHARACTER
-%token	<token> NAME
-%token	<token> AM_VARIABLE
 
-%type <token> head_token target_token value_token name_token space_token rule_token equal_token token automake_token prerequisite_token
-%type <token> am_variable
-%type <token> value head space prerequisite target depend rule variable commands head_with_space
-%type <token> value_list strip_value_list prerequisite_list target_list token_list target_list2
-%type <token> optional_space space_list_value
+%token	EOL	'\n'
+%token	SPACE
+%token	TAB '\t'
+%token	MACRO
+%token	VARIABLE
+%token	COLON ':'
+%token	DOUBLE_COLON "::"
+%token	ORDER '|'
+%token	SEMI_COLON ';'
+%token	EQUAL '='
+%token	IMMEDIATE_EQUAL ":="
+%token	CONDITIONAL_EQUAL "?="
+%token	APPEND "+="
+%token	CHARACTER
+%token	NAME
+%token	AM_VARIABLE
+
+%token  SUBDIRS
+%token  DIST_SUBDIRS
+%token  _DATA
+%token  _HEADERS
+%token  _LIBRARIES
+%token  _LISP
+%token  _LTLIBRARIES
+%token  _MANS
+%token  _PROGRAMS
+%token  _PYTHON
+%token  _JAVA
+%token  _SCRIPTS
+%token  _SOURCES
+%token  _TEXINFOS
 
 %defines
 
-%pure_parser
-
-/* Necessary because autotools wrapper always looks for a file named "y.tab.c",
- * not "amp-scanner.c"
-%output="y.tab.c"*/
+%define api.pure
+%define api.push_pull "push"
 
-%glr-parser
-
-%parse-param {void* scanner}
-%lex-param   {void* scanner}
+%parse-param {AmpAmScanner* scanner}
+%lex-param   {AmpAmScanner* scanner}
 
 %name-prefix="amp_am_yy"
 
@@ -79,9 +81,28 @@
 
 %{
 
-//amp_am_yydebug = 1;
-
-static void amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s);
+static gint
+amp_am_automake_variable (AnjutaToken *token)
+{
+    switch (anjuta_token_get_type (token))
+    {
+    case SUBDIRS: return AM_TOKEN_SUBDIRS;
+    case DIST_SUBDIRS: return AM_TOKEN_DIST_SUBDIRS;
+    case _DATA: return AM_TOKEN__DATA;
+    case _HEADERS: return AM_TOKEN__HEADERS;
+    case _LIBRARIES: return AM_TOKEN__LIBRARIES;
+    case _LISP: return AM_TOKEN__LISP;
+    case _LTLIBRARIES: return AM_TOKEN__LTLIBRARIES;
+    case _MANS: return AM_TOKEN__MANS;
+    case _PROGRAMS: return AM_TOKEN__PROGRAMS;
+    case _PYTHON: return AM_TOKEN__PYTHON;
+    case _JAVA: return AM_TOKEN__JAVA;
+    case _SCRIPTS: return AM_TOKEN__SCRIPTS;
+    case _SOURCES: return AM_TOKEN__SOURCES;
+    case _TEXINFOS: return AM_TOKEN__TEXINFOS;
+    default: return ANJUTA_TOKEN_NAME;
+    }
+}
 
 %}
 
@@ -104,87 +125,48 @@ line:
 	| line token
 	;
 		
-variable:
-	head_with_space equal_token optional_space value_list optional_space
-	| head equal_token optional_space value_list optional_space
-	;
-
-rule:
-	depend
-	| depend SEMI_COLON commands
-	| depend EOL TAB commands
-	;
-		
-depend:
-	target_list rule_token optional_space prerequisite_list optional_space ORDER optional_space prerequisite_list 
-	;
-
-commands:
-	token_list
-	| commands EOL TAB token_list
-	;
-		
 am_variable:
-	AM_VARIABLE space_list_value {
-		$$ = anjuta_token_merge (
-			anjuta_token_insert_before ($1,
-					anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT, NULL)),
-			$2);
+	automake_token space_list_value {
+		$$= anjuta_token_merge_previous ($2, $1);
+		amp_am_scanner_set_am_variable (scanner, amp_am_automake_variable ($1), $1, anjuta_token_last_item ($2));
 	}
-	| AM_VARIABLE optional_space equal_token optional_space
+	| automake_token optional_space equal_token optional_space
+    {
+		$$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+        anjuta_token_merge ($$, $1);
+    }
 	;
 				
 space_list_value: optional_space  equal_token   value_list  {
-		$$ = $3;
+		$$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+		if ($1 != NULL) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
+		anjuta_token_merge ($$, $1);
+		anjuta_token_merge ($$, $2);
+		anjuta_token_merge ($$, $3);
 	}
 	;
 
 value_list:
 	optional_space strip_value_list optional_space {
-		if ($1) anjuta_token_merge_previous ($2, $1);
-		if ($3) anjuta_token_merge ($2, $3);
+		if ($1 != NULL) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
+		if ($3 != NULL) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
+		anjuta_token_merge_previous ($2, $1);
+		anjuta_token_merge ($2, $3);
 		$$ = $2;
 	}
 		
 strip_value_list:
 	value {
-		$$ = anjuta_token_merge (
-			anjuta_token_insert_before ($1,
-					anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL)),
-			$1);
+		$$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+		anjuta_token_merge ($$, $1);
 	}
 	| strip_value_list  space  value {
+		anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
+		anjuta_token_merge ($1, $2);
 		anjuta_token_merge ($1, $3);
 	}
 	;
 
-target_list:
-	head
-	| head_with_space
-	| head_with_space target_list2 optional_space
-	;
-
-target_list2:
-	target
-	| target_list2  space  target {
-		anjuta_token_merge ($1, $3);
-	}
-	;
-		
-token_list:
-	token
-	| token_list token
-	;
-		
-prerequisite_list:
-	prerequisite
-	| prerequisite_list space prerequisite {
-		anjuta_token_merge ($1, $3);
-	}
-	;
-
-		
-
 optional_space:
 	/* empty */ {
 		$$ = NULL;
@@ -192,41 +174,20 @@ optional_space:
 	| space
 	;
 
-
-head_with_space:
-	head space
-	;
-		
-head:
-	head_token
-	| head name_token {
-		anjuta_token_merge ($1, $2);
-	}
-	;
-
-target:
-	head_token
-	| target target_token {
-		anjuta_token_merge ($1, $2);
-	}
-	;
-		
 value:
-	value_token
+	value_token {
+		$$ = anjuta_token_new_static (ANJUTA_TOKEN_ARGUMENT, NULL);
+		anjuta_token_merge ($$, $1);
+	}
 	| value value_token {
 		anjuta_token_merge ($1, $2);
 	}
 	;
 
-prerequisite:
-	prerequisite_token
-	| prerequisite prerequisite_token {
-		anjuta_token_merge ($1, $2);
-	}
-	;
-		
 space:
-	space_token
+	space_token {
+		$$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+		anjuta_token_merge ($$, $1);}
 	| space space_token	{
 		anjuta_token_merge ($1, $2);
 	}
@@ -244,21 +205,11 @@ value_token:
 	| target_token
 	;
 
-prerequisite_token:
-	equal_token
-	| rule_token
-	| name_token
-	| automake_token
-	| ORDER
-	| SEMI_COLON
-	;
-
 target_token:
 	head_token
 	| automake_token
 	;
-		
-		
+
 space_token:
 	SPACE
 	| TAB
@@ -293,28 +244,21 @@ name_token:
 	;
 		
 automake_token:
-	AM_VARIABLE
-	;
+    SUBDIRS
+    | DIST_SUBDIRS
+    | _DATA
+    | _HEADERS
+    | _LIBRARIES
+    | _LISP
+    | _LTLIBRARIES
+    | _MANS
+    | _PROGRAMS
+    | _PYTHON
+    | _JAVA
+    | _SCRIPTS
+    | _SOURCES
+    | _TEXINFOS
+    ;
+    
 		
 %%
-
-static void
-amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s)
-{
-    gchar *filename;
-
-	g_message ("scanner %p", scanner);
-    filename = amp_am_scanner_get_filename ((AmpAmScanner *)scanner);
-    if (filename == NULL) filename = "?";
-    g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-     
-/*static void
-amp_am_yyerror (YYLTYPE *loc, void *scanner, char const *s)
-{
-        g_message ("(%d:%d-%d:%d) %s\n", loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}*/
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/am-project/am-project-private.h b/plugins/am-project/am-project-private.h
index c49c1c3..641a2b9 100644
--- a/plugins/am-project/am-project-private.h
+++ b/plugins/am-project/am-project-private.h
@@ -26,8 +26,19 @@
 
 G_BEGIN_DECLS
 
+struct _AmpPackage {
+    gchar *name;
+    gchar *version;
+};
+
+struct _AmpModule {
+    GList *packages;
+    AnjutaToken *module;
+};
+
 struct _AmpProperty {
 	AnjutaToken *ac_init;				/* AC_INIT macro */
+	AnjutaToken *args;
 	gchar *name;
 	gchar *version;
 	gchar *bug_report;
@@ -44,7 +55,8 @@ struct _AmpProject {
 
 	/* project data */
 	AnjutaTokenFile		*configure_file;		/* configure.in file */
-
+	AnjutaToken			*configure_token;
+	
 	AmpProperty			*property;
 	
 	AmpGroup              *root_node;         	/* tree containing project data;
@@ -63,7 +75,8 @@ struct _AmpProject {
 	GHashTable         *monitors;
 
 	/* Keep list style */
-	AnjutaTokenStyle *space_list;
+	AnjutaTokenStyle *ac_space_list;
+	AnjutaTokenStyle *am_space_list;
 	AnjutaTokenStyle *arg_list;
 };
 
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index 38ba080..3f8129c 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -48,6 +48,7 @@
 #include "ac-writer.h"
 #include "am-scanner.h"
 #include "am-dialogs.h"
+#include "am-writer.h"
 //#include "am-config.h"
 //#include "am-properties.h"
 
@@ -67,20 +68,14 @@ static const gchar *valid_am_makefiles[] = {"GNUmakefile.am", "makefile.am", "Ma
 #define AMP_TARGET_DATA(node)  ((node) != NULL ? (AmpTargetData *)((node)->data) : NULL)
 #define AMP_SOURCE_DATA(node)  ((node) != NULL ? (AmpSourceData *)((node)->data) : NULL)
 
-typedef struct _AmpPackage AmpPackage;
+#define STR_REPLACE(target, source) \
+	{ g_free (target); target = source == NULL ? NULL : g_strdup (source);}
 
-struct _AmpPackage {
-    gchar *name;
-    gchar *version;
-};
+
+typedef struct _AmpPackage AmpPackage;
 
 typedef struct _AmpModule AmpModule;
 	
-struct _AmpModule {
-    GList *packages;
-    AnjutaToken *module;
-};
-
 typedef enum {
 	AM_GROUP_TOKEN_CONFIGURE,
 	AM_GROUP_TOKEN_SUBDIRS,
@@ -97,6 +92,7 @@ struct _AmpGroupData {
 	GFile *makefile;				/* GFile corresponding to group makefile */
 	AnjutaTokenFile *tfile;		/* Corresponding Makefile */
 	GList *tokens[AM_GROUP_TOKEN_LAST];					/* List of token used by this group */
+	AnjutaToken *make_token;
 };
 
 typedef enum _AmpTargetFlag
@@ -341,58 +337,6 @@ file_type (GFile *file, const gchar *filename)
 	return type;
 }
 
-gboolean
-remove_list_item (AnjutaToken *token, AnjutaTokenStyle *user_style)
-{
-	AnjutaTokenStyle *style;
-	AnjutaToken *space;
-
-	DEBUG_PRINT ("remove list item");
-
-	style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
-	anjuta_token_style_update (style, anjuta_token_parent (token));
-	
-	anjuta_token_remove (token);
-	space = anjuta_token_next_sibling (token);
-	if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
-	{
-		/* Remove following space */
-		anjuta_token_remove (space);
-	}
-	else
-	{
-		space = anjuta_token_previous_sibling (token);
-		if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
-		{
-			anjuta_token_remove (space);
-		}
-	}
-	
-	anjuta_token_style_format (style, anjuta_token_parent (token));
-	if (user_style == NULL) anjuta_token_style_free (style);
-	
-	return TRUE;
-}
-
-static gboolean
-add_list_item (AnjutaToken *list, AnjutaToken *token, AnjutaTokenStyle *user_style)
-{
-	AnjutaTokenStyle *style;
-	AnjutaToken *space;
-
-	style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
-	anjuta_token_style_update (style, anjuta_token_parent (list));
-	
-	space = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
-	space = anjuta_token_insert_after (list, space);
-	anjuta_token_insert_after (space, token);
-
-	anjuta_token_style_format (style, anjuta_token_parent (list));
-	if (user_style == NULL) anjuta_token_style_free (style);
-	
-	return TRUE;
-}
-
 /* Automake parsing function
  *---------------------------------------------------------------------------*/
 
@@ -501,6 +445,8 @@ ac_init_default_tarname (const gchar *name)
 {
 	gchar *tarname;
 
+	if (name == NULL) return NULL;
+	
 	/* Remove GNU prefix */
 	if (strncmp (name, "GNU ", 4) == 0) name += 4;
 
@@ -522,6 +468,7 @@ amp_config_file_new (const gchar *pathname, GFile *project_root, AnjutaToken *to
 
 	config = g_slice_new0(AmpConfigFile);
 	config->file = g_file_resolve_relative_path (project_root, pathname);
+	g_message ("new config file =%s= token %p group %p", pathname, token, anjuta_token_list (token));
 	config->token = token;
 
 	return config;
@@ -618,20 +565,28 @@ amp_project_free_module_hash (AmpProject *project)
  *---------------------------------------------------------------------------*/
 
 static AmpProperty*
-amp_property_new (AnjutaToken *token)
+amp_property_new (AnjutaToken *macro, AnjutaToken *list)
 {
 	AmpProperty *prop;
 	AnjutaToken *arg;
 	
 	prop = g_slice_new0(AmpProperty); 
-	prop->ac_init = token;
+	prop->ac_init = macro;
+	prop->args = list;
 
-	arg = anjuta_token_next_child (token);
-	arg = anjuta_token_get_next_arg (arg, &prop->name);
-	arg = anjuta_token_get_next_arg (arg, &prop->version);
-	arg = anjuta_token_get_next_arg (arg, &prop->bug_report);
-	arg = anjuta_token_get_next_arg (arg, &prop->tarname);
-	arg = anjuta_token_get_next_arg (arg, &prop->url);
+	if (list != NULL)
+	{
+		arg = anjuta_token_nth_word (list, 0);
+		prop->name = anjuta_token_evaluate (arg);
+		arg = anjuta_token_nth_word (list, 1);
+		prop->version = anjuta_token_evaluate (arg);
+		arg = anjuta_token_nth_word (list, 2);
+		prop->bug_report = anjuta_token_evaluate (arg);
+		arg = anjuta_token_nth_word (list, 3);
+		prop->tarname = anjuta_token_evaluate (arg);
+		arg = anjuta_token_nth_word (list, 4);
+		prop->url = anjuta_token_evaluate (arg);
+	}
 	
 	return prop;
 }
@@ -671,6 +626,17 @@ amp_group_get_token (AmpGroup *node, AmpGroupTokenCategory category)
 	return group->tokens[category];
 }
 
+static AnjutaToken*
+amp_group_get_first_token (AmpGroup *node, AmpGroupTokenCategory category)
+{
+	GList *list;
+	
+	list = amp_group_get_token (node, category);
+	if (list == NULL) return NULL;
+
+	return (AnjutaToken *)list->data;
+}
+
 static void
 amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
 {
@@ -680,7 +646,7 @@ amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
 }
 
 static AnjutaTokenFile*
-amp_group_set_makefile (AmpGroup *node, GFile *makefile)
+amp_group_set_makefile (AmpGroup *node, GFile *makefile, AmpProject* project)
 {
     AmpGroupData *group;
 	
@@ -691,13 +657,23 @@ amp_group_set_makefile (AmpGroup *node, GFile *makefile)
 	if (group->tfile != NULL) anjuta_token_file_free (group->tfile);
 	if (makefile != NULL)
 	{
+		AnjutaToken *token;
+		AmpAmScanner *scanner;
+		
 		group->makefile = g_object_ref (makefile);
 		group->tfile = anjuta_token_file_new (makefile);
+
+		token = anjuta_token_file_load (group->tfile, NULL);
+			
+		scanner = amp_am_scanner_new (project, node);
+		group->make_token = amp_am_scanner_parse_token (scanner, token, NULL);
+		amp_am_scanner_free (scanner);
 	}
 	else
 	{
 		group->makefile = NULL;
 		group->tfile = NULL;
+		group->make_token = NULL;
 	}
 
 	return group->tfile;
@@ -740,7 +716,7 @@ amp_group_free (AmpGroup *node)
  *---------------------------------------------------------------------------*/
 
 static void
-amp_target_add_token (AmpGroup *node, AnjutaToken *token)
+amp_target_add_token (AmpTarget *node, AnjutaToken *token)
 {
     AmpTargetData *target;
 	
@@ -751,7 +727,7 @@ amp_target_add_token (AmpGroup *node, AnjutaToken *token)
 }
 
 static GList *
-amp_target_get_token (AmpGroup *node)
+amp_target_get_token (AmpTarget *node)
 {
     AmpTargetData *target;
 	
@@ -804,7 +780,7 @@ amp_source_new (GFile *file)
     return g_node_new (source);
 }
 
-static void
+void
 amp_source_free (AmpSource *node)
 {
     AmpSourceData *source = AMP_SOURCE_DATA (node);
@@ -923,7 +899,7 @@ monitors_setup (AmpProject *project)
  */
 
 static void
-amp_dump_node (GNode *g_node)
+amp_dump_node (AnjutaProjectNode *g_node)
 {
 	gchar *name = NULL;
 	
@@ -947,8 +923,8 @@ amp_dump_node (GNode *g_node)
 	g_free (name);
 }
 
-static gboolean 
-foreach_node_destroy (GNode    *g_node,
+static void
+foreach_node_destroy (AnjutaProjectNode    *g_node,
 		      gpointer  data)
 {
 	switch (AMP_NODE_DATA (g_node)->type) {
@@ -967,100 +943,85 @@ foreach_node_destroy (GNode    *g_node,
 			g_assert_not_reached ();
 			break;
 	}
-	
-
-	return FALSE;
 }
 
 static void
-project_node_destroy (AmpProject *project, GNode *g_node)
+project_node_destroy (AmpProject *project, AnjutaProjectNode *g_node)
 {
 	g_return_if_fail (project != NULL);
 	g_return_if_fail (AMP_IS_PROJECT (project));
 	
 	if (g_node) {
 		/* free each node's data first */
-		g_node_traverse (g_node,
-				 G_POST_ORDER, G_TRAVERSE_ALL, -1,
+		anjuta_project_node_all_foreach (g_node,
 				 foreach_node_destroy, project);
-
+		
 		/* now destroy the tree itself */
 		//g_node_destroy (g_node);
 	}
 }
 
-static gboolean
-project_reload_property (AmpProject *project)
+void
+amp_project_load_properties (AmpProject *project, AnjutaToken *macro, AnjutaToken *list)
 {
-	AnjutaToken *ac_init_tok;
-	AnjutaToken *sequence;
-	AnjutaToken *init;
-
-	ac_init_tok = anjuta_token_new_static (AC_TOKEN_AC_INIT, NULL);
-	                                       
-	sequence = anjuta_token_file_first (project->configure_file);
-	if (anjuta_token_match (ac_init_tok, ANJUTA_SEARCH_INTO, sequence, &init))
-	{
-		g_message ("find ac_init");
-		anjuta_token_style_update (project->arg_list, init);
-		project->property = amp_property_new (init);
-	}
-
-	return TRUE;                                       
+	fprintf (stdout, "property list:\n");
+	anjuta_token_dump (list);
+	project->property = amp_property_new (macro, list);
 }
 
-static void
-project_reload_packages   (AmpProject *project)
+void
+amp_project_load_module (AmpProject *project, AnjutaToken *module)
 {
-	AnjutaToken *pkg_check_tok;
-	AnjutaToken *sequence;
 	AmpAcScanner *scanner = NULL;
-	
-	pkg_check_tok = anjuta_token_new_static (AC_TOKEN_PKG_CHECK_MODULES, "PKG_CHECK_MODULES(");
-	
-    sequence = anjuta_token_file_first (project->configure_file);
-	for (;;)
+
+	if (module != NULL)
 	{
-		AnjutaToken *module;
 		AnjutaToken *arg;
+		AnjutaToken *list;
+		AnjutaToken *item;
 		gchar *value;
 		AmpModule *mod;
 		AmpPackage *pack;
 		gchar *compare;
-		
-		if (!anjuta_token_match (pkg_check_tok, ANJUTA_SEARCH_INTO, sequence, &module)) break;
 
-		arg = anjuta_token_next_child (module);	/* Name */
 
+		fprintf(stdout, "Load module\n");
+		anjuta_token_dump (module);
+		
+		/* Module name */
+		arg = anjuta_token_first_item (module);
 		value = anjuta_token_evaluate (arg);
 		mod = amp_module_new (arg);
 		mod->packages = NULL;
 		g_hash_table_insert (project->modules, value, mod);
 
-		arg = anjuta_token_next_sibling (arg);	/* Separator */
-
-		arg = anjuta_token_next_sibling (arg);	/* Package list */
-		if (scanner == NULL) scanner = amp_ac_scanner_new ();
-		amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+		/* Package list */
+		arg = anjuta_token_next_word (arg);
+		scanner = amp_ac_scanner_new (project);
+		list = amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+		anjuta_token_free_children (arg);
+		list = anjuta_token_delete_parent (list);
+		anjuta_token_prepend_items (arg, list);
+		amp_ac_scanner_free (scanner);
 		
 		pack = NULL;
 		compare = NULL;
-		for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+		for (item = anjuta_token_first_word (arg); item != NULL; item = anjuta_token_next_word (item))
 		{
-			switch (anjuta_token_get_type (arg))
+			value = anjuta_token_evaluate (item);
+			if (value == NULL) continue;		/* Empty value, a comment of a quote by example */
+			if (*value == '\0')
+			{
+				g_free (value);
+				continue;
+			}
+			if (strcmp (value, "$VTE_NEW_REQUIRED") == 0)
 			{
-				case ANJUTA_TOKEN_START:
-				case ANJUTA_TOKEN_NEXT:
-				case ANJUTA_TOKEN_LAST:
-				case ANJUTA_TOKEN_JUNK:
-					continue;
-				default:
-					break;
+				int i = 0;
+				i++;
+				i++;
 			}
 			
-			value = anjuta_token_evaluate (arg);
-			if (value == NULL) continue;		/* Empty value, a comment of a quote by example */
-
 			if ((pack != NULL) && (compare != NULL))
 			{
 				amp_package_set_version (pack, compare, value);
@@ -1069,7 +1030,7 @@ project_reload_packages   (AmpProject *project)
 				pack = NULL;
 				compare = NULL;
 			}
-			else if ((pack != NULL) && (anjuta_token_get_type (arg) == ANJUTA_TOKEN_OPERATOR))
+			else if ((pack != NULL) && (anjuta_token_get_type (item) == ANJUTA_TOKEN_OPERATOR))
 			{
 				compare = value;
 			}
@@ -1082,100 +1043,55 @@ project_reload_packages   (AmpProject *project)
 			}
 		}
 		mod->packages = g_list_reverse (mod->packages);
-
-		sequence = anjuta_token_next_sibling (module);
 	}
-	anjuta_token_free (pkg_check_tok);
-	if (scanner) amp_ac_scanner_free (scanner);
 }
 
-/* Add a GFile in the list for each makefile in the token list */
 void
-amp_project_add_config_files (AmpProject *project, AnjutaToken *list)
+amp_project_load_config (AmpProject *project, AnjutaToken *arg_list)
 {
-	AnjutaToken* arg;
-
-	for (arg = anjuta_token_next_child (list); arg != NULL; arg = anjuta_token_next_sibling (arg))
-	{
-		gchar *value;
-		AmpConfigFile *cfg;
-
-		switch (anjuta_token_get_type (arg))
-		{
-			case ANJUTA_TOKEN_START:
-			case ANJUTA_TOKEN_NEXT:
-			case ANJUTA_TOKEN_LAST:
-			case ANJUTA_TOKEN_JUNK:
-				continue;
-			default:
-				break;
-		}
-			
-		value = anjuta_token_evaluate (arg);
-		if (value == NULL) continue;
-		
-		cfg = amp_config_file_new (value, project->root_file, arg);
-		g_hash_table_insert (project->configs, cfg->file, cfg);
-		g_free (value);
-	}
-}							   
-                           
-static gboolean
-project_list_config_files (AmpProject *project)
-{
-	AnjutaToken *config_files_tok;
-	AnjutaToken *sequence;
 	AmpAcScanner *scanner = NULL;
 
-	//g_message ("load config project %p root file %p", project, project->root_file);	
-	/* Search the new AC_CONFIG_FILES macro */
-	config_files_tok = anjuta_token_new_static (AC_TOKEN_AC_CONFIG_FILES, NULL);
-
-    sequence = anjuta_token_file_first (project->configure_file);
-	while (sequence != NULL)
+	if (arg_list != NULL)
 	{
 		AnjutaToken *arg;
+		AnjutaToken *list;
+		AnjutaToken *item;
 
-		if (!anjuta_token_match (config_files_tok, ANJUTA_SEARCH_INTO, sequence, &sequence)) break;
-		arg = anjuta_token_next_child (sequence);	/* List */
-		if (scanner == NULL) scanner = amp_ac_scanner_new ();
-		amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
-		amp_project_add_config_files (project, arg);
-		sequence = anjuta_token_next_sibling (sequence);
-	}
-	
-	/* Search the old AC_OUTPUT macro */
-    anjuta_token_free(config_files_tok);
-    config_files_tok = anjuta_token_new_static (AC_TOKEN_OBSOLETE_AC_OUTPUT, NULL);
+		/* File list */
+		scanner = amp_ac_scanner_new (project);
+		fprintf (stdout, "\nParse list\n");
 		
-    sequence = anjuta_token_file_first (project->configure_file);
-	while (sequence != NULL)
-	{
-		AnjutaToken *arg;
+		arg = anjuta_token_first_item (arg_list);
+		list = amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+		anjuta_token_free_children (arg);
+		list = anjuta_token_delete_parent (list);
+		anjuta_token_prepend_items (arg, list);
+		amp_ac_scanner_free (scanner);
+		
+		for (item = anjuta_token_first_word (arg); item != NULL; item = anjuta_token_next_word (item))
+		{
+			gchar *value;
+			AmpConfigFile *cfg;
 
-		if (!anjuta_token_match (config_files_tok, ANJUTA_SEARCH_INTO, sequence, &sequence)) break;
-		arg = anjuta_token_next_child (sequence);	/* List */
-		if (scanner == NULL) scanner = amp_ac_scanner_new ();
-		amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
-		amp_project_add_config_files (project, arg);
-		sequence = anjuta_token_next_sibling (sequence);
+			value = anjuta_token_evaluate (item);
+			if (value == NULL) continue;
+		
+			cfg = amp_config_file_new (value, project->root_file, item);
+			g_hash_table_insert (project->configs, cfg->file, cfg);
+			g_free (value);
+		}
 	}
-	
-	if (scanner) amp_ac_scanner_free (scanner);
-	anjuta_token_free (config_files_tok);
-
-	return TRUE;
 }
 
 static void
-find_target (GNode *node, gpointer data)
+find_target (AnjutaProjectTarget *node, gpointer data)
 {
 	if (AMP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
 	{
 		if (strcmp (AMP_TARGET_DATA (node)->base.name, *(gchar **)data) == 0)
 		{
 			/* Find target, return node value in pointer */
-			*(GNode **)data = node;
+			*(AnjutaProjectTarget **)data = node;
 
 			return;
 		}
@@ -1183,7 +1099,7 @@ find_target (GNode *node, gpointer data)
 }
 
 static void
-find_canonical_target (GNode *node, gpointer data)
+find_canonical_target (AnjutaProjectTarget *node, gpointer data)
 {
 	if (AMP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
 	{
@@ -1192,7 +1108,7 @@ find_canonical_target (GNode *node, gpointer data)
 		if (strcmp (canon_name, *(gchar **)data) == 0)
 		{
 			/* Find target, return node value in pointer */
-			*(GNode **)data = node;
+			*(AnjutaProjectTarget **)data = node;
 			g_free (canon_name);
 
 			return;
@@ -1202,19 +1118,19 @@ find_canonical_target (GNode *node, gpointer data)
 }
 
 static AnjutaToken*
-project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+project_load_target (AmpProject *project, AnjutaToken *name, AnjutaToken *list, AnjutaProjectGroup *parent, GHashTable *orphan_sources)
 {
 	AnjutaToken *arg;
 	AnjutaProjectTargetType type = NULL;
 	gchar *install;
-	gchar *name;
+	gchar *value;
 	gint flags;
 	AmpTargetInformation *targets = AmpTargetTypes; 
 
 	type = (AnjutaProjectTargetType)targets;
 	while (targets->base.name != NULL)
 	{
-		if (anjuta_token_get_type (start) == targets->token)
+		if (anjuta_token_get_type (name) == targets->token)
 		{
 			type = (AnjutaProjectTargetType)targets;
 			break;
@@ -1222,20 +1138,13 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
 		targets++;
 	}
 
-	name = anjuta_token_get_value (start);
-	split_automake_variable (name, &flags, &install, NULL);
-	g_free (name);
+	value = anjuta_token_evaluate (name);
+	split_automake_variable (value, &flags, &install, NULL);
+	g_free (value);
 
-	amp_group_add_token (parent, start, AM_GROUP_TARGET);
+	amp_group_add_token (parent, name, AM_GROUP_TARGET);
 	
-	arg = anjuta_token_next_sibling (start);		/* Get variable data */
-	if (arg == NULL) return NULL;
-	if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
-	if (arg == NULL) return NULL;
-	arg = anjuta_token_next_sibling (arg);			/* Skip equal */
-	if (arg == NULL) return NULL;
-
-	for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+	for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
 	{
 		gchar *value;
 		gchar *canon_id;
@@ -1244,14 +1153,12 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
 		gchar *orig_key;
 		gpointer find;
 
-		if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-			
 		value = anjuta_token_evaluate (arg);
 		canon_id = canonicalize_automake_variable (value);		
 		
 		/* Check if target already exists */
 		find = value;
-		g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
+		anjuta_project_node_children_foreach (parent, find_target, &find);
 		if ((gchar *)find != value)
 		{
 			/* Find target */
@@ -1263,7 +1170,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
 		/* Create target */
 		target = amp_target_new (value, type, install, flags);
 		amp_target_add_token (target, arg);
-		g_node_append (parent, target);
+		anjuta_project_node_append (parent, target);
 		DEBUG_PRINT ("create target %p name %s", target, value);
 
 		/* Check if there are source availables */
@@ -1275,7 +1182,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
 			{
 				AmpSource *source = src->data;
 
-				g_node_prepend (target, source);
+				anjuta_project_node_prepend (target, source);
 			}
 			g_free (orig_key);
 			g_list_free (sources);
@@ -1289,7 +1196,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
 }
 
 static AnjutaToken*
-project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+project_load_sources (AmpProject *project, AnjutaToken *name, AnjutaToken *list, AnjutaProjectGroup *parent, GHashTable *orphan_sources)
 {
 	AnjutaToken *arg;
 	AmpGroupData *group = AMP_GROUP_DATA (parent);
@@ -1297,7 +1204,7 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
 	gchar *target_id = NULL;
 	GList *orphan = NULL;
 
-	target_id = anjuta_token_get_value (start);
+	target_id = anjuta_token_evaluate (name);
 	if (target_id)
 	{
 		gchar *end = strrchr (target_id, '_');
@@ -1313,24 +1220,15 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
 		
 		find = target_id;
 		DEBUG_PRINT ("search for canonical %s", target_id);
-		g_node_children_foreach (parent, G_TRAVERSE_ALL, find_canonical_target, &find);
-		parent = (gchar *)find != target_id ? (GNode *)find : NULL;
-
-		arg = anjuta_token_next_sibling (start);		/* Get variable data */
-		if (arg == NULL) return NULL;
-		if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
-		if (arg == NULL) return NULL;
-		arg = anjuta_token_next_sibling (arg);			/* Skip equal */
-		if (arg == NULL) return NULL;
+		anjuta_project_node_children_foreach (parent, find_canonical_target, &find);
+		parent = (gchar *)find != target_id ? (AnjutaProjectTarget *)find : NULL;
 
-		for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+		for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
 		{
 			gchar *value;
 			AmpSource *source;
 			GFile *src_file;
 		
-			if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-			
 			value = anjuta_token_evaluate (arg);
 
 			/* Create source */
@@ -1348,7 +1246,7 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
 			{
 				DEBUG_PRINT ("add target child %p", parent);
 				/* Add as target child */
-				g_node_append (parent, source);
+				anjuta_project_node_append (parent, source);
 			}
 
 			g_free (value);
@@ -1381,23 +1279,14 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
 static AmpGroup* project_load_makefile (AmpProject *project, GFile *file, AmpGroup *parent, gboolean dist_only);
 
 static void
-project_load_subdirs (AmpProject *project, AnjutaToken *start, AmpGroup *parent, gboolean dist_only)
+project_load_subdirs (AmpProject *project, AnjutaToken *list, AmpGroup *parent, gboolean dist_only)
 {
 	AnjutaToken *arg;
 
-	arg = anjuta_token_next_sibling (start);		/* Get variable data */
-	if (arg == NULL) return;
-	if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
-	if (arg == NULL) return;
-	arg = anjuta_token_next_sibling (arg);			/* Skip equal */
-	if (arg == NULL) return;
-
-	for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+	for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
 	{
 		gchar *value;
 		
-		if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-			
 		value = anjuta_token_evaluate (arg);
 		
 		/* Skip ., it is a special case, used to defined build order */
@@ -1432,13 +1321,6 @@ project_load_subdirs (AmpProject *project, AnjutaToken *start, AmpGroup *parent,
 }
 
 static void
-free_source_list (GList *source_list)
-{
-	g_list_foreach (source_list, (GFunc)amp_source_free, NULL);
-	g_list_free (source_list);
-}
-
-static void
 remove_config_file (gpointer data, GObject *object, gboolean is_last_ref)
 {
 	if (is_last_ref)
@@ -1449,17 +1331,16 @@ remove_config_file (gpointer data, GObject *object, gboolean is_last_ref)
 }
 
 static AmpGroup*
-project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean dist_only)
+project_load_makefile (AmpProject *project, GFile *file, AnjutaProjectGroup *parent, gboolean dist_only)
 {
-	GHashTable *orphan_sources = NULL;
+	//GHashTable *orphan_sources = NULL;
 	const gchar **filename;
 	AmpAmScanner *scanner;
 	AmpGroup *group;
-	AnjutaToken *significant_tok;
+	//AnjutaToken *significant_tok;
 	AnjutaToken *arg;
 	AnjutaTokenFile *tfile;
 	GFile *makefile = NULL;
-	gboolean found;
 
 	/* Create group */
 	group = amp_group_new (file, dist_only);
@@ -1470,7 +1351,7 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
 	}
 	else
 	{
-		g_node_append (parent, group);
+		anjuta_project_node_append (parent, group);
 	}
 		
 	/* Find makefile name
@@ -1494,6 +1375,7 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
 			g_object_unref (final_file);
 			if (config != NULL)
 			{
+				g_message ("add group =%s= token %p group %p", *filename, config->token, anjuta_token_list (config->token));
 				amp_group_add_token (group, config->token, AM_GROUP_TOKEN_CONFIGURE);
 				break;
 			}
@@ -1509,57 +1391,44 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
 	
 	/* Parse makefile.am */	
 	DEBUG_PRINT ("Parse: %s", g_file_get_uri (makefile));
-	tfile = amp_group_set_makefile (group, makefile);
+	tfile = amp_group_set_makefile (group, makefile, project);
 	g_hash_table_insert (project->files, makefile, tfile);
 	g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project);
-	scanner = amp_am_scanner_new ();
-	amp_am_scanner_parse (scanner, tfile, NULL);
-	amp_am_scanner_free (scanner);
-
-	/* Find significant token */
-	significant_tok = anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT, NULL);
 	
-	arg = anjuta_token_file_first (AMP_GROUP_DATA (group)->tfile);
-	//anjuta_token_old_dump_range (arg, NULL);
+	return group;
+}
 
-	/* Create hash table for sources list */
-	orphan_sources = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)free_source_list);
-	
-	for (found = anjuta_token_match (significant_tok, ANJUTA_SEARCH_INTO, arg, &arg); found; found = anjuta_token_match (significant_tok, ANJUTA_SEARCH_INTO, anjuta_token_next_sibling (arg), &arg))
-	{
-		AnjutaToken *name = anjuta_token_next_child (arg);
-		
-		switch (anjuta_token_get_type (name))
-		{
-		case AM_TOKEN_SUBDIRS:
-				project_load_subdirs (project, name, group, FALSE);
-				break;
-		case AM_TOKEN_DIST_SUBDIRS:
-				project_load_subdirs (project, name, group, TRUE);
-				break;
-		case AM_TOKEN__DATA:
-		case AM_TOKEN__HEADERS:
-		case AM_TOKEN__LIBRARIES:
-		case AM_TOKEN__LISP:
-		case AM_TOKEN__LTLIBRARIES:
-		case AM_TOKEN__MANS:
-		case AM_TOKEN__PROGRAMS:
-		case AM_TOKEN__PYTHON:
-		case AM_TOKEN__JAVA:
-		case AM_TOKEN__SCRIPTS:
-		case AM_TOKEN__TEXINFOS:
-				project_load_target (project, name, group, orphan_sources);
-				break;
-		case AM_TOKEN__SOURCES:
-				project_load_sources (project, name, group, orphan_sources);
-				break;
-		}
+void
+amp_project_set_am_variable (AmpProject* project, AmpGroup* group, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list, GHashTable *orphan_sources)
+{
+	
+	switch (variable)
+	{
+	case AM_TOKEN_SUBDIRS:
+		project_load_subdirs (project, list, group, FALSE);
+		break;
+	case AM_TOKEN_DIST_SUBDIRS:
+		project_load_subdirs (project, list, group, TRUE);
+		break;
+	case AM_TOKEN__DATA:
+	case AM_TOKEN__HEADERS:
+	case AM_TOKEN__LIBRARIES:
+	case AM_TOKEN__LISP:
+	case AM_TOKEN__LTLIBRARIES:
+	case AM_TOKEN__MANS:
+	case AM_TOKEN__PROGRAMS:
+	case AM_TOKEN__PYTHON:
+	case AM_TOKEN__JAVA:
+	case AM_TOKEN__SCRIPTS:
+	case AM_TOKEN__TEXINFOS:
+		project_load_target (project, name, list, group, orphan_sources);
+		break;
+	case AM_TOKEN__SOURCES:
+		project_load_sources (project, name, list, group, orphan_sources);
+		break;
+	default:
+		break;
 	}
-
-	/* Free unused sources files */
-	g_hash_table_destroy (orphan_sources);
-
-	return group;
 }
 
 /* Public functions
@@ -1569,9 +1438,10 @@ gboolean
 amp_project_reload (AmpProject *project, GError **error) 
 {
 	AmpAcScanner *scanner;
+	AnjutaToken *arg;
 	GFile *root_file;
 	GFile *configure_file;
-	gboolean ok;
+	gboolean ok = TRUE;
 	GError *err = NULL;
 
 	/* Unload current project */
@@ -1583,11 +1453,13 @@ amp_project_reload (AmpProject *project, GError **error)
 	/* shortcut hash tables */
 	project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 	project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
-	project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, amp_config_file_free);
+	project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, (GDestroyNotify)amp_config_file_free);
+	amp_project_new_module_hash (project);
 
 	/* Initialize list styles */
-	project->space_list = anjuta_token_style_new (NULL, " ", "\\n", NULL, 0);
-	project->arg_list = anjuta_token_style_new (NULL, ", ", ",\\n ", ")", 0);
+	project->ac_space_list = anjuta_token_style_new (NULL, " ", "\n", NULL, 0);
+	project->am_space_list = anjuta_token_style_new (NULL, " ", " \\\n", NULL, 0);
+	project->arg_list = anjuta_token_style_new (NULL, ", ", ", ", ")", 0);
 	
 	/* Find configure file */
 	if (file_type (root_file, "configure.ac") == G_FILE_TYPE_REGULAR)
@@ -1611,10 +1483,18 @@ amp_project_reload (AmpProject *project, GError **error)
 	project->configure_file = anjuta_token_file_new (configure_file);
 	g_hash_table_insert (project->files, configure_file, project->configure_file);
 	g_object_add_toggle_ref (G_OBJECT (project->configure_file), remove_config_file, project);
-	scanner = amp_ac_scanner_new ();
-	ok = amp_ac_scanner_parse (scanner, project->configure_file, &err);
+	arg = anjuta_token_file_load (project->configure_file, NULL);
+	fprintf (stdout, "AC file before parsing\n");
+	anjuta_token_dump (arg);
+	fprintf (stdout, "\n");
+	scanner = amp_ac_scanner_new (project);
+	project->configure_token = amp_ac_scanner_parse_token (scanner, arg, 0, &err);
+	fprintf (stdout, "AC file after parsing\n");
+	anjuta_token_check (arg);
+	anjuta_token_dump (project->configure_token);
+	fprintf (stdout, "\n");
 	amp_ac_scanner_free (scanner);
-	if (!ok)
+	if (project->configure_token == NULL)
 	{
 		g_set_error (error, IANJUTA_PROJECT_ERROR, 
 		             	IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED,
@@ -1626,13 +1506,7 @@ amp_project_reload (AmpProject *project, GError **error)
 		     
 	monitors_setup (project);
 
-	project_reload_property (project);
-	
-	amp_project_new_module_hash (project);
-	project_reload_packages (project);
-	
 	/* Load all makefiles recursively */
-	project_list_config_files (project);
 	if (project_load_makefile (project, project->root_file, NULL, FALSE) == NULL)
 	{
 		g_set_error (error, IANJUTA_PROJECT_ERROR, 
@@ -1673,6 +1547,7 @@ amp_project_unload (AmpProject *project)
 
 	if (project->configure_file)	g_object_unref (G_OBJECT (project->configure_file));
 	project->configure_file = NULL;
+	if (project->configure_token) anjuta_token_free (project->configure_token);
 
 	if (project->root_file) g_object_unref (project->root_file);
 	project->root_file = NULL;
@@ -1689,7 +1564,8 @@ amp_project_unload (AmpProject *project)
 	project->configs = NULL;
 
 	/* List styles */
-	if (project->space_list) anjuta_token_style_free (project->space_list);
+	if (project->am_space_list) anjuta_token_style_free (project->am_space_list);
+	if (project->ac_space_list) anjuta_token_style_free (project->ac_space_list);
 	if (project->arg_list) anjuta_token_style_free (project->arg_list);
 	
 	amp_project_free_module_hash (project);
@@ -1736,19 +1612,38 @@ amp_project_probe (GFile *file,
 	return probe ? IANJUTA_PROJECT_PROBE_PROJECT_FILES : 0;
 }
 
-AmpGroup* 
-amp_project_add_group (AmpProject  *project,
-		AmpGroup *parent,
-		const gchar *name,
-		GError     **error)
+gboolean
+amp_project_get_token_location (AmpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token)
+{
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
+
+	g_hash_table_iter_init (&iter, project->files);
+	while (g_hash_table_iter_next (&iter, &key, &value))
+	{
+		if (anjuta_token_file_get_token_location ((AnjutaTokenFile *)value, location, token))
+		{
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+AmpGroup*
+amp_project_add_sibling_group (AmpProject  *project,
+    	AmpGroup *parent,
+    	const gchar *name,
+    	gboolean after,
+    	AmpGroup *sibling,
+    	GError **error)
 {
 	AmpGroup *last;
 	AmpGroup *child;
 	GFile *directory;
 	GFile *makefile;
-	AnjutaToken* token;
-	AnjutaToken* prev_token;
-	GList *token_list;
+	AnjutaToken *list;
 	gchar *basename;
 	gchar *uri;
 	AnjutaTokenFile* tfile;
@@ -1789,18 +1684,34 @@ amp_project_add_group (AmpProject  *project,
 			_("Group already exists"));
 		return NULL;
 	}
+
+	/* If a sibling is used, check that the parent is right */
+	if ((sibling != NULL) && (parent != anjuta_project_node_parent (sibling)))
+	{
+		g_free (uri);
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			_("Sibling group has not the same parent"));
+		return NULL;
+	}
 	
 	/* Add group node in project tree */
 	child = amp_group_new (directory, FALSE);
 	g_hash_table_insert (project->groups, uri, child);
 	g_object_unref (directory);
-	g_node_append (parent, child);
+	if (after)
+	{
+		anjuta_project_node_insert_after (parent, sibling, child);
+	}
+	else
+	{
+		anjuta_project_node_insert_before (parent, sibling, child);
+	}
 
 	/* Create directory */
 	g_file_make_directory (directory, NULL, NULL);
 
 	/* Create Makefile.am */
-	basename = g_file_get_basename (AMP_GROUP_DATA (parent)->makefile);
+	basename = AMP_GROUP_DATA (parent)->makefile != NULL ? g_file_get_basename (AMP_GROUP_DATA (parent)->makefile) : NULL;
 	if (basename != NULL)
 	{
 		makefile = g_file_get_child (directory, basename);
@@ -1811,19 +1722,56 @@ amp_project_add_group (AmpProject  *project,
 		makefile = g_file_get_child (directory, "Makefile.am");
 	}
 	g_file_replace_contents (makefile, "", 0, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, NULL);
-	tfile = amp_group_set_makefile (child, makefile);
+	tfile = amp_group_set_makefile (child, makefile, project);
 	g_hash_table_insert (project->files, makefile, tfile);
 	g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project);
 
+	if (sibling == NULL)
+	{
+		/* Find a sibling before */
+		for (last = anjuta_project_node_prev_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = anjuta_project_node_prev_sibling (last));
+		if (last != NULL)
+		{
+			sibling = last;
+			after = TRUE;
+		}
+		else
+		{
+			/* Find a sibling after */
+			for (last = anjuta_project_node_next_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = anjuta_project_node_next_sibling (last));
+			if (last != NULL)
+			{
+				sibling = last;
+				after = FALSE;
+			}
+		}
+	}
+	
 	/* Add in configure */
-	token_list= amp_group_get_token (parent, AM_GROUP_TOKEN_CONFIGURE);
-	if (token_list != NULL)
+	list = NULL;
+	if (sibling) list = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_CONFIGURE);
+	if (list == NULL) list= amp_group_get_first_token (parent, AM_GROUP_TOKEN_CONFIGURE);
+	if (list != NULL) list = anjuta_token_list (list);
+	if (list == NULL)
+	{
+		list = amp_project_write_config_list (project);
+		list = anjuta_token_next (list);
+	}
+	if (list != NULL)
 	{
 		gchar *relative_make;
 		gchar *ext;
-		AnjutaTokenStyle *style;
-		
-		prev_token = (AnjutaToken *)token_list->data;
+		AnjutaToken *prev = NULL;
+
+		if (sibling)
+		{
+			prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_CONFIGURE);
+			/*if ((prev != NULL) && after)
+			{
+				prev = anjuta_token_next_word (prev);
+			}*/
+		}
+		//prev_token = (AnjutaToken *)token_list->data;
 
 		relative_make = g_file_get_relative_path (project->root_file, makefile);
 		ext = relative_make + strlen (relative_make) - 3;
@@ -1831,89 +1779,85 @@ amp_project_add_group (AmpProject  *project,
 		{
 			*ext = '\0';
 		}
-		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED,  relative_make);
+		//token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED,  relative_make);
+		amp_project_write_config_file (project, list, after, prev, relative_make);
 		g_free (relative_make);
 		
-		style = anjuta_token_style_new (NULL," ","\\n",NULL,0);
-		add_list_item (prev_token, token, style);
-		anjuta_token_style_free (style);
+		//style = anjuta_token_style_new (NULL," ","\n",NULL,0);
+		//anjuta_token_add_word (prev_token, token, style);
+		//anjuta_token_style_free (style);
 	}
 	
 	/* Add in Makefile.am */
-	for (last = g_node_prev_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = g_node_prev_sibling (last));
-	if (last == NULL)
+	if (sibling == NULL)
 	{
-		AnjutaToken *prev_token;
-		gint space = 0;
-		AnjutaToken *list;
-
-		/* Skip comment and one space at the beginning */
-		for (prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile)); prev_token != NULL; prev_token = anjuta_token_next_sibling (prev_token))
+		AnjutaToken *pos;
+		static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+	
+		pos = anjuta_token_find_type (AMP_GROUP_DATA (parent)->make_token, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+		if (pos == NULL)
 		{
-			switch (anjuta_token_get_type (prev_token))
-			{
-				case ANJUTA_TOKEN_COMMENT:
-					space = 0;
-					continue;
-				case ANJUTA_TOKEN_SPACE:
-					if (space == 0)
-					{
-						space = 1;
-						continue;
-					}
-					break;
-				default:
-					break;
-			}
-			break;
+			pos = anjuta_token_prepend_child (AMP_GROUP_DATA (parent)->make_token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE, "\n"));
 		}
 
-		if (prev_token == NULL)
-		{
-			prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile));
-			if (prev_token)
-			{
-				prev_token = anjuta_token_file_last (AMP_GROUP_DATA (parent)->tfile);
-			}
-		}
+		list = anjuta_token_insert_token_list (FALSE, pos,
+		    	ANJUTA_TOKEN_SPACE, "\n");
+		list = anjuta_token_insert_token_list (FALSE, list,
+	    		AM_TOKEN_SUBDIRS, "SUBDIRS",
+		    	ANJUTA_TOKEN_SPACE, " ",
+		    	ANJUTA_TOKEN_OPERATOR, "=",
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_LAST, NULL,
+	    		NULL);
+		list = anjuta_token_next (anjuta_token_next ( anjuta_token_next (list)));
+	}
+	else
+	{
+		AnjutaToken *prev;
+		
+		prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_SUBDIRS);
+		list = anjuta_token_list (prev);
+	}
+
+	if (list != NULL)
+	{
+		AnjutaToken *token;
+		AnjutaToken *prev;
 
-		token = anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT | ANJUTA_TOKEN_ADDED, NULL);
-		if (prev_token == NULL)
+		if (sibling)
+		{
+			prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_SUBDIRS);
+		}		
+		
+		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
+		if (after)
 		{
-			prev_token = anjuta_token_insert_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile), token);
+			anjuta_token_insert_word_after (list, prev, token);
 		}
 		else
 		{
-			prev_token = anjuta_token_insert_after (prev_token, token);
+			anjuta_token_insert_word_before (list, prev, token);
 		}
-		list = prev_token;
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (AM_TOKEN_SUBDIRS | ANJUTA_TOKEN_ADDED, "SUBDIRS"));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL));
-		token = prev_token;
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name));
-		anjuta_token_merge (token, prev_token);
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n"));
-		anjuta_token_merge (list, prev_token);
-	}
-	else
-	{
-		token_list = amp_group_get_token (parent, AM_GROUP_TOKEN_SUBDIRS);
-		if (token_list != NULL)
-		{
-			prev_token = (AnjutaToken *)token_list->data;
+	
+		anjuta_token_style_format (project->am_space_list, list);
+		anjuta_token_file_update (AMP_GROUP_DATA (parent)->tfile, token);
 		
-			token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
-			add_list_item (prev_token, token, NULL);
-		}
+		amp_group_add_token (child, token, AM_GROUP_TOKEN_SUBDIRS);
 	}
-	amp_group_add_token (child, token, AM_GROUP_TOKEN_SUBDIRS);
 
 	return child;
 }
 
+
+AmpGroup* 
+amp_project_add_group (AmpProject  *project,
+		AmpGroup *parent,
+		const gchar *name,
+		GError     **error)
+{
+	return amp_project_add_sibling_group (project, parent, name, TRUE, NULL, error);
+}
+
 void 
 amp_project_remove_group (AmpProject  *project,
 		   AmpGroup *group,
@@ -1925,31 +1869,28 @@ amp_project_remove_group (AmpProject  *project,
 	
 	for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_CONFIGURE); token_list != NULL; token_list = g_list_next (token_list))
 	{
-		remove_list_item ((AnjutaToken *)token_list->data, NULL);
+		anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
 	}
 	for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_SUBDIRS); token_list != NULL; token_list = g_list_next (token_list))
 	{
-		remove_list_item ((AnjutaToken *)token_list->data, NULL);
+		anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
 	}
 	for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_DIST_SUBDIRS); token_list != NULL; token_list = g_list_next (token_list))
 	{
-		remove_list_item ((AnjutaToken *)token_list->data, NULL);
+		anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
 	}
 
 	amp_group_free (group);
 }
 
-AmpTarget*
-amp_project_add_target (AmpProject  *project,
-		 AmpGroup *parent,
-		 const gchar *name,
-		 AnjutaProjectTargetType type,
-		 GError     **error)
+AmpTarget* 
+amp_project_add_sibling_target (AmpProject  *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, gboolean after, AmpTarget *sibling, GError **error)
 {
 	AmpTarget *child;
 	AnjutaToken* token;
-	AnjutaToken* prev_token;
-	AnjutaToken *list;
+	AnjutaToken *args;
+	AnjutaToken *var;
+	AnjutaToken *prev;
 	gchar *targetname;
 	gchar *find;
 	GList *last;
@@ -1997,10 +1938,18 @@ amp_project_add_target (AmpProject  *project,
 			return NULL;
 		}
 	}
+
+	/* If a sibling is used, check that the parent is right */
+	if ((sibling != NULL) && (parent != anjuta_project_node_parent (sibling)))
+	{
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			_("Sibling target has not the same parent"));
+		return NULL;
+	}
 	
 	/* Check that the new target doesn't already exist */
 	find = (gchar *)name;
-	g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
+	anjuta_project_node_children_foreach (parent, find_target, &find);
 	if ((gchar *)find != name)
 	{
 		error_set (error, IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
@@ -2011,87 +1960,110 @@ amp_project_add_target (AmpProject  *project,
 	
 	/* Add target node in project tree */
 	child = amp_target_new (name, type, "", 0);
-	g_node_append (parent, child);
+	if (after)
+	{
+		anjuta_project_node_insert_after (parent, sibling, child);
+	}
+	else
+	{
+		anjuta_project_node_insert_before (parent, sibling, child);
+	}
+	//anjuta_project_node_append (parent, child);
 
 	/* Add in Makefile.am */
 	targetname = g_strconcat (((AmpTargetInformation *)type)->install, ((AmpTargetInformation *)type)->prefix, NULL);
 
-	for (last = amp_group_get_token (parent, AM_GROUP_TARGET); last != NULL; last = g_list_next (last))
+	// Get token corresponding to sibling and check if the target are compatible
+	args = NULL;
+	var = NULL;
+	if (sibling != NULL)
 	{
-		gchar *value = anjuta_token_evaluate ((AnjutaToken *)last->data);
-		
-		if ((value != NULL) && (strcmp (targetname, value) == 0))
+		last = amp_target_get_token (sibling);
+
+		if (last != NULL) 
 		{
-			g_free (value);
-			break;
+			AnjutaToken *token = (AnjutaToken *)last->data;
+
+			token = anjuta_token_list (token);
+			if (token != NULL)
+			{
+				token = anjuta_token_list (token);
+				var = token;
+				if (token != NULL)
+				{
+					token = anjuta_token_first_item (token);
+					if (token != NULL)
+					{
+						gchar *value;
+						
+						value = anjuta_token_evaluate (token);
+		
+						if ((value != NULL) && (strcmp (targetname, value) == 0))
+						{
+							g_free (value);
+							prev = (AnjutaToken *)last->data;
+							args = anjuta_token_last_item (anjuta_token_list (prev));
+						}
+					}
+				}
+			}	
 		}
-		g_free (value);
 	}
 
-	token = anjuta_token_new_string (((AmpTargetInformation *)type)->token, targetname);
-	g_free (targetname);
-
-	if (last == NULL)
+	if (args == NULL)
 	{
-		prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile));
-		if (prev_token != NULL)
+		for (last = amp_group_get_token (parent, AM_GROUP_TARGET); last != NULL; last = g_list_next (last))
 		{
-			/* Add at the end of the file */
-			while (anjuta_token_next_sibling (prev_token) != NULL)
+			gchar *value = anjuta_token_evaluate ((AnjutaToken *)last->data);
+		
+			if ((value != NULL) && (strcmp (targetname, value) == 0))
 			{
-				prev_token = anjuta_token_next_sibling (prev_token);
+				g_free (value);
+				args = anjuta_token_last_item (anjuta_token_list ((AnjutaToken *)last->data));
+				break;
 			}
+			g_free (value);
 		}
+	}
 
-		list = anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n");
-		if (prev_token == NULL)
-		{
-			prev_token = anjuta_token_insert_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile), list);
-		}
-		else
-		{
-			prev_token = anjuta_token_insert_after (prev_token, list);
-		}
 
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT | ANJUTA_TOKEN_ADDED, NULL));
-		list = prev_token;
-		prev_token = anjuta_token_insert_after (prev_token, token);
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL));
-		token = prev_token;
-		prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		anjuta_token_merge (token, prev_token);
-		anjuta_token_merge (list, token);
-		anjuta_token_insert_after (token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n"));
-		token = prev_token;
+	if (args == NULL)
+	{
+		args = amp_project_write_target (AMP_GROUP_DATA (parent)->make_token, ((AmpTargetInformation *)type)->token, targetname, after, var);
 	}
-	else
+	g_free (targetname);
+	
+	if (args != NULL)
 	{
-		for (token = (AnjutaToken *)last->data; anjuta_token_get_type (token) != ANJUTA_TOKEN_LIST; token = anjuta_token_next_sibling (token));
-
-		if (anjuta_token_next_child (token) == NULL)
+		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
+		if (after)
 		{
-			token = anjuta_token_insert_child (token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
+			anjuta_token_insert_word_after (args, prev, token);
 		}
 		else
 		{
-			token = anjuta_token_next_child (token);
+			anjuta_token_insert_word_before (args, prev, token);
 		}
-
-		for (; anjuta_token_next_sibling (token) != NULL; token = anjuta_token_next_sibling (token));
-	}
-
-	if (anjuta_token_get_type (token) != ANJUTA_TOKEN_SPACE)
-	{
-		token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
+	
+		anjuta_token_style_format (project->am_space_list, args);
+		anjuta_token_file_update (AMP_GROUP_DATA (parent)->tfile, token);
+		
+		amp_target_add_token (child, token);
 	}
-	token = anjuta_token_insert_after (token, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name));
-	amp_target_add_token (child, token);
 
 	return child;
 }
 
+AmpTarget*
+amp_project_add_target (AmpProject  *project,
+		 AmpGroup *parent,
+		 const gchar *name,
+		 AnjutaProjectTargetType type,
+		 GError     **error)
+{
+	return amp_project_add_sibling_target (project, parent, name, type, TRUE, NULL, error);
+}
+
 void 
 amp_project_remove_target (AmpProject  *project,
 		    AmpTarget *target,
@@ -2103,82 +2075,112 @@ amp_project_remove_target (AmpProject  *project,
 	
 	for (token_list = amp_target_get_token (target); token_list != NULL; token_list = g_list_next (token_list))
 	{
-		anjuta_token_remove ((AnjutaToken *)token_list->data);
+		anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
 	}
 
 	amp_target_free (target);
 }
 
 AmpSource* 
-amp_project_add_source (AmpProject  *project,
-		 AmpTarget *target,
-		 GFile *file,
-		 GError     **error)
+amp_project_add_sibling_source (AmpProject  *project, AmpTarget *target, GFile *file, gboolean after, AmpSource *sibling, GError **error)
 {
 	AmpGroup *group;
-	AmpSource *last;
 	AmpSource *source;
-	AnjutaToken* token;
+	AnjutaToken *token;
+	AnjutaToken *prev;
+	AnjutaToken *args;
 	gchar *relative_name;
 	
 	g_return_val_if_fail (file != NULL, NULL);
 	g_return_val_if_fail (target != NULL, NULL);
-	
-	if (AMP_NODE_DATA (target)->type != ANJUTA_PROJECT_TARGET) return NULL;
 
+	if (AMP_NODE_DATA (target)->type != ANJUTA_PROJECT_TARGET) return NULL;
+	
 	group = (AmpGroup *)(target->parent);
 	relative_name = g_file_get_relative_path (AMP_GROUP_DATA (group)->base.directory, file);
 
-	/* Add token */
-	last = g_node_last_child (target);
-	if (last == NULL)
+	/* Add in Makefile.am */
+
+	// Get token corresponding to sibling and check if the target are compatible
+	prev = NULL;
+	args = NULL;
+	if (sibling != NULL)
+	{
+		prev = AMP_SOURCE_DATA (sibling)->token;
+		args = anjuta_token_list (prev);
+	}
+
+	if (args == NULL)
 	{
-		/* First child */
-		AnjutaToken *tok;
-		AnjutaToken *close_tok;
-		AnjutaToken *eol_tok;
 		gchar *target_var;
 		gchar *canon_name;
-
-		/* Search where the target is declared */
-		tok = (AnjutaToken *)amp_target_get_token (target)->data;
-		close_tok = anjuta_token_new_static (ANJUTA_TOKEN_CLOSE, NULL);
-		eol_tok = anjuta_token_new_static (ANJUTA_TOKEN_EOL, NULL);
-		//anjuta_token_match (close_tok, ANJUTA_SEARCH_OVER, tok, &tok);
-		anjuta_token_match (eol_tok, ANJUTA_SEARCH_OVER, tok, &tok);
-		anjuta_token_free (close_tok);
-		anjuta_token_free (eol_tok);
-
-		/* Add a _SOURCES variable just after */
+		AnjutaToken *var;
+		GList *list;
+		
 		canon_name = canonicalize_automake_variable (AMP_TARGET_DATA (target)->base.name);
 		target_var = g_strconcat (canon_name,  "_SOURCES", NULL);
-		g_free (canon_name);
-		tok = anjuta_token_insert_after (tok, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, target_var));
+
+		/* Search where the target is declared */
+		var = NULL;
+		list = amp_target_get_token (target);
+		if (list != NULL)
+		{
+			var = (AnjutaToken *)list->data;
+			if (var != NULL)
+			{
+				var = anjuta_token_list (var);
+				if (var != NULL)
+				{
+					var = anjuta_token_list (var);
+				}
+			}
+		}
+		
+		args = amp_project_write_source_list (AMP_GROUP_DATA (group)->make_token, target_var, after, var);
 		g_free (target_var);
-		tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
-		tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
-		token = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
-		tok = anjuta_token_insert_after (tok, token);
-		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_name);
-		tok = anjuta_token_insert_after (tok, token);
-		tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_EOL | ANJUTA_TOKEN_ADDED, "\n"));
 	}
-	else
+	
+	if (args != NULL)
 	{
 		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_name);
-		add_list_item (AMP_SOURCE_DATA (last)->token, token, NULL);
-	}
-	g_free (relative_name);
+		if (after)
+		{
+			anjuta_token_insert_word_after (args, prev, token);
+		}
+		else
+		{
+			anjuta_token_insert_word_before (args, prev, token);
+		}
 	
+		anjuta_token_style_format (project->am_space_list, args);
+		anjuta_token_file_update (AMP_GROUP_DATA (group)->tfile, token);
+	}
+
 	/* Add source node in project tree */
 	source = amp_source_new (file);
 	AMP_SOURCE_DATA(source)->token = token;
-	g_node_append (target, source);
+	if (after)
+	{
+		anjuta_project_node_insert_after (target, sibling, source);
+	}
+	else
+	{
+		anjuta_project_node_insert_before (target, sibling, source);
+	}
 
 	return source;
 }
 
+
+AmpSource* 
+amp_project_add_source (AmpProject  *project,
+		 AmpTarget *target,
+		 GFile *file,
+		 GError     **error)
+{
+	return amp_project_add_sibling_source (project, target, file, TRUE, NULL, error);
+}
+
 void 
 amp_project_remove_source (AmpProject  *project,
 		    AmpSource *source,
@@ -2187,7 +2189,7 @@ amp_project_remove_source (AmpProject  *project,
 	amp_dump_node (source);
 	if (AMP_NODE_DATA (source)->type != ANJUTA_PROJECT_SOURCE) return;
 	
-	remove_list_item (AMP_SOURCE_DATA (source)->token, NULL);
+	anjuta_token_remove_word (AMP_SOURCE_DATA (source)->token, NULL);
 
 	amp_source_free (source);
 }
@@ -2267,10 +2269,45 @@ amp_project_save (AmpProject *project, GError **error)
 	return TRUE;
 }
 
+typedef struct _AmpMovePacket {
+	AmpProject *project;
+	GFile *old_root_file;
+} AmpMovePacket;
+
+static void
+foreach_node_move (AnjutaProjectNode *g_node, gpointer data)
+{
+	AmpProject *project = ((AmpMovePacket *)data)->project;
+	const gchar *old_root_file = ((AmpMovePacket *)data)->old_root_file;
+	GFile *relative;
+	GFile *new_file;
+	
+	switch (AMP_NODE_DATA (g_node)->type)
+	{
+	case ANJUTA_PROJECT_GROUP:
+		relative = get_relative_path (old_root_file, AMP_GROUP_DATA (g_node)->base.directory);
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		g_object_unref (AMP_GROUP_DATA (g_node)->base.directory);
+		AMP_GROUP_DATA (g_node)->base.directory = new_file;
+
+		g_hash_table_insert (project->groups, g_file_get_uri (new_file), g_node);
+		break;
+	case ANJUTA_PROJECT_SOURCE:
+		relative = get_relative_path (old_root_file, AMP_SOURCE_DATA (g_node)->base.file);
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		g_object_unref (AMP_SOURCE_DATA (g_node)->base.file);
+		AMP_SOURCE_DATA (g_node)->base.file = new_file;
+		break;
+	default:
+		break;
+	}
+}
+
 gboolean
 amp_project_move (AmpProject *project, const gchar *path)
 {
-	GFile	*old_root_file;
 	GFile *new_file;
 	gchar *relative;
 	GHashTableIter iter;
@@ -2279,27 +2316,16 @@ amp_project_move (AmpProject *project, const gchar *path)
 	AnjutaTokenFile *tfile;
 	AmpConfigFile *cfg;
 	GHashTable* old_hash;
+	AmpMovePacket packet= {project, NULL};
 
 	/* Change project root directory */
-	old_root_file = project->root_file;
+	packet.old_root_file = project->root_file;
 	project->root_file = g_file_new_for_path (path);
 
 	/* Change project root directory in groups */
 	old_hash = project->groups;
 	project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	g_hash_table_iter_init (&iter, old_hash);
-	while (g_hash_table_iter_next (&iter, &key, &value))
-	{
-		AmpGroup *group = (AmpGroup *)value;
-		
-		relative = get_relative_path (old_root_file, AMP_GROUP_DATA (group)->base.directory);
-		new_file = g_file_resolve_relative_path (project->root_file, relative);
-		g_free (relative);
-		g_object_unref (AMP_GROUP_DATA (group)->base.directory);
-		AMP_GROUP_DATA (group)->base.directory = new_file;
-
-		g_hash_table_insert (project->groups, g_file_get_uri (new_file), group);
-	}
+	anjuta_project_node_all_foreach (project->root_node, foreach_node_move, &packet);
 	g_hash_table_destroy (old_hash);
 
 	/* Change all files */
@@ -2308,7 +2334,7 @@ amp_project_move (AmpProject *project, const gchar *path)
 	g_hash_table_iter_init (&iter, old_hash);
 	while (g_hash_table_iter_next (&iter, &key, (gpointer *)&tfile))
 	{
-		relative = get_relative_path (old_root_file, anjuta_token_file_get_file (tfile));
+		relative = get_relative_path (packet.old_root_file, anjuta_token_file_get_file (tfile));
 		new_file = g_file_resolve_relative_path (project->root_file, relative);
 		g_free (relative);
 		anjuta_token_file_move (tfile, new_file);
@@ -2321,11 +2347,11 @@ amp_project_move (AmpProject *project, const gchar *path)
 
 	/* Change all configs */
 	old_hash = project->configs;
-	project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, amp_config_file_free);
+	project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, (GDestroyNotify)amp_config_file_free);
 	g_hash_table_iter_init (&iter, old_hash);
 	while (g_hash_table_iter_next (&iter, &key, (gpointer *)&cfg))
 	{
-		relative = get_relative_path (old_root_file, cfg->file);
+		relative = get_relative_path (packet.old_root_file, cfg->file);
 		new_file = g_file_resolve_relative_path (project->root_file, relative);
 		g_free (relative);
 		g_object_unref (cfg->file);
@@ -2337,7 +2363,7 @@ amp_project_move (AmpProject *project, const gchar *path)
 	g_hash_table_destroy (old_hash);
 
 	
-	g_object_unref (old_root_file);
+	g_object_unref (packet.old_root_file);
 
 	return TRUE;
 }
@@ -2403,7 +2429,7 @@ amp_project_get_source (AmpProject *project, const gchar *id)
 gchar *
 amp_project_get_node_id (AmpProject *project, const gchar *path)
 {
-	GNode *node = NULL;
+	AnjutaProjectNode *node = NULL;
 
 	if (path != NULL)
 	{
@@ -2424,7 +2450,7 @@ amp_project_get_node_id (AmpProject *project, const gchar *path)
 			}
 			else
 			{
-				node = g_node_nth_child (node, child);
+				node = anjuta_project_node_nth_child (node, child);
 			}
 			if (node == NULL)
 			{
@@ -2499,30 +2525,30 @@ amp_project_get_property (AmpProject *project, AmpPropertyType type)
 gboolean
 amp_project_set_property (AmpProject *project, AmpPropertyType type, const gchar *value)
 {
-	if (project->property != NULL)
+	if (project->property == NULL)
 	{
-		switch (type)
-		{
-			case AMP_PROPERTY_NAME:
-				project->property->name = g_strdup (value);
-				break;
-			case AMP_PROPERTY_VERSION:
-				project->property->version = g_strdup (value);
-				break;
-			case AMP_PROPERTY_BUG_REPORT:
-				project->property->bug_report = g_strdup (value);
-				break;
-			case AMP_PROPERTY_TARNAME:
-				project->property->tarname = g_strdup (value);
-				break;
-			case AMP_PROPERTY_URL:
-				project->property->url = g_strdup (value);
-				break;
-		}
-		return amp_project_update_property (project, type);
+		project->property = amp_property_new (NULL, NULL);
+	}
+	switch (type)
+	{
+		case AMP_PROPERTY_NAME:
+			STR_REPLACE (project->property->name, value);
+			break;
+		case AMP_PROPERTY_VERSION:
+			STR_REPLACE (project->property->version, value);
+			break;
+		case AMP_PROPERTY_BUG_REPORT:
+			STR_REPLACE (project->property->bug_report, value);
+			break;
+		case AMP_PROPERTY_TARNAME:
+			STR_REPLACE (project->property->tarname, value);
+			break;
+		case AMP_PROPERTY_URL:
+			STR_REPLACE (project->property->url, value);
+			break;
 	}
 	
-	return TRUE;
+	return amp_project_update_property (project, type);
 }
 
 /* Implement IAnjutaProject
@@ -2713,10 +2739,12 @@ amp_project_instance_init (AmpProject *project)
 	/* project data */
 	project->root_file = NULL;
 	project->configure_file = NULL;
+	project->configure_token = NULL;
 	project->root_node = NULL;
 	project->property = NULL;
 
-	project->space_list = NULL;
+	project->am_space_list = NULL;
+	project->ac_space_list = NULL;
 	project->arg_list = NULL;
 }
 
diff --git a/plugins/am-project/am-project.h b/plugins/am-project/am-project.h
index 9298272..cd56897 100644
--- a/plugins/am-project/am-project.h
+++ b/plugins/am-project/am-project.h
@@ -27,7 +27,7 @@
 #include <libanjuta/anjuta-project.h>
 #include <libanjuta/anjuta-token.h>
 #include <libanjuta/anjuta-token-file.h>
-#include <libanjuta/anjuta-token-style.h>
+#include <libanjuta/anjuta-token-list.h>
 
 G_BEGIN_DECLS
 
@@ -71,11 +71,16 @@ gboolean amp_project_load (AmpProject *project, GFile *directory, GError **error
 gboolean amp_project_reload (AmpProject *project, GError **error);
 void amp_project_unload (AmpProject *project);
 
+void amp_project_load_config (AmpProject *project, AnjutaToken *arg_list);
+void amp_project_load_properties (AmpProject *project, AnjutaToken *macro, AnjutaToken *list);
+void amp_project_load_module (AmpProject *project, AnjutaToken *module);
+
+
 AmpGroup *amp_project_get_root (AmpProject *project);
 AmpGroup *amp_project_get_group (AmpProject *project, const gchar *id);
 AmpTarget *amp_project_get_target (AmpProject *project, const gchar *id);
 AmpSource *amp_project_get_source (AmpProject *project, const gchar *id);
-
+gboolean amp_project_get_token_location (AmpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token);
 
 gboolean amp_project_move (AmpProject *project, const gchar *path);
 gboolean amp_project_save (AmpProject *project, GError **error);
@@ -84,12 +89,15 @@ gchar * amp_project_get_uri (AmpProject *project);
 GFile* amp_project_get_file (AmpProject *project);
 
 AmpGroup* amp_project_add_group (AmpProject  *project, AmpGroup *parent, const gchar *name, GError **error);
+AmpGroup* amp_project_add_sibling_group (AmpProject  *project, AmpGroup *parent, const gchar *name, gboolean after, AmpGroup *sibling, GError **error);
 void amp_project_remove_group (AmpProject  *project, AmpGroup *group, GError **error);
 
 AmpTarget* amp_project_add_target (AmpProject  *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, GError **error);
+AmpTarget* amp_project_add_sibling_target (AmpProject  *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, gboolean after, AmpTarget *sibling, GError **error);
 void amp_project_remove_target (AmpProject  *project, AmpTarget *target, GError **error);
 
 AmpSource* amp_project_add_source (AmpProject  *project, AmpTarget *parent, GFile *file, GError **error);
+AmpSource* amp_project_add_sibling_source (AmpProject  *project, AmpTarget *parent, GFile *file, gboolean after, AmpSource *sibling, GError **error);
 void amp_project_remove_source (AmpProject  *project, AmpSource *source, GError **error);
 
 
@@ -119,6 +127,7 @@ const gchar *amp_target_get_name (AmpTarget *target);
 AnjutaProjectTargetType amp_target_get_type (AmpTarget *target);
 gchar *amp_target_get_id (AmpTarget *target);
 
+void amp_source_free (AmpSource *node);
 gchar *amp_source_get_id (AmpSource *source);
 GFile *amp_source_get_file (AmpSource *source);
 
diff --git a/plugins/am-project/am-scanner.h b/plugins/am-project/am-scanner.h
index 70a8a4a..55640a5 100644
--- a/plugins/am-project/am-scanner.h
+++ b/plugins/am-project/am-scanner.h
@@ -20,6 +20,8 @@
 #ifndef _AM_SCANNER_H_
 #define _AM_SCANNER_H_
 
+#include "am-project.h"
+
 #include "libanjuta/anjuta-token.h"
 #include "libanjuta/anjuta-token-file.h"
 
@@ -28,14 +30,20 @@
 
 G_BEGIN_DECLS
 
+//#define YYSTYPE AnjutaToken*
+#define YYLTYPE AnjutaToken*
+#define YYSTYPE AnjutaToken*
+
 typedef struct _AmpAmScanner AmpAmScanner;
 
-AmpAmScanner *amp_am_scanner_new (void);
+AmpAmScanner *amp_am_scanner_new (AmpProject *project, AmpGroup *group);
 void amp_am_scanner_free (AmpAmScanner *scanner);
 
-gboolean amp_am_scanner_parse (AmpAmScanner *scanner, AnjutaTokenFile *file, GError **error);
+AnjutaToken *amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *token, GError **error);
+
+void amp_am_scanner_set_am_variable (AmpAmScanner *scanner, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list);
 
-const gchar* amp_am_scanner_get_filename (AmpAmScanner *scanner);
+void amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s);
 
 typedef enum
 {
diff --git a/plugins/am-project/am-scanner.l b/plugins/am-project/am-scanner.l
index fe574c4..4f18edd 100644
--- a/plugins/am-project/am-scanner.l
+++ b/plugins/am-project/am-scanner.l
@@ -19,42 +19,48 @@
  
 %{
 
-#include <stdlib.h>
-#include <string.h>
 #include "am-scanner.h"
 #include "am-parser.h"
 
 #include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
 
+#include <stdlib.h>
+#include <string.h>
 
-/* Eliminate warning */
-#define YY_NO_UNPUT 1 
 
-#define YY_INPUT(buf,result,the_max_size) \
-    result = 0;
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
 
-#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
-    
 #define YY_EXTRA_TYPE  AmpAmScanner*
 
+#define YY_DECL static int am_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner)
+
 //#define YY_USER_INIT {yy_flex_debug = 1;}
- 
-static AnjutaToken* amp_am_scanner_append_token (AmpAmScanner *scanner, gint token);
-static gint amp_am_scanner_last_token (AmpAmScanner *scanner);
-static gint amp_am_scanner_last_flags (AmpAmScanner *scanner);
-static void amp_am_scanner_update_line_width (AmpAmScanner *scanner, YYLTYPE *loc);
-static void amp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static int amp_am_parse (yyscan_t scanner);
+
+static int amp_am_scanner_parse_end (AmpAmScanner *scanner);
+
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
+                    return tok
+
+struct _AmpAmScanner
+{
+    yyscan_t scanner;
+
+	AnjutaTokenStream *stream;
+
+    AmpProject *project;
+    AmpGroup *group;
+	GHashTable *orphan_sources;
+};
 
 %}
 
-%option reentrant stack noyywrap yylineno
+%option reentrant noyywrap yylineno
 
-%option prefix="amp_am_yy"
+/* Remove some warnings */
+%option nounput noinput noyy_pop_state noyy_top_state
 
-/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
- * not "lex.amp_am_yy.c" 
-%option outfile="lex.yy.c"*/
+%option prefix="amp_am_yy"
 
 %option bison-bridge bison-locations
 
@@ -68,294 +74,213 @@ NAME          [^ \t\n\r:#=$"'`&@\\]*
 
 %%
 
-<INITIAL>\n {
-	yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_EOL);
-	return EOL;
-}
+<INITIAL>\n 						{ RETURN (EOL); }
 
-<INITIAL>([ ]|\\\n)([ \t]|\\\n)* {
-	yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_SPACE);
-	return SPACE;
-}
+<INITIAL>([ ]|\\\n)([ \t]|\\\n)* 	{ RETURN (SPACE); }
 
-<INITIAL>([ \t])*#.*\n {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_COMMENT);   
-    return EOL;
-}
+<INITIAL>([ \t])*#.*\n 				{ RETURN (EOL); }
 
-<INITIAL>\t {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_SPACE);   
-    return TAB;
-}
+<INITIAL>\t 						{ RETURN (TAB); }
 
-<INITIAL>@{NAME}@ {
-	yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_MACRO);
-	return MACRO;
-}
+<INITIAL>@{NAME}@ 					{ RETURN (MACRO); }
 
-<INITIAL>\$\([^ \t\n\r:#=$)]+\) {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_VARIABLE);   
-	amp_am_scanner_update_line_width (yyextra, yylloc);
-    return VARIABLE;
-}
+<INITIAL>\$\([^ \t\n\r:#=$)]+\) 	{ RETURN (VARIABLE); }
 
-<INITIAL>\$\{[^ \t\n\r:#=$}]+\} {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_VARIABLE);   
-	amp_am_scanner_update_line_width (yyextra, yylloc);
-    return VARIABLE;
-}
+<INITIAL>\$\{[^ \t\n\r:#=$}]+\} 	{ RETURN (VARIABLE); }
 
-<INITIAL>\$[^ \t\n\r\(\{] {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_VARIABLE);   
-	amp_am_scanner_update_line_width (yyextra, yylloc);
-    return VARIABLE;
-}
+<INITIAL>\$[^ \t\n\r\(\{] 			{ RETURN (VARIABLE); }
 
-<INITIAL>: {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ':');   
-    return COLON;
-}
+<INITIAL>: 							{ RETURN (COLON); }
 
-<INITIAL>:: {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return DOUBLE_COLON;
-}
+<INITIAL>:: 						{ RETURN (DOUBLE_COLON); }
 
-<INITIAL>; {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return SEMI_COLON;
-}
+<INITIAL>; 							{ RETURN (SEMI_COLON); }
 
-<INITIAL>\| {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return ORDER;
-}
+<INITIAL>\| 						{ RETURN (ORDER); }
 
-<INITIAL>\= {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return EQUAL;
-}
+<INITIAL>\= 						{ RETURN (EQUAL); }
 
-<INITIAL>:= {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return IMMEDIATE_EQUAL;
-}
+<INITIAL>:= 						{ RETURN (IMMEDIATE_EQUAL); }
 
-<INITIAL>\?= {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return CONDITIONAL_EQUAL;
-}
+<INITIAL>\?= 						{ RETURN (CONDITIONAL_EQUAL); }
 
-<INITIAL>\+= {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return APPEND;
-}
+<INITIAL>\+= 						{ RETURN (APPEND); }
 
-<INITIAL>\\[ ] {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return CHARACTER;
-}
+<INITIAL>\\[ ] 						{ RETURN (CHARACTER); }
 
-<INITIAL>\\: {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return CHARACTER;
-}
+<INITIAL>\\: 						{ RETURN (CHARACTER); }
 
-<INITIAL>\\= {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return CHARACTER;
-}
+<INITIAL>\\= 						{ RETURN (CHARACTER); }
 
-<INITIAL>\\# {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
-    return CHARACTER;
-}
+<INITIAL>\\# 						{ RETURN (CHARACTER); }
 
-<INITIAL>SUBDIRS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN_SUBDIRS);   
-    return AM_VARIABLE;
-}
+<INITIAL>SUBDIRS 					{ RETURN (SUBDIRS); }
 
-<INITIAL>DIST_SUBDIRS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN_DIST_SUBDIRS);   
-    return AM_VARIABLE;
-}
+<INITIAL>DIST_SUBDIRS 				{ RETURN (DIST_SUBDIRS); }
 
-<INITIAL>{NAME}_DATA {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__DATA);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_DATA 				{ RETURN (_DATA); }
 
-<INITIAL>{NAME}_HEADERS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__HEADERS);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_HEADERS 			{ RETURN (_HEADERS); }
 
-<INITIAL>{NAME}_LIBRARIES {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LIBRARIES);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LIBRARIES 			{ RETURN (_LIBRARIES); }
 
-<INITIAL>{NAME}_LISP {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LISP);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LISP 				{ RETURN (_LISP); }
 
-<INITIAL>{NAME}_LTLIBRARIES {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LTLIBRARIES);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LTLIBRARIES 		{ RETURN (_LTLIBRARIES); }
 
-<INITIAL>{NAME}_MANS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__MANS);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_MANS 				{ RETURN (_MANS); }
 
-<INITIAL>{NAME}_PROGRAMS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__PROGRAMS);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_PROGRAMS 			{ RETURN (_PROGRAMS); }
 
-<INITIAL>{NAME}_PYTHON {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__PYTHON);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_PYTHON 				{ RETURN (_PYTHON); }
 
-<INITIAL>{NAME}_JAVA {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__JAVA);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_JAVA 				{ RETURN (_JAVA); }
 
-<INITIAL>{NAME}_SCRIPTS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__SCRIPTS);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_SCRIPTS 			{ RETURN (_SCRIPTS); }
 
-<INITIAL>{NAME}_SOURCES {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__SOURCES);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_SOURCES 			{ RETURN (_SOURCES); }
 
-<INITIAL>{NAME}_TEXINFOS {
-    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__TEXINFOS);   
-    return AM_VARIABLE;
-}
+<INITIAL>{NAME}_TEXINFOS 			{ RETURN (_TEXINFOS); }
 
-<INITIAL>{NAME} {
-    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_NAME);   
-	amp_am_scanner_update_line_width (yyextra, yylloc);
-    return NAME;
-}
+<INITIAL>{NAME} 					{ RETURN (NAME); }
 
-<INITIAL>. {
-    yylval->token = amp_am_scanner_append_token  (yyextra, *yytext);   
-    return CHARACTER;
-}
+<INITIAL>. 							{ RETURN (CHARACTER); }
 
 %%
-     
-struct _AmpAmScanner
+
+typedef struct _AmpAmBuffer AmpAmBuffer;
+       
+struct _AmpAmBuffer
 {
-    const gchar *pos;
-    yyscan_t scanner;
-    YY_BUFFER_STATE	 buffer;
+    AnjutaToken *token;
 
-    AnjutaTokenFile *file;
-    gchar *filename;
+    /* Beginning of current token */
+    AnjutaToken *start;
+    gsize begin;
 
-	guint line_width;
-};
+    AnjutaToken *end;   /* Last token */
 
+    /* Next data read buffer */
+    AnjutaToken *next;
+    gsize pos;
+
+    /* Place to put new token */
+    AnjutaToken *first;
+    AnjutaToken *last;
+
+    AmpAmBuffer *parent;    
+};
+     
 /* Private functions
  *---------------------------------------------------------------------------*/
 
-static AnjutaToken*
-amp_am_scanner_append_token (AmpAmScanner *scanner, gint token)
+static gint
+amp_am_scanner_parse_end (AmpAmScanner *scanner)
 {
-    AnjutaToken *frag;
-            
-    frag = anjuta_token_new_fragment (token, scanner->pos, yyget_leng (scanner->scanner));
-	anjuta_token_file_append (scanner->file, frag);
-    scanner->pos += yyget_leng (scanner->scanner);
-	//anjuta_token_old_dump (frag);
-    
-    return frag;
+    yypop_buffer_state(scanner->scanner);
+    scanner->stream = anjuta_token_stream_pop (scanner->stream);
+
+    if (scanner->stream == NULL)
+    {
+        yyterminate();
+    }
+    else
+    {
+        return 1;
+    }
 }
 
-static void
-amp_am_scanner_update_line_width (AmpAmScanner *scanner, YYLTYPE *loc)
+/* Parser functions
+ *---------------------------------------------------------------------------*/
+
+void
+amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s)
 {
-	anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+    AnjutaTokenFileLocation location;
+
+    if (amp_project_get_token_location (scanner->project, &location, *loc))
+    {
+        g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+        g_free (location.filename);
+    }
+    else
+    {
+        g_message ("%s \n", s);
+    }
 }
 
-static void
-amp_update_location (YYLTYPE *loc, const gchar *text, gint length)
+void
+amp_am_scanner_set_am_variable (AmpAmScanner *scanner, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list)
 {
-	const gchar *ptr;
-	const gchar *end = text + length;
-
-    loc->first_line = loc->last_line;
-    loc->first_column = loc->last_column + 1;
-
-	for (ptr = text; ptr != end; ptr++)
-	{
-		if (*ptr == '\n')
-		{
-			loc->last_column = 0;
-			loc->last_line++;
-			length -= (ptr + 1 - text);
-		}
-	}
-
-	loc->last_column += length;
+    amp_project_set_am_variable (scanner->project, scanner->group, variable, name, list, scanner->orphan_sources);
 }
 
 /* Public functions
  *---------------------------------------------------------------------------*/
 
-gboolean
-amp_am_scanner_parse (AmpAmScanner *scanner, AnjutaTokenFile *file, GError **error)
+AnjutaToken *
+amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *token, GError **error)
 {
-    if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
-
-	scanner->file = file;
-	if (scanner->file== NULL) return FALSE;
+    AnjutaToken *first;
+    AnjutaTokenStream *stream;
+
+    stream = anjuta_token_stream_push (scanner->stream, token);
+    first = anjuta_token_stream_get_root (stream);
+
+    if (scanner->stream != NULL)
+    {
+        /* Parse an included file or a expanded variable */
+
+        scanner->stream = stream;
+        yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+    }
+    else
+    {
+        amp_am_yypstate *ps;
+        gint status;
+
+        scanner->stream = stream;
+        ps = amp_am_yypstate_new ();
+        do
+        {
+            YYSTYPE yylval_param;
+            YYLTYPE yylloc_param;
+            gint yychar = am_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+
+			yylloc_param = yylval_param;
+            status = amp_am_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
+ 
+        } while (status == YYPUSH_MORE);
+        amp_am_yypstate_delete (ps);
 
-    scanner->pos = anjuta_token_file_get_content (scanner->file, error);
-	if (scanner->pos == NULL) return FALSE;
+    }
 
-    scanner->buffer = yy_scan_string (scanner->pos, scanner->scanner);
-	
-	return amp_am_yyparse (scanner->scanner) == 0;
+    return first;
 }
 
-guint
-amp_am_scanner_get_line_width (AmpAmScanner *scanner)
-{
-	return scanner->line_width;
-}
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
 
-const gchar*
-amp_am_scanner_get_filename (AmpAmScanner *scanner)
+static void
+free_source_list (GList *source_list)
 {
-	g_free (scanner->filename);
-    scanner->filename = NULL;
-    if (scanner->file) scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
-	
-	return scanner->filename;
+	g_list_foreach (source_list, (GFunc)amp_source_free, NULL);
+	g_list_free (source_list);
 }
 
-
-/* Constructor & Destructor
- *---------------------------------------------------------------------------*/
-
 AmpAmScanner *
-amp_am_scanner_new (void)
+amp_am_scanner_new (AmpProject *project, AmpGroup *group)
 {
 	AmpAmScanner *scanner;
 
 	scanner = g_new0 (AmpAmScanner, 1);
 
+    scanner->project = project;
+    scanner->group = group;
+
+	/* Create hash table for sources list */
+	scanner->orphan_sources = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)free_source_list);
+
     yylex_init(&scanner->scanner);
     yyset_extra (scanner, scanner->scanner);
 
@@ -367,11 +292,10 @@ amp_am_scanner_free (AmpAmScanner *scanner)
 {
 	g_return_if_fail (scanner != NULL);
 
-    if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
     yylex_destroy(scanner->scanner);
 
-	g_free (scanner->filename);
-	scanner->filename = NULL;
+	/* Free unused sources files */
+	g_hash_table_destroy (scanner->orphan_sources);
 
 	g_free (scanner);
 }
diff --git a/plugins/am-project/am-writer.c b/plugins/am-project/am-writer.c
new file mode 100644
index 0000000..a68f534
--- /dev/null
+++ b/plugins/am-project/am-writer.c
@@ -0,0 +1,219 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-writer.c
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "am-writer.h"
+#include "ac-scanner.h"
+#include "ac-parser.h"
+
+#include "am-project-private.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+/* Types
+  *---------------------------------------------------------------------------*/
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+AnjutaToken *
+amp_project_write_config_list (AmpProject *project)
+{
+	AnjutaToken *pos;
+	AnjutaToken *token;
+	static gint output_type[] = {AC_TOKEN_AC_OUTPUT, 0};
+	static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+	
+	pos = anjuta_token_find_type (project->configure_token, 0, output_type);
+	if (pos == NULL)
+	{
+		gint other_type[] = {AC_TOKEN_AC_INIT,
+			AC_TOKEN_PKG_CHECK_MODULES,
+			AC_TOKEN_AC_CONFIG_FILES, 
+			AC_TOKEN_OBSOLETE_AC_OUTPUT,
+			AC_TOKEN_AC_PREREQ,
+			0};
+			
+		pos = anjuta_token_find_type (project->configure_token, ANJUTA_TOKEN_SEARCH_LAST, other_type);
+		if (pos == NULL)
+		{
+			pos = anjuta_token_skip_comment (project->configure_token);
+		}
+		else
+		{
+			AnjutaToken* next;
+
+			next = anjuta_token_find_type (pos, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+		}
+		
+	}
+
+	token = anjuta_token_insert_token_list (FALSE, pos,
+	    		AC_TOKEN_AC_CONFIG_FILES, "AC_CONFIG_FILES(",
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_LAST, NULL,
+	    		RIGHT_PAREN, ")",
+	    		NULL);
+	
+	return token;
+}
+
+AnjutaToken *
+amp_project_write_subdirs_list (AmpGroup *project)
+{
+	AnjutaToken *pos;
+	AnjutaToken *token;
+	static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+	
+	pos = anjuta_token_find_type (pos, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+
+	token = anjuta_token_insert_token_list (FALSE, pos,
+	    		AC_TOKEN_AC_CONFIG_FILES, "AC_CONFIG_FILES(",
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_LAST, NULL,
+	    		RIGHT_PAREN, ")",
+	    		NULL);
+	
+	return token;
+}
+
+AnjutaToken *
+amp_project_write_config_file (AmpProject *project, AnjutaToken *list, gboolean after, AnjutaToken *sibling, const gchar *filename)
+{
+	AnjutaToken *token;
+
+	token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, filename);
+	fprintf (stdout, "Dump config list:\n");
+	anjuta_token_dump (list);
+	if (after)
+	{
+		anjuta_token_insert_word_after (list, sibling, token);
+	}
+	else
+	{
+		anjuta_token_insert_word_before (list, sibling, token);
+	}
+	fprintf (stdout, "Dump config list after insertion:\n");
+	anjuta_token_dump (list);
+	
+	anjuta_token_style_format (project->ac_space_list, list);
+	
+	fprintf (stdout, "Dump config list after format:\n");
+	anjuta_token_dump (list);
+	
+	anjuta_token_file_update (project->configure_file, list);
+	
+	return token;
+}
+
+AnjutaToken *
+amp_project_write_target (AnjutaToken *makefile, gint type, const gchar *name, gboolean after, AnjutaToken* sibling)
+{
+	AnjutaToken *pos;
+	AnjutaToken *token;
+	
+	if (sibling == NULL)
+	{
+		pos = anjuta_token_first_item (makefile);
+		
+		/* Add at the end of the file */
+		while (anjuta_token_next_item (pos) != NULL)
+		{
+			pos = anjuta_token_next_item (pos);
+		}
+	}
+	else
+	{
+		pos = sibling;
+	}
+
+	token = anjuta_token_insert_token_list (after, pos,
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		type, name,
+	    		ANJUTA_TOKEN_SPACE, " ",
+	    		ANJUTA_TOKEN_OPERATOR, "=",
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_START, NULL,
+	    		NULL);
+
+	return anjuta_token_last_item (token);
+}
+
+AnjutaToken *
+amp_project_write_source_list (AnjutaToken *makefile, const gchar *name, gboolean after, AnjutaToken* sibling)
+{
+	AnjutaToken *pos;
+	AnjutaToken *token;
+	static gint eol_type[] = {ANJUTA_TOKEN_EOL, 0};
+	
+	if (sibling == NULL)
+	{
+		pos = anjuta_token_first_item (makefile);
+		
+		/* Add at the end of the file */
+		while (anjuta_token_next_item (pos) != NULL)
+		{
+			pos = anjuta_token_next_item (pos);
+		}
+	}
+	else
+	{
+		pos = sibling;
+	}
+
+	if (after && (pos != NULL))
+	{
+		token = anjuta_token_find_type (pos, 0, eol_type);
+		if (token != NULL)
+		{
+			pos = token;
+		}
+		else
+		{
+			pos = anjuta_token_insert_token_list (after, pos,
+			    ANJUTA_TOKEN_EOL, "\n",
+			    NULL);
+		}
+	}
+	
+	token = anjuta_token_insert_token_list (after, pos,
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_NAME, name,
+	    		ANJUTA_TOKEN_SPACE, " ",
+	    		ANJUTA_TOKEN_OPERATOR, "=",
+	    		ANJUTA_TOKEN_LIST, NULL,
+	    		ANJUTA_TOKEN_START, NULL,
+	    		NULL);
+
+	return anjuta_token_last_item (token);
+}
diff --git a/plugins/am-project/am-writer.h b/plugins/am-project/am-writer.h
new file mode 100644
index 0000000..290f4df
--- /dev/null
+++ b/plugins/am-project/am-writer.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-writer.h
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AM_WRITER_H_
+#define _AM_WRITER_H_
+
+#include "am-project.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+AnjutaToken *amp_project_write_config_list (AmpProject *project);
+AnjutaToken *amp_project_write_config_file (AmpProject *project, AnjutaToken *list, gboolean after, AnjutaToken *sibling, const gchar *filename);
+AnjutaToken *amp_project_write_target (AnjutaToken *makefile, gint type, const gchar *name, gboolean after, AnjutaToken* sibling);
+AnjutaToken *amp_project_write_source_list (AnjutaToken *makefile, const gchar *name, gboolean after, AnjutaToken* sibling);
+
+G_END_DECLS
+
+#endif /* _AM_WRITER_H_ */
diff --git a/plugins/mk-project/mk-parser.y b/plugins/mk-project/mk-parser.y
index 31d1da0..ecf5289 100644
--- a/plugins/mk-project/mk-parser.y
+++ b/plugins/mk-project/mk-parser.y
@@ -25,10 +25,14 @@
 
 #define YYDEBUG 1
 
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N)	((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
+
 %}
 
-%token	EOL	'\n'
-%token	SPACE
+%token  EOL	'\n'
+%token	SPACE ' '
 %token	TAB '\t'
 %token  HASH '#'
 %token	MACRO
@@ -59,14 +63,10 @@
 %token  _EXPORT_ALL_VARIABLES
 %token  _NOTPARALLEL
 
-
 %defines
 
-%pure_parser
-
-/* Necessary because autotools wrapper always looks for a file named "y.tab.c",
- * not "amp-scanner.c"
-%output="y.tab.c"*/
+%define api.pure
+%define api.push_pull "push"
 
 /*%glr-parser*/
 
@@ -87,12 +87,84 @@
 
 //mkp_yydebug = 1;
 
-static void mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s);
-static gint mkp_special_target (AnjutaToken *list);
-static gint mkp_special_prerequisite (AnjutaToken *token);
+static gint
+mkp_special_prerequisite (AnjutaToken *token)
+{
+    switch (anjuta_token_get_type (token))
+    {
+        case ORDER:
+            return MK_TOKEN_ORDER;
+        default:
+            return ANJUTA_TOKEN_NAME;
+    }
+}
 
-%}
+static void
+mkp_special_target (AnjutaToken *list)
+{
+    AnjutaToken *arg = anjuta_token_first_item (list);
+    AnjutaToken *target = arg != NULL ? anjuta_token_first_item (arg) : NULL;
 
+    if ((target != NULL) && (anjuta_token_next_item (target) == NULL))
+    {
+        gint mk_token = 0;
+
+        switch (anjuta_token_get_type (target))
+        {
+        case _PHONY:
+            mk_token = MK_TOKEN__PHONY;
+            break;
+        case _SUFFIXES:
+            mk_token = MK_TOKEN__SUFFIXES;
+            break;
+        case _DEFAULT:
+            mk_token = MK_TOKEN__DEFAULT;
+            break;
+        case _PRECIOUS:
+            mk_token = MK_TOKEN__PRECIOUS;
+            break;
+        case _INTERMEDIATE:
+            mk_token = MK_TOKEN__INTERMEDIATE;
+            break;
+        case _SECONDARY:
+            mk_token = MK_TOKEN__SECONDARY;
+            break;
+        case _SECONDEXPANSION:
+            mk_token = MK_TOKEN__SECONDEXPANSION;
+            break;
+        case _DELETE_ON_ERROR:
+            mk_token = MK_TOKEN__DELETE_ON_ERROR;
+            break;
+        case _IGNORE:
+            mk_token = MK_TOKEN__IGNORE;
+            break;
+        case _LOW_RESOLUTION_TIME:
+            mk_token = MK_TOKEN__LOW_RESOLUTION_TIME;
+            break;
+        case _SILENT:
+            mk_token = MK_TOKEN__SILENT;
+            break;
+        case _EXPORT_ALL_VARIABLES:
+            mk_token = MK_TOKEN__EXPORT_ALL_VARIABLES;
+            break;
+        case _NOTPARALLEL:
+            mk_token = MK_TOKEN__NOTPARALLEL;
+            break;
+        case ORDER:
+            mk_token = MK_TOKEN_ORDER;
+            break;
+        default:
+            break;
+        }
+        
+        if (mk_token)
+        {
+            anjuta_token_set_type (arg, mk_token);
+        }
+    }
+}
+
+%}
 
 %%
 
@@ -106,34 +178,44 @@ statement:
     | space end_of_line
     | definition end_of_line
     | rule  command_list {
-        if ($2 != NULL) $$ = anjuta_token_group ($1, $2);
-        mkp_scanner_add_rule (scanner, $$);
+        anjuta_token_merge_children ($1, $2);
+        mkp_scanner_add_rule (scanner, $1);
     }
 	;
 
 definition:
-    head_list equal_token value_list {
-		$$ = anjuta_token_merge (
-			anjuta_token_insert_before ($1,
-					anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL)),
-			$3 != NULL ? $3 : $2);
+    head_list equal_group value {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL);
+        anjuta_token_merge_own_children ($1);
+        anjuta_token_merge ($$, $1);
+        anjuta_token_merge ($$, $2);
+        anjuta_token_merge ($$, $3);
+        mkp_scanner_update_variable (scanner, $$);
+    }
+    | head_list equal_group {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL);
+        anjuta_token_merge_own_children ($1);
+        anjuta_token_merge ($$, $1);
+        anjuta_token_merge ($$, $2);
         mkp_scanner_update_variable (scanner, $$);
-    }        
+    }
     ;    
 
 rule:
     depend_list  end_of_line {
-        $$ = anjuta_token_group ($1, $2);
+        anjuta_token_merge ($1, $2);
     }
     | depend_list  SEMI_COLON  command_line  EOL {
-        $$ = anjuta_token_group ($1, $4);
+        anjuta_token_merge ($1, $2);
+        anjuta_token_merge ($1, $3);
+        anjuta_token_merge ($1, $4);
     }
     ;
 
 depend_list:
     head_list  rule_token  prerequisite_list {
-        $$ = anjuta_token_group_new (MK_TOKEN_RULE, $1);
-        anjuta_token_set_type ($1, MK_TOKEN_TARGET);
+        $$ = anjuta_token_new_static (MK_TOKEN_RULE, NULL);
+        anjuta_token_merge ($$, $1);
         mkp_special_target ($1);
         switch (anjuta_token_get_type ($2))
         {
@@ -146,16 +228,19 @@ depend_list:
         default:
             break;
         }
-        anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+        anjuta_token_merge ($$, $2);
+        anjuta_token_merge ($$, $3);
     }
     ;
 
 command_list:
     /* empty */ {
-        $$ = NULL;
+        $$ = anjuta_token_new_static (MK_TOKEN_COMMANDS, NULL);
     }
 	| command_list TAB command_line EOL {
-        $$ = $4;
+        anjuta_token_merge ($1, $2);
+        anjuta_token_merge ($1, $3);
+        anjuta_token_merge ($1, $4);
     }
 	;
 
@@ -164,15 +249,16 @@ command_list:
  *----------------------------------------------------------------------------*/
 
 end_of_line:
-    EOL
-    | comment
+    EOL {
+        $$ = NULL;
+    }
+    | comment {
+        $$ = NULL;
+    }
     ;
 
 comment:
-    HASH not_eol_list EOL {
-        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
-        anjuta_token_group ($1, $3);
-    }
+    HASH not_eol_list EOL
     ;
 
 not_eol_list:
@@ -180,69 +266,59 @@ not_eol_list:
     | not_eol_list not_eol_token
     ;
 
-value_list:
+prerequisite_list:
     /* empty */ {
-        $$ = NULL;
+        $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
     }
     | space {
-        $$ = $1;
-    }
-    | optional_space value_list_body optional_space {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_VALUE, $1 != NULL ? $1 : $2);
-        if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
-        if ($3) anjuta_token_set_type ($1, ANJUTA_TOKEN_LAST);
-        anjuta_token_group ($$, $3 != NULL ? $3 : $2);
-    }
-    ;
-
-value_list_body:
-    value
-    | value_list_body  space  value {
-        anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
-        $$ = $3;
-    }
-    ;
-
-prerequisite_list:
-    /* empty */ {
-        $$ = NULL;
+        $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
     }
     | optional_space  prerequisite_list_body  optional_space {
-        $$ = anjuta_token_group_new (MK_TOKEN_PREREQUISITE, $1 != NULL ? $1 : $2);
         if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
         if ($3) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+        anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($2, $3);
+        $$ = $2;
     }
     ;
 
 prerequisite_list_body:
-	prerequisite
+	prerequisite {
+        $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
+        anjuta_token_merge ($$, $1);
+    }
 	| prerequisite_list_body  space  prerequisite {
         anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
-        $$ = $3;
+        anjuta_token_merge ($1, $2);
+        anjuta_token_merge ($1, $3);
 	}
 	;
 
 head_list:
     optional_space head_list_body optional_space {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NAME, $1 != NULL ? $1 : $2);
-        if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
-        if ($3) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
-        anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+        $$ = anjuta_token_merge_previous ($2, $1);
+        anjuta_token_merge ($$, $3);
     }
     ;
 
 head_list_body:
-    head
+    head {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+        anjuta_token_merge ($$, $1);
+    }
     | head_list_body  space  head {
-        anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
-        $$ = $3;
+        anjuta_token_merge ($1, $2);
+        anjuta_token_merge ($1, $3);
     }
     ;
 
 command_line:
-    /* empty */
-    | command_line command_token
+    /* empty */ {
+        $$ = anjuta_token_new_static (MK_TOKEN_COMMAND, NULL);
+    }
+    | command_line command_token {
+        anjuta_token_merge ($1, $2);
+    }
     ;
 
 /* Items
@@ -256,43 +332,82 @@ optional_space:
 	;
 
 space:
-	space_token
+	space_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+        anjuta_token_merge ($$, $1);
+    }
 	| space space_token	{
-		anjuta_token_merge ($1, $2);
+        anjuta_token_merge ($1, $2);
 	}
+    | space variable_token
 	;
 
 head:
     head_token {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NAME, $1);    
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+        anjuta_token_merge ($$, $1);
     }
     | head head_token {
-        anjuta_token_group ($$, $2);
+        anjuta_token_merge ($1, $2);
     }
+    | head variable_token
     ;
 
 value:
     value_token {
-        $$ = anjuta_token_group_new (ANJUTA_TOKEN_VALUE, $1);
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_VALUE, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+    | space_token {
+        $$ = anjuta_token_new_static (ANJUTA_TOKEN_VALUE, NULL);
+        anjuta_token_merge ($$, $1);
     }
     | value value_token {
-        anjuta_token_group ($$, $2);
+        anjuta_token_merge ($1, $2);
+    }
+    | value space_token {
+        anjuta_token_merge ($1, $2);
     }
     ;     
 
 prerequisite:
+    name_prerequisite
+    ;
+
+name_prerequisite:
     prerequisite_token {
-        $$ = anjuta_token_group_new (mkp_special_prerequisite ($$), $1);
+        $$ = anjuta_token_new_static (mkp_special_prerequisite ($1), NULL);
+        anjuta_token_merge ($$, $1);
     }
-    | prerequisite prerequisite_token {
-        $$ = anjuta_token_group ($1, $2);
-        anjuta_token_set_type ($$, ANJUTA_TOKEN_VALUE);
+    | name_prerequisite prerequisite_token {
+        anjuta_token_merge ($1, $2);
     }
+    | name_prerequisite variable_token
     ;     
 
+equal_group:
+	EQUAL {
+        $$ = anjuta_token_new_static (MK_TOKEN_EQUAL, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+	| IMMEDIATE_EQUAL {
+        $$ = anjuta_token_new_static (MK_TOKEN_IMMEDIATE_EQUAL, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+	| CONDITIONAL_EQUAL {
+        $$ = anjuta_token_new_static (MK_TOKEN_CONDITIONAL_EQUAL, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+	| APPEND {
+        $$ = anjuta_token_new_static (MK_TOKEN_APPEND, NULL);
+        anjuta_token_merge ($$, $1);
+    }
+	;
+
+
 /* Tokens
  *----------------------------------------------------------------------------*/
-		
+	
 not_eol_token:
     word_token
     | space_token
@@ -306,6 +421,7 @@ prerequisite_token:
 
 command_token:
     name_token
+    | variable_token
     | equal_token
     | rule_token
     | depend_token
@@ -314,6 +430,7 @@ command_token:
 
 value_token:
     name_token
+    | variable_token
     | equal_token
     | rule_token
     | depend_token
@@ -324,11 +441,14 @@ head_token:
     | depend_token
     ;
 
-name_token:
+variable_token:
 	VARIABLE {
-        anjuta_token_set_type ($$, MK_TOKEN_VARIABLE);
+        mkp_scanner_parse_variable (scanner, $$);
     }
-	| NAME
+    ;
+
+name_token:
+	NAME
 	| CHARACTER
     | COMMA
     | ORDER
@@ -391,114 +511,10 @@ space_token:
 	;
 
 equal_token:
-	EQUAL {
-        anjuta_token_set_type ($$, MK_TOKEN_EQUAL);
-    }
-	| IMMEDIATE_EQUAL {
-        anjuta_token_set_type ($$, MK_TOKEN_IMMEDIATE_EQUAL);
-    }
-	| CONDITIONAL_EQUAL {
-        anjuta_token_set_type ($$, MK_TOKEN_CONDITIONAL_EQUAL);
-    }
-	| APPEND {
-        anjuta_token_set_type ($$, MK_TOKEN_APPEND);
-    }
+	EQUAL
+	| IMMEDIATE_EQUAL
+	| CONDITIONAL_EQUAL
+	| APPEND
 	;
 		
 %%
-
-static void
-mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s)
-{
-    gchar *filename;
-
-	g_message ("scanner %p", scanner);
-    filename = mkp_scanner_get_filename ((MkpScanner *)scanner);
-    if (filename == NULL) filename = "?";
-    g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-
-static gint
-mkp_special_prerequisite (AnjutaToken *token)
-{
-    switch (anjuta_token_get_type (token))
-    {
-        case ORDER:
-            return MK_TOKEN_ORDER;
-        default:
-            return ANJUTA_TOKEN_NAME;
-    }
-}
-
-static gint
-mkp_special_target (AnjutaToken *list)
-{
-    AnjutaToken *arg;
-
-    for (arg = anjuta_token_list_first (list); arg != NULL; arg = anjuta_token_list_next (arg))
-    {
-        AnjutaToken *child = anjuta_token_next_child (arg);
-
-        if ((child != NULL) && (anjuta_token_next_sibling (child) == NULL))
-        {
-            gint mk_token = 0;
-
-            switch (anjuta_token_get_type (child))
-            {
-            case _PHONY:
-                mk_token = MK_TOKEN__PHONY;
-                break;
-            case _SUFFIXES:
-                mk_token = MK_TOKEN__SUFFIXES;
-                break;
-            case _DEFAULT:
-                mk_token = MK_TOKEN__DEFAULT;
-                break;
-            case _PRECIOUS:
-                mk_token = MK_TOKEN__PRECIOUS;
-                break;
-            case _INTERMEDIATE:
-                mk_token = MK_TOKEN__INTERMEDIATE;
-                break;
-            case _SECONDARY:
-                mk_token = MK_TOKEN__SECONDARY;
-                break;
-            case _SECONDEXPANSION:
-                mk_token = MK_TOKEN__SECONDEXPANSION;
-                break;
-            case _DELETE_ON_ERROR:
-                mk_token = MK_TOKEN__DELETE_ON_ERROR;
-                break;
-            case _IGNORE:
-                mk_token = MK_TOKEN__IGNORE;
-                break;
-            case _LOW_RESOLUTION_TIME:
-                mk_token = MK_TOKEN__LOW_RESOLUTION_TIME;
-                break;
-            case _SILENT:
-                mk_token = MK_TOKEN__SILENT;
-                break;
-            case _EXPORT_ALL_VARIABLES:
-                mk_token = MK_TOKEN__EXPORT_ALL_VARIABLES;
-                break;
-            case _NOTPARALLEL:
-                mk_token = MK_TOKEN__NOTPARALLEL;
-                break;
-            case ORDER:
-                mk_token = MK_TOKEN_ORDER;
-                break;
-            default:
-                break;
-            }
-        
-            if (mk_token)
-            {
-                anjuta_token_set_type (arg, mk_token);
-            }
-        }
-    }
-}
-     
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/mk-project/mk-project.c b/plugins/mk-project/mk-project.c
index d3e48cc..d0d9c9d 100644
--- a/plugins/mk-project/mk-project.c
+++ b/plugins/mk-project/mk-project.c
@@ -25,6 +25,7 @@
 #endif
 
 #include "mk-project.h"
+#include "mk-rule.h"
 
 #include "mk-project-private.h"
 
@@ -522,7 +523,7 @@ monitors_setup (MkpProject *project)
  */
 
 static void
-mkp_dump_node (GNode *g_node)
+mkp_dump_node (AnjutaProjectNode *g_node)
 {
 	gchar *name = NULL;
 	
@@ -546,8 +547,8 @@ mkp_dump_node (GNode *g_node)
 	g_free (name);
 }
 
-static gboolean 
-foreach_node_destroy (GNode    *g_node,
+static void 
+foreach_node_destroy (AnjutaProjectNode    *g_node,
 		      gpointer  data)
 {
 	switch (MKP_NODE_DATA (g_node)->type) {
@@ -566,21 +567,17 @@ foreach_node_destroy (GNode    *g_node,
 			g_assert_not_reached ();
 			break;
 	}
-	
-
-	return FALSE;
 }
 
 static void
-project_node_destroy (MkpProject *project, GNode *g_node)
+project_node_destroy (MkpProject *project, AnjutaProjectNode *g_node)
 {
 	g_return_if_fail (project != NULL);
 	g_return_if_fail (MKP_IS_PROJECT (project));
 	
 	if (g_node) {
 		/* free each node's data first */
-		g_node_traverse (g_node,
-				 G_POST_ORDER, G_TRAVERSE_ALL, -1,
+		anjuta_project_node_all_foreach (g_node,
 				 foreach_node_destroy, project);
 
 		/* now destroy the tree itself */
@@ -589,79 +586,20 @@ project_node_destroy (MkpProject *project, GNode *g_node)
 }
 
 static void
-find_target (GNode *node, gpointer data)
+find_target (AnjutaProjectTarget *node, gpointer data)
 {
 	if (MKP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
 	{
 		if (strcmp (MKP_TARGET_DATA (node)->base.name, *(gchar **)data) == 0)
 		{
 			/* Find target, return node value in pointer */
-			*(GNode **)data = node;
+			*(AnjutaProjectTarget **)data = node;
 
 			return;
 		}
 	}
 }
 
-static AnjutaToken*
-project_load_rule (MkpProject *project, AnjutaToken *rule, GNode *parent)
-{
-	AnjutaToken *arg;
-	AnjutaToken *prerequisite;
-
-	/* Search for prerequisite */
-	prerequisite = NULL;
-	for (arg = anjuta_token_list_first (rule); arg != NULL; arg = anjuta_token_list_next (arg))
-	{
-		if (anjuta_token_get_type (arg) == MK_TOKEN_PREREQUISITE)
-		{
-			prerequisite = anjuta_token_list_next (arg);
-		}
-	}
-	
-	for (arg = anjuta_token_list_first (rule); arg != NULL; arg = anjuta_token_list_next (arg))
-	{
-		gchar *value;
-		gpointer find;
-		MkpTarget *target;
-
-		value = anjuta_token_evaluate (arg);
-
-		/* Check if target already exists */
-		find = value;
-		g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
-		if ((gchar *)find != value)
-		{
-			/* Find target */
-			target = (MkpTarget *)find;
-		}
-		else
-		{
-			/* Create target */
-			target = mkp_target_new (value, (AnjutaProjectTargetType)&MkpTargetTypes[0]);
-			mkp_target_add_token (target, arg);
-			g_node_append (parent, target);
-		}
-
-		g_free (value);
-
-		/* Add prerequisite */
-		for (arg = prerequisite; arg != NULL; arg = anjuta_token_list_next (arg))
-		{
-			MkpSource *source;
-			GFile *src_file;
-
-			value = anjuta_token_evaluate (arg);
-			src_file = g_file_get_child (project->root_file, value);
-			source = mkp_source_new (src_file);
-			g_object_unref (src_file);
-			g_node_append (target, source);
-		}
-	}
-
-	return NULL;
-}
-
 static void
 remove_make_file (gpointer data, GObject *object, gboolean is_last_ref)
 {
@@ -676,10 +614,9 @@ static MkpGroup*
 project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GError **error)
 {
 	MkpScanner *scanner;
-	AnjutaToken *rule_tok;
 	AnjutaToken *arg;
 	AnjutaTokenFile *tfile;
-	gboolean found;
+	AnjutaToken *parse;
 	gboolean ok;
 	GError *err = NULL;
 
@@ -688,8 +625,10 @@ project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GErro
 	tfile = mkp_group_set_makefile (parent, file);
 	g_hash_table_insert (project->files, g_object_ref (file), g_object_ref (tfile));
 //	g_object_add_toggle_ref (G_OBJECT (project->make_file), remove_make_file, project);
+	arg = anjuta_token_file_load (tfile, NULL);
 	scanner = mkp_scanner_new (project);
-	ok = mkp_scanner_parse (scanner, tfile, &err);
+	parse = mkp_scanner_parse_token (scanner, arg, &err);
+	ok = parse != NULL;
 	mkp_scanner_free (scanner);
 	if (!ok)
 	{
@@ -703,14 +642,6 @@ project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GErro
 
 	/* Load target */
 	mkp_project_enumerate_targets (project, parent);
-	
-	/*rule_tok = anjuta_token_new_static (MK_TOKEN_RULE, NULL);
-	
-	arg = anjuta_token_file_first (tfile);
-	for (found = anjuta_token_match (rule_tok, ANJUTA_SEARCH_INTO, arg, &arg); found; found = anjuta_token_match (rule_tok, ANJUTA_SEARCH_INTO, anjuta_token_next_sibling (arg), &arg))
-	{
-		project_load_rule (project, arg, parent);
-	}*/
 
 	return parent;
 }
@@ -786,7 +717,7 @@ mkp_project_get_source (MkpProject *project, const gchar *id)
 gchar *
 mkp_project_get_node_id (MkpProject *project, const gchar *path)
 {
-	GNode *node = NULL;
+	AnjutaProjectNode *node = NULL;
 
 	if (path != NULL)
 	{
@@ -807,7 +738,7 @@ mkp_project_get_node_id (MkpProject *project, const gchar *path)
 			}
 			else
 			{
-				node = g_node_nth_child (node, child);
+				node = anjuta_project_node_nth_child (node, child);
 			}
 			if (node == NULL)
 			{
@@ -864,6 +795,25 @@ mkp_project_get_target_types (MkpProject *project, GError **error)
 	return types;
 }
 
+gboolean
+mkp_project_get_token_location (MkpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token)
+{
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
+
+	g_hash_table_iter_init (&iter, project->files);
+	while (g_hash_table_iter_next (&iter, &key, &value))
+	{
+		if (anjuta_token_file_get_token_location ((AnjutaTokenFile *)value, location, token))
+		{
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 /* Group access functions
  *---------------------------------------------------------------------------*/
 
@@ -931,7 +881,7 @@ mkp_variable_get_name (MkpVariable *variable)
 }
 
 gchar *
-mkp_variable_evaluate (MkpVariable *variable, AnjutaProjectNode *context)
+mkp_variable_evaluate (MkpVariable *variable, MkpProject *project)
 {
 	return anjuta_token_evaluate (variable->value);
 }
@@ -962,81 +912,82 @@ mkp_variable_free (MkpVariable *variable)
 /* Public functions
  *---------------------------------------------------------------------------*/
 
-static void
-mkp_project_token_evaluate_token (MkpProject *project, AnjutaToken *token, GString *value)
+void
+mkp_project_update_variable (MkpProject *project, AnjutaToken *variable)
 {
-	if ((token != NULL) && (anjuta_token_get_length (token) != 0))
+	AnjutaToken *arg;
+	char *name = NULL;
+	MakeTokenType assign = 0;	
+	AnjutaToken *value = NULL;
+
+	fprintf(stdout, "update variable");
+	anjuta_token_dump (variable);
+	
+	arg = anjuta_token_first_item (variable);
+	name = g_strstrip (anjuta_token_evaluate (arg));
+	arg = anjuta_token_next_item (arg);
+	
+	g_message ("new variable %s", name);
+	switch (anjuta_token_get_type (arg))
+	{
+	case MK_TOKEN_EQUAL:
+	case MK_TOKEN_IMMEDIATE_EQUAL:
+	case MK_TOKEN_CONDITIONAL_EQUAL:
+	case MK_TOKEN_APPEND:
+		assign = anjuta_token_get_type (arg);
+		break;
+	default:
+		break;
+	}
+	
+	value = anjuta_token_next_item (arg);
+
+	if (assign != 0)
 	{
-		gint type = anjuta_token_get_type (token);
-		guint length;
-		const gchar *string;
-		gchar *name;
 		MkpVariable *var;
-		
-		switch (type)
+
+		g_message ("assign %d name %s value %s\n", assign, name, anjuta_token_evaluate (value));
+		var = (MkpVariable *)g_hash_table_lookup (project->variables, name);
+		if (var != NULL)
 		{
-		case ANJUTA_TOKEN_COMMENT:
-		case ANJUTA_TOKEN_OPEN_QUOTE:
-		case ANJUTA_TOKEN_CLOSE_QUOTE:
-		case ANJUTA_TOKEN_ESCAPE:
-			break;
-		case MK_TOKEN_VARIABLE:
-			length = anjuta_token_get_length (token);
-			string = anjuta_token_get_string (token);
-			if (string[1] == '(')
-			{
-				name = g_strndup (string + 2, length - 3);
-			}
-			else
-			{
-				name = g_strndup (string + 1, 1);
-			}
-			var = g_hash_table_lookup (project->variables, name);
-			g_free (name);
-			if (var != NULL)
-			{
-				name = mkp_variable_evaluate (var, NULL);
-				g_string_append (value, name);
-				g_free (name);
-			}
-			break;	
-		default:
-			g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
+			var->assign = assign;
+			var->value = value;
+		}
+		else
+		{
+			var = mkp_variable_new (name, assign, value);
+			g_hash_table_insert (project->variables, var->name, var);
 		}
+
 	}
-}	
 
-static  void
-mkp_project_token_evaluate_child (MkpProject *project, AnjutaToken *token, GString *value)
-{
-	AnjutaToken *child;
+	g_message ("update variable %s", name);
 	
-	mkp_project_token_evaluate_token (project, token, value);
-
-	child = anjuta_token_next_child (token);
-	if (child) mkp_project_token_evaluate_child (project, child, value);
-
-	child = anjuta_token_next_sibling (token);
-	if (child) mkp_project_token_evaluate_child (project, child, value);
+	if (name) g_free (name);
 }
 
-gchar *mkp_project_token_evaluate (MkpProject *project, AnjutaToken *token)
+AnjutaToken*
+mkp_project_get_variable_token (MkpProject *project, AnjutaToken *variable)
 {
-	GString *value = g_string_new (NULL);
-	gchar *str;
-
-	if (token != NULL)
-	{
-		AnjutaToken *child;
+	guint length;
+	const gchar *string;
+	gchar *name;
+	MkpVariable *var;
 		
-		mkp_project_token_evaluate_token (project, token, value);
-
-		child = anjuta_token_next_child (token);
-		if (child != NULL) mkp_project_token_evaluate_child (project, child, value);
+	length = anjuta_token_get_length (variable);
+	string = anjuta_token_get_string (variable);
+	if (string[1] == '(')
+	{
+		name = g_strndup (string + 2, length - 3);
 	}
+	else
+	{
+		name = g_strndup (string + 1, 1);
+	}
+	var = g_hash_table_lookup (project->variables, name);
+	g_free (name);
 
-	str = g_string_free (value, FALSE);
-	return *str == '\0' ? NULL : str; 	
+	return var != NULL ? var->value : NULL;
 }
 
 gboolean
@@ -1057,14 +1008,14 @@ mkp_project_reload (MkpProject *project, GError **error)
 	/* shortcut hash tables */
 	project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 	project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
-	project->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, mkp_variable_free);
+	project->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)mkp_variable_free);
 
 	/* Initialize rules data */
 	mkp_project_init_rules (project);
 	
 	/* Initialize list styles */
-	project->space_list = anjuta_token_style_new (NULL, " ", "\\n", NULL, 0);
-	project->arg_list = anjuta_token_style_new (NULL, ", ", ",\\n ", ")", 0);
+	project->space_list = anjuta_token_style_new (NULL, " ", "\n", NULL, 0);
+	project->arg_list = anjuta_token_style_new (NULL, ", ", ",\n ", ")", 0);
 
 	/* Find make file */
 	for (makefile = valid_makefiles; *makefile != NULL; makefile++)
@@ -1179,72 +1130,6 @@ mkp_project_probe (GFile *directory,
 	return probe ? IANJUTA_PROJECT_PROBE_MAKE_FILES : 0;
 }
 
-void
-mkp_project_update_variable (MkpProject *project, AnjutaToken *variable)
-{
-	AnjutaToken *arg;
-	char *name = NULL;
-	MakeTokenType assign = 0;	
-	AnjutaToken *value = NULL;
-
-	for (arg = anjuta_token_next_child (variable); arg != NULL; arg = anjuta_token_next_sibling (arg))
-	{
-		if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_NAME)
-		{
-			name = g_strstrip (anjuta_token_evaluate (arg));
-			break;
-		}
-	}
-	for (; arg != NULL; arg = anjuta_token_next_sibling (arg))
-	{
-		switch (anjuta_token_get_type (arg))
-		{
-		case MK_TOKEN_EQUAL:
-		case MK_TOKEN_IMMEDIATE_EQUAL:
-		case MK_TOKEN_CONDITIONAL_EQUAL:
-		case MK_TOKEN_APPEND:
-			assign = anjuta_token_get_type (arg);
-			break;
-		default:
-			continue;
-		}
-		break;
-	}
-	for (; arg != NULL; arg = anjuta_token_next_sibling (arg))
-	{
-		if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_VALUE)
-		{
-			value = arg;
-			break;
-		}
-	}
-
-	if (assign != 0)
-	{
-		MkpVariable *var;
-
-		var = (MkpVariable *)g_hash_table_lookup (project->variables, name);
-		if (var != NULL)
-		{
-			var->assign = assign;
-			var->value = value;
-		}
-		else
-		{
-			var = mkp_variable_new (name, assign, value);
-			g_hash_table_insert (project->variables, var->name, var);
-		}
-
-	}
-
-	g_message ("update variable %s", name);
-	
-	if (name) g_free (name);
-}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
 gboolean
 mkp_project_save (MkpProject *project, GError **error)
 {
@@ -1413,7 +1298,7 @@ iproject_iface_init(IAnjutaProjectIface* iface)
 	iface->remove_node = iproject_remove_node;
 }
 
-/* GbfProject implementation
+/* GObject implementation
  *---------------------------------------------------------------------------*/
 
 static void
@@ -1457,4 +1342,3 @@ mkp_project_class_init (MkpProjectClass *klass)
 ANJUTA_TYPE_BEGIN(MkpProject, mkp_project, G_TYPE_OBJECT);
 ANJUTA_TYPE_ADD_INTERFACE(iproject, IANJUTA_TYPE_PROJECT);
 ANJUTA_TYPE_END;
-//GBF_BACKEND_BOILERPLATE (MkpProject, mkp_project);
diff --git a/plugins/mk-project/mk-project.h b/plugins/mk-project/mk-project.h
index 22c2fc0..b1d4b88 100644
--- a/plugins/mk-project/mk-project.h
+++ b/plugins/mk-project/mk-project.h
@@ -27,11 +27,11 @@
 #include <libanjuta/anjuta-project.h>
 #include <libanjuta/anjuta-token.h>
 #include <libanjuta/anjuta-token-file.h>
-#include <libanjuta/anjuta-token-style.h>
+#include <libanjuta/anjuta-token-list.h>
 
 G_BEGIN_DECLS
 
-#define YYSTYPE AnjutaToken*
+//#define YYSTYPE AnjutaToken*
 
 #define MKP_TYPE_PROJECT		(mkp_project_get_type ())
 #define MKP_PROJECT(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), MKP_TYPE_PROJECT, MkpProject))
@@ -78,6 +78,10 @@ void mkp_project_unload (MkpProject *project);
 MkpGroup *mkp_project_get_root (MkpProject *project);
 MkpVariable *mkp_project_get_variable (MkpProject *project, const gchar *name);
 GList *mkp_project_list_variable (MkpProject *project);
+AnjutaToken* mkp_project_get_variable_token (MkpProject *project, AnjutaToken *variable);
+
+void mkp_project_update_variable (MkpProject *project, AnjutaToken *variable);
+void mkp_project_add_rule (MkpProject *project, AnjutaToken *rule);
 
 MkpGroup *mkp_project_get_group (MkpProject *project, const gchar *id);
 MkpTarget *mkp_project_get_target (MkpProject *project, const gchar *id);
@@ -88,6 +92,7 @@ gboolean mkp_project_save (MkpProject *project, GError **error);
 
 gchar * mkp_project_get_uri (MkpProject *project);
 GFile* mkp_project_get_file (MkpProject *project);
+gboolean mkp_project_get_token_location (MkpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token);
 
 MkpGroup* mkp_project_add_group (MkpProject  *project, MkpGroup *parent,	const gchar *name, GError **error);
 void mkp_project_remove_group (MkpProject  *project, MkpGroup *group, GError **error);
@@ -111,9 +116,10 @@ gchar *mkp_target_get_id (MkpTarget *target);
 gchar *mkp_source_get_id (MkpSource *source);
 GFile *mkp_source_get_file (MkpSource *source);
 
-gchar *mkp_variable_evaluate (MkpVariable *variable, AnjutaProjectNode *context);
+gchar *mkp_variable_evaluate (MkpVariable *variable, MkpProject *project);
 const gchar* mkp_variable_get_name (MkpVariable *variable);
 
+
 G_END_DECLS
 
 #endif /* _MK_PROJECT_H_ */
diff --git a/plugins/mk-project/mk-rule.c b/plugins/mk-project/mk-rule.c
index 39422ad..cbad543 100644
--- a/plugins/mk-project/mk-rule.c
+++ b/plugins/mk-project/mk-rule.c
@@ -30,6 +30,7 @@
 #include "mk-scanner.h"
 
 #include <string.h>
+#include <stdio.h>
 
 /* Rule object
  *---------------------------------------------------------------------------*/
@@ -141,22 +142,25 @@ mkp_project_find_source (MkpProject *project, gchar *target, AnjutaProjectGroup
 }
 
 
-/* Public functions
+/* Parser functions
  *---------------------------------------------------------------------------*/
 
 void
-mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
+mkp_project_add_rule (MkpProject *project, AnjutaToken *group)
 {
 	AnjutaToken *targ;
 	AnjutaToken *dep;
 	AnjutaToken *arg;
 	gboolean double_colon = FALSE;
 
-	targ = anjuta_token_list_first (token);
-	arg = anjuta_token_list_next (targ);
+	fprintf(stdout, "add rule\n");
+	anjuta_token_dump (group);
+	
+	targ = anjuta_token_first_item (group);
+	arg = anjuta_token_next_word (targ);
 	if (anjuta_token_get_type (arg) == MK_TOKEN_DOUBLE_COLON) double_colon = TRUE;
-	dep = anjuta_token_list_next (arg);
-	for (arg = anjuta_token_list_first (targ); arg != NULL; arg = anjuta_token_list_next (arg))
+	dep = anjuta_token_next_word (arg);
+	for (arg = anjuta_token_first_word (targ); arg != NULL; arg = anjuta_token_next_word (arg))
 	{
 		AnjutaToken *src;
 		gchar *target;
@@ -167,11 +171,11 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
 		switch (anjuta_token_get_type (arg))
 		{
 		case MK_TOKEN__PHONY:
-			for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+			for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
 			{
 				if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
 				{
-					target = mkp_project_token_evaluate (project, src);
+					target = anjuta_token_evaluate (src);
 					
 					rule = g_hash_table_lookup (project->rules, target);
 					if (rule == NULL)
@@ -187,13 +191,13 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
 			}
 			break;
 		case MK_TOKEN__SUFFIXES:
-			for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+			for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
 			{
 				if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
 				{
 					gchar *suffix;
 
-					suffix = mkp_project_token_evaluate (project, src);
+					suffix = anjuta_token_evaluate (src);
 					/* The pointer value must only be not NULL, it does not matter if it is
 	 				 * invalid */
 					g_hash_table_replace (project->suffix, suffix, suffix);
@@ -221,31 +225,34 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
 			/* Do nothing with these targets, just ignore them */
 			break;
 		default:
-			target = g_strstrip (mkp_project_token_evaluate (project, arg));
+			target = g_strstrip (anjuta_token_evaluate (arg));
 			if (*target == '\0') break;	
 			g_message ("add rule =%s=", target);
-
+				
 			rule = g_hash_table_lookup (project->rules, target);
 			if (rule == NULL)
 			{
-				rule = mkp_rule_new (target, token);
+				rule = mkp_rule_new (target, group);
 				g_hash_table_insert (project->rules, rule->name, rule);
 			}
 			else
 			{
-				rule->rule = arg;
+				rule->rule = group;
 			}
 				
-			for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+			for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
 			{
-				gchar *src_name = mkp_project_token_evaluate (project, src);
-				
-				g_message ("    with source %s", src_name);
-				if (anjuta_token_get_type (src) == MK_TOKEN_ORDER)
+				gchar *src_name = anjuta_token_evaluate (src);
+
+				if (src_name != NULL)
 				{
-					order = TRUE;
+					g_message ("    with source %s", src_name);
+					if (anjuta_token_get_type (src) == MK_TOKEN_ORDER)
+					{
+						order = TRUE;
+					}
+					rule->prerequisite = g_list_prepend (rule->prerequisite, src_name);
 				}
-				rule->prerequisite = g_list_prepend (rule->prerequisite, src_name);
 			}
 
 			if (target != NULL) g_free (target);
@@ -253,6 +260,9 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
 	}
 }
 
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
 void
 mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent)
 {
@@ -317,35 +327,33 @@ mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent)
 		/* Create target */
 		target = mkp_target_new (rule->name, NULL);
 		mkp_target_add_token (target, rule->rule);
-		g_node_append (parent, target);
+		anjuta_project_node_append (parent, target);
 
-		/* Search for prerequisite */
-		prerequisite = NULL;
-		for (arg = anjuta_token_list_first (rule->rule); arg != NULL; arg = anjuta_token_list_next (arg))
-		{
-			if (anjuta_token_get_type (arg) == MK_TOKEN_PREREQUISITE)
-			{
-				prerequisite = arg;
-				break;
-			}
-		}
+		/* Get prerequisite */
+		prerequisite = anjuta_token_first_word (rule->rule);
+		if (prerequisite != NULL) prerequisite = anjuta_token_next_word (prerequisite);
+		if (prerequisite != NULL) prerequisite = anjuta_token_next_word (prerequisite);
 		
 		/* Add prerequisite */
-		for (arg = anjuta_token_list_first (prerequisite); arg != NULL; arg = anjuta_token_list_next (arg))
+		for (arg = anjuta_token_first_word (prerequisite); arg != NULL; arg = anjuta_token_next_word (arg))
 		{
 			MkpSource *source;
 			GFile *src_file;
 			gchar *name;
 
-			name = g_strstrip (mkp_project_token_evaluate (project, arg));
-			name = mkp_project_find_source (project, name, parent, 0);
+			name = anjuta_token_evaluate (arg);
+			if (name != NULL)
+			{
+				name = g_strstrip (name);
+				name = mkp_project_find_source (project, name, parent, 0);
+			}
 
 			if (name != NULL)
 			{
 				src_file = g_file_get_child (project->root_file, name);
 				source = mkp_source_new (src_file);
 				g_object_unref (src_file);
-				g_node_append (target, source);
+				anjuta_project_node_append (target, source);
 
 				g_free (name);
 			}
diff --git a/plugins/mk-project/mk-rule.h b/plugins/mk-project/mk-rule.h
index e02db66..88a29cd 100644
--- a/plugins/mk-project/mk-rule.h
+++ b/plugins/mk-project/mk-rule.h
@@ -31,7 +31,9 @@ G_BEGIN_DECLS
 
 void mkp_project_init_rules (MkpProject *project);
 void mkp_project_free_rules (MkpProject *project);
-void mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent);
+void mkp_project_enumerate_targets (MkpProject *project, MkpGroup *parent);
+void mkp_project_add_rule (MkpProject *project, AnjutaToken *group);
+
 
 G_END_DECLS
 
diff --git a/plugins/mk-project/mk-scanner.h b/plugins/mk-project/mk-scanner.h
index dd5ec57..83d64bc 100644
--- a/plugins/mk-project/mk-scanner.h
+++ b/plugins/mk-project/mk-scanner.h
@@ -20,32 +20,34 @@
 #ifndef _MK_SCANNER_H_
 #define _MK_SCANNER_H_
 
+#include "mk-project.h"
+
 #include "libanjuta/anjuta-token.h"
 #include "libanjuta/anjuta-token-file.h"
-#include "libanjuta/anjuta-token-style.h"
+#include "libanjuta/anjuta-token-list.h"
 
 #include <glib.h>
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
+/* Token location is found directly from token value. We don't maintain a 
+ * independent position. */
+#define YYLTYPE AnjutaToken*
 #define YYSTYPE AnjutaToken*
 
-#ifndef _MK_PROJECT_H_
-typedef struct _MkpProject        MkpProject;
-#endif
-
 typedef struct _MkpScanner MkpScanner;
 
 MkpScanner *mkp_scanner_new (MkpProject *project);
 void mkp_scanner_free (MkpScanner *scanner);
 
-gboolean mkp_scanner_parse (MkpScanner *scanner, AnjutaTokenFile *file, GError **error);
+AnjutaToken *mkp_scanner_parse_token (MkpScanner *scanner, AnjutaToken *token, GError **error);
 
 void mkp_scanner_update_variable (MkpScanner *scanner, AnjutaToken *variable);
+void mkp_scanner_parse_variable (MkpScanner *scanner, AnjutaToken *variable);
 void mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule);
 
-const gchar* mkp_scanner_get_filename (MkpScanner *scanner);
+void mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s);
 
 typedef enum
 {
@@ -58,6 +60,8 @@ typedef enum
 	MK_TOKEN_PREREQUISITE,
 	MK_TOKEN_ORDER_PREREQUISITE,
 	MK_TOKEN_ORDER,
+	MK_TOKEN_COMMAND,
+	MK_TOKEN_COMMANDS,
 	MK_TOKEN_COLON,
 	MK_TOKEN_DOUBLE_COLON,
 	MK_TOKEN_VARIABLE,
diff --git a/plugins/mk-project/mk-scanner.l b/plugins/mk-project/mk-scanner.l
index 972069d..03ff3d3 100644
--- a/plugins/mk-project/mk-scanner.l
+++ b/plugins/mk-project/mk-scanner.l
@@ -19,49 +19,44 @@
  
 %{
 
-#include <stdlib.h>
-#include <string.h>
 #include "mk-scanner.h"
 #include "mk-parser.h"
+#include "mk-rule.h"
 
 #include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
 
+#include <stdlib.h>
+#include <string.h>
 
-/* Eliminate warning */
-#define YY_NO_UNPUT 1 
-
-#define YY_INPUT(buf,result,the_max_size) \
-    result = 0;
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
 
-#define YY_USER_ACTION mkp_update_location(yylloc, yytext, yyleng);
-    
 #define YY_EXTRA_TYPE  MkpScanner*
 
 //#define YY_USER_INIT {yy_flex_debug = 1;}
- 
-static AnjutaToken* mkp_scanner_append_token (MkpScanner *scanner, gint token);
-static gint mkp_scanner_last_token (MkpScanner *scanner);
-static gint mkp_scanner_last_flags (MkpScanner *scanner);
-static void mkp_scanner_update_line_width (MkpScanner *scanner, YYLTYPE *loc);
-static void mkp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static int mkp_parse (yyscan_t scanner);
-
-void mkp_project_update_variable (MkpProject *project, AnjutaToken *variable);
-void mkp_project_add_rule (MkpProject *project, AnjutaToken *rule);
 
+static gint mkp_scanner_parse_end (MkpScanner *scanner);
 
-#define RETURN(tok) *yylval = mkp_scanner_append_token (yyextra, tok); \
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
                     return tok
 
+struct _MkpScanner
+{
+    yyscan_t scanner;
+
+    AnjutaTokenStream *stream;
+
+    MkpProject *project;
+};
+
 %}
 
-%option reentrant stack noyywrap yylineno
+%option reentrant noyywrap yylineno
 
-%option prefix="mkp_mk_yy"
+/* Remove some warnings */
+%option nounput noinput
 
-/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
- * not "lex.mkp_yy.c" 
-%option outfile="lex.yy.c"*/
+%option prefix="mkp_mk_yy"
 
 %option bison-bridge bison-locations
 
@@ -146,42 +141,48 @@ NAME          [^ \t\n\r:#=$"'`&@\\]*
 
 .                           { RETURN (CHARACTER); }
 
-%%
-     
-struct _MkpScanner
-{
-    const gchar *pos;
-    yyscan_t scanner;
-    YY_BUFFER_STATE	 buffer;
-
-    AnjutaTokenFile *file;
-    gchar *filename;
+<<EOF>>                     { if (mkp_scanner_parse_end (yyextra) == YY_NULL) return YY_NULL; }
 
-    MkpProject *project;
 
-	guint line_width;
-};
+%%
 
 /* Private functions
  *---------------------------------------------------------------------------*/
 
-static AnjutaToken*
-mkp_scanner_append_token (MkpScanner *scanner, gint token)
+static gint
+mkp_scanner_parse_end (MkpScanner *scanner)
 {
-    AnjutaToken *frag;
-            
-    frag = anjuta_token_new_fragment (token, scanner->pos, yyget_leng (scanner->scanner));
-	anjuta_token_file_append (scanner->file, frag);
-    scanner->pos += yyget_leng (scanner->scanner);
-	//anjuta_token_old_dump (frag);
-    
-    return frag;
+    yypop_buffer_state(scanner->scanner);
+    scanner->stream = anjuta_token_stream_pop (scanner->stream);
+
+    if (scanner->stream == NULL)
+    {
+        yyterminate();
+    }
+    else
+    {
+        return 1;
+    }
 }
 
-static void
-mkp_scanner_update_line_width (MkpScanner *scanner, YYLTYPE *loc)
+/* Parser functions
+ *---------------------------------------------------------------------------*/
+
+void
+mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s)
 {
-	anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+    AnjutaTokenFileLocation location;
+
+    //g_message ("error at %d  error at * %d string \"%s\"", anjuta_token_get_type((AnjutaToken *)loc), anjuta_token_get_type(*loc), anjuta_token_get_string ((AnjutaToken *loc));
+    if (mkp_project_get_token_location (scanner->project, &location, *loc))
+    {
+        g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+        g_free (location.filename);
+    }
+    else
+    {
+        g_message ("%s \n", s);
+    }
 }
 
 void
@@ -196,71 +197,74 @@ mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule)
     mkp_project_add_rule (scanner->project, rule);
 }
 
-static void
-mkp_update_location (YYLTYPE *loc, const gchar *text, gint length)
+void
+mkp_scanner_parse_variable (MkpScanner *scanner, AnjutaToken *variable)
 {
-	const gchar *ptr;
-	const gchar *end = text + length;
-
-    loc->first_line = loc->last_line;
-    loc->first_column = loc->last_column + 1;
-
-	for (ptr = text; ptr != end; ptr++)
-	{
-		if (*ptr == '\n')
-		{
-			loc->last_column = 0;
-			loc->last_line++;
-			length -= (ptr + 1 - text);
-		}
-	}
-
-	loc->last_column += length;
+    AnjutaToken *group;
+    AnjutaToken *content;
+
+    anjuta_token_set_type (variable, ANJUTA_TOKEN_VARIABLE);
+    content = anjuta_token_new_static (ANJUTA_TOKEN_CONTENT, NULL);
+    anjuta_token_stream_append_token (scanner->stream, content);
+
+    group = mkp_project_get_variable_token (scanner->project, variable);
+    fprintf(stdout, "get variable %s is %p\n", anjuta_token_evaluate (variable), group);
+    if (group != NULL)
+    {
+        //AnjutaToken *token;
+
+        //anjuta_token_dump (group);
+        //token = anjuta_token_group_into_token (group);
+        //anjuta_token_set_type (token, ANJUTA_TOKEN_CONTENT);
+        //anjuta_token_dump (token);
+        fprintf (stdout,"variable %s\n", anjuta_token_get_string (variable));
+        anjuta_token_dump (group);
+        mkp_scanner_parse_token (scanner, group, NULL);
+        //anjuta_token_free (token);
+    }
 }
 
 /* Public functions
  *---------------------------------------------------------------------------*/
 
-int
-mkp_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,MkpScanner *scanner)
+AnjutaToken *
+mkp_scanner_parse_token (MkpScanner *scanner, AnjutaToken *token, GError **error)
 {
-    return mkp_mk_yylex (yylval_param, yylloc_param, scanner->scanner);
+    AnjutaToken *first;
+    AnjutaTokenStream *stream;
+
+    stream = anjuta_token_stream_push (scanner->stream, token);
+    first = anjuta_token_stream_get_root (stream);
+
+    if (scanner->stream != NULL)
+    {
+        /* Parse an included file or a expanded variable */
+
+        scanner->stream = stream;
+        yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+    }
+    else
+    {
+        mkp_yypstate *ps;
+        gint status;
+
+        scanner->stream = stream;
+        ps = mkp_yypstate_new ();
+        do
+        {
+	        YYSTYPE yylval_param;
+    	    YYLTYPE yylloc_param;
+            gint yychar = mkp_mk_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+        
+            yylloc_param = yylval_param;
+            status = mkp_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
+        } while (status == YYPUSH_MORE);
+        mkp_yypstate_delete (ps);
+    }
+
+    return first;
 }
 
-
-gboolean
-mkp_scanner_parse (MkpScanner *scanner, AnjutaTokenFile *file, GError **error)
-{
-    if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
-
-	scanner->file = file;
-	if (scanner->file== NULL) return FALSE;
-
-    scanner->pos = anjuta_token_file_get_content (scanner->file, error);
-	if (scanner->pos == NULL) return FALSE;
-
-    scanner->buffer = yy_scan_string (scanner->pos, scanner->scanner);
-	
-	return mkp_yyparse (scanner) == 0;
-}
-
-guint
-mkp_scanner_get_line_width (MkpScanner *scanner)
-{
-	return scanner->line_width;
-}
-
-const gchar*
-mkp_scanner_get_filename (MkpScanner *scanner)
-{
-	g_free (scanner->filename);
-    scanner->filename = NULL;
-    if (scanner->file) scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
-	
-	return scanner->filename;
-}
-
-
 /* Constructor & Destructor
  *---------------------------------------------------------------------------*/
 
@@ -284,11 +288,7 @@ mkp_scanner_free (MkpScanner *scanner)
 {
 	g_return_if_fail (scanner != NULL);
 
-    if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
     yylex_destroy(scanner->scanner);
 
-	g_free (scanner->filename);
-	scanner->filename = NULL;
-
 	g_free (scanner);
 }
diff --git a/plugins/project-manager/gbf-project-model.c b/plugins/project-manager/gbf-project-model.c
index d9ede16..6b6569a 100644
--- a/plugins/project-manager/gbf-project-model.c
+++ b/plugins/project-manager/gbf-project-model.c
@@ -486,7 +486,7 @@ update_target (GbfProjectModel *model, AnjutaProjectTarget *target, GtkTreeIter
 		return;
 	
 	/* update target data here */
-	sources = anjuta_project_node_all_child (target, ANJUTA_PROJECT_SOURCE);
+	sources = gbf_project_util_all_child (target, ANJUTA_PROJECT_SOURCE);
 	
 	/* walk the tree target */
 	if (gtk_tree_model_iter_children (tree_model, &child, iter)) {
@@ -572,8 +572,8 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
 	tree_model = GTK_TREE_MODEL (model);
 	
 	/* update group data. nothing to do here */
-	groups = anjuta_project_node_all_child (group, ANJUTA_PROJECT_GROUP);
-	targets = anjuta_project_node_all_child (group, ANJUTA_PROJECT_TARGET);
+	groups = gbf_project_util_all_child (group, ANJUTA_PROJECT_GROUP);
+	targets = gbf_project_util_all_child (group, ANJUTA_PROJECT_TARGET);
 
 	/* walk the tree group */
 	/* group can be NULL, but we iterate anyway to remove any
diff --git a/plugins/project-manager/gbf-project-util.c b/plugins/project-manager/gbf-project-util.c
index 8cb178b..651b68a 100644
--- a/plugins/project-manager/gbf-project-util.c
+++ b/plugins/project-manager/gbf-project-util.c
@@ -794,3 +794,49 @@ gbf_project_util_add_source_multi (GbfProjectModel     *model,
     g_object_unref (gui);
     return new_sources;
 }
+
+GList *
+gbf_project_util_all_child (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+{
+    AnjutaProjectNode *node;
+    GList *list = NULL;
+ 
+    for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
+    {
+        if (anjuta_project_node_get_type (node) == type)
+        {
+            list = g_list_prepend (list, node);
+        }
+    }
+ 
+    list = g_list_reverse (list);
+ 
+    return list;
+}
+ 
+GList *
+gbf_project_util_node_all (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+{
+    AnjutaProjectNode *node;
+    GList *list = NULL;
+ 
+    for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
+    {
+        if (anjuta_project_node_get_type (node) == type)
+        {
+            list = g_list_prepend (list, node);
+        }
+        if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_GROUP)
+        {
+            GList *child_list;
+ 
+            child_list = gbf_project_util_node_all (node, type);
+            child_list = g_list_reverse (child_list);
+            list = g_list_concat (child_list, list);
+        }
+    }
+ 
+    list = g_list_reverse (list);
+ 
+    return list;
+}
diff --git a/plugins/project-manager/gbf-project-util.h b/plugins/project-manager/gbf-project-util.h
index 55f6a77..602f13a 100644
--- a/plugins/project-manager/gbf-project-util.h
+++ b/plugins/project-manager/gbf-project-util.h
@@ -52,7 +52,13 @@ GList* gbf_project_util_add_source_multi (GbfProjectModel   *model,
 				        AnjutaProjectGroup  *default_group,
 				        GList               *uris_to_add);
 				    
-				    
+
+GList * gbf_project_util_all_child (AnjutaProjectNode *parent,
+                                        AnjutaProjectNodeType type);
+
+GList * gbf_project_util_node_all (AnjutaProjectNode *parent,
+                                        AnjutaProjectNodeType type);
+
 				    
 G_END_DECLS
 
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 0ccb9cc..8360ec5 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1928,7 +1928,7 @@ iproject_manager_get_elements (IAnjutaProjectManager *project_manager,
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 
-	return anjuta_project_node_all (ianjuta_project_get_root (plugin->project, NULL), element_type); 
+	return gbf_project_util_node_all (ianjuta_project_get_root (plugin->project, NULL), element_type); 
 }
 
 static AnjutaProjectTargetClass
@@ -1977,7 +1977,7 @@ iproject_manager_get_targets (IAnjutaProjectManager *project_manager,
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 
 	/* Get all targets */
-	targets = anjuta_project_node_all (ianjuta_project_get_root (plugin->project, NULL), ANJUTA_PROJECT_TARGET);
+	targets = gbf_project_util_node_all (ianjuta_project_get_root (plugin->project, NULL), ANJUTA_PROJECT_TARGET);
 
 	/* Remove all targets not in specified class */
 	for (node = g_list_first (targets); node != NULL;)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]