[anjuta/newproject] Add new IAnjutaProject interface and replace autotools and makefile plugins



commit 6716d853f0e934239cda1f01b28821a2de31c3c8
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sat Oct 10 21:41:50 2009 +0200

    Add new IAnjutaProject interface and replace autotools and makefile plugins

 configure.in                                       |   43 +-
 libanjuta/Makefile.am                              |   14 +-
 libanjuta/anjuta-project.c                         |  179 +
 libanjuta/anjuta-project.h                         |  113 +
 libanjuta/anjuta-token-file.c                      |  368 ++
 libanjuta/anjuta-token-file.h                      |   60 +
 libanjuta/anjuta-token-style.c                     |  491 +++
 libanjuta/anjuta-token-style.h                     |   47 +
 libanjuta/anjuta-token.c                           |  648 ++++
 libanjuta/anjuta-token.h                           |  162 +
 libanjuta/interfaces/libanjuta.idl                 |  254 ++-
 libanjuta/libanjuta.h                              |    2 +
 manuals/reference/libanjuta/libanjuta-sections.txt |    7 -
 manuals/reference/libanjuta/libanjuta.types        |    3 -
 plugins/Makefile.am                                |    6 +-
 plugins/am-project/Makefile.am                     |   95 +
 plugins/am-project/ac-parser.y                     |  528 +++
 plugins/am-project/ac-scanner.h                    |   64 +
 plugins/am-project/ac-scanner.l                    |  443 +++
 plugins/am-project/ac-writer.c                     |  146 +
 plugins/am-project/ac-writer.h                     |   36 +
 plugins/am-project/am-dialogs.c                    |  159 +
 plugins/am-project/am-dialogs.h                    |   37 +
 plugins/am-project/am-parser.y                     |  320 ++
 .../am-project-plugin-48.png}                      |  Bin 866 -> 866 bytes
 plugins/am-project/am-project-private.h            |   72 +
 plugins/am-project/am-project.c                    | 2737 ++++++++++++++
 plugins/am-project/am-project.h                    |  127 +
 .../am-project.plugin.in}                          |    2 +-
 plugins/am-project/am-project.ui                   |  419 +++
 plugins/am-project/am-scanner.h                    |   60 +
 plugins/am-project/am-scanner.l                    |  377 ++
 plugins/{gbf-am => am-project}/plugin.c            |   38 +-
 plugins/{gbf-mkfile => am-project}/plugin.h        |   26 +-
 plugins/build-basic-autotools/executer.c           |    4 +-
 plugins/class-gen/plugin.c                         |    6 +-
 plugins/debug-manager/start.c                      |    9 +-
 plugins/file-wizard/file.c                         |    7 +-
 plugins/gbf-am/GBF/AmFiles.pm                      | 1647 ---------
 plugins/gbf-am/GBF/Makefile.am                     |    6 -
 plugins/gbf-am/Makefile.am                         |   83 -
 plugins/gbf-am/gbf-am-config.c                     |  385 --
 plugins/gbf-am/gbf-am-config.h                     |   86 -
 plugins/gbf-am/gbf-am-dialogs.ui                   |  419 ---
 plugins/gbf-am/gbf-am-parse.in                     | 2615 --------------
 plugins/gbf-am/gbf-am-project.c                    | 3781 --------------------
 plugins/gbf-am/gbf-am-project.h                    |  131 -
 plugins/gbf-am/gbf-am-properties.c                 | 1595 ---------
 plugins/gbf-am/gbf-am-properties.h                 |   38 -
 plugins/gbf-am/output.dtd                          |   39 -
 plugins/gbf-am/program.xpm                         |   56 -
 plugins/gbf-am/run-test.sh                         |   82 -
 plugins/gbf-am/shared.xpm                          |   70 -
 plugins/gbf-am/static.xpm                          |   57 -
 plugins/gbf-am/test.c                              |  218 --
 plugins/gbf-am/unknown.xpm                         |  119 -
 plugins/gbf-mkfile/GBF/General.pm                  |  119 -
 plugins/gbf-mkfile/GBF/Make.pm                     | 1321 -------
 plugins/gbf-mkfile/GBF/Makefile.am                 |    6 -
 plugins/gbf-mkfile/gbf-mkfile-config.c             |  351 --
 plugins/gbf-mkfile/gbf-mkfile-config.h             |   89 -
 plugins/gbf-mkfile/gbf-mkfile-parse.in             | 1797 ----------
 plugins/gbf-mkfile/gbf-mkfile-project.c            | 3523 ------------------
 plugins/gbf-mkfile/gbf-mkfile-project.h            |  135 -
 plugins/gbf-mkfile/gbf-mkfile-properties.c         |  428 ---
 plugins/gbf-mkfile/gbf-mkfile-properties.h         |   42 -
 plugins/glade/plugin.c                             |    5 +-
 plugins/{gbf-mkfile => mk-project}/Makefile.am     |   52 +-
 plugins/mk-project/mk-parser.y                     |  504 +++
 .../mk-project-plugin-48.png}                      |  Bin 866 -> 866 bytes
 plugins/mk-project/mk-project-private.h            |   89 +
 plugins/mk-project/mk-project.c                    | 1460 ++++++++
 plugins/mk-project/mk-project.h                    |  119 +
 .../mk-project.plugin.in}                          |    4 +-
 plugins/mk-project/mk-project.ui                   |  419 +++
 plugins/mk-project/mk-rule.c                       |  372 ++
 plugins/mk-project/mk-rule.h                       |   38 +
 plugins/mk-project/mk-scanner.h                    |   81 +
 plugins/mk-project/mk-scanner.l                    |  294 ++
 plugins/{gbf-mkfile => mk-project}/plugin.c        |   39 +-
 plugins/{gbf-am => mk-project}/plugin.h            |   26 +-
 plugins/project-manager/gbf-project-model.c        |  196 +-
 plugins/project-manager/gbf-project-model.h        |   21 +-
 plugins/project-manager/gbf-project-util.c         |  128 +-
 plugins/project-manager/gbf-project-util.h         |   43 +-
 plugins/project-manager/gbf-project-view.c         |    8 +-
 plugins/project-manager/gbf-project-view.h         |    9 +-
 plugins/project-manager/gbf-tree-data.c            |   69 +-
 plugins/project-manager/gbf-tree-data.h            |   33 +-
 plugins/project-manager/plugin.c                   |  688 ++--
 plugins/project-manager/plugin.h                   |    5 +-
 plugins/run-program/parameters.c                   |    2 +-
 plugins/search/search-replace_backend.c            |    2 +-
 plugins/symbol-db/plugin.c                         |    4 +-
 94 files changed, 11999 insertions(+), 20058 deletions(-)
---
diff --git a/configure.in b/configure.in
index 95e1de5..4ee8dd3 100644
--- a/configure.in
+++ b/configure.in
@@ -71,6 +71,14 @@ GNOME_DOC_INIT
 #Check for C Compiler
 AC_PROG_CC
 AC_PROG_CPP
+AC_PROG_LEX
+if [["$LEX" != "flex"]]; then
+	AC_MSG_ERROR(flex is required)
+fi
+AC_PROG_YACC
+if [["$YACC" != "bison"]]; then
+	AC_MSG_ERROR(bison is required)
+fi
 AC_LANG_C
 AM_PROG_CC_C_O
 
@@ -153,29 +161,6 @@ if test x$AUTOGEN_PATH = xno; then
    AC_MSG_ERROR([Couldn't find autogen, please install the autogen package. You can get it from http://autogen.sourceforge.net/])
 fi
 
-dnl Check for perl required by gbf-am/mkfile
-dnl ----------------------------------------
-# Automake backend requirements
-# Also needed by Makefile backend
-AC_PATH_PROG(PERL, perl)
-if test -z "$PERL"; then
-   AC_MSG_ERROR([perl not found])
-fi
-$PERL -e 'require 5.005;' || {
-   AC_MSG_ERROR([perl 5.005 or better is required])
-}
-
-# Check for perl Locale::gettext module
-if test "x$PERL" != x; then
-        AC_MSG_CHECKING(for perl module Locale::gettext)
-        $PERL "-MLocale::gettext" -e exit > /dev/null 2>&1
-        if test $? -ne 0; then
-                AC_MSG_ERROR([not found, you should installed perl-gettext package for your distribution]);
-        else
-        AC_MSG_RESULT(ok);
-        fi
-fi
-
 dnl Check for Devhelp
 dnl -----------------
 
@@ -309,6 +294,8 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
 AM_GLIB_GNU_GETTEXT
 IT_PROG_INTLTOOL([0.40.1])
 
+BISON_I18N
+
 dnl ***************************************************************************
 dnl Check for gtk-doc.
 dnl ***************************************************************************
@@ -747,12 +734,6 @@ plugins/file-wizard/Makefile
 plugins/terminal/Makefile
 plugins/build-basic-autotools/Makefile
 plugins/project-manager/Makefile
-plugins/gbf-am/Makefile
-plugins/gbf-am/gbf-am-parse
-plugins/gbf-am/GBF/Makefile
-plugins/gbf-mkfile/Makefile
-plugins/gbf-mkfile/gbf-mkfile-parse
-plugins/gbf-mkfile/GBF/Makefile
 plugins/symbol-db/benchmark/Makefile
 plugins/symbol-db/images/Makefile
 plugins/symbol-db/Makefile
@@ -816,6 +797,8 @@ plugins/project-wizard/templates/library/Makefile
 plugins/project-wizard/templates/library/src/Makefile
 plugins/project-wizard/templates/library/po/Makefile
 plugins/project-wizard/templates/m4/Makefile
+plugins/am-project/Makefile
+plugins/mk-project/Makefile
 plugins/language-support-cpp-java/Makefile
 plugins/run-program/Makefile
 plugins/starter/Makefile
@@ -829,8 +812,6 @@ manuals/anjuta-faqs/Makefile
 manuals/anjuta-build-tutorial/Makefile
 mime/Makefile
 ])
-chmod +x ${ac_top_build_dir}plugins/gbf-am/gbf-am-parse
-chmod +x ${ac_top_build_dir}plugins/gbf-mkfile/gbf-mkfile-parse
 echo " "
 echo "-------------------------------------------------------------------"
 echo "Conditionally built plugins:"
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index 5251aee..c280c92 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -81,7 +81,15 @@ libanjuta_la_SOURCES= \
 	gbf-project.c \
 	gbf-project.h \
 	anjuta-command-queue.c \
-	anjuta-command-queue.h
+	anjuta-command-queue.h \
+	anjuta-token.c \
+	anjuta-token.h \
+	anjuta-token-style.c \
+	anjuta-token-style.h \
+	anjuta-token-file.c \
+	anjuta-token-file.h \
+	anjuta-project.h \
+	anjuta-project.c
 
 if HAVE_PLUGIN_GLADE
 
@@ -140,7 +148,9 @@ libanjuta_include = \
 	anjuta-sync-command.h \
 	anjuta-version.h \
 	gbf-project.h \
-	anjuta-command-queue.h
+	anjuta-command-queue.h \
+	anjuta-project.h \
+	anjuta-token.h
 
 libanjutainclude_HEADERS = \
 	$(libanjuta_include) \
diff --git a/libanjuta/anjuta-project.c b/libanjuta/anjuta-project.c
new file mode 100644
index 0000000..75ea98b
--- /dev/null
+++ b/libanjuta/anjuta-project.c
@@ -0,0 +1,179 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-project.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-project.h"
+
+#include "anjuta-debug.h"
+
+/* 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)
+#define TARGET_DATA(node)  ((node) != NULL ? (AnjutaProjectTargetData *)((node)->data) : NULL)
+#define SOURCE_DATA(node)  ((node) != NULL ? (AnjutaProjectSourceData *)((node)->data) : NULL)
+
+
+/* Node access functions
+ *---------------------------------------------------------------------------*/
+
+AnjutaProjectNode *
+anjuta_project_node_parent(AnjutaProjectNode *node)
+{
+	return node->parent;
+}
+
+AnjutaProjectNode *
+anjuta_project_node_first_child(AnjutaProjectNode *node)
+{
+	return g_node_first_child (node);
+}
+
+AnjutaProjectNode *
+anjuta_project_node_last_child(AnjutaProjectNode *node)
+{
+	return g_node_last_child (node);
+}
+
+AnjutaProjectNode *
+anjuta_project_node_next_sibling (AnjutaProjectNode *node)
+{
+	return g_node_next_sibling (node);
+}
+
+AnjutaProjectNode *
+anjuta_project_node_prev_sibling (AnjutaProjectNode *node)
+{
+	return g_node_prev_sibling (node);
+}
+
+AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint n)
+{
+	return g_node_nth_child (node, n);
+}
+
+GList *
+anjuta_project_node_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 *
+anjuta_project_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 = anjuta_project_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;
+}
+
+void
+anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
+{
+	g_node_traverse (node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, func, data);
+}
+
+AnjutaProjectNodeType
+anjuta_project_node_get_type (const AnjutaProjectNode *node)
+{
+	return NODE_DATA (node)->type;
+}
+
+/* Group access functions
+ *---------------------------------------------------------------------------*/
+
+GFile*
+anjuta_project_group_get_directory (const AnjutaProjectGroup *group)
+{
+	return GROUP_DATA (group)->directory;
+}
+
+/* Target access functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+anjuta_project_target_get_name (const AnjutaProjectTarget *target)
+{
+	return TARGET_DATA (target)->name;
+}
+
+AnjutaProjectTargetType
+anjuta_project_target_get_type (const AnjutaProjectTarget *target)
+{
+	return TARGET_DATA (target)->type;
+}
+
+/* Source access functions
+ *---------------------------------------------------------------------------*/
+
+GFile*
+anjuta_project_source_get_file (const AnjutaProjectSource *source)
+{
+	return SOURCE_DATA (source)->file;
+}
+
+/* Target type functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+anjuta_project_target_type_name (const AnjutaProjectTargetType type)
+{
+	return type->name;
+}
+
+const gchar *   
+anjuta_project_target_type_mime (const AnjutaProjectTargetType type)
+{
+	return type->mime_type;
+}
+
+AnjutaProjectTargetClass
+anjuta_project_target_type_class (const AnjutaProjectTargetType type)
+{
+	return type->base;
+}
diff --git a/libanjuta/anjuta-project.h b/libanjuta/anjuta-project.h
new file mode 100644
index 0000000..31fbed1
--- /dev/null
+++ b/libanjuta/anjuta-project.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-project.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_PROJECT_H_
+#define _ANJUTA_PROJECT_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define ANJUTA_IS_PROJECT_GROUP(obj) (((AnjutaProjectNodeData *)obj->data)->type == ANJUTA_PROJECT_GROUP)
+#define ANJUTA_IS_PROJECT_TARGET(obj) (((AnjutaProjectNodeData *)obj->data)->type == ANJUTA_PROJECT_TARGET)
+#define ANJUTA_IS_PROJECT_NODE(obj) (1)
+
+typedef enum
+{
+	ANJUTA_PROJECT_UNKNOWN,
+	ANJUTA_PROJECT_GROUP,
+	ANJUTA_PROJECT_TARGET,
+	ANJUTA_PROJECT_SOURCE,
+	ANJUTA_PROJECT_VARIABLE
+} AnjutaProjectNodeType;
+	
+typedef enum
+{
+	ANJUTA_TARGET_UNKNOWN,
+	ANJUTA_TARGET_SHAREDLIB,
+	ANJUTA_TARGET_STATICLIB,
+	ANJUTA_TARGET_EXECUTABLE,
+	ANJUTA_TARGET_PYTHON,
+	ANJUTA_TARGET_JAVA
+} AnjutaProjectTargetClass;
+
+typedef struct 
+{
+	gchar *name;
+	AnjutaProjectTargetClass base;
+	gchar *mime_type;
+} AnjutaProjectTargetInformation;
+
+typedef AnjutaProjectTargetInformation* AnjutaProjectTargetType;
+
+typedef struct
+{
+	AnjutaProjectNodeType type;
+} AnjutaProjectNodeData;
+
+typedef struct {
+	AnjutaProjectNodeData node;
+	GFile *directory;
+} AnjutaProjectGroupData;
+
+typedef struct {
+	AnjutaProjectNodeData node;
+	gchar *name;
+	AnjutaProjectTargetType type;
+} AnjutaProjectTargetData;
+
+typedef struct {
+	AnjutaProjectNodeData node;
+	GFile *file;
+} AnjutaProjectSourceData;
+
+typedef GNode AnjutaProjectNode;
+typedef GNode AnjutaProjectGroup;
+typedef GNode AnjutaProjectTarget;
+typedef GNode AnjutaProjectSource;
+
+typedef GNodeTraverseFunc AnjutaProjectNodeFunc;
+
+AnjutaProjectNode *anjuta_project_node_parent (AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_first_child (AnjutaProjectNode *node);
+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);
+void anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
+
+AnjutaProjectNodeType anjuta_project_node_get_type (const AnjutaProjectNode *node);
+
+GFile *anjuta_project_group_get_directory (const AnjutaProjectGroup *group);
+
+const gchar *anjuta_project_target_get_name (const AnjutaProjectTarget *target);
+AnjutaProjectTargetType anjuta_project_target_get_type (const AnjutaProjectTarget *target);
+
+GFile *anjuta_project_source_get_file (const AnjutaProjectSource *source);
+
+const gchar *anjuta_project_target_type_name (const AnjutaProjectTargetType type);
+const gchar *anjuta_project_target_type_mime (const AnjutaProjectTargetType type);
+AnjutaProjectTargetClass anjuta_project_target_type_class (const AnjutaProjectTargetType type);
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/anjuta-token-file.c b/libanjuta/anjuta-token-file.c
new file mode 100644
index 0000000..9fb09a8
--- /dev/null
+++ b/libanjuta/anjuta-token-file.c
@@ -0,0 +1,368 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-file.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-file.h"
+
+#include "anjuta-debug.h"
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/* Types declarations
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaTokenFile
+{
+	GObject parent;
+	
+	GFile* file;
+	
+	gsize length;
+	gchar *content;
+	
+	AnjutaToken *first;
+	AnjutaToken *last;
+
+	guint line_width;
+};
+
+struct _AnjutaTokenFileClass
+{
+	GObjectClass parent_class;
+};
+
+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.
+ * */
+
+static gboolean
+make_directory_with_parents (GFile *file,
+							   GCancellable *cancellable,
+							   GError **error)
+{
+	GError *path_error = NULL;
+	GList *children = NULL;
+
+	for (;;)
+	{
+		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))
+		{
+			g_clear_error (&path_error);
+			children = g_list_prepend (children, file);
+			file = g_file_get_parent (file);
+		}
+		else
+		{
+			g_object_unref (file);
+			g_list_foreach (children, (GFunc)g_object_unref, NULL);
+			g_list_free (children);
+			g_propagate_error (error, path_error);
+			
+			return FALSE;
+		}
+	}				
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+anjuta_token_file_get_content (AnjutaTokenFile *file, GError **error)
+{
+	if (file->content == NULL)
+	{
+		gchar *content;
+		gsize length;
+	
+		if (g_file_load_contents (file->file, NULL, &content, &length, NULL, error))
+		{
+			file->content = content;
+			file->length = length;
+		}
+	}
+	
+	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)
+{
+	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;
+			}
+		}
+	}
+	
+	return FALSE;
+}
+
+gboolean
+anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
+{
+	GFileOutputStream *stream;
+	gboolean ok;
+	GError *err = NULL;
+	AnjutaTokenFileSaveData data;
+	
+	stream = g_file_replace (file->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &err);
+	if (stream == NULL)
+	{
+		if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+		{
+			/* 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))
+			{
+				g_object_unref (parent);
+				g_clear_error (&err);
+				stream = g_file_replace (file->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
+				if (stream == NULL) return FALSE;
+			}
+			else
+			{
+				g_object_unref (parent);
+				g_propagate_error (error, err);
+
+				return FALSE;
+			}
+		}
+		else
+		{
+			g_propagate_error (error, err);
+			return FALSE;
+		}
+	}
+
+	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);
+	g_object_unref (stream);
+	
+	return !data.fail;
+}
+
+void
+anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file)
+{
+	if (file->file) g_object_unref (file->file);
+	file->file = new_file != NULL ? g_object_ref (new_file) : NULL;
+}
+
+void
+anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token)
+{
+	if (file->last == NULL)
+	{
+		file->first = token;
+	}
+	else if (file->last == file->first)
+	{
+		g_node_insert_after ((GNode *)file->first, NULL, (GNode *)token);
+	}
+	else
+	{
+		while (((GNode *)file->last)->parent != (GNode *)file->first)
+		{
+			file->last = (AnjutaToken *)((GNode *)file->last)->parent;
+		}
+		g_node_insert_after ((GNode *)file->first, (GNode *)file->last, (GNode *)token);
+	}
+	file->last = token;
+}
+
+void
+anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width)
+{
+	if (width > file->line_width) file->line_width = width;
+}
+
+AnjutaToken*
+anjuta_token_file_first (AnjutaTokenFile *file)
+{
+	return file->first;
+}
+
+AnjutaToken*
+anjuta_token_file_last (AnjutaTokenFile *file)
+{
+	return file->last;
+}
+
+GFile*
+anjuta_token_file_get_file (AnjutaTokenFile *file)
+{
+	return file->file;
+}
+
+guint
+anjuta_token_file_get_line_width (AnjutaTokenFile *file)
+{
+	return file->line_width;
+}
+
+/* GObject functions
+ *---------------------------------------------------------------------------*/
+
+/* dispose is the first destruction step. It is used to unref object created
+ * with instance_init in order to break reference counting cycles. This
+ * function could be called several times. All function should still work
+ * after this call. It has to called its parents.*/
+
+static void
+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;
+	
+	if (file->file) g_object_unref (file->file);
+	file->file = NULL;
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+/* instance_init is the constructor. All functions should work after this
+ * call. */
+
+static void
+anjuta_token_file_instance_init (AnjutaTokenFile *file)
+{
+	file->file = NULL;
+}
+
+/* class_init intialize the class itself not the instance */
+
+static void
+anjuta_token_file_class_init (AnjutaTokenFileClass * klass)
+{
+	GObjectClass *gobject_class;
+
+	g_return_if_fail (klass != NULL);
+	
+	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+	gobject_class = G_OBJECT_CLASS (klass);
+	
+	gobject_class->dispose = anjuta_token_file_dispose;
+}
+
+GType
+anjuta_token_file_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type)
+	{
+		static const GTypeInfo type_info = 
+		{
+			sizeof (AnjutaTokenFileClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) anjuta_token_file_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,           /* class_data */
+			sizeof (AnjutaTokenFile),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) anjuta_token_file_instance_init,
+			NULL            /* value_table */
+		};
+
+		type = g_type_register_static (G_TYPE_OBJECT,
+		                            "AnjutaTokenFile", &type_info, 0);
+	}
+	
+	return type;
+}
+
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+AnjutaTokenFile *
+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;
+	}
+	
+	return file;
+};
+
+void
+anjuta_token_file_free (AnjutaTokenFile *tfile)
+{
+	g_object_unref (tfile);
+}
diff --git a/libanjuta/anjuta-token-file.h b/libanjuta/anjuta-token-file.h
new file mode 100644
index 0000000..d1053f1
--- /dev/null
+++ b/libanjuta/anjuta-token-file.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-file.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_FILE_H_
+#define _ANJUTA_TOKEN_FILE_H_
+
+#include <gio/gio.h>
+#include <glib.h>
+
+#include <libanjuta/anjuta-token.h>
+
+G_BEGIN_DECLS
+
+#define ANJUTA_TOKEN_FILE_TYPE                     (anjuta_token_file_get_type ())
+#define ANJUTA_TOKEN_FILE(obj)                      (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TOKEN_FILE_TYPE, AnjutaTokenFile))
+#define ANJUTA_TOKEN_FILE_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), ANJUTA_TOKEN_FILE_TYPE, AnjutaTokenFileClass))
+#define IS_ANJUTA_TOKEN_FILE(obj)                  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANJUTA_TOKEN_FILE_TYPE))
+#define IS_ANJUTA_TOKEN_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), ANJUTA_TOKEN_FILE_TYPE))
+#define GET_ANJUTA_TOKEN_FILE_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), ANJUTA_TOKEN_FILE_TYPE, AnjutaTokenFileClass))
+
+typedef struct _AnjutaTokenFile AnjutaTokenFile;
+typedef struct _AnjutaTokenFileClass AnjutaTokenFileClass;
+
+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);
+gboolean anjuta_token_file_save (AnjutaTokenFile *file, GError **error);
+
+void anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token);
+void anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width);
+
+AnjutaToken* anjuta_token_file_first (AnjutaTokenFile *file);
+AnjutaToken* anjuta_token_file_last (AnjutaTokenFile *file);
+GFile *anjuta_token_file_get_file (AnjutaTokenFile *file);
+guint anjuta_token_file_get_line_width (AnjutaTokenFile *file);
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/anjuta-token-style.c b/libanjuta/anjuta-token-style.c
new file mode 100644
index 0000000..87b8b7e
--- /dev/null
+++ b/libanjuta/anjuta-token-style.c
@@ -0,0 +1,491 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-style.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-style.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)
+{
+	DEBUG_PRINT ("free sep %p count %d", sep, sep->count);
+	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;
+		DEBUG_PRINT ("alloc sep %p count %d", sep, sep->count);
+		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)
+{
+	GList *list;
+	
+	list = g_hash_table_lookup (style->separator, GINT_TO_POINTER (ANJUTA_TOKEN_NEXT));
+
+	return anjuta_token_new_string (ANJUTA_TOKEN_NEXT, ((AnjutaTokenStyleSeparator *)list->data)->value);
+}
+
+/* Public 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_value (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_next_child (list); token != NULL; token = next_token)
+	{
+		gchar *value = NULL;
+		const gchar *eol;
+		gsize len;
+		gint type;
+		
+		next_token = anjuta_token_next_sibling (token);
+		type = anjuta_token_get_type (token);
+		next = next_token == NULL ? 0 : anjuta_token_get_type (next_token);
+
+		value = anjuta_token_value (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;
+		}
+	}
+}	
+
+static void
+anjuta_token_style_format_line (AnjutaTokenStyle *style, AnjutaToken *bol, AnjutaToken *eol)
+{
+	
+}
+
+void
+anjuta_token_style_format (AnjutaTokenStyle *style, AnjutaToken *list)
+{
+	AnjutaToken *arg;
+
+	for (arg = anjuta_token_next_child (list); arg != NULL; arg = anjuta_token_next_sibling (arg))
+	{
+		if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_NEXT) && (anjuta_token_get_flags (arg) & (ANJUTA_TOKEN_ADDED)))
+		{
+			anjuta_token_insert_after (arg, anjuta_token_style_lookup (style));
+			anjuta_token_free (arg);
+		}
+	}
+#if 0	
+	AnjutaToken *arg;
+
+	if (style->sep == NULL)
+	{
+		for (arg = anjuta_token_next_child (list); arg != NULL; arg = anjuta_token_next_sibling (arg))
+		{
+			if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) && (anjuta_token_get_flags (arg) & (ANJUTA_TOKEN_ADDED)))
+			{
+				anjuta_token_insert_after (arg, anjuta_token_copy (style->eol));
+				anjuta_token_free (arg);
+			}
+		}
+	}
+	else
+	{
+		AnjutaToken *bol = anjuta_token_next_child (list);
+		gboolean modified = FALSE;
+		
+		for (arg = bol; arg != NULL; arg = anjuta_token_next_sibling (arg))
+		{
+			gchar *value = anjuta_token_evaluate (arg);
+			if (anjuta_token_get_flags (arg) & (ANJUTA_TOKEN_REMOVED | ANJUTA_TOKEN_ADDED)) modified = TRUE;
+			if (strchr (value, '\n'))
+			{
+				if (modified) anjuta_token_style_format_line (style, list, arg);
+				bol = arg;
+				if (style->sep == NULL) modified = FALSE;
+			}
+			g_free (value);
+		}
+		if (modified) anjuta_token_style_format_line (style, bol, NULL);
+	}
+#endif
+}
+
+AnjutaToken *
+anjuta_token_list_first (AnjutaToken *list)
+{
+	AnjutaToken *token;
+
+	token = anjuta_token_next_child (list);
+	if (token == NULL) return token;
+
+	if (anjuta_token_get_type (token) == ANJUTA_TOKEN_START)
+	{
+		token = anjuta_token_next_sibling (token);
+	}
+	
+	return token;
+}
+
+AnjutaToken *
+anjuta_token_list_last (AnjutaToken *list)
+{
+	AnjutaToken *token;
+
+	token = anjuta_token_list_first (list);
+	for (;;)
+	{
+		AnjutaToken *next = anjuta_token_list_next (list);
+		if (next == NULL) return token;
+		token = next;
+	}
+}
+
+AnjutaToken *
+anjuta_token_list_next (AnjutaToken *sibling)
+{
+	AnjutaToken *token;
+
+	token = anjuta_token_next_sibling (sibling);
+	if (token == NULL) return token;
+
+	if (anjuta_token_get_type (token) == ANJUTA_TOKEN_NEXT)
+	{
+		token = anjuta_token_next_sibling (token);
+	}
+
+	return token;
+}
+
+AnjutaToken *
+anjuta_token_list_replace (AnjutaToken *sibling, AnjutaToken *baby)
+{
+	AnjutaToken *token;
+	
+	token = anjuta_token_insert_before (sibling, baby);
+	if ((anjuta_token_get_type (sibling) != ANJUTA_TOKEN_NEXT) && (anjuta_token_get_type (sibling) != ANJUTA_TOKEN_LAST))
+	{
+		anjuta_token_remove (sibling);
+	}
+
+	return token;
+}
+
+AnjutaToken *
+anjuta_token_list_replace_nth (AnjutaToken *list, guint n, AnjutaToken *baby)
+{
+	AnjutaToken *token;
+
+	token = anjuta_token_list_first (list); 
+	if (token == NULL)
+	{
+		token = anjuta_token_insert_child (list, anjuta_token_new_static (ANJUTA_TOKEN_START | ANJUTA_TOKEN_ADDED, NULL));
+		token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+	}
+
+	for (; n != 0; n--)
+	{
+		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));
+				continue;
+			case ANJUTA_TOKEN_NEXT:
+				break;
+			default:
+				token = anjuta_token_next_sibling (token);
+				if (token == NULL)
+				{
+					token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				}
+				else if (anjuta_token_get_type (token) == ANJUTA_TOKEN_LAST)
+				{
+					token = anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+				}
+				break;
+		}
+
+		next = anjuta_token_next_sibling (token);
+		if (next == NULL)
+		{
+			token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+		}
+		else
+		{
+			token = next;
+		}
+	}
+
+	return anjuta_token_list_replace (token, baby); 
+}
+
+AnjutaToken *
+anjuta_token_list_insert_after (AnjutaToken *sibling, AnjutaToken *baby)
+{
+	AnjutaToken *token = sibling;
+	AnjutaToken *separator;
+
+	if (anjuta_token_get_type (token) == ANJUTA_TOKEN_LAST)
+	{
+		token = anjuta_token_previous_sibling (token);
+	}
+	else if ((anjuta_token_get_type (token) != ANJUTA_TOKEN_NEXT) && (anjuta_token_next_sibling (token) != NULL))
+	{
+		token = anjuta_token_next_sibling (token);
+	}
+	
+	separator = anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL);
+	token = anjuta_token_insert_after (token, separator);
+	token = anjuta_token_insert_after (token, baby);
+
+	return token;
+}
+
+void
+anjuta_token_list_remove (AnjutaToken *sibling)
+{
+	AnjutaToken *token;
+	
+	if ((anjuta_token_get_type (sibling) != ANJUTA_TOKEN_NEXT) && (anjuta_token_get_type (sibling) != ANJUTA_TOKEN_LAST))
+	{
+		anjuta_token_remove (sibling);
+	}
+
+	token = anjuta_token_next_sibling (sibling);
+	if (anjuta_token_get_type (token) == ANJUTA_TOKEN_NEXT)
+	{
+		anjuta_token_remove (token);
+		return;
+	}
+
+	token = anjuta_token_previous_sibling (sibling);
+	if (anjuta_token_get_type (token) == ANJUTA_TOKEN_NEXT)
+	{
+		anjuta_token_remove (token);
+		return;
+	}
+
+	return;
+}
+
+
+/* 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-style.h b/libanjuta/anjuta-token-style.h
new file mode 100644
index 0000000..55a8859
--- /dev/null
+++ b/libanjuta/anjuta-token-style.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-style.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_STYLE_H_
+#define _ANJUTA_TOKEN_STYLE_H_
+
+#include <glib.h>
+
+#include "anjuta-token.h"
+
+G_BEGIN_DECLS
+
+typedef struct _AnjutaTokenStyle AnjutaTokenStyle;
+
+AnjutaTokenStyle *anjuta_token_style_new (const gchar *start, const gchar *next, const gchar *eol, const gchar *last, guint max_width);
+void anjuta_token_style_free (AnjutaTokenStyle *style);
+
+void anjuta_token_style_update (AnjutaTokenStyle *style, AnjutaToken *list);
+void anjuta_token_style_format (AnjutaTokenStyle *style, AnjutaToken *list);
+
+AnjutaToken *anjuta_token_list_first (AnjutaToken *list);
+AnjutaToken *anjuta_token_list_last (AnjutaToken *list);
+AnjutaToken *anjuta_token_list_next (AnjutaToken *sibling);
+AnjutaToken *anjuta_token_list_replace (AnjutaToken *sibling, AnjutaToken *baby);
+AnjutaToken *anjuta_token_list_replace_nth (AnjutaToken *list, guint n, AnjutaToken *baby);
+AnjutaToken *anjuta_token_list_insert_after (AnjutaToken *sibling, AnjutaToken *baby);
+void anjuta_token_list_delete (AnjutaToken *sibling);
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/anjuta-token.c b/libanjuta/anjuta-token.c
new file mode 100644
index 0000000..088e9f8
--- /dev/null
+++ b/libanjuta/anjuta-token.c
@@ -0,0 +1,648 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token.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.h"
+
+#include "anjuta-debug.h"
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include <string.h>
+
+typedef struct _AnjutaTokenData AnjutaTokenData;
+
+struct _AnjutaTokenData
+{
+	AnjutaTokenType type;	
+	gint flags;
+	gchar *pos;
+	gsize length;
+};
+
+struct _AnjutaToken
+{
+	AnjutaTokenData	*data;
+	AnjutaToken	*next;
+	AnjutaToken	*prev;
+	AnjutaToken	*parent;
+	AnjutaToken	*children;
+};
+		
+#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)
+{
+
+	for (; sequence != NULL; /*sequence = flags & ANJUTA_SEARCH_BACKWARD ? anjuta_token_previous (sequence) : anjuta_token_next (sequence)*/)
+	{
+		AnjutaToken *toka;
+		AnjutaToken *tokb = token;
+
+		for (toka = sequence; toka != NULL; toka = anjuta_token_next_sibling (toka))
+		{
+			if (anjuta_token_compare (toka, tokb))
+			{
+				tokb = anjuta_token_next (tokb);
+				if (tokb == NULL)
+				{
+					if (end) *end = sequence;
+					return TRUE;
+				}
+			}
+			else
+			{
+				break;
+			}
+		}
+
+		if (flags & ANJUTA_SEARCH_BACKWARD)
+		{
+			sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_previous (sequence) : anjuta_token_previous_sibling (sequence);
+		}
+		else
+		{
+			sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_next (sequence) : anjuta_token_next_sibling (sequence);
+		}
+	}
+	/*g_message ("matched %p %d", sequence, level);*/
+	
+	if (end) *end = sequence;
+	
+	return FALSE;
+}
+
+
+gboolean
+anjuta_token_remove (AnjutaToken *token)
+{
+	ANJUTA_TOKEN_DATA (token)->flags |= ANJUTA_TOKEN_REMOVED;
+
+	return TRUE;
+}
+
+gboolean
+anjuta_token_compare (AnjutaToken *toka, AnjutaToken *tokb)
+{
+	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (toka);
+	AnjutaTokenData *datb = ANJUTA_TOKEN_DATA (tokb);
+
+	if (datb->type)
+	{
+		if (datb->type != data->type) return FALSE;
+	}
+	
+	if (datb != ANJUTA_TOKEN_NONE)
+	{
+		if (datb->length != 0)
+		{
+			if (data->length != datb->length) return FALSE;
+		
+			if ((data->flags & ANJUTA_TOKEN_CASE_INSENSITIVE)  && (datb->flags & ANJUTA_TOKEN_CASE_INSENSITIVE))
+			{
+				if (g_ascii_strncasecmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+			}
+			else
+			{
+				if (strncmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+			}
+		}
+	}
+		
+	if (datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS)
+	{
+		if ((data->flags & datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS) == 0)
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+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_next (AnjutaToken *token)
+{
+	if (token->children != NULL)
+	{
+		return token->children;
+	}
+	else 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_previous (AnjutaToken *token)
+{
+	if (token->prev != NULL)
+	{
+		return token->prev;
+	}
+	else
+	{
+		return token->parent;
+	}
+}
+
+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)
+{
+	AnjutaToken *last = NULL;
+
+	for (; token != NULL; token = (AnjutaToken *)g_node_last_child ((GNode *)last))
+	{
+		last = token;
+	}
+
+	return last;
+}
+
+AnjutaToken *
+anjuta_token_parent (AnjutaToken *token)
+{
+	return token->parent;
+}
+
+void
+anjuta_token_set_type (AnjutaToken *token, gint type)
+{
+	ANJUTA_TOKEN_DATA (token)->type = type;
+}
+
+void
+anjuta_token_set_flags (AnjutaToken *token, gint flags)
+{
+	ANJUTA_TOKEN_DATA (token)->flags |= flags;
+}
+
+void
+anjuta_token_clear_flags (AnjutaToken *token, gint flags)
+{
+	ANJUTA_TOKEN_DATA (token)->flags &= ~flags;
+}
+
+gint
+anjuta_token_get_type (AnjutaToken *token)
+{
+	return ANJUTA_TOKEN_DATA (token)->type;
+}
+
+gint
+anjuta_token_get_flags (AnjutaToken *token)
+{
+	return ANJUTA_TOKEN_DATA (token)->flags;
+}
+
+gchar *
+anjuta_token_get_value (AnjutaToken *token)
+{
+	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
+
+	return data && (data->pos != NULL) ? g_strndup (data->pos, data->length) : NULL;
+}
+
+const gchar *
+anjuta_token_get_string (AnjutaToken *token)
+{
+	return ANJUTA_TOKEN_DATA (token)->pos;
+}
+
+guint
+anjuta_token_get_length (AnjutaToken *token)
+{
+	return ANJUTA_TOKEN_DATA (token)->length;
+}
+
+static void
+anjuta_token_evaluate_token (AnjutaToken *token, GString *value, gboolean raw)
+{
+	if ((token != NULL) && (ANJUTA_TOKEN_DATA (token)->length != 0))
+	{
+		if (!raw)
+		{
+			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))
+			{
+				return;
+			}
+		}
+		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);
+
+	for (;;)
+	{
+		if (start == NULL) break;
+		anjuta_token_evaluate_token (start, value, FALSE);
+		if (start == end) break;
+		
+		start = anjuta_token_next (start);
+	}
+	
+
+	return g_string_free (value, FALSE);
+}
+
+static  void
+anjuta_token_evaluate_child (AnjutaToken *token, GString *value, gboolean raw)
+{
+	anjuta_token_evaluate_token (token, value, raw);
+
+	if (token->children) anjuta_token_evaluate_child (token->children, value, raw);
+
+	if (token->next) anjuta_token_evaluate_child (token->next, value, raw);
+}
+
+gchar *
+anjuta_token_evaluate (AnjutaToken *token)
+{
+	GString *value = g_string_new (NULL);
+	gchar *str;
+
+	if (token != NULL)
+	{
+		anjuta_token_evaluate_token (token, value, FALSE);
+		if (token->children) anjuta_token_evaluate_child (token->children, value, FALSE);
+	}
+
+	str = g_string_free (value, FALSE);
+	return *str == '\0' ? NULL : str; 	
+}
+
+gchar *
+anjuta_token_value (AnjutaToken *token)
+{
+	GString *value = g_string_new (NULL);
+	gchar *str;
+
+	if (token != NULL)
+	{
+		anjuta_token_evaluate_token (token, value, TRUE);
+		if (token->children) anjuta_token_evaluate_child (token->children, value, TRUE);
+	}
+
+	str = g_string_free (value, FALSE);
+	return *str == '\0' ? NULL : str; 	
+}
+
+AnjutaToken *
+anjuta_token_merge (AnjutaToken *first, AnjutaToken *end)
+{
+	AnjutaToken *child;
+	AnjutaToken *tok;
+
+	if (first == end) return first;
+
+	child = (AnjutaToken *)g_node_last_child ((GNode *)first);
+	do
+	{
+		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);
+
+	}
+	while (tok != end);
+
+	return first;
+}
+
+AnjutaToken *
+anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end)
+{
+	AnjutaToken *child;
+	AnjutaToken *tok;
+
+	if (first == end) return first;
+
+	child = (AnjutaToken *)g_node_first_child ((GNode *)first);
+	do
+	{
+		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);
+
+	}
+	while (tok != end);
+
+	return first;
+}
+
+AnjutaToken *
+anjuta_token_copy (const AnjutaToken *token)
+{
+	AnjutaToken *copy = NULL;
+
+	if (token != NULL)
+	{
+		AnjutaTokenData *org = ANJUTA_TOKEN_DATA (token);
+		AnjutaTokenData *data = NULL;
+		AnjutaToken *child;
+		AnjutaToken *last;
+
+		data = g_slice_new0 (AnjutaTokenData);
+		data->type =org->type;
+		data->flags = org->type;
+		if ((data->flags & ANJUTA_TOKEN_STATIC) || (org->pos == NULL))
+		{
+			data->pos = org->pos;
+		}
+		else
+		{
+			data->pos = g_strdup (ANJUTA_TOKEN_DATA (token)->pos);
+		}
+		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))
+		{
+			AnjutaToken *new_child = anjuta_token_copy (child);
+			last =  last == NULL ? anjuta_token_insert_child (copy, new_child) : anjuta_token_insert_after (last, new_child);
+		}
+	}
+
+	return copy;
+}
+
+AnjutaToken *
+anjuta_token_clear (AnjutaToken *token)
+{
+	AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
+
+	if (!(data->flags & ANJUTA_TOKEN_STATIC))
+	{
+		g_free (data->pos);
+	}
+	data->length = 0;
+	data->pos = NULL;
+
+	return token;
+}
+
+AnjutaToken *
+anjuta_token_delete (AnjutaToken *token)
+{
+	GNode *last;
+	GNode *child;
+	AnjutaToken *next;
+	
+	for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+	{
+		g_node_unlink (child);
+		last = g_node_insert_after (((GNode *)token)->parent, last, child);
+	}
+
+	next = (AnjutaToken *)g_node_next_sibling (token);
+	anjuta_token_clear (token);
+	g_node_destroy ((GNode *)token);
+
+	return next;
+}
+
+AnjutaToken *
+anjuta_token_insert_child (AnjutaToken *parent, AnjutaToken *child)
+{
+	return (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)NULL, (GNode *)child);
+}
+
+AnjutaToken *
+anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *token)
+{
+	return (AnjutaToken *)g_node_insert_after ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)token);
+}
+
+AnjutaToken *
+anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *baby)
+{
+	return (AnjutaToken *)g_node_insert_before ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)baby);
+}	
+
+AnjutaToken *anjuta_token_group (AnjutaToken *parent, AnjutaToken *last)
+{
+	AnjutaToken *child;
+	AnjutaToken *tok;
+
+	if (parent == last) return parent; 
+	if (parent->children == last) return parent;
+
+	child = (AnjutaToken *)g_node_last_child ((GNode *)parent);
+	do
+	{
+		tok = (AnjutaToken *)g_node_next_sibling ((GNode *)parent);
+		if (tok == NULL) break;
+		
+		g_node_unlink ((GNode *)tok);
+		child = (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)child, (GNode *)tok);
+
+	}
+	while (tok != last);
+
+	return parent;
+	
+}
+
+AnjutaToken *anjuta_token_group_new (AnjutaTokenType type, AnjutaToken* first)
+{
+	AnjutaToken *parent = anjuta_token_new_static (type, NULL);
+
+	g_node_insert_before ((GNode *)first->parent, (GNode *)first, (GNode *)parent);
+	return anjuta_token_group (parent, first);
+}
+
+AnjutaToken *anjuta_token_ungroup (AnjutaToken *token)
+{
+	GNode *last = (GNode *)token;
+	GNode *child;
+	
+	for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+	{
+		g_node_unlink (child);
+		last = g_node_insert_after (((GNode *)token)->parent, last, child);
+	}
+
+	return token;
+}
+
+AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
+{
+	if (ANJUTA_TOKEN_DATA (token)->length > size)
+	{
+		AnjutaToken *copy;
+
+		copy = anjuta_token_copy (token);
+		g_node_insert_before ((GNode *)token->parent, (GNode *)token, (GNode *)copy);
+
+		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);
+		}
+
+		return copy;
+	}
+	else
+	{
+		return token;
+	}
+}
+
+AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value)
+{
+	for (;arg != NULL;)
+	{
+		switch (anjuta_token_get_type (arg))
+		{
+			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;
+		}
+		break;
+	}
+	
+	return arg;
+}
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const char *value)
+{
+	if (value == NULL)
+	{
+		return anjuta_token_new_static (type, NULL);
+	}
+	else
+	{
+		AnjutaTokenData *data;
+
+		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 (AnjutaToken *)g_node_new (data);
+	}
+}
+	
+AnjutaToken *
+anjuta_token_new_fragment (gint type, const gchar *pos, gsize length)
+{
+	AnjutaTokenData *data;
+
+	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;
+
+	return (AnjutaToken *)g_node_new (data);
+};
+
+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)
+{
+	g_slice_free (AnjutaTokenData, node->data);
+}
+
+void
+anjuta_token_free (AnjutaToken *token)
+{
+	if (token == NULL) return;
+
+	g_node_children_foreach ((GNode *)token, G_TRAVERSE_ALL, free_token_data, NULL);
+	g_node_destroy ((GNode *)token);
+}
diff --git a/libanjuta/anjuta-token.h b/libanjuta/anjuta-token.h
new file mode 100644
index 0000000..ed6c319
--- /dev/null
+++ b/libanjuta/anjuta-token.h
@@ -0,0 +1,162 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token.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_H_
+#define _ANJUTA_TOKEN_H_
+
+#include <gio/gio.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+	ANJUTA_TOKEN_NONE 							= 0,
+	ANJUTA_TOKEN_EOL								= '\n',
+	ANJUTA_TOKEN_COMMA							=',',
+	
+	ANJUTA_TOKEN_TYPE 							= 0xFFFF,
+
+	ANJUTA_TOKEN_FIRST								= 16384,	
+	ANJUTA_TOKEN_FILE 								= 16384,
+	ANJUTA_TOKEN_KEYWORD,
+	ANJUTA_TOKEN_OPERATOR,
+	ANJUTA_TOKEN_NAME,
+	ANJUTA_TOKEN_VALUE,
+	ANJUTA_TOKEN_MACRO,
+	ANJUTA_TOKEN_VARIABLE,
+	ANJUTA_TOKEN_DEFINITION,
+	ANJUTA_TOKEN_STATEMENT,
+	ANJUTA_TOKEN_NUMBER,
+	ANJUTA_TOKEN_JUNK,
+	ANJUTA_TOKEN_COMMENT,
+	ANJUTA_TOKEN_OPEN_QUOTE,
+	ANJUTA_TOKEN_CLOSE_QUOTE,
+	ANJUTA_TOKEN_ESCAPE,
+	ANJUTA_TOKEN_FUNCTION,
+	ANJUTA_TOKEN_SPACE,
+	ANJUTA_TOKEN_START,
+	ANJUTA_TOKEN_NEXT,
+	ANJUTA_TOKEN_LAST,
+	ANJUTA_TOKEN_ARGUMENT,
+	ANJUTA_TOKEN_ITEM,
+	ANJUTA_TOKEN_STRING,
+	ANJUTA_TOKEN_ERROR,
+	ANJUTA_TOKEN_WORD,
+	ANJUTA_TOKEN_LIST,
+	ANJUTA_TOKEN_ANY,
+	ANJUTA_TOKEN_USER,
+		
+	ANJUTA_TOKEN_FLAGS 							= 0xFFFF << 16,
+	
+	ANJUTA_TOKEN_PUBLIC_FLAGS 				= 0x00FF << 16,
+	
+	ANJUTA_TOKEN_IRRELEVANT 					= 1 << 16,
+	ANJUTA_TOKEN_OPEN 							= 1 << 17,
+	ANJUTA_TOKEN_CLOSE 							= 1 << 18,
+	ANJUTA_TOKEN_SIGNIFICANT					= 1 << 20,
+
+	ANJUTA_TOKEN_PRIVATE_FLAGS 			= 0x00FF << 24,
+	
+	ANJUTA_TOKEN_CASE_INSENSITIVE 		= 1 << 24,
+	ANJUTA_TOKEN_STATIC 							= 1 << 25,
+	ANJUTA_TOKEN_REMOVED						= 1 << 26,
+	ANJUTA_TOKEN_ADDED							= 1 << 27
+	
+} 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_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);
+
+void anjuta_token_set_type (AnjutaToken *token, gint type);
+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);
+
+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_parent (AnjutaToken *token);
+gboolean anjuta_token_compare (AnjutaToken *tokena, AnjutaToken *tokenb);
+
+AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value);
+
+
+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);
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index d64c03d..9b32391 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -2954,6 +2954,199 @@ interface IAnjutaTerminal
 }
 
 /**
+ * SECTION:ianjuta-project
+ * @title: IAnjutaProject
+ * @short_description: Interface implemented by project backend
+ * @see_also: 
+ * @stability: Unstable
+ * @include: libanjuta/interfaces/ianjuta-project-backend.h
+ * 
+ * This is the new interface that is replacing Gnome Build.
+ */
+interface IAnjutaProject
+{
+	#include <libanjuta/anjuta-project.h>
+	#include <gtk/gtk.h>
+
+	/* Types */
+	enum Error
+	{
+		ERROR_SUCCESS = 0,
+		ERROR_DOESNT_EXIST,
+		ERROR_ALREADY_EXISTS,
+		ERROR_VALIDATION_FAILED,
+		ERROR_PROJECT_MALFORMED,
+		ERROR_GENERAL_FAILURE
+	}
+
+	enum Probe
+		PROBE_FILES = 10,
+		PROBE_MAKE_FILES = 100,
+		PROBE_PROJECT_FILES = 200
+	}
+
+	enum Capabilities
+	{
+		CAN_ADD_NONE	= 0,
+		CAN_ADD_GROUP	= 1 << 0,
+		CAN_ADD_TARGET	= 1 << 1,
+		CAN_ADD_SOURCE	= 1 << 2,
+		HAS_PACKAGES	= 1 << 3
+	}
+	
+	/* Signals */
+	
+	/**
+	* IAnjutaProject::project_updated:
+	* @obj: Self
+	* 
+	* This signal is emitted when the project is changed.
+	*/
+	void ::project_updated ();
+
+	/**
+	 * ianjuta_project_load:
+	 * @obj: Self
+	 * @file: Project directory
+	 * @err: Error propagation and reporting
+	 *
+	 * Load a project
+	 *
+	 * Return value: TRUE is loaded without errors
+	 */
+	gboolean load (GFile *file);
+
+	/**
+	 * ianjuta_project_refresh:
+	 * @obj: Self
+	 * @err: Error propagation and reporting
+	 *
+	 * Reload the current project
+	 *
+	 * Return value: TRUE is loaded without errors
+	 */
+	gboolean refresh ();
+
+	/**
+	* ianjuta_project_get_capabilities:
+	* @obj: Self
+	* @err: Error propagation and reporting.
+	*
+	* Returns the capabilites of project whether it can add group, target
+	* sources etc.
+	*
+	* Returns: Supported capabilites.
+	*/
+	guint get_capabilities ();
+
+	/*
+	 * ianjuta_project_get_target_types
+	 * @obj: Self
+	 * @err: Error propagation and reporting.
+	 *
+	 * Returns: the list of supported target types
+	 */
+	List<AnjutaProjectTargetType> get_target_types();
+	
+	/**
+	* ianjuta_project_configure:
+	* @obj: Self
+	* @err: Error propagation and reporting.
+	*
+	* Return a widget that can be use to set any options needed by the project
+	*
+	* Returns: A GtkWidget
+	*/
+	GtkWidget* configure ();
+	
+	/**
+	* ianjuta_project_get_root:
+	* @obj: Self
+	* @err: Error propagation and reporting.
+	*
+	* Get the root node of the project (always a group)
+	*
+	* Returns: The new group or NULL on error.
+	*/
+	AnjutaProjectGroup* get_root ();
+
+	/*
+	 * ianjuta_project_get_packages
+	 * @obj: Self
+	 * @err: Error propagation and reporting.
+	 *
+	 * Returns: the list of pkg-config packages that the current project
+	 * requires in it's configure.ac. Can be NULL if there is no project
+	 * opened currently or no package is required.
+	 */
+	List<gchar*> get_packages();
+	
+	/**
+	* ianjuta_project_add_group:
+	* @obj: Self
+	* @parent: parent group
+	* @name: new group name
+	* @err: Error propagation and reporting.
+	*
+	* Create a new group, parent can be NULL.
+	*
+	* Returns: The new group or NULL on error.
+	*/
+	AnjutaProjectGroup* add_group (AnjutaProjectGroup *parent, const gchar *name);
+
+	/**
+	* ianjuta_project_add_target:
+	* @obj: Self
+	* @parent: parent group
+	* @name: new target name
+	* @type: new target type
+	* @err: Error propagation and reporting.
+	*
+	* Create a new target, parent cannot be NULL
+	*
+	* Returns: The new target or NULL on error.
+	*/
+	AnjutaProjectTarget* add_target (AnjutaProjectGroup *parent, const gchar *name, AnjutaProjectTargetType type);
+
+	/**
+	* ianjuta_project_add_source:
+	* @obj: Self
+	* @parent: parent target
+	* @file: source file
+	* @err: Error propagation and reporting.
+	*
+	* Create a new source, parent cannot be NULL
+	*
+	* Returns: The new source or NULL on error.
+	*/
+	AnjutaProjectSource* add_source (AnjutaProjectTarget *parent, GFile *file);
+
+	/**
+	* ianjuta_project_remove_node:
+	* @obj: Self
+	* @node: node to configure
+	* @err: Error propagation and reporting.
+	*
+	* Remove a node (a group, a target or a source) from the project.
+	*
+	* Returns: TRUE if the node has been removed
+	*/
+	gboolean remove_node (AnjutaProjectNode *node);
+
+	/**
+	* ianjuta_project_configure_node:
+	* @obj: Self
+	* @node: node to configure
+	* @err: Error propagation and reporting.
+	*
+	* Return a widget that can be use to set any options needed by this node
+	*
+	* Returns: A GtkWidget
+	*/
+	GtkWidget* configure_node (AnjutaProjectNode *node);
+}
+
+/**
  * SECTION:ianjuta-project-backend
  * @title: IAnjutaProjectBackend
  * @short_description: Interface for creating new project
@@ -2964,7 +3157,7 @@ interface IAnjutaTerminal
  */
 interface IAnjutaProjectBackend
 {
-	#include <libanjuta/gbf-project.h>
+	#include "ianjuta-project.h"
 	
 	/**
 	 * ianjuta_project_backend_new_project:
@@ -2975,7 +3168,22 @@ interface IAnjutaProjectBackend
 	 *
 	 * Return value: An object derived from GbfProject
 	 */
-	GbfProject* new_project ();
+	IAnjutaProject* new_project ();
+
+	
+	/**
+	 * ianjuta_project_backend_probe:
+	 * @obj: Self
+	 * @file: Project directory
+	 * @err: Error propagation and reporting
+	 *
+	 * Check if the directory contains a project supported by this
+	 * backend
+	 *
+	 * Return value: 0 if the project is invalid and > 0 if the
+	 * project is valid. 
+	 */
+	gint probe (GFile *directory);
 }
 
 /**
@@ -2989,6 +3197,10 @@ interface IAnjutaProjectBackend
  */
 interface IAnjutaProjectManager
 {
+
+	#include <libanjuta/anjuta-project.h>
+	#include <libanjuta/interfaces/ianjuta-project.h>
+	
 	/**
 	* IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
 	*
@@ -3003,30 +3215,6 @@ interface IAnjutaProjectManager
 	*/
 	#define CURRENT_URI		"project_manager_current_uri"
 
-	enum ElementType
-	{
-		UNKNOWN,
-		SOURCE,
-		TARGET,
-		GROUP
-	}
-	
-	enum TargetType
-	{
-		TARGET_UNKNOWN,
-		TARGET_SHAREDLIB,
-		TARGET_STATICLIB,
-		TARGET_EXECUTABLE
-	}
-	
-	enum Capabilities
-	{
-		CAN_ADD_NONE     = 0,
-		CAN_ADD_GROUP    = 1 << 0,
-		CAN_ADD_TARGET   = 1 << 1,
-		CAN_ADD_SOURCE   = 1 << 2
-	}
-	
 	// Signals
 	
 	/**
@@ -3071,7 +3259,7 @@ interface IAnjutaProjectManager
 	*
 	* Returns: fixme
 	*/
-	ElementType get_element_type (const gchar *element_uri);
+	AnjutaProjectNodeType get_element_type (const gchar *element_uri);
 	
 	/**
 	* ianjuta_project_manager_get_elements:
@@ -3083,7 +3271,7 @@ interface IAnjutaProjectManager
 	* 
 	* Returns: fixme
 	*/
-	List<const gchar*> get_elements (ElementType element_type);
+	List<const gchar*> get_elements (AnjutaProjectNodeType element_type);
 	
 	/**
 	* ianjuta_project_manager_get_target_type:
@@ -3095,7 +3283,7 @@ interface IAnjutaProjectManager
 	* 
 	* Returns: fixme
 	*/
-	TargetType get_target_type (const gchar *target_uri);
+	AnjutaProjectTargetClass get_target_type (const gchar *target_uri);
 	
 	/**
 	* ianjuta_project_manager_get_targets:
@@ -3107,7 +3295,7 @@ interface IAnjutaProjectManager
 	* 
 	* Returns: fixme
 	*/
-	List<const gchar*> get_targets (TargetType target_type);
+	List<const gchar*> get_targets (AnjutaProjectTargetClass target_type);
 	
 	/**
 	* ianjuta_project_manager_get_parent:
@@ -3150,7 +3338,7 @@ interface IAnjutaProjectManager
 	* 
 	* fixme
 	*/
-	gchar* get_selected_id (ElementType element_type);
+	gchar* get_selected_id (AnjutaProjectNodeType element_type);
 	
 	/**
 	* ianjuta_project_manager_get_capabilities:
@@ -3162,7 +3350,7 @@ interface IAnjutaProjectManager
 	*
 	* Returns: Supported capabilites.
 	*/
-	Capabilities get_capabilities ();
+	guint get_capabilities ();
 
 	/**
 	* ianjuta_project_manager_add_source:
@@ -3189,7 +3377,7 @@ interface IAnjutaProjectManager
 	*
 	* Returns: element ID. Must be freed when no longer required.
 	*/
-	gchar* add_source_quiet (const gchar *source_uri_to_add, const gchar *target_id);
+	gchar* add_source_quiet (const gchar *source_uri_to_add, const gchar *target_uri);
 	
 	/**
 	* ianjuta_project_manager_add_sources:
diff --git a/libanjuta/libanjuta.h b/libanjuta/libanjuta.h
index ae341e8..bc5d661 100644
--- a/libanjuta/libanjuta.h
+++ b/libanjuta/libanjuta.h
@@ -51,5 +51,7 @@
 #include <libanjuta/anjuta-async-notify.h>
 #include <libanjuta/anjuta-sync-command.h>
 #include <libanjuta/gbf-project.h>
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
 
 #endif
diff --git a/manuals/reference/libanjuta/libanjuta-sections.txt b/manuals/reference/libanjuta/libanjuta-sections.txt
index a9fa8e8..1949be6 100644
--- a/manuals/reference/libanjuta/libanjuta-sections.txt
+++ b/manuals/reference/libanjuta/libanjuta-sections.txt
@@ -1554,17 +1554,11 @@ IANJUTA_PRINT_GET_IFACE
 
 <SECTION>
 <FILE>ianjuta-project-manager</FILE>
-IANJUTA_TYPE_PROJECT_MANAGER_CAPABILITIES
-IANJUTA_TYPE_PROJECT_MANAGER_ELEMENT_TYPE
-IANJUTA_TYPE_PROJECT_MANAGER_TARGET_TYPE
 IANJUTA_PROJECT_MANAGER_ERROR
 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
 IANJUTA_PROJECT_MANAGER_CURRENT_URI
 IAnjutaProjectManager
 IAnjutaProjectManagerIface
-IAnjutaProjectManagerCapabilities
-IAnjutaProjectManagerElementType
-IAnjutaProjectManagerTargetType
 ianjuta_project_manager_element_type_get_type
 ianjuta_project_manager_target_type_get_type
 ianjuta_project_manager_error_quark
@@ -1587,7 +1581,6 @@ ianjuta_project_manager_is_open
 IANJUTA_PROJECT_MANAGER
 IANJUTA_IS_PROJECT_MANAGER
 IANJUTA_TYPE_PROJECT_MANAGER
-ianjuta_project_manager_capabilities_get_type
 IANJUTA_PROJECT_MANAGER_GET_IFACE
 </SECTION>
 
diff --git a/manuals/reference/libanjuta/libanjuta.types b/manuals/reference/libanjuta/libanjuta.types
index 83b2d8c..fe09a1a 100644
--- a/manuals/reference/libanjuta/libanjuta.types
+++ b/manuals/reference/libanjuta/libanjuta.types
@@ -98,9 +98,6 @@ ianjuta_plugin_factory_error_get_type
 ianjuta_plugin_factory_get_type
 ianjuta_preferences_get_type
 ianjuta_print_get_type
-ianjuta_project_manager_capabilities_get_type
-ianjuta_project_manager_element_type_get_type
-ianjuta_project_manager_target_type_get_type
 ianjuta_project_manager_get_type
 ianjuta_stream_get_type
 ianjuta_stream_loader_get_type
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index e5099b1..dd017b6 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -29,8 +29,8 @@ SUBDIRS = . \
 	git \
 	sourceview \
 	run-program \
-	gbf-am \
-	gbf-mkfile \
-	starter
+	starter \
+	am-project \
+	mk-project
 
 -include $(top_srcdir)/git.mk
diff --git a/plugins/am-project/Makefile.am b/plugins/am-project/Makefile.am
new file mode 100644
index 0000000..29ee16d
--- /dev/null
+++ b/plugins/am-project/Makefile.am
@@ -0,0 +1,95 @@
+# Plugin UI file
+plugin_uidir = $(anjuta_ui_dir)
+plugin_ui_DATA = 
+
+# Plugin glade file
+plugin_gladedir = $(anjuta_glade_dir)
+plugin_glade_DATA = am-project.ui
+
+# Plugin icon file
+plugin_pixmapsdir = $(anjuta_image_dir)
+plugin_pixmaps_DATA = am-project-plugin-48.png
+
+# Plugin description file
+plugin_in_files = am-project.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugindir = $(anjuta_plugin_dir)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+AM_CPPFLAGS = 					\
+	$(WARN_CFLAGS) \
+	$(DEPRECATED_FLAGS) \
+	$(GIO_CFLAGS) \
+	$(LIBANJUTA_CFLAGS) \
+	-DG_LOG_DOMAIN=\"am-project\"
+
+plugin_LTLIBRARIES = \
+	libam-project.la
+
+libam_project_la_SOURCES = \
+	plugin.c \
+	plugin.h \
+	am-project.c \
+	am-project.h \
+	am-scanner.l \
+	am-parser.y \
+	am-scanner.h \
+	ac-scanner.l \
+	ac-parser.y \
+	ac-scanner.h \
+	ac-writer.h \
+	ac-writer.c \
+	am-project-private.h \
+	am-dialogs.h \
+	am-dialogs.c
+
+libam_project_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
+
+libam_project_la_LIBADD = \
+	$(GIO_LIBS) \
+	$(LIBANJUTA_LIBS)
+
+AM_YFLAGS = -t -v -g -rall
+
+ac-scanner.c: $(srcdir)/ac-scanner.l ac-parser.c
+	$(LEXCOMPILE) -o $@ $<
+
+ac-parser.c: $(srcdir)/ac-parser.y
+	$(YACCCOMPILE) -o $@ $<
+
+ac-scanner.h: ac-parser.c
+
+am-scanner.c: $(srcdir)/am-scanner.l am-parser.c
+	$(LEXCOMPILE) -o $@ $<
+
+am-parser.c: $(srcdir)/am-parser.y
+	$(YACCCOMPILE) -o $@ $<
+
+am-scanner.h: am-parser.c
+
+# Test program
+
+#noinst_PROGRAMS = test
+
+test_SOURCES = \
+	test.c
+
+test_LDADD = \
+	mk-project.la \
+	$(LIBANJUTA_LIBS)
+
+
+EXTRA_DIST = \
+	$(plugin_in_files) \
+	$(plugin_DATA) \
+	$(plugin_ui_DATA) \
+	$(plugin_pixmaps_DATA) \
+	$(plugin_glade_DATA) \
+	ac-parser.h \
+	am-parser.h
+
+DISTCLEANFILES = \
+	$(plugin_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/am-project/ac-parser.y b/plugins/am-project/ac-parser.y
new file mode 100644
index 0000000..959675e
--- /dev/null
+++ b/plugins/am-project/ac-parser.y
@@ -0,0 +1,528 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * ac-parser.y
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 <stdlib.h>
+#include "ac-scanner.h"
+#include "ac-parser.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;
+
+%}
+
+/*%union {
+	AnjutaToken *token;
+}*/
+
+%token  EOL '\n'
+
+%token  SPACE ' '
+
+%token  HASH '#'
+%token  LEFT_PAREN     '('
+%token  RIGHT_PAREN    ')'
+%token  LEFT_CURLY		'{'
+%token  RIGHT_CURLY    '}'
+%token  LEFT_BRACE     '['
+%token  RIGHT_BRACE    ']'
+%token  EQUAL             '='
+%token  COMMA             ','
+%token  LOWER           '<'
+%token  GREATER         '>'
+    
+%token  NAME
+%token  VARIABLE
+%token  MACRO
+%token  OPERATOR
+%token  WORD
+%token  JUNK
+
+%token  START_SPACE_LIST
+
+%left   ARG
+%left   EMPTY
+
+/* M4 macros */
+
+%token  DNL
+
+
+/* Autoconf macros */
+
+%token	AC_MACRO_WITH_ARG
+%token	AC_MACRO_WITHOUT_ARG
+
+%token	PKG_CHECK_MODULES
+%token	OBSOLETE_AC_OUTPUT
+%token	AC_OUTPUT
+%token	AC_CONFIG_FILES
+%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
+
+%parse-param {AmpAcScanner* scanner}
+%lex-param   {AmpAcScanner* scanner}
+
+%name-prefix="amp_ac_yy"
+
+%locations
+
+%start input
+
+%debug
+
+
+%{
+static void amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s);
+
+%}
+
+
+%%
+
+input:
+    START_SPACE_LIST space_list
+    | file
+    ;
+
+file:
+    /* empty */
+	| file statement
+	;
+   
+statement:
+    line
+    | macro
+    ;
+
+line:
+    space_token
+    | comment
+    | shell_string
+    | args_token
+    | EQUAL
+    | LOWER
+    | GREATER
+    | NAME
+    | VARIABLE
+    | WORD
+    ;
+
+macro:
+    dnl
+	| ac_macro_with_arg
+	| ac_macro_without_arg
+    | ac_init
+	| pkg_check_modules 
+	| obsolete_ac_output
+	| ac_output
+	| ac_config_files
+	;
+
+/* Space list
+ *----------------------------------------------------------------------------*/
+
+space_list:
+    /* empty */
+    | space_list_body
+    | space_list_body spaces
+    ;
+
+space_list_body:
+    item
+    | spaces item {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_NEXT);
+    }
+    | space_list_body spaces item {
+        anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
+    }
+    ;
+
+item:
+    name
+    | operator
+    ;
+
+operator:
+    OPERATOR {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_OPERATOR);
+    }
+    ;
+
+name:
+    not_operator_token
+    | name  word_token {
+        anjuta_token_group ($1, $2);
+    }
+    ;
+
+junks:
+    JUNK
+    | junks JUNK {
+        anjuta_token_group ($1, $2);
+    }
+    ;
+
+/* Macros
+ *----------------------------------------------------------------------------*/
+
+dnl:
+    DNL  not_eol_list  EOL {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
+        anjuta_token_group ($1, $3);
+    }
+    ;
+    
+
+pkg_check_modules:
+    PKG_CHECK_MODULES arg_list {
+        anjuta_token_set_type ($1, AC_TOKEN_PKG_CHECK_MODULES);
+        $$ = anjuta_token_group ($1, $2);
+    }
+	;
+
+ac_macro_without_arg:
+	AC_MACRO_WITHOUT_ARG
+	;
+
+optional_arg:
+    /* empty */     %prec EMPTY
+    | COMMA NAME %prec ARG
+    ;
+
+ac_macro_with_arg:
+	AC_MACRO_WITH_ARG optional_arg RIGHT_PAREN {
+        anjuta_token_group ($1, $1);
+    }
+	;
+
+ac_init:
+    AC_INIT arg_list {
+        anjuta_token_set_type ($1, AC_TOKEN_AC_INIT);
+        $$ = anjuta_token_group ($1, $2);
+    }
+
+ac_output:
+	AC_OUTPUT {
+        anjuta_token_set_type ($1, AC_TOKEN_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);
+    }
+	;
+	
+ac_config_files:
+    AC_CONFIG_FILES  arg_list {
+        anjuta_token_set_type ($1, AC_TOKEN_AC_CONFIG_FILES);
+        $$ = anjuta_token_group ($1, $2);
+    }
+	;
+
+/* Lists
+ *----------------------------------------------------------------------------*/
+
+arg_list:
+    arg_list_body  RIGHT_PAREN {
+        anjuta_token_set_type ($2, ANJUTA_TOKEN_LAST);
+        $$ = $2;
+    }
+    | spaces  arg_list_body  RIGHT_PAREN {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
+        anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
+        $$ = $3;
+    }
+    ;
+
+arg_list_body:
+    arg
+    | arg_list_body  separator  arg
+    ;
+    
+comment:
+    HASH not_eol_list EOL {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
+        anjuta_token_group ($1, $3);
+    }
+    ;
+
+not_eol_list:
+    /* empty */
+    | not_eol_list not_eol_token
+    ;
+
+
+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);
+    }
+    ;
+
+shell_string_body:
+    /* empty */
+    | shell_string_body not_brace_token
+    | shell_string_body shell_string
+    ;
+
+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);
+    }
+    ;
+
+raw_string_body:
+    /* empty */
+    | raw_string_body not_brace_token
+    | raw_string_body raw_string
+    ;
+
+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);
+    }
+    ;
+
+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
+    | arg_string_body macro
+    | arg_string_body raw_string
+    ;
+
+/* Items
+ *----------------------------------------------------------------------------*/
+
+arg:
+    /* empty */ {
+        $$ = NULL;
+    }
+    | arg_part arg_body {
+        $$ = anjuta_token_group_new (ANJUTA_TOKEN_ARGUMENT, $1);
+        if ($2 != NULL) anjuta_token_group ($$, $2);
+    }        
+    ;
+
+arg_body:
+    /* empty */ {
+        $$ = NULL;
+    }
+    | arg_body arg_part_or_space {
+        $$ = $2;
+    }
+    ;
+
+arg_part_or_space:
+    space_token
+    | arg_part
+    ;
+
+arg_part:
+    arg_string
+    | expression
+    | macro
+    | HASH
+    | EQUAL
+    | LOWER
+    | GREATER
+    | NAME
+    | VARIABLE
+    | WORD
+    ;
+
+separator:
+    COMMA {
+        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
+    }
+    | COMMA spaces {
+        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
+        anjuta_token_group ($$, $2);
+    }
+    ;
+
+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);
+    }
+    ;
+
+expression_body:
+    /* empty */ {
+        $$ = NULL;
+    }
+    | 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 macro
+    | expression_body expression
+    ;
+
+spaces:
+	space_token
+	| spaces space_token {
+        anjuta_token_group ($$, $2);
+	}
+	| spaces JUNK {
+        anjuta_token_group ($$, $2);
+	}
+	;
+
+/* Tokens
+ *----------------------------------------------------------------------------*/
+
+not_eol_token:
+    SPACE
+    | word_token    
+    ;
+
+not_brace_token:
+    space_token
+    | args_token
+    | HASH
+    | EQUAL
+    | LOWER
+    | GREATER
+    | OPERATOR
+    | NAME
+    | VARIABLE
+    | WORD
+    | any_macro
+    ;
+
+space_token:
+    SPACE
+    | EOL
+    ;
+
+args_token:
+    LEFT_PAREN
+    | RIGHT_PAREN
+    | COMMA
+    ;
+
+operator_token:
+    EQUAL
+    | LOWER
+    | GREATER
+    ;
+
+not_operator_token:
+    HASH
+    | LEFT_BRACE
+    | RIGHT_BRACE
+    | LEFT_PAREN
+    | RIGHT_PAREN
+    | COMMA
+    | NAME
+    | VARIABLE
+    | WORD
+    | any_macro
+    ;
+
+word_token:
+    HASH
+    | LEFT_BRACE
+    | RIGHT_BRACE
+    | LEFT_PAREN
+    | RIGHT_PAREN
+    | COMMA
+    | OPERATOR
+    | EQUAL
+    | LOWER
+    | GREATER
+    | NAME
+    | VARIABLE
+    | WORD
+    | any_macro
+    ;
+
+any_macro:
+    AC_CONFIG_FILES
+	| AC_MACRO_WITH_ARG
+	| AC_MACRO_WITHOUT_ARG
+    | AC_OUTPUT
+    | DNL
+    | OBSOLETE_AC_OUTPUT
+    | PKG_CHECK_MODULES
+    ;
+
+%%
+    
+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
new file mode 100644
index 0000000..f3d03a6
--- /dev/null
+++ b/plugins/am-project/ac-scanner.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * ac-scanner.h
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 _AC_SCANNER_H_
+#define _AC_SCANNER_H_
+
+#include "libanjuta/anjuta-token.h"
+#include "libanjuta/anjuta-token-file.h"
+
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define YYSTYPE AnjutaToken*
+
+typedef struct _AmpAcScanner AmpAcScanner;
+
+AmpAcScanner *amp_ac_scanner_new (void);
+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);
+
+
+const gchar* amp_ac_scanner_get_filename (AmpAcScanner *scanner);
+
+enum 
+{
+	AC_TOKEN_AC_INIT = ANJUTA_TOKEN_USER,
+	AC_TOKEN_PKG_CHECK_MODULES,
+	AC_TOKEN_AC_CONFIG_FILES,
+	AC_TOKEN_OBSOLETE_AC_OUTPUT,
+	AC_TOKEN_AC_OUTPUT,
+	AC_TOKEN_SPACE_LIST,
+	AC_TOKEN_OPEN_STRING,
+	AC_TOKEN_CLOSE_STRING
+};
+
+enum
+{
+	AC_SPACE_LIST_STATE = 1
+};
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/am-project/ac-scanner.l b/plugins/am-project/ac-scanner.l
new file mode 100644
index 0000000..b1868a2
--- /dev/null
+++ b/plugins/am-project/ac-scanner.l
@@ -0,0 +1,443 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * ac-scanner.l
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 <stdlib.h>
+#include <string.h>
+
+#include "ac-scanner.h"
+#include "ac-parser.h"
+
+#include "libanjuta/anjuta-debug.h"
+
+/* Eliminate warning */
+#define YY_NO_UNPUT 1 
+
+#define YY_INPUT(buf, result, max_size) result = amp_ac_scanner_input (yyextra, buf, max_size)
+
+#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
+
+#define YY_EXTRA_TYPE  AmpAcScanner*
+
+#define YY_DECL static int ac_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner)
+
+//#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);
+
+
+#define RETURN(tok) *yylval = amp_ac_scanner_append_token (yyextra, tok); \
+                    return tok
+                    
+
+struct _AmpAcScanner
+{
+    yyscan_t scanner;
+
+    AnjutaTokenFile *file;
+    gchar *filename;
+
+    AnjutaToken *token;
+    gint first;
+
+    /* Beginning of current token */
+    AnjutaToken *start;
+    gsize begin;
+
+    /* Position in buffer */
+    AnjutaToken *next;
+    gsize pos;
+};
+
+%}
+
+%option reentrant stack noyywrap yylineno
+
+%option prefix="amp_ac_yy"
+
+/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
+ * not "lex.amp_ac_yy.c"
+%option outfile="lex.yy.c"*/			
+
+%option bison-bridge bison-locations
+
+%option never-interactive
+
+%option batch
+
+%option debug
+
+WS          [ \t\r\v]+
+NL          \n
+WSNL        [ \t\v\r\n]+
+COMMENT     #
+OPENQUOTE   \[
+CLOSEQUOTE  \]
+OPENPARG   \(
+CLOSEPARG  \)
+COMMA       ,
+EQUAL       =
+LOWER       <
+GREATER     >
+NAME        [A-Za-z_][A-Za-z0-9_]*
+VARIABLE    $[A-Za-z_0-9]+
+OTHER       [^ \t\r\v\n#\[\]\\(),=><$_A-Za-z_]+
+
+%x SPACE_LIST
+
+%%
+
+{WS}                    { RETURN (SPACE); }
+
+\\\n                    { RETURN (SPACE); }
+
+{NL}                    { RETURN (EOL); }
+
+{COMMENT}               { RETURN (HASH); }
+
+{OPENQUOTE}             { RETURN (LEFT_BRACE); }
+
+{CLOSEQUOTE}            { RETURN (RIGHT_BRACE); }
+
+{OPENPARG}              { RETURN (LEFT_PAREN); }
+
+{CLOSEPARG}             { RETURN (RIGHT_PAREN); }
+
+{COMMA}                 { RETURN (COMMA); }
+
+{EQUAL}                 { RETURN (EQUAL); }
+
+{LOWER}                 { RETURN (LOWER); }
+
+{GREATER}                 { RETURN (GREATER); }
+
+dnl                     { RETURN (DNL); }
+
+PKG_CHECK_MODULES\(     { RETURN (PKG_CHECK_MODULES); }
+
+AC_OUTPUT\(             { RETURN (OBSOLETE_AC_OUTPUT); }
+ 
+AC_OUTPUT               { RETURN (AC_OUTPUT); }
+
+AC_INIT\(               { RETURN (AC_INIT); }
+ 
+AC_CONFIG_FILES\(       { RETURN (AC_CONFIG_FILES); }
+
+{NAME}                  { RETURN (NAME); }
+
+{VARIABLE}              { RETURN (VARIABLE); }
+
+{OTHER}|\$|\\           { RETURN (WORD); }
+
+
+<SPACE_LIST>{
+
+{WSNL}                    { RETURN (SPACE); }
+
+=|<|>|<=|>=             { RETURN (OPERATOR); }
+
+{NAME}                    { RETURN (WORD); }
+
+.                           {RETURN (WORD);}
+}
+
+%%
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static AnjutaToken*
+amp_ac_scanner_append_token (AmpAcScanner *scanner, gint token)
+{
+    AnjutaToken *frag;
+
+    if (scanner->file != 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);
+    }
+    else if (scanner->token != NULL)
+    {
+        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 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;
+}
+
+static gint
+amp_ac_scanner_input (AmpAcScanner *scanner, gchar *buffer, gsize max_size)
+{
+    gint result = YY_NULL;
+
+    if (scanner->file != NULL)
+    {
+        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;
+        }
+    }
+    else if (scanner->token != NULL)
+    {
+        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;
+            }
+        }
+
+    }
+
+    return result;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+int
+amp_ac_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,AmpAcScanner *scanner)
+{
+    /* 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;
+    }
+
+	/* Parse unknown data */
+    return ac_yylex (yylval_param, yylloc_param, scanner->scanner);
+}
+
+gboolean
+amp_ac_scanner_parse (AmpAcScanner *scanner, AnjutaTokenFile *file, GError **error)
+{
+
+    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;
+}
+
+gboolean
+amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error)
+{
+    AnjutaToken *child;
+
+    scanner->token = token;
+    scanner->pos = 0;
+    scanner->begin = 0;
+    scanner->file = NULL;
+    scanner->first = start;
+
+    if (anjuta_token_get_length (token) != 0)
+    {
+        AnjutaToken *copy = anjuta_token_copy (token);
+        
+        anjuta_token_insert_child (token, copy);
+        anjuta_token_clear (token);
+    }
+
+    /* Move all know data in a list */
+    for (child = anjuta_token_next_child (token); child != NULL;)
+    {
+        if (anjuta_token_get_type (child) < ANJUTA_TOKEN_FIRST)
+        {
+            child = anjuta_token_ungroup (child);
+            if (anjuta_token_get_length (child) == 0)
+            {
+                child = anjuta_token_delete (child);
+                continue;
+            }
+        }
+        child = anjuta_token_next_sibling (child);
+    }
+
+    scanner->next = anjuta_token_next_child (token);
+    scanner->start = scanner->next;
+
+	return amp_ac_yyparse (scanner) == 0;
+}
+
+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);
+    }
+	
+	return scanner->filename;
+}
+
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+AmpAcScanner *
+amp_ac_scanner_new (void)
+{
+	AmpAcScanner *scanner;
+
+	scanner = g_new0 (AmpAcScanner, 1);
+
+    yylex_init(&scanner->scanner);
+
+    yyset_extra (scanner, scanner->scanner);
+
+	return scanner;
+};
+
+void
+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
new file mode 100644
index 0000000..71d2bfc
--- /dev/null
+++ b/plugins/am-project/ac-writer.c
@@ -0,0 +1,146 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* ac-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 "ac-writer.h"
+
+#include "am-project-private.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+/* Types
+  *---------------------------------------------------------------------------*/
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static 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;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+amp_project_update_property (AmpProject *project, AmpPropertyType type)
+{
+	AnjutaToken *token;
+	guint pos;
+	const gchar *value;
+	
+	if (project->property == NULL)
+	{
+		return FALSE;
+	}
+	gchar *name;
+	gchar *version;
+	gchar *bug_report;
+	gchar *tarname;
+	gchar *url;
+
+	switch (type)
+	{
+		case AMP_PROPERTY_NAME:
+			pos = 0;
+			value = project->property->name;
+			break;
+		case AMP_PROPERTY_VERSION:
+			pos = 1;
+			value = project->property->version;
+			break;
+		case AMP_PROPERTY_BUG_REPORT:
+			pos = 2;
+			value = project->property->bug_report;
+			break;
+		case AMP_PROPERTY_TARNAME:
+			pos = 3;
+			value = project->property->tarname;
+			break;
+		case AMP_PROPERTY_URL:
+			pos = 4;
+			value = project->property->url;
+			break;
+	}
+	
+	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);
+	
+	return TRUE;
+}
+
diff --git a/plugins/am-project/ac-writer.h b/plugins/am-project/ac-writer.h
new file mode 100644
index 0000000..7a5c200
--- /dev/null
+++ b/plugins/am-project/ac-writer.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* ac-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 _AC_WRITER_H_
+#define _AC_WRITER_H_
+
+#include "am-project.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+gboolean amp_project_update_property (AmpProject *project, AmpPropertyType type); 
+
+G_END_DECLS
+
+#endif /* _AC_WRITER_H_ */
diff --git a/plugins/am-project/am-dialogs.c b/plugins/am-project/am-dialogs.c
new file mode 100644
index 0000000..8a53b9b
--- /dev/null
+++ b/plugins/am-project/am-dialogs.c
@@ -0,0 +1,159 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-dialogs.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 <glib/gi18n.h>
+
+#include "am-dialogs.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+#define GLADE_FILE  PACKAGE_DATA_DIR "/glade/am-project.ui"
+
+/* Types
+  *---------------------------------------------------------------------------*/
+
+typedef struct _AmpConfigureProjectDialog
+{
+	AmpProject *project;
+
+	GtkWidget *top_level;
+} AmpConfigureProjectDialog;
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_project_widget_destroy (GtkWidget *wid, AmpConfigureProjectDialog *dlg)
+{
+	g_object_unref (dlg->top_level);
+	g_free (dlg);
+}
+
+static void
+add_entry (AmpProject *project, const gchar *id, const gchar *display_name, AmpPropertyType type, GtkWidget *table, gint position)
+{
+	GtkWidget *label;
+	GtkWidget *entry;
+	gchar *value;
+
+	label = gtk_label_new (display_name);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, -1);
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, position, position+1,
+			  GTK_FILL, GTK_FILL, 5, 3);
+	
+	entry = gtk_entry_new ();
+	value = amp_project_get_property (project, type);
+	gtk_entry_set_text (GTK_ENTRY (entry), value);
+	g_free (value);
+	gtk_misc_set_alignment (GTK_MISC (entry), 0, -1);
+	gtk_widget_show (entry);
+	gtk_table_attach (GTK_TABLE (table), entry, 1, 2, position, position+1,
+			  GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3);
+}
+
+static void
+add_label (const gchar *display_name, const gchar *value, GtkWidget *table, gint position)
+{
+	GtkWidget *label;
+	
+	label = gtk_label_new (display_name);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, -1);
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, position, position+1,
+			  GTK_FILL, GTK_FILL, 5, 3);
+
+	label = gtk_label_new (value);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, -1);
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 1, 2, position, position+1,
+			  GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 3);
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+GtkWidget *
+amp_configure_project_dialog (AmpProject *project, GError **error)
+{
+	GtkBuilder *bxml = gtk_builder_new ();
+	GtkWidget *top_level;
+	AmpConfigureProjectDialog *dlg;
+	GtkWidget *table;
+	gchar *name;
+
+	bxml = anjuta_util_builder_new (GLADE_FILE, NULL);
+	if (!bxml) return NULL;
+
+	dlg = g_new0 (AmpConfigureProjectDialog, 1);
+	anjuta_util_builder_get_objects (bxml,
+	                                "top_level", &top_level,
+	    							"general_properties_table", &table,
+	                                NULL);
+	dlg->top_level = top_level;
+	g_object_ref (top_level);
+	g_signal_connect (top_level, "destroy", G_CALLBACK (on_project_widget_destroy), dlg);
+
+	name = g_file_get_parse_name (amp_project_get_file (project));
+	add_label (_("Path:"), name, table, 0);
+	g_free (name);
+
+	add_entry (project, NULL, _("Name:"), AMP_PROPERTY_NAME, table, 1);
+	add_entry (project, NULL, _("Version:"), AMP_PROPERTY_VERSION, table, 2);
+	add_entry (project, NULL, _("Bug report URL:"), AMP_PROPERTY_BUG_REPORT, table, 3);
+	add_entry (project, NULL, _("Package name:"), AMP_PROPERTY_TARNAME, table, 4);
+	add_entry (project, NULL, _("URL:"), AMP_PROPERTY_URL, table, 5);
+	
+	gtk_widget_show_all (top_level);
+	g_object_unref (bxml);
+
+	g_message ("get config dialog %p", top_level);
+	
+	return top_level;
+}
+
+GtkWidget *
+amp_configure_group_dialog (AmpProject *project, AmpGroup *group, GError **error)
+{
+	return NULL;
+}
+
+GtkWidget *
+amp_configure_target_dialog (AmpProject *project, AmpTarget *target, GError **error)
+{
+	return NULL;
+}
+
+GtkWidget *
+amp_configure_source_dialog (AmpProject *project, AmpSource *target, GError **error)
+{
+	return NULL;
+}
diff --git a/plugins/am-project/am-dialogs.h b/plugins/am-project/am-dialogs.h
new file mode 100644
index 0000000..99027d2
--- /dev/null
+++ b/plugins/am-project/am-dialogs.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-dialogs.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_DIALOGS_H_
+#define _AM_DIALOGS_H_
+
+#include <gtk/gtk.h>
+#include "am-project.h"
+
+G_BEGIN_DECLS
+
+GtkWidget *amp_configure_project_dialog (AmpProject *project, GError **error);
+GtkWidget *amp_configure_group_dialog (AmpProject *project, AmpGroup *group, GError **error);
+GtkWidget *amp_configure_target_dialog (AmpProject *project, AmpTarget *target, GError **error);
+GtkWidget *amp_configure_source_dialog (AmpProject *project, AmpSource *target, GError **error);
+
+G_END_DECLS
+
+#endif /* _AM_DIALOGS_H_ */
diff --git a/plugins/am-project/am-parser.y b/plugins/am-project/am-parser.y
new file mode 100644
index 0000000..a6fbcd7
--- /dev/null
+++ b/plugins/am-project/am-parser.y
@@ -0,0 +1,320 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * am-parser.y
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 <am-scanner.h>
+
+#include <stdlib.h>
+
+#define YYDEBUG 1
+
+%}
+
+/* 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
+
+%defines
+
+%pure_parser
+
+/* Necessary because autotools wrapper always looks for a file named "y.tab.c",
+ * not "amp-scanner.c"
+%output="y.tab.c"*/
+
+%glr-parser
+
+%parse-param {void* scanner}
+%lex-param   {void* scanner}
+
+%name-prefix="amp_am_yy"
+
+%locations
+
+%start file
+
+%debug
+
+%{
+
+//amp_am_yydebug = 1;
+
+static void amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s);
+
+%}
+
+
+%%
+
+file:
+	optional_space statement
+	| file EOL optional_space statement
+	;
+        
+statement:
+	/* empty */
+	| line
+	| am_variable
+	;
+
+line:
+	name_token
+	| 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);
+	}
+	| AM_VARIABLE optional_space equal_token optional_space
+	;
+				
+space_list_value: optional_space  equal_token   value_list  {
+		$$ = $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);
+		$$ = $2;
+	}
+		
+strip_value_list:
+	value {
+		$$ = anjuta_token_merge (
+			anjuta_token_insert_before ($1,
+					anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL)),
+			$1);
+	}
+	| strip_value_list  space  value {
+		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;
+	}
+	| 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 value_token {
+		anjuta_token_merge ($1, $2);
+	}
+	;
+
+prerequisite:
+	prerequisite_token
+	| prerequisite prerequisite_token {
+		anjuta_token_merge ($1, $2);
+	}
+	;
+		
+space:
+	space_token
+	| space space_token	{
+		anjuta_token_merge ($1, $2);
+	}
+	;
+
+		
+token:
+	space_token
+	| value_token
+	;            
+	
+value_token:
+	equal_token
+	| rule_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
+	;
+
+equal_token:
+	EQUAL
+	| IMMEDIATE_EQUAL
+	| CONDITIONAL_EQUAL
+	| APPEND
+	;
+
+rule_token:
+	COLON
+	| DOUBLE_COLON
+	;
+		
+head_token:
+	MACRO
+	| VARIABLE
+	| NAME
+	| CHARACTER
+	| ORDER
+	| SEMI_COLON
+	;
+
+name_token:
+	MACRO
+	| VARIABLE
+	| NAME
+	| CHARACTER
+	;
+		
+automake_token:
+	AM_VARIABLE
+	;
+		
+%%
+
+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/gbf-am/gbf-am-plugin-48.png b/plugins/am-project/am-project-plugin-48.png
similarity index 100%
rename from plugins/gbf-am/gbf-am-plugin-48.png
rename to plugins/am-project/am-project-plugin-48.png
diff --git a/plugins/am-project/am-project-private.h b/plugins/am-project/am-project-private.h
new file mode 100644
index 0000000..c49c1c3
--- /dev/null
+++ b/plugins/am-project/am-project-private.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-project-private.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_PROJECT_PRIVATE_H_
+#define _AM_PROJECT_PRIVATE_H_
+
+#include "am-project.h"
+
+G_BEGIN_DECLS
+
+struct _AmpProperty {
+	AnjutaToken *ac_init;				/* AC_INIT macro */
+	gchar *name;
+	gchar *version;
+	gchar *bug_report;
+	gchar *tarname;
+	gchar *url;
+};
+
+struct _AmpProject {
+	GObject         parent;
+
+	/* uri of the project; this can be a full uri, even though we
+	 * can only work with native local files */
+	GFile			*root_file;
+
+	/* project data */
+	AnjutaTokenFile		*configure_file;		/* configure.in file */
+
+	AmpProperty			*property;
+	
+	AmpGroup              *root_node;         	/* tree containing project data;
+								 * each GNode's data is a
+								 * AmpNode, and the root of
+								 * the tree is the root group. */
+
+	/* shortcut hash tables, mapping id -> GNode from the tree above */
+	GHashTable		*groups;
+	GHashTable		*files;
+	GHashTable		*configs;		/* Config file from configure_file */
+	
+	GHashTable	*modules;
+	
+	/* project files monitors */
+	GHashTable         *monitors;
+
+	/* Keep list style */
+	AnjutaTokenStyle *space_list;
+	AnjutaTokenStyle *arg_list;
+};
+
+G_END_DECLS
+
+#endif /* _AM_PROJECT_PRIVATE_H_ */
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
new file mode 100644
index 0000000..38ba080
--- /dev/null
+++ b/plugins/am-project/am-project.c
@@ -0,0 +1,2737 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-project.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-project.h"
+
+#include "am-project-private.h"
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <glib.h>
+
+#include "ac-scanner.h"
+#include "ac-writer.h"
+#include "am-scanner.h"
+#include "am-dialogs.h"
+//#include "am-config.h"
+//#include "am-properties.h"
+
+
+#define UNIMPLEMENTED  G_STMT_START { g_warning (G_STRLOC": unimplemented"); } G_STMT_END
+
+/* Constant strings for parsing perl script error output */
+#define ERROR_PREFIX      "ERROR("
+#define WARNING_PREFIX    "WARNING("
+#define MESSAGE_DELIMITER ": "
+
+static const gchar *valid_am_makefiles[] = {"GNUmakefile.am", "makefile.am", "Makefile.am", NULL};
+
+/* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
+#define AMP_NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
+#define AMP_GROUP_DATA(node)  ((node) != NULL ? (AmpGroupData *)((node)->data) : NULL)
+#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;
+
+struct _AmpPackage {
+    gchar *name;
+    gchar *version;
+};
+
+typedef struct _AmpModule AmpModule;
+	
+struct _AmpModule {
+    GList *packages;
+    AnjutaToken *module;
+};
+
+typedef enum {
+	AM_GROUP_TOKEN_CONFIGURE,
+	AM_GROUP_TOKEN_SUBDIRS,
+	AM_GROUP_TOKEN_DIST_SUBDIRS,
+	AM_GROUP_TARGET,
+	AM_GROUP_TOKEN_LAST
+} AmpGroupTokenCategory;
+
+typedef struct _AmpGroupData AmpGroupData;
+
+struct _AmpGroupData {
+	AnjutaProjectGroupData base;		/* Common node data */
+	gboolean dist_only;			/* TRUE if the group is distributed but not built */
+	GFile *makefile;				/* GFile corresponding to group makefile */
+	AnjutaTokenFile *tfile;		/* Corresponding Makefile */
+	GList *tokens[AM_GROUP_TOKEN_LAST];					/* List of token used by this group */
+};
+
+typedef enum _AmpTargetFlag
+{
+	AM_TARGET_CHECK = 1 << 0,
+	AM_TARGET_NOINST = 1 << 1,
+	AM_TARGET_DIST = 1 << 2,
+	AM_TARGET_NODIST = 1 << 3,
+	AM_TARGET_NOBASE = 1 << 4,
+	AM_TARGET_NOTRANS = 1 << 5,
+	AM_TARGET_MAN = 1 << 6,
+	AM_TARGET_MAN_SECTION = 31 << 7
+} AmpTargetFlag;
+
+typedef struct _AmpTargetData AmpTargetData;
+
+struct _AmpTargetData {
+	AnjutaProjectTargetData base;
+	gchar *install;
+	gint flags;
+	GList* tokens;
+};
+
+typedef struct _AmpSourceData AmpSourceData;
+
+struct _AmpSourceData {
+	AnjutaProjectSourceData base;
+	AnjutaToken* token;
+};
+
+typedef struct _AmpConfigFile AmpConfigFile;
+
+struct _AmpConfigFile {
+	GFile *file;
+	AnjutaToken *token;
+};
+
+typedef struct _AmpTargetInformation AmpTargetInformation;
+
+struct _AmpTargetInformation {
+	AnjutaProjectTargetInformation base;
+	AnjutaTokenType token;
+	const gchar *prefix;
+	const gchar *install;
+};
+
+/* Target types
+ *---------------------------------------------------------------------------*/
+
+static AmpTargetInformation AmpTargetTypes[] = {
+	{{N_("Unknown"), ANJUTA_TARGET_UNKNOWN,
+	"text/plain"},
+	ANJUTA_TOKEN_NONE,
+	NULL,
+	NULL},
+
+	{{N_("Program"), ANJUTA_TARGET_EXECUTABLE,
+	"application/x-executable"},
+	AM_TOKEN__PROGRAMS,
+	"_PROGRAMS",
+	"bin"},
+	
+	{{N_("Shared Library"), ANJUTA_TARGET_SHAREDLIB,
+	"application/x-sharedlib"},
+	AM_TOKEN__LTLIBRARIES,
+	"_LTLIBRARIES",
+	"lib"},
+	
+	{{N_("Static Library"), ANJUTA_TARGET_STATICLIB,
+	"application/x-archive"},
+	AM_TOKEN__LIBRARIES,
+	"_LIBRARIES",
+	"lib"},
+	
+	{{N_("Header Files"), ANJUTA_TARGET_UNKNOWN,
+	"text/x-chdr"},
+	AM_TOKEN__HEADERS,
+	"_HEADERS",
+	"include"},
+	
+	{{N_("Man Documentation"), ANJUTA_TARGET_UNKNOWN,
+	"text/x-troff-man"},
+	AM_TOKEN__MANS,
+	"_MANS",
+	"man"},
+	
+	{{N_("Miscellaneous Data"), ANJUTA_TARGET_UNKNOWN,
+	"application/octet-stream"},
+	AM_TOKEN__DATA,
+	"_DATA",
+	"data"},
+	
+	{{N_("Script"), ANJUTA_TARGET_EXECUTABLE,
+	"text/x-shellscript"},
+	AM_TOKEN__SCRIPTS,
+	"_SCRIPTS",
+	"bin"},
+	
+	{{N_("Info Documentation"), ANJUTA_TARGET_UNKNOWN,
+	"application/x-tex-info"},
+	AM_TOKEN__TEXINFOS,
+	"_TEXINFOS",
+	"info"},
+	
+	{{N_("Java Module"), ANJUTA_TARGET_JAVA,
+	"application/x-java"},
+	AM_TOKEN__JAVA,
+	"_JAVA",
+	NULL},
+	
+	{{N_("Python Module"), ANJUTA_TARGET_PYTHON,
+	"application/x-python"},
+	AM_TOKEN__PYTHON,
+	"_PYTHON",
+	NULL},
+	
+	{{N_("Lisp Module"), ANJUTA_TARGET_UNKNOWN,
+	"text/plain"},
+	AM_TOKEN__LISP,
+	"_LISP",
+	"lisp"},
+	
+	{{NULL, ANJUTA_TARGET_UNKNOWN,
+	NULL},
+	ANJUTA_TOKEN_NONE,
+	NULL,
+	NULL}
+};
+
+
+/* ----- Standard GObject types and variables ----- */
+
+enum {
+	PROP_0,
+	PROP_PROJECT_DIR
+};
+
+static GObject *parent_class;
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+error_set (GError **error, gint code, const gchar *message)
+{
+        if (error != NULL) {
+                if (*error != NULL) {
+                        gchar *tmp;
+
+                        /* error already created, just change the code
+                         * and prepend the string */
+                        (*error)->code = code;
+                        tmp = (*error)->message;
+                        (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
+                        g_free (tmp);
+
+                } else {
+                        *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
+                                                      code,
+                                                      message);
+                }
+        }
+}
+
+/* Work even if file is not a descendant of parent */
+static gchar*
+get_relative_path (GFile *parent, GFile *file)
+{
+	gchar *relative;
+
+	relative = g_file_get_relative_path (parent, file);
+	if (relative == NULL)
+	{
+		if (g_file_equal (parent, file))
+		{
+			relative = g_strdup ("");
+		}
+		else
+		{
+			GFile *grand_parent = g_file_get_parent (parent);
+			gint level;
+			gchar *grand_relative;
+			gchar *ptr;
+			gsize len;
+			
+			
+			for (level = 1;  !g_file_has_prefix (file, grand_parent); level++)
+			{
+				GFile *next = g_file_get_parent (grand_parent);
+				
+				g_object_unref (grand_parent);
+				grand_parent = next;
+			}
+
+			grand_relative = g_file_get_relative_path (grand_parent, file);
+			g_object_unref (grand_parent);
+
+			len = strlen (grand_relative);
+			relative = g_new (gchar, len + level * 3 + 1);
+			ptr = relative;
+			for (; level; level--)
+			{
+				memcpy(ptr, ".." G_DIR_SEPARATOR_S, 3);
+				ptr += 3;
+			}
+			memcpy (ptr, grand_relative, len + 1);
+			g_free (grand_relative);
+		}
+	}
+
+	return relative;
+}
+
+static GFileType
+file_type (GFile *file, const gchar *filename)
+{
+	GFile *child;
+	GFileInfo *info;
+	GFileType type;
+
+	child = filename != NULL ? g_file_get_child (file, filename) : g_object_ref (file);
+
+	//g_message ("check file %s", g_file_get_path (child));
+	
+	info = g_file_query_info (child,
+	                          G_FILE_ATTRIBUTE_STANDARD_TYPE, 
+	                          G_FILE_QUERY_INFO_NONE,
+	                          NULL,
+	                          NULL);
+	if (info != NULL)
+	{
+		type = g_file_info_get_file_type (info);
+		g_object_unref (info);
+	}
+	else
+	{
+		type = G_FILE_TYPE_UNKNOWN;
+	}
+	
+	g_object_unref (child);
+	
+	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
+ *---------------------------------------------------------------------------*/
+
+/* Remove invalid character according to automake rules */
+gchar*
+canonicalize_automake_variable (gchar *name)
+{
+	gchar *canon_name = g_strdup (name);
+	gchar *ptr;
+	
+	for (ptr = canon_name; *ptr != '\0'; ptr++)
+	{
+		if (!g_ascii_isalnum (*ptr) && (*ptr != '@'))
+		{
+			*ptr = '_';
+		}
+	}
+
+	return canon_name;
+}
+
+gboolean
+split_automake_variable (gchar *name, gint *flags, gchar **module, gchar **primary)
+{
+	GRegex *regex;
+	GMatchInfo *match_info;
+	gint start_pos;
+	gint end_pos;
+
+	regex = g_regex_new ("(nobase_|notrans_)?"
+	                     "(dist_|nodist_)?"
+	                     "(noinst_|check_|man_|man[0-9al]_)?"
+	                     "(.*_)?"
+	                     "([^_]+)",
+	                     G_REGEX_ANCHORED,
+	                     G_REGEX_MATCH_ANCHORED,
+	                     NULL);
+
+	if (!g_regex_match (regex, name, G_REGEX_MATCH_ANCHORED, &match_info)) return FALSE;
+
+	if (flags)
+	{
+		*flags = 0;
+		g_match_info_fetch_pos (match_info, 1, &start_pos, &end_pos);
+		if (start_pos >= 0)
+		{
+			if (*(name + start_pos + 2) == 'b') *flags |= AM_TARGET_NOBASE;
+			if (*(name + start_pos + 2) == 't') *flags |= AM_TARGET_NOTRANS;
+		}
+
+		g_match_info_fetch_pos (match_info, 2, &start_pos, &end_pos);
+		if (start_pos >= 0)
+		{
+			if (*(name + start_pos) == 'd') *flags |= AM_TARGET_DIST;
+			if (*(name + start_pos) == 'n') *flags |= AM_TARGET_NODIST;
+		}
+
+		g_match_info_fetch_pos (match_info, 3, &start_pos, &end_pos);
+		if (start_pos >= 0)
+		{
+			if (*(name + start_pos) == 'n') *flags |= AM_TARGET_NOINST;
+			if (*(name + start_pos) == 'c') *flags |= AM_TARGET_CHECK;
+			if (*(name + start_pos) == 'm')
+			{
+				gchar section = *(name + end_pos - 1);
+				*flags |= AM_TARGET_MAN;
+				if (section != 'n') *flags |= (section & 0x1F) << 7;
+			}
+		}
+	}
+
+	if (module)
+	{
+		g_match_info_fetch_pos (match_info, 4, &start_pos, &end_pos);
+		if (start_pos >= 0)
+		{
+			*module = name + start_pos;
+			*(name + end_pos - 1) = '\0';
+		}
+		else
+		{
+			*module = NULL;
+		}
+	}
+
+	if (primary)
+	{
+		g_match_info_fetch_pos (match_info, 5, &start_pos, &end_pos);
+		if (start_pos >= 0)
+		{
+			*primary = name + start_pos;
+		}
+		else
+		{
+			*primary = NULL;
+		}
+	}
+
+	g_regex_unref (regex);
+
+	return TRUE;
+}
+
+gchar*
+ac_init_default_tarname (const gchar *name)
+{
+	gchar *tarname;
+
+	/* Remove GNU prefix */
+	if (strncmp (name, "GNU ", 4) == 0) name += 4;
+
+	tarname = g_ascii_strdown (name, -1);
+	g_strcanon (tarname, "abcdefghijklmnopqrstuvwxyz0123456789", '-');
+	
+	return tarname;
+}
+
+/* Config file objects
+ *---------------------------------------------------------------------------*/
+
+static AmpConfigFile*
+amp_config_file_new (const gchar *pathname, GFile *project_root, AnjutaToken *token)
+{
+	AmpConfigFile *config;
+
+	g_return_val_if_fail ((pathname != NULL) && (project_root != NULL), NULL);
+
+	config = g_slice_new0(AmpConfigFile);
+	config->file = g_file_resolve_relative_path (project_root, pathname);
+	config->token = token;
+
+	return config;
+}
+
+static void
+amp_config_file_free (AmpConfigFile *config)
+{
+	if (config)
+	{
+		g_object_unref (config->file);
+		g_slice_free (AmpConfigFile, config);
+	}
+}
+
+/* Package objects
+ *---------------------------------------------------------------------------*/
+
+void
+amp_package_set_version (AmpPackage *package, const gchar *compare, const gchar *version)
+{
+	g_return_if_fail (package != NULL);
+	g_return_if_fail ((version == NULL) || (compare != NULL));
+
+	g_free (package->version);
+	package->version = version != NULL ? g_strconcat (compare, version, NULL) : NULL;
+}
+
+static AmpPackage*
+amp_package_new (const gchar *name)
+{
+	AmpPackage *package;
+
+	g_return_val_if_fail (name != NULL, NULL);
+	
+	package = g_slice_new0(AmpPackage); 
+	package->name = g_strdup (name);
+
+	return package;
+}
+
+static void
+amp_package_free (AmpPackage *package)
+{
+	if (package)
+	{
+		g_free (package->name);
+		g_free (package->version);
+		g_slice_free (AmpPackage, package);
+	}
+}
+
+/* Module objects
+ *---------------------------------------------------------------------------*/
+
+static AmpModule*
+amp_module_new (AnjutaToken *token)
+{
+	AmpModule *module;
+	
+	module = g_slice_new0(AmpModule); 
+	module->module = token;
+
+	return module;
+}
+
+static void
+amp_module_free (AmpModule *module)
+{
+	if (module)
+	{
+		g_list_foreach (module->packages, (GFunc)amp_package_free, NULL);
+		g_slice_free (AmpModule, module);
+	}
+}
+
+static void
+amp_project_new_module_hash (AmpProject *project)
+{
+	project->modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)amp_module_free);
+}
+
+static void
+amp_project_free_module_hash (AmpProject *project)
+{
+	if (project->modules != NULL)
+	{
+		g_hash_table_destroy (project->modules);
+		project->modules = NULL;
+	}
+}
+
+/* Property objects
+ *---------------------------------------------------------------------------*/
+
+static AmpProperty*
+amp_property_new (AnjutaToken *token)
+{
+	AmpProperty *prop;
+	AnjutaToken *arg;
+	
+	prop = g_slice_new0(AmpProperty); 
+	prop->ac_init = token;
+
+	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);
+	
+	return prop;
+}
+
+static void
+amp_property_free (AmpProperty *prop)
+{
+	g_free (prop->name);
+	g_free (prop->version);
+	g_free (prop->bug_report);
+	g_free (prop->tarname);
+    g_slice_free (AmpProperty, prop);
+}
+
+/* Group objects
+ *---------------------------------------------------------------------------*/
+
+static void
+amp_group_add_token (AmpGroup *node, AnjutaToken *token, AmpGroupTokenCategory category)
+{
+    AmpGroupData *group;
+	
+	g_return_if_fail ((node != NULL) && (node->data != NULL)); 
+
+ 	group = AMP_GROUP_DATA (node);
+	group->tokens[category] = g_list_prepend (group->tokens[category], token);
+}
+
+static GList *
+amp_group_get_token (AmpGroup *node, AmpGroupTokenCategory category)
+{
+    AmpGroupData *group;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	group = AMP_GROUP_DATA (node);
+	return group->tokens[category];
+}
+
+static void
+amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
+{
+	g_return_if_fail ((node != NULL) && (node->data != NULL)); 
+
+ 	AMP_GROUP_DATA (node)->dist_only = dist_only;
+}
+
+static AnjutaTokenFile*
+amp_group_set_makefile (AmpGroup *node, GFile *makefile)
+{
+    AmpGroupData *group;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	group = AMP_GROUP_DATA (node);
+	if (group->makefile != NULL) g_object_unref (group->makefile);
+	if (group->tfile != NULL) anjuta_token_file_free (group->tfile);
+	if (makefile != NULL)
+	{
+		group->makefile = g_object_ref (makefile);
+		group->tfile = anjuta_token_file_new (makefile);
+	}
+	else
+	{
+		group->makefile = NULL;
+		group->tfile = NULL;
+	}
+
+	return group->tfile;
+}
+
+static AmpGroup*
+amp_group_new (GFile *file, gboolean dist_only)
+{
+    AmpGroupData *group = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	
+	group = g_slice_new0(AmpGroupData); 
+	group->base.node.type = ANJUTA_PROJECT_GROUP;
+	group->base.directory = g_object_ref (file);
+	group->dist_only = dist_only;
+
+    return g_node_new (group);
+}
+
+static void
+amp_group_free (AmpGroup *node)
+{
+    AmpGroupData *group = (AmpGroupData *)node->data;
+	gint i;
+	
+	if (group->base.directory) g_object_unref (group->base.directory);
+	if (group->tfile) anjuta_token_file_free (group->tfile);
+	if (group->makefile) g_object_unref (group->makefile);
+	for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
+	{
+		if (group->tokens[i] != NULL) g_list_free (group->tokens[i]);
+	}
+    g_slice_free (AmpGroupData, group);
+
+	g_node_destroy (node);
+}
+
+/* Target objects
+ *---------------------------------------------------------------------------*/
+
+static void
+amp_target_add_token (AmpGroup *node, AnjutaToken *token)
+{
+    AmpTargetData *target;
+	
+	g_return_if_fail ((node != NULL) && (node->data != NULL)); 
+
+ 	target = AMP_TARGET_DATA (node);
+	target->tokens = g_list_prepend (target->tokens, token);
+}
+
+static GList *
+amp_target_get_token (AmpGroup *node)
+{
+    AmpTargetData *target;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	target = AMP_TARGET_DATA (node);
+	return target->tokens;
+}
+
+
+static AmpTarget*
+amp_target_new (const gchar *name, AnjutaProjectTargetType type, const gchar *install, gint flags)
+{
+    AmpTargetData *target = NULL;
+
+	target = g_slice_new0(AmpTargetData); 
+	target->base.node.type = ANJUTA_PROJECT_TARGET;
+	target->base.name = g_strdup (name);
+	target->base.type = type;
+	target->install = g_strdup (install);
+	target->flags = flags;
+
+    return g_node_new (target);
+}
+
+static void
+amp_target_free (AmpTarget *node)
+{
+    AmpTargetData *target = AMP_TARGET_DATA (node);
+	
+    g_free (target->base.name);
+    g_free (target->install);
+    g_slice_free (AmpTargetData, target);
+
+	g_node_destroy (node);
+}
+
+/* Source objects
+ *---------------------------------------------------------------------------*/
+
+static AmpSource*
+amp_source_new (GFile *file)
+{
+    AmpSourceData *source = NULL;
+
+	source = g_slice_new0(AmpSourceData); 
+	source->base.node.type = ANJUTA_PROJECT_SOURCE;
+	source->base.file = g_object_ref (file);
+
+    return g_node_new (source);
+}
+
+static void
+amp_source_free (AmpSource *node)
+{
+    AmpSourceData *source = AMP_SOURCE_DATA (node);
+	
+    g_object_unref (source->base.file);
+    g_slice_free (AmpSourceData, source);
+
+	g_node_destroy (node);
+}
+
+/*
+ * File monitoring support --------------------------------
+ * FIXME: review these
+ */
+static void
+monitor_cb (GFileMonitor *monitor,
+			GFile *file,
+			GFile *other_file,
+			GFileMonitorEvent event_type,
+			gpointer data)
+{
+	AmpProject *project = data;
+
+	g_return_if_fail (project != NULL && AMP_IS_PROJECT (project));
+
+	switch (event_type) {
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		case G_FILE_MONITOR_EVENT_DELETED:
+			/* monitor will be removed here... is this safe? */
+			amp_project_reload (project, NULL);
+			g_signal_emit_by_name (G_OBJECT (project), "project-updated");
+			break;
+		default:
+			break;
+	}
+}
+
+
+static void
+monitor_add (AmpProject *project, GFile *file)
+{
+	GFileMonitor *monitor = NULL;
+	
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (project->monitors != NULL);
+	
+	if (file == NULL)
+		return;
+	
+	monitor = g_hash_table_lookup (project->monitors, file);
+	if (!monitor) {
+		gboolean exists;
+		
+		/* FIXME clarify if uri is uri, path or both */
+		exists = g_file_query_exists (file, NULL);
+		
+		if (exists) {
+			monitor = g_file_monitor_file (file, 
+						       G_FILE_MONITOR_NONE,
+						       NULL,
+						       NULL);
+			if (monitor != NULL)
+			{
+				g_signal_connect (G_OBJECT (monitor),
+						  "changed",
+						  G_CALLBACK (monitor_cb),
+						  project);
+				g_hash_table_insert (project->monitors,
+						     g_object_ref (file),
+						     monitor);
+			}
+		}
+	}
+}
+
+static void
+monitors_remove (AmpProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	if (project->monitors)
+		g_hash_table_destroy (project->monitors);
+	project->monitors = NULL;
+}
+
+static void
+group_hash_foreach_monitor (gpointer key,
+			    gpointer value,
+			    gpointer user_data)
+{
+	AmpGroup *group_node = value;
+	AmpProject *project = user_data;
+
+	monitor_add (project, AMP_GROUP_DATA(group_node)->base.directory);
+}
+
+static void
+monitors_setup (AmpProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	monitors_remove (project);
+	
+	/* setup monitors hash */
+	project->monitors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+						   (GDestroyNotify) g_file_monitor_cancel);
+
+	monitor_add (project, anjuta_token_file_get_file (project->configure_file));
+	if (project->groups)
+		g_hash_table_foreach (project->groups, group_hash_foreach_monitor, project);
+}
+
+
+/*
+ * ---------------- Data structures managment
+ */
+
+static void
+amp_dump_node (GNode *g_node)
+{
+	gchar *name = NULL;
+	
+	switch (AMP_NODE_DATA (g_node)->type) {
+		case ANJUTA_PROJECT_GROUP:
+			name = g_file_get_uri (AMP_GROUP_DATA (g_node)->base.directory);
+			DEBUG_PRINT ("GROUP: %s", name);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			name = g_strdup (AMP_TARGET_DATA (g_node)->base.name);
+			DEBUG_PRINT ("TARGET: %s", name);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			name = g_file_get_uri (AMP_SOURCE_DATA (g_node)->base.file);
+			DEBUG_PRINT ("SOURCE: %s", name);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+	g_free (name);
+}
+
+static gboolean 
+foreach_node_destroy (GNode    *g_node,
+		      gpointer  data)
+{
+	switch (AMP_NODE_DATA (g_node)->type) {
+		case ANJUTA_PROJECT_GROUP:
+			//g_hash_table_remove (project->groups, g_file_get_uri (AMP_GROUP_NODE (g_node)->file));
+			amp_group_free (g_node);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			amp_target_free (g_node);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			//g_hash_table_remove (project->sources, AMP_NODE (g_node)->id);
+			amp_source_free (g_node);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+	
+
+	return FALSE;
+}
+
+static void
+project_node_destroy (AmpProject *project, GNode *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,
+				 foreach_node_destroy, project);
+
+		/* now destroy the tree itself */
+		//g_node_destroy (g_node);
+	}
+}
+
+static gboolean
+project_reload_property (AmpProject *project)
+{
+	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;                                       
+}
+
+static void
+project_reload_packages   (AmpProject *project)
+{
+	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 (;;)
+	{
+		AnjutaToken *module;
+		AnjutaToken *arg;
+		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 */
+
+		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);
+		
+		pack = NULL;
+		compare = NULL;
+		for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+		{
+			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;		/* Empty value, a comment of a quote by example */
+
+			if ((pack != NULL) && (compare != NULL))
+			{
+				amp_package_set_version (pack, compare, value);
+				g_free (value);
+				g_free (compare);
+				pack = NULL;
+				compare = NULL;
+			}
+			else if ((pack != NULL) && (anjuta_token_get_type (arg) == ANJUTA_TOKEN_OPERATOR))
+			{
+				compare = value;
+			}
+			else
+			{
+				pack = amp_package_new (value);
+				mod->packages = g_list_prepend (mod->packages, pack);
+				g_free (value);
+				compare = NULL;
+			}
+		}
+		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)
+{
+	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)
+	{
+		AnjutaToken *arg;
+
+		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);
+		
+    sequence = anjuta_token_file_first (project->configure_file);
+	while (sequence != NULL)
+	{
+		AnjutaToken *arg;
+
+		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);
+	}
+	
+	if (scanner) amp_ac_scanner_free (scanner);
+	anjuta_token_free (config_files_tok);
+
+	return TRUE;
+}
+
+static void
+find_target (GNode *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;
+
+			return;
+		}
+	}
+}
+
+static void
+find_canonical_target (GNode *node, gpointer data)
+{
+	if (AMP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
+	{
+		gchar *canon_name = canonicalize_automake_variable (AMP_TARGET_DATA (node)->base.name);	
+		DEBUG_PRINT ("compare canon %s vs %s node %p", canon_name, *(gchar **)data, node);
+		if (strcmp (canon_name, *(gchar **)data) == 0)
+		{
+			/* Find target, return node value in pointer */
+			*(GNode **)data = node;
+			g_free (canon_name);
+
+			return;
+		}
+		g_free (canon_name);
+	}
+}
+
+static AnjutaToken*
+project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+{
+	AnjutaToken *arg;
+	AnjutaProjectTargetType type = NULL;
+	gchar *install;
+	gchar *name;
+	gint flags;
+	AmpTargetInformation *targets = AmpTargetTypes; 
+
+	type = (AnjutaProjectTargetType)targets;
+	while (targets->base.name != NULL)
+	{
+		if (anjuta_token_get_type (start) == targets->token)
+		{
+			type = (AnjutaProjectTargetType)targets;
+			break;
+		}
+		targets++;
+	}
+
+	name = anjuta_token_get_value (start);
+	split_automake_variable (name, &flags, &install, NULL);
+	g_free (name);
+
+	amp_group_add_token (parent, start, 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))
+	{
+		gchar *value;
+		gchar *canon_id;
+		AmpTarget *target;
+		GList *sources;
+		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);
+		if ((gchar *)find != value)
+		{
+			/* Find target */
+			g_free (canon_id);
+			g_free (value);
+			continue;
+		}
+
+		/* Create target */
+		target = amp_target_new (value, type, install, flags);
+		amp_target_add_token (target, arg);
+		g_node_append (parent, target);
+		DEBUG_PRINT ("create target %p name %s", target, value);
+
+		/* Check if there are source availables */
+		if (g_hash_table_lookup_extended (orphan_sources, canon_id, (gpointer *)&orig_key, (gpointer *)&sources))
+		{
+			GList *src;
+			g_hash_table_steal (orphan_sources, canon_id);
+			for (src = sources; src != NULL; src = g_list_next (src))
+			{
+				AmpSource *source = src->data;
+
+				g_node_prepend (target, source);
+			}
+			g_free (orig_key);
+			g_list_free (sources);
+		}
+
+		g_free (canon_id);
+		g_free (value);
+	}
+
+	return NULL;
+}
+
+static AnjutaToken*
+project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+{
+	AnjutaToken *arg;
+	AmpGroupData *group = AMP_GROUP_DATA (parent);
+	GFile *parent_file = g_object_ref (group->base.directory);
+	gchar *target_id = NULL;
+	GList *orphan = NULL;
+
+	target_id = anjuta_token_get_value (start);
+	if (target_id)
+	{
+		gchar *end = strrchr (target_id, '_');
+		if (end)
+		{
+			*end = '\0';
+		}
+	}
+
+	if (target_id)
+	{
+		gpointer find;
+		
+		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;
+
+		for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (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 */
+			src_file = g_file_get_child (parent_file, value);
+			source = amp_source_new (src_file);
+			g_object_unref (src_file);
+			AMP_SOURCE_DATA(source)->token = arg;
+
+			if (parent == NULL)
+			{
+				/* Add in orphan list */
+				orphan = g_list_prepend (orphan, source);
+			}
+			else
+			{
+				DEBUG_PRINT ("add target child %p", parent);
+				/* Add as target child */
+				g_node_append (parent, source);
+			}
+
+			g_free (value);
+		}
+		
+		if (parent == NULL)
+		{
+			gchar *orig_key;
+			GList *orig_sources;
+
+			if (g_hash_table_lookup_extended (orphan_sources, target_id, (gpointer *)&orig_key, (gpointer *)&orig_sources))
+			{
+				g_hash_table_steal (orphan_sources, target_id);
+				orphan = g_list_concat (orphan, orig_sources);	
+				g_free (orig_key);
+			}
+			g_hash_table_insert (orphan_sources, target_id, orphan);
+		}
+		else
+		{
+			g_free (target_id);
+		}
+	}
+
+	g_object_unref (parent_file);
+
+	return NULL;
+}
+
+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)
+{
+	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))
+	{
+		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 */
+		if (strcmp (value, ".") != 0)
+		{
+			GFile *subdir;
+			gchar *group_id;
+			AmpGroup *group;
+
+			subdir = g_file_resolve_relative_path (AMP_GROUP_DATA (parent)->base.directory, value);
+			
+			/* Look for already existing group */
+			group_id = g_file_get_uri (subdir);
+			group = g_hash_table_lookup (project->groups, group_id);
+			g_free (group_id);
+
+			if (group != NULL)
+			{
+				/* Already existing group, mark for built if needed */
+				if (!dist_only) amp_group_set_dist_only (group, FALSE);
+			}
+			else
+			{
+				/* Create new group */
+				group = project_load_makefile (project, subdir, parent, dist_only);
+			}
+			amp_group_add_token (group, arg, dist_only ? AM_GROUP_TOKEN_DIST_SUBDIRS : AM_GROUP_TOKEN_SUBDIRS);
+			g_object_unref (subdir);
+		}
+		g_free (value);
+	}
+}
+
+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)
+	{
+		AmpProject *project = (AmpProject *)data;
+		g_hash_table_remove (project->files, anjuta_token_file_get_file (ANJUTA_TOKEN_FILE (object)));
+	}
+}
+
+static AmpGroup*
+project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean dist_only)
+{
+	GHashTable *orphan_sources = NULL;
+	const gchar **filename;
+	AmpAmScanner *scanner;
+	AmpGroup *group;
+	AnjutaToken *significant_tok;
+	AnjutaToken *arg;
+	AnjutaTokenFile *tfile;
+	GFile *makefile = NULL;
+	gboolean found;
+
+	/* Create group */
+	group = amp_group_new (file, dist_only);
+	g_hash_table_insert (project->groups, g_file_get_uri (file), group);
+	if (parent == NULL)
+	{
+		project->root_node = group;
+	}
+	else
+	{
+		g_node_append (parent, group);
+	}
+		
+	/* Find makefile name
+	 * It has to be in the config_files list with .am extension */
+	for (filename = valid_am_makefiles; *filename != NULL; filename++)
+	{
+		makefile = g_file_get_child (file, *filename);
+		if (file_type (file, *filename) == G_FILE_TYPE_REGULAR)
+		{
+			gchar *final_filename = g_strdup (*filename);
+			gchar *ptr;
+			GFile *final_file;
+			AmpConfigFile *config;
+
+			ptr = g_strrstr (final_filename,".am");
+			if (ptr != NULL) *ptr = '\0';
+			final_file = g_file_get_child (file, final_filename);
+			g_free (final_filename);
+			
+			config = g_hash_table_lookup (project->configs, final_file);
+			g_object_unref (final_file);
+			if (config != NULL)
+			{
+				amp_group_add_token (group, config->token, AM_GROUP_TOKEN_CONFIGURE);
+				break;
+			}
+		}
+		g_object_unref (makefile);
+	}
+
+	if (*filename == NULL)
+	{
+		/* Unable to find automake file */
+		return group;
+	}
+	
+	/* Parse makefile.am */	
+	DEBUG_PRINT ("Parse: %s", g_file_get_uri (makefile));
+	tfile = amp_group_set_makefile (group, makefile);
+	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);
+
+	/* 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;
+		}
+	}
+
+	/* Free unused sources files */
+	g_hash_table_destroy (orphan_sources);
+
+	return group;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+amp_project_reload (AmpProject *project, GError **error) 
+{
+	AmpAcScanner *scanner;
+	GFile *root_file;
+	GFile *configure_file;
+	gboolean ok;
+	GError *err = NULL;
+
+	/* Unload current project */
+	root_file = g_object_ref (project->root_file);
+	amp_project_unload (project);
+	project->root_file = root_file;
+	DEBUG_PRINT ("reload project %p root file %p", project, project->root_file);
+
+	/* 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);
+
+	/* Initialize list styles */
+	project->space_list = anjuta_token_style_new (NULL, " ", "\\n", NULL, 0);
+	project->arg_list = anjuta_token_style_new (NULL, ", ", ",\\n ", ")", 0);
+	
+	/* Find configure file */
+	if (file_type (root_file, "configure.ac") == G_FILE_TYPE_REGULAR)
+	{
+		configure_file = g_file_get_child (root_file, "configure.ac");
+	}
+	else if (file_type (root_file, "configure.in") == G_FILE_TYPE_REGULAR)
+	{
+		configure_file = g_file_get_child (root_file, "configure.in");
+	}
+	else
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+
+		return FALSE;
+	}
+	
+	/* Parse configure */	
+	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);
+	amp_ac_scanner_free (scanner);
+	if (!ok)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             	IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED,
+		    			err == NULL ? _("Unable to parse project file") : err->message);
+		if (err != NULL) g_error_free (err);
+
+		return FALSE;
+	}
+		     
+	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, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+
+		ok = FALSE;
+	}
+	
+	return ok;
+}
+
+gboolean
+amp_project_load (AmpProject  *project,
+    GFile *directory,
+	GError     **error)
+{
+	g_return_val_if_fail (directory != NULL, FALSE);
+
+	project->root_file = g_object_ref (directory);
+	if (!amp_project_reload (project, error))
+	{
+		g_object_unref (project->root_file);
+		project->root_file = NULL;
+	}
+
+	return project->root_file != NULL;
+}
+
+void
+amp_project_unload (AmpProject *project)
+{
+	monitors_remove (project);
+	
+	/* project data */
+	project_node_destroy (project, project->root_node);
+	project->root_node = NULL;
+
+	if (project->configure_file)	g_object_unref (G_OBJECT (project->configure_file));
+	project->configure_file = NULL;
+
+	if (project->root_file) g_object_unref (project->root_file);
+	project->root_file = NULL;
+
+	if (project->property) amp_property_free (project->property);
+	project->property = NULL;
+	
+	/* shortcut hash tables */
+	if (project->groups) g_hash_table_destroy (project->groups);
+	if (project->files) g_hash_table_destroy (project->files);
+	if (project->configs) g_hash_table_destroy (project->configs);
+	project->groups = NULL;
+	project->files = NULL;
+	project->configs = NULL;
+
+	/* List styles */
+	if (project->space_list) anjuta_token_style_free (project->space_list);
+	if (project->arg_list) anjuta_token_style_free (project->arg_list);
+	
+	amp_project_free_module_hash (project);
+}
+
+gint
+amp_project_probe (GFile *file,
+	    GError     **error)
+{
+	gint probe;
+	gboolean dir;
+
+	dir = (file_type (file, NULL) == G_FILE_TYPE_DIRECTORY);
+	if (!dir)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+	}
+	
+	probe =  dir; 
+	if (probe)
+	{
+		const gchar **makefile;
+
+		/* Look for makefiles */
+		probe = FALSE;
+		for (makefile = valid_am_makefiles; *makefile != NULL; makefile++)
+		{
+			if (file_type (file, *makefile) == G_FILE_TYPE_REGULAR)
+			{
+				probe = TRUE;
+				break;
+			}
+		}
+
+		if (probe)
+		{
+			probe = ((file_type (file, "configure.ac") == G_FILE_TYPE_REGULAR) ||
+			 				(file_type (file, "configure.in") == G_FILE_TYPE_REGULAR));
+		}
+	}
+
+	return probe ? IANJUTA_PROJECT_PROBE_PROJECT_FILES : 0;
+}
+
+AmpGroup* 
+amp_project_add_group (AmpProject  *project,
+		AmpGroup *parent,
+		const gchar *name,
+		GError     **error)
+{
+	AmpGroup *last;
+	AmpGroup *child;
+	GFile *directory;
+	GFile *makefile;
+	AnjutaToken* token;
+	AnjutaToken* prev_token;
+	GList *token_list;
+	gchar *basename;
+	gchar *uri;
+	AnjutaTokenFile* tfile;
+	
+	g_return_val_if_fail (name != NULL, NULL);
+	g_return_val_if_fail (parent != NULL, NULL);
+
+	/* Validate group name */
+	if (!name || strlen (name) <= 0)
+	{
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			   _("Please specify group name"));
+		return NULL;
+	}
+	{
+		gboolean failed = FALSE;
+		const gchar *ptr = name;
+		while (*ptr) {
+			if (!isalnum (*ptr) && *ptr != '.' && *ptr != '-' &&
+			    *ptr != '_')
+				failed = TRUE;
+			ptr++;
+		}
+		if (failed) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Group name can only contain alphanumeric, '_', '-' or '.' characters"));
+			return NULL;
+		}
+	}
+
+	/* Check that the new group doesn't already exist */
+	directory = g_file_get_child (AMP_GROUP_DATA (parent)->base.directory, name);
+	uri = g_file_get_uri (directory);
+	if (g_hash_table_lookup (project->groups, uri) != NULL)
+	{
+		g_free (uri);
+		error_set (error, IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			_("Group already exists"));
+		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);
+
+	/* Create directory */
+	g_file_make_directory (directory, NULL, NULL);
+
+	/* Create Makefile.am */
+	basename = g_file_get_basename (AMP_GROUP_DATA (parent)->makefile);
+	if (basename != NULL)
+	{
+		makefile = g_file_get_child (directory, basename);
+		g_free (basename);
+	}
+	else
+	{
+		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);
+	g_hash_table_insert (project->files, makefile, tfile);
+	g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project);
+
+	/* Add in configure */
+	token_list= amp_group_get_token (parent, AM_GROUP_TOKEN_CONFIGURE);
+	if (token_list != NULL)
+	{
+		gchar *relative_make;
+		gchar *ext;
+		AnjutaTokenStyle *style;
+		
+		prev_token = (AnjutaToken *)token_list->data;
+
+		relative_make = g_file_get_relative_path (project->root_file, makefile);
+		ext = relative_make + strlen (relative_make) - 3;
+		if (strcmp (ext, ".am") == 0)
+		{
+			*ext = '\0';
+		}
+		token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED,  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);
+	}
+	
+	/* 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)
+	{
+		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))
+		{
+			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;
+		}
+
+		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);
+			}
+		}
+
+		token = anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT | ANJUTA_TOKEN_ADDED, NULL);
+		if (prev_token == NULL)
+		{
+			prev_token = anjuta_token_insert_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile), token);
+		}
+		else
+		{
+			prev_token = anjuta_token_insert_after (prev_token, 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;
+		
+			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);
+
+	return child;
+}
+
+void 
+amp_project_remove_group (AmpProject  *project,
+		   AmpGroup *group,
+		   GError     **error)
+{
+	GList *token_list;
+
+	if (AMP_NODE_DATA (group)->type != ANJUTA_PROJECT_GROUP) return;
+	
+	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);
+	}
+	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);
+	}
+	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);
+	}
+
+	amp_group_free (group);
+}
+
+AmpTarget*
+amp_project_add_target (AmpProject  *project,
+		 AmpGroup *parent,
+		 const gchar *name,
+		 AnjutaProjectTargetType type,
+		 GError     **error)
+{
+	AmpTarget *child;
+	AnjutaToken* token;
+	AnjutaToken* prev_token;
+	AnjutaToken *list;
+	gchar *targetname;
+	gchar *find;
+	GList *last;
+	
+	g_return_val_if_fail (name != NULL, NULL);
+	g_return_val_if_fail (parent != NULL, NULL);
+
+	/* Validate target name */
+	if (!name || strlen (name) <= 0)
+	{
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			   _("Please specify target name"));
+		return NULL;
+	}
+	{
+		gboolean failed = FALSE;
+		const gchar *ptr = name;
+		while (*ptr) {
+			if (!isalnum (*ptr) && *ptr != '.' && *ptr != '-' &&
+			    *ptr != '_')
+				failed = TRUE;
+			ptr++;
+		}
+		if (failed) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Target name can only contain alphanumeric, '_', '-' or '.' characters"));
+			return NULL;
+		}
+	}
+	if (type->base == ANJUTA_TARGET_SHAREDLIB) {
+		if (strlen (name) < 7 ||
+		    strncmp (name, "lib", strlen("lib")) != 0 ||
+		    strcmp (&name[strlen(name) - 3], ".la") != 0) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Shared library target name must be of the form 'libxxx.la'"));
+			return NULL;
+		}
+	}
+	else if (type->base == ANJUTA_TARGET_STATICLIB) {
+		if (strlen (name) < 6 ||
+		    strncmp (name, "lib", strlen("lib")) != 0 ||
+		    strcmp (&name[strlen(name) - 2], ".a") != 0) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Static library target name must be of the form 'libxxx.a'"));
+			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);
+	if ((gchar *)find != name)
+	{
+		error_set (error, IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			_("Target already exists"));
+
+		return NULL;
+	}
+	
+	/* Add target node in project tree */
+	child = amp_target_new (name, type, "", 0);
+	g_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))
+	{
+		gchar *value = anjuta_token_evaluate ((AnjutaToken *)last->data);
+		
+		if ((value != NULL) && (strcmp (targetname, value) == 0))
+		{
+			g_free (value);
+			break;
+		}
+		g_free (value);
+	}
+
+	token = anjuta_token_new_string (((AmpTargetInformation *)type)->token, targetname);
+	g_free (targetname);
+
+	if (last == NULL)
+	{
+		prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile));
+		if (prev_token != NULL)
+		{
+			/* Add at the end of the file */
+			while (anjuta_token_next_sibling (prev_token) != NULL)
+			{
+				prev_token = anjuta_token_next_sibling (prev_token);
+			}
+		}
+
+		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;
+	}
+	else
+	{
+		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_insert_child (token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
+		}
+		else
+		{
+			token = anjuta_token_next_child (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, " "));
+	}
+	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;
+}
+
+void 
+amp_project_remove_target (AmpProject  *project,
+		    AmpTarget *target,
+		    GError     **error)
+{
+	GList *token_list;
+
+	if (AMP_NODE_DATA (target)->type != ANJUTA_PROJECT_TARGET) return;
+	
+	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);
+	}
+
+	amp_target_free (target);
+}
+
+AmpSource* 
+amp_project_add_source (AmpProject  *project,
+		 AmpTarget *target,
+		 GFile *file,
+		 GError     **error)
+{
+	AmpGroup *group;
+	AmpSource *last;
+	AmpSource *source;
+	AnjutaToken* token;
+	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;
+
+	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)
+	{
+		/* 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 */
+		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));
+		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
+	{
+		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);
+	
+	/* Add source node in project tree */
+	source = amp_source_new (file);
+	AMP_SOURCE_DATA(source)->token = token;
+	g_node_append (target, source);
+
+	return source;
+}
+
+void 
+amp_project_remove_source (AmpProject  *project,
+		    AmpSource *source,
+		    GError     **error)
+{
+	amp_dump_node (source);
+	if (AMP_NODE_DATA (source)->type != ANJUTA_PROJECT_SOURCE) return;
+	
+	remove_list_item (AMP_SOURCE_DATA (source)->token, NULL);
+
+	amp_source_free (source);
+}
+
+GList *
+amp_project_get_config_modules   (AmpProject *project, GError **error)
+{
+	return project->modules == NULL ? NULL : g_hash_table_get_keys (project->modules);
+}
+
+GList *
+amp_project_get_config_packages  (AmpProject *project,
+			   const gchar* module,
+			   GError **error)
+{
+	AmpModule *mod;
+	GList *packages = NULL;
+
+	g_return_val_if_fail (project != NULL, NULL);
+	g_return_val_if_fail (module != NULL, NULL);
+
+	mod = g_hash_table_lookup (project->modules, module);
+
+	if (mod != NULL)
+	{
+		GList *node;
+
+		for (node = mod->packages; node != NULL; node = g_list_next (node))
+		{
+			packages = g_list_prepend (packages, ((AmpPackage *)node->data)->name);
+		}
+
+		packages = g_list_reverse (packages);
+	}
+
+	return packages;
+}
+
+GList *
+amp_project_get_target_types (AmpProject *project, GError **error)
+{
+	AmpTargetInformation *targets = AmpTargetTypes; 
+	GList *types = NULL;
+
+	while (targets->base.name != NULL)
+	{
+		types = g_list_prepend (types, targets);
+		targets++;
+	}
+	types = g_list_reverse (types);
+
+	return types;
+}
+
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+amp_project_save (AmpProject *project, GError **error)
+{
+	gpointer key;
+	gpointer value;
+	GHashTableIter iter;
+
+	g_return_val_if_fail (project != NULL, FALSE);
+
+	g_hash_table_iter_init (&iter, project->files);
+	while (g_hash_table_iter_next (&iter, &key, &value))
+	{
+		GError *error = NULL;
+		AnjutaTokenFile *tfile = (AnjutaTokenFile *)value;
+		;
+		anjuta_token_file_save (tfile, &error);
+	}
+
+	return TRUE;
+}
+
+gboolean
+amp_project_move (AmpProject *project, const gchar *path)
+{
+	GFile	*old_root_file;
+	GFile *new_file;
+	gchar *relative;
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
+	AnjutaTokenFile *tfile;
+	AmpConfigFile *cfg;
+	GHashTable* old_hash;
+
+	/* Change project root directory */
+	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);
+	}
+	g_hash_table_destroy (old_hash);
+
+	/* Change all files */
+	old_hash = project->files;
+	project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
+	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));
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		anjuta_token_file_move (tfile, new_file);
+		
+		g_hash_table_insert (project->files, new_file, tfile);
+		g_object_unref (key);
+	}
+	g_hash_table_steal_all (old_hash);
+	g_hash_table_destroy (old_hash);
+
+	/* 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);
+	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);
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		g_object_unref (cfg->file);
+		cfg->file = new_file;
+		
+		g_hash_table_insert (project->configs, new_file, cfg);
+	}
+	g_hash_table_steal_all (old_hash);
+	g_hash_table_destroy (old_hash);
+
+	
+	g_object_unref (old_root_file);
+
+	return TRUE;
+}
+
+AmpProject *
+amp_project_new (void)
+{
+	return AMP_PROJECT (g_object_new (AMP_TYPE_PROJECT, NULL));
+}
+
+/* Project access functions
+ *---------------------------------------------------------------------------*/
+
+AmpGroup *
+amp_project_get_root (AmpProject *project)
+{
+	AmpGroup *g_node = NULL;
+	
+	if (project->root_file != NULL)
+	{
+		gchar *id = g_file_get_uri (project->root_file);
+		g_node = (AmpGroup *)g_hash_table_lookup (project->groups, id);
+		g_free (id);
+	}
+
+	return g_node;
+}
+
+AmpGroup *
+amp_project_get_group (AmpProject *project, const gchar *id)
+{
+	return (AmpGroup *)g_hash_table_lookup (project->groups, id);
+}
+
+AmpTarget *
+amp_project_get_target (AmpProject *project, const gchar *id)
+{
+	AmpTarget **buffer;
+	AmpTarget *target;
+	gsize dummy;
+
+	buffer = (AmpTarget **)g_base64_decode (id, &dummy);
+	target = *buffer;
+	g_free (buffer);
+
+	return target;
+}
+
+AmpSource *
+amp_project_get_source (AmpProject *project, const gchar *id)
+{
+	AmpSource **buffer;
+	AmpSource *source;
+	gsize dummy;
+
+	buffer = (AmpSource **)g_base64_decode (id, &dummy);
+	source = *buffer;
+	g_free (buffer);
+
+	return source;
+}
+
+gchar *
+amp_project_get_node_id (AmpProject *project, const gchar *path)
+{
+	GNode *node = NULL;
+
+	if (path != NULL)
+	{
+		for (; *path != '\0';)
+		{
+			gchar *end;
+			guint child = g_ascii_strtoull (path, &end, 10);
+
+			if (end == path)
+			{
+				/* error */
+				return NULL;
+			}
+
+			if (node == NULL)
+			{
+				if (child == 0) node = project->root_node;
+			}
+			else
+			{
+				node = g_node_nth_child (node, child);
+			}
+			if (node == NULL)
+			{
+				/* no node */
+				return NULL;
+			}
+
+			if (*end == '\0') break;
+			path = end + 1;
+		}
+	}
+
+	switch (AMP_NODE_DATA (node)->type)
+	{
+		case ANJUTA_PROJECT_GROUP:
+			return g_file_get_uri (AMP_GROUP_DATA (node)->base.directory);
+		case ANJUTA_PROJECT_TARGET:
+		case ANJUTA_PROJECT_SOURCE:
+			return g_base64_encode ((guchar *)&node, sizeof (node));
+		default:
+			return NULL;
+	}
+}
+
+gchar *
+amp_project_get_uri (AmpProject *project)
+{
+	g_return_val_if_fail (project != NULL, NULL);
+
+	return project->root_file != NULL ? g_file_get_uri (project->root_file) : NULL;
+}
+
+GFile*
+amp_project_get_file (AmpProject *project)
+{
+	g_return_val_if_fail (project != NULL, NULL);
+
+	return project->root_file;
+}
+	
+gchar *
+amp_project_get_property (AmpProject *project, AmpPropertyType type)
+{
+	const gchar *value = NULL;
+
+	if (project->property != NULL)
+	{
+		switch (type)
+		{
+			case AMP_PROPERTY_NAME:
+				value = project->property->name;
+				break;
+			case AMP_PROPERTY_VERSION:
+				value = project->property->version;
+				break;
+			case AMP_PROPERTY_BUG_REPORT:
+				value = project->property->bug_report;
+				break;
+			case AMP_PROPERTY_TARNAME:
+				value = project->property->tarname;
+				if (value == NULL) return ac_init_default_tarname (project->property->name);
+				break;
+			case AMP_PROPERTY_URL:
+				value = project->property->url;
+				break;
+		}
+	}
+
+	return value == NULL ? NULL : g_strdup (value);
+}
+
+gboolean
+amp_project_set_property (AmpProject *project, AmpPropertyType type, const gchar *value)
+{
+	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);
+	}
+	
+	return TRUE;
+}
+
+/* Implement IAnjutaProject
+ *---------------------------------------------------------------------------*/
+
+static AnjutaProjectGroup* 
+iproject_add_group (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name, GError **err)
+{
+	return amp_project_add_group (AMP_PROJECT (obj), AMP_GROUP (parent), name, err);
+}
+
+static AnjutaProjectSource* 
+iproject_add_source (IAnjutaProject *obj, AnjutaProjectGroup *parent,  GFile *file, GError **err)
+{
+	return amp_project_add_source (AMP_PROJECT (obj), AMP_TARGET (parent), file, err);
+}
+
+static AnjutaProjectTarget* 
+iproject_add_target (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name,  AnjutaProjectTargetType type, GError **err)
+{
+	return amp_project_add_target (AMP_PROJECT (obj), AMP_GROUP (parent), name, type, err);
+}
+
+static GtkWidget* 
+iproject_configure (IAnjutaProject *obj, GError **err)
+{
+	return amp_configure_project_dialog (AMP_PROJECT (obj), err);
+}
+
+static guint 
+iproject_get_capabilities (IAnjutaProject *obj, GError **err)
+{
+	return (IANJUTA_PROJECT_CAN_ADD_GROUP |
+		IANJUTA_PROJECT_CAN_ADD_TARGET |
+		IANJUTA_PROJECT_CAN_ADD_SOURCE);
+}
+
+static GList* 
+iproject_get_packages (IAnjutaProject *obj, GError **err)
+{
+	GList *modules;
+	GList *packages;
+	GList* node;
+	GHashTable *all = g_hash_table_new (g_str_hash, g_str_equal);
+	
+	modules = amp_project_get_config_modules (AMP_PROJECT (obj), NULL);
+	for (node = modules; node != NULL; node = g_list_next (node))
+	{
+		GList *pack;
+		
+		packages = amp_project_get_config_packages (AMP_PROJECT (obj), (const gchar *)node->data, NULL);
+		for (pack = packages; pack != NULL; pack = g_list_next (pack))
+		{
+			g_hash_table_replace (all, pack->data, NULL);
+		}
+	    g_list_free (packages);
+	}
+    g_list_free (modules);
+
+	packages = g_hash_table_get_keys (all);
+	g_hash_table_destroy (all);
+	
+	return packages;
+}
+
+static AnjutaProjectGroup* 
+iproject_get_root (IAnjutaProject *obj, GError **err)
+{
+	return amp_project_get_root (AMP_PROJECT (obj));
+}
+
+static GList* 
+iproject_get_target_types (IAnjutaProject *obj, GError **err)
+{
+	return amp_project_get_target_types (AMP_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_load (IAnjutaProject *obj, GFile *file, GError **err)
+{
+	return amp_project_load (AMP_PROJECT (obj), file, err);
+}
+
+static gboolean
+iproject_refresh (IAnjutaProject *obj, GError **err)
+{
+	return amp_project_reload (AMP_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_remove_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+{
+	return TRUE;
+}
+
+static void
+iproject_iface_init(IAnjutaProjectIface* iface)
+{
+	iface->add_group = iproject_add_group;
+	iface->add_source = iproject_add_source;
+	iface->add_target = iproject_add_target;
+	iface->configure = iproject_configure;
+	iface->get_capabilities = iproject_get_capabilities;
+	iface->get_packages = iproject_get_packages;
+	iface->get_root = iproject_get_root;
+	iface->get_target_types = iproject_get_target_types;
+	iface->load = iproject_load;
+	iface->refresh = iproject_refresh;
+	iface->remove_node = iproject_remove_node;
+}
+
+/* Group access functions
+ *---------------------------------------------------------------------------*/
+
+GFile*
+amp_group_get_directory (AmpGroup *group)
+{
+	return AMP_GROUP_DATA (group)->base.directory;
+}
+
+GFile*
+amp_group_get_makefile (AmpGroup *group)
+{
+	return AMP_GROUP_DATA (group)->makefile;
+}
+
+gchar *
+amp_group_get_id (AmpGroup *group)
+{
+	return g_file_get_uri (AMP_GROUP_DATA (group)->base.directory);
+}
+
+/* Target access functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+amp_target_get_name (AmpTarget *target)
+{
+	return AMP_TARGET_DATA (target)->base.name;
+}
+
+AnjutaProjectTargetType
+amp_target_get_type (AmpTarget *target)
+{
+	return AMP_TARGET_DATA (target)->base.type;
+}
+
+gchar *
+amp_target_get_id (AmpTarget *target)
+{
+	return g_base64_encode ((guchar *)&target, sizeof (target));
+}
+
+/* Source access functions
+ *---------------------------------------------------------------------------*/
+
+gchar *
+amp_source_get_id (AmpSource *source)
+{
+	return g_base64_encode ((guchar *)&source, sizeof (source));
+}
+
+GFile*
+amp_source_get_file (AmpSource *source)
+{
+	return AMP_SOURCE_DATA (source)->base.file;
+}
+
+/* GbfProject implementation
+ *---------------------------------------------------------------------------*/
+
+static void
+amp_project_dispose (GObject *object)
+{
+	g_return_if_fail (AMP_IS_PROJECT (object));
+
+	amp_project_unload (AMP_PROJECT (object));
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);	
+}
+
+static void
+amp_project_instance_init (AmpProject *project)
+{
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (AMP_IS_PROJECT (project));
+	
+	/* project data */
+	project->root_file = NULL;
+	project->configure_file = NULL;
+	project->root_node = NULL;
+	project->property = NULL;
+
+	project->space_list = NULL;
+	project->arg_list = NULL;
+}
+
+static void
+amp_project_class_init (AmpProjectClass *klass)
+{
+	GObjectClass *object_class;
+	
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->dispose = amp_project_dispose;
+}
+
+ANJUTA_TYPE_BEGIN(AmpProject, amp_project, G_TYPE_OBJECT);
+ANJUTA_TYPE_ADD_INTERFACE(iproject, IANJUTA_TYPE_PROJECT);
+ANJUTA_TYPE_END;
+//GBF_BACKEND_BOILERPLATE (AmpProject, amp_project);
diff --git a/plugins/am-project/am-project.h b/plugins/am-project/am-project.h
new file mode 100644
index 0000000..9298272
--- /dev/null
+++ b/plugins/am-project/am-project.h
@@ -0,0 +1,127 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-project.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_PROJECT_H_
+#define _AM_PROJECT_H_
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+#include <libanjuta/anjuta-token-style.h>
+
+G_BEGIN_DECLS
+
+#define AMP_TYPE_PROJECT		(amp_project_get_type ())
+#define AMP_PROJECT(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), AMP_TYPE_PROJECT, AmpProject))
+#define AMP_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), AMP_TYPE_PROJECT, AmpProjectClass))
+#define AMP_IS_PROJECT(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), AMP_TYPE_PROJECT))
+#define AMP_IS_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), AMP_TYPE_PROJECT))
+
+#define AMP_GROUP(obj)		((AmpGroup *)obj)
+#define AMP_TARGET(obj)		((AmpTarget *)obj)
+#define AMP_SOURCE(obj)		((AmpSource *)obj)
+
+
+typedef struct _AmpProject        AmpProject;
+typedef struct _AmpProjectClass   AmpProjectClass;
+
+struct _AmpProjectClass {
+	GObjectClass parent_class;
+};
+
+typedef AnjutaProjectGroup AmpGroup;
+typedef AnjutaProjectTarget AmpTarget;
+typedef AnjutaProjectSource AmpSource;
+typedef struct _AmpProperty AmpProperty;
+
+typedef enum {
+	AMP_PROPERTY_NAME = 0,
+	AMP_PROPERTY_VERSION,
+	AMP_PROPERTY_BUG_REPORT,
+	AMP_PROPERTY_TARNAME,
+	AMP_PROPERTY_URL
+} AmpPropertyType;
+
+
+GType         amp_project_get_type (void);
+AmpProject   *amp_project_new      (void);
+
+gint amp_project_probe (GFile *directory, GError     **error);
+gboolean amp_project_load (AmpProject *project, GFile *directory, GError **error);
+gboolean amp_project_reload (AmpProject *project, GError **error);
+void amp_project_unload (AmpProject *project);
+
+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_move (AmpProject *project, const gchar *path);
+gboolean amp_project_save (AmpProject *project, GError **error);
+
+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);
+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);
+void amp_project_remove_target (AmpProject  *project, AmpTarget *target, GError **error);
+
+AmpSource* amp_project_add_source (AmpProject  *project, AmpTarget *parent, GFile *file, GError **error);
+void amp_project_remove_source (AmpProject  *project, AmpSource *source, GError **error);
+
+
+GList *amp_project_get_config_modules (AmpProject *project, GError **error);
+GList *amp_project_get_config_packages  (AmpProject *project, const gchar* module, GError **error);
+
+GList *amp_project_get_target_types (AmpProject *project, GError **error);
+
+gchar* amp_project_get_property (AmpProject *project, AmpPropertyType type);
+gboolean amp_project_set_property (AmpProject *project, AmpPropertyType type, const gchar* value);
+
+gchar * amp_project_get_node_id (AmpProject *project, const gchar *path);
+
+AnjutaProjectNode *amp_node_parent (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_first_child (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_last_child (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_next_sibling (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_prev_sibling (AnjutaProjectNode *node);
+AnjutaProjectNodeType amp_node_get_type (AnjutaProjectNode *node);
+void amp_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
+
+GFile *amp_group_get_directory (AmpGroup *group);
+GFile *amp_group_get_makefile (AmpGroup *group);
+gchar *amp_group_get_id (AmpGroup *group);
+
+const gchar *amp_target_get_name (AmpTarget *target);
+AnjutaProjectTargetType amp_target_get_type (AmpTarget *target);
+gchar *amp_target_get_id (AmpTarget *target);
+
+gchar *amp_source_get_id (AmpSource *source);
+GFile *amp_source_get_file (AmpSource *source);
+
+G_END_DECLS
+
+#endif /* _AM_PROJECT_H_ */
diff --git a/plugins/gbf-am/gbf-am.plugin.in b/plugins/am-project/am-project.plugin.in
similarity index 90%
rename from plugins/gbf-am/gbf-am.plugin.in
rename to plugins/am-project/am-project.plugin.in
index 74590b3..87a82bc 100644
--- a/plugins/gbf-am/gbf-am.plugin.in
+++ b/plugins/am-project/am-project.plugin.in
@@ -1,7 +1,7 @@
 [Anjuta Plugin]
 _Name=Autotools backend
 _Description=Autotools backend for project manager
-Location=gbf-am:GbfAmPlugin
+Location=am-project:AmpPlugin
 Icon=gbf-am-plugin-48.png
 Interfaces=IAnjutaProjectBackend
 Dependencies=anjuta-project-manager:ProjectManagerPlugin
diff --git a/plugins/am-project/am-project.ui b/plugins/am-project/am-project.ui
new file mode 100644
index 0000000..931f50b
--- /dev/null
+++ b/plugins/am-project/am-project.ui
@@ -0,0 +1,419 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="package_selection_dialog">
+    <property name="title" translatable="yes">Select package</property>
+    <property name="default_width">600</property>
+    <property name="default_height">500</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkVBox" id="vbox2">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkFrame" id="frame1">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment3">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="border_width">5</property>
+                        <property name="hscrollbar_policy">automatic</property>
+                        <property name="vscrollbar_policy">automatic</property>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="pkg_treeview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Select Package to add:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancelbutton1">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="okbutton1">
+                <property name="label">gtk-add</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">cancelbutton1</action-widget>
+      <action-widget response="-3">okbutton1</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkNotebook" id="top_level">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="border_width">6</property>
+    <child>
+      <object class="GtkTable" id="general_properties_table">
+        <property name="visible">True</property>
+        <property name="border_width">6</property>
+        <property name="n_rows">7</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">General</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="vbox1">
+        <property name="height_request">300</property>
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHButtonBox" id="hbuttonbox1">
+            <property name="visible">True</property>
+            <property name="border_width">5</property>
+            <property name="spacing">5</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="add_module_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox1">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image1">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-add</property>
+                            <property name="icon-size">4</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Add _module</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="add_package_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox2">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image2">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-add</property>
+                            <property name="icon-size">4</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Add _Package</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove_button">
+                <property name="label">gtk-remove</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">etched-in</property>
+            <child>
+              <object class="GtkTreeView" id="packages_treeview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label2">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Packages</property>
+      </object>
+      <packing>
+        <property name="position">1</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="vbox3">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHButtonBox" id="hbuttonbox2">
+            <property name="visible">True</property>
+            <property name="spacing">5</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="add_variable_button">
+                <property name="label">gtk-add</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove_variable_button">
+                <property name="label">gtk-remove</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow3">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTreeView" id="variables_treeview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label6">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Variables</property>
+      </object>
+      <packing>
+        <property name="position">2</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/am-project/am-scanner.h b/plugins/am-project/am-scanner.h
new file mode 100644
index 0000000..70a8a4a
--- /dev/null
+++ b/plugins/am-project/am-scanner.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * am-scanner.h
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 _AM_SCANNER_H_
+#define _AM_SCANNER_H_
+
+#include "libanjuta/anjuta-token.h"
+#include "libanjuta/anjuta-token-file.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _AmpAmScanner AmpAmScanner;
+
+AmpAmScanner *amp_am_scanner_new (void);
+void amp_am_scanner_free (AmpAmScanner *scanner);
+
+gboolean amp_am_scanner_parse (AmpAmScanner *scanner, AnjutaTokenFile *file, GError **error);
+
+const gchar* amp_am_scanner_get_filename (AmpAmScanner *scanner);
+
+typedef enum
+{
+	AM_TOKEN_SUBDIRS = ANJUTA_TOKEN_USER,
+	AM_TOKEN_DIST_SUBDIRS,
+	AM_TOKEN__DATA,
+	AM_TOKEN__HEADERS,
+	AM_TOKEN__LIBRARIES,
+	AM_TOKEN__LISP,
+	AM_TOKEN__LTLIBRARIES,
+	AM_TOKEN__MANS,
+	AM_TOKEN__PROGRAMS,
+	AM_TOKEN__PYTHON,
+	AM_TOKEN__SCRIPTS,
+	AM_TOKEN__SOURCES,
+	AM_TOKEN__TEXINFOS,
+	AM_TOKEN__JAVA
+} AmTokenType;
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/am-project/am-scanner.l b/plugins/am-project/am-scanner.l
new file mode 100644
index 0000000..fe574c4
--- /dev/null
+++ b/plugins/am-project/am-scanner.l
@@ -0,0 +1,377 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * am-scanner.l
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 <stdlib.h>
+#include <string.h>
+#include "am-scanner.h"
+#include "am-parser.h"
+
+#include "libanjuta/anjuta-debug.h"
+
+
+/* Eliminate warning */
+#define YY_NO_UNPUT 1 
+
+#define YY_INPUT(buf,result,the_max_size) \
+    result = 0;
+
+#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
+    
+#define YY_EXTRA_TYPE  AmpAmScanner*
+
+//#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);
+
+%}
+
+%option reentrant stack noyywrap yylineno
+
+%option prefix="amp_am_yy"
+
+/* 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 bison-bridge bison-locations
+
+%option never-interactive
+
+%option batch
+
+%option debug
+
+NAME          [^ \t\n\r:#=$"'`&@\\]*
+
+%%
+
+<INITIAL>\n {
+	yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_EOL);
+	return EOL;
+}
+
+<INITIAL>([ ]|\\\n)([ \t]|\\\n)* {
+	yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_SPACE);
+	return SPACE;
+}
+
+<INITIAL>([ \t])*#.*\n {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_COMMENT);   
+    return EOL;
+}
+
+<INITIAL>\t {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_SPACE);   
+    return TAB;
+}
+
+<INITIAL>@{NAME}@ {
+	yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_MACRO);
+	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:#=$}]+\} {
+    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\(\{] {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_VARIABLE);   
+	amp_am_scanner_update_line_width (yyextra, yylloc);
+    return VARIABLE;
+}
+
+<INITIAL>: {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ':');   
+    return COLON;
+}
+
+<INITIAL>:: {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return DOUBLE_COLON;
+}
+
+<INITIAL>; {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return SEMI_COLON;
+}
+
+<INITIAL>\| {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return ORDER;
+}
+
+<INITIAL>\= {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return EQUAL;
+}
+
+<INITIAL>:= {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return IMMEDIATE_EQUAL;
+}
+
+<INITIAL>\?= {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return CONDITIONAL_EQUAL;
+}
+
+<INITIAL>\+= {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return APPEND;
+}
+
+<INITIAL>\\[ ] {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return CHARACTER;
+}
+
+<INITIAL>\\: {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return CHARACTER;
+}
+
+<INITIAL>\\= {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return CHARACTER;
+}
+
+<INITIAL>\\# {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_OPERATOR);   
+    return CHARACTER;
+}
+
+<INITIAL>SUBDIRS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN_SUBDIRS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>DIST_SUBDIRS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN_DIST_SUBDIRS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_DATA {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__DATA);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_HEADERS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__HEADERS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_LIBRARIES {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LIBRARIES);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_LISP {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LISP);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_LTLIBRARIES {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__LTLIBRARIES);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_MANS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__MANS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_PROGRAMS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__PROGRAMS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_PYTHON {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__PYTHON);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_JAVA {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__JAVA);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_SCRIPTS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__SCRIPTS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_SOURCES {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__SOURCES);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME}_TEXINFOS {
+    yylval->token = amp_am_scanner_append_token  (yyextra, AM_TOKEN__TEXINFOS);   
+    return AM_VARIABLE;
+}
+
+<INITIAL>{NAME} {
+    yylval->token = amp_am_scanner_append_token  (yyextra, ANJUTA_TOKEN_NAME);   
+	amp_am_scanner_update_line_width (yyextra, yylloc);
+    return NAME;
+}
+
+<INITIAL>. {
+    yylval->token = amp_am_scanner_append_token  (yyextra, *yytext);   
+    return CHARACTER;
+}
+
+%%
+     
+struct _AmpAmScanner
+{
+    const gchar *pos;
+    yyscan_t scanner;
+    YY_BUFFER_STATE	 buffer;
+
+    AnjutaTokenFile *file;
+    gchar *filename;
+
+	guint line_width;
+};
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static AnjutaToken*
+amp_am_scanner_append_token (AmpAmScanner *scanner, gint token)
+{
+    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;
+}
+
+static void
+amp_am_scanner_update_line_width (AmpAmScanner *scanner, YYLTYPE *loc)
+{
+	anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+}
+
+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;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+amp_am_scanner_parse (AmpAmScanner *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 amp_am_yyparse (scanner->scanner) == 0;
+}
+
+guint
+amp_am_scanner_get_line_width (AmpAmScanner *scanner)
+{
+	return scanner->line_width;
+}
+
+const gchar*
+amp_am_scanner_get_filename (AmpAmScanner *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
+ *---------------------------------------------------------------------------*/
+
+AmpAmScanner *
+amp_am_scanner_new (void)
+{
+	AmpAmScanner *scanner;
+
+	scanner = g_new0 (AmpAmScanner, 1);
+
+    yylex_init(&scanner->scanner);
+    yyset_extra (scanner, scanner->scanner);
+
+	return scanner;
+};
+
+void
+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;
+
+	g_free (scanner);
+}
diff --git a/plugins/gbf-am/plugin.c b/plugins/am-project/plugin.c
similarity index 77%
rename from plugins/gbf-am/plugin.c
rename to plugins/am-project/plugin.c
index 1325da6..d8d5809 100644
--- a/plugins/gbf-am/plugin.c
+++ b/plugins/am-project/plugin.c
@@ -24,10 +24,10 @@
 #include <libanjuta/interfaces/ianjuta-project-backend.h>
 
 #include "plugin.h"
-#include "gbf-am-project.h"
+#include "am-project.h"
 
 
-#define ICON_FILE "gfb-am-plugin-48.png"
+#define ICON_FILE "am-project-plugin-48.png"
 
 /* AnjutaPlugin functions
  *---------------------------------------------------------------------------*/
@@ -35,7 +35,7 @@
 static gboolean
 activate_plugin (AnjutaPlugin *plugin)
 {
-	DEBUG_PRINT ("GbfAmPlugin: Activating Gnome build am backend Plugin ...");
+	DEBUG_PRINT ("AmpPlugin: Activating Anjuta am backend Plugin ...");
 	
 	return TRUE;
 }
@@ -43,7 +43,7 @@ activate_plugin (AnjutaPlugin *plugin)
 static gboolean
 deactivate_plugin (AnjutaPlugin *plugin)
 {
-	DEBUG_PRINT ("GbfAmPlugin: Deacctivating Gnome build am backend Plugin ...");
+	DEBUG_PRINT ("AmpPlugin: Deacctivating Anjuta am backend Plugin ...");
 	return TRUE;
 }
 
@@ -51,20 +51,29 @@ deactivate_plugin (AnjutaPlugin *plugin)
 /* IAnjutaProjectBackend implementation
  *---------------------------------------------------------------------------*/
 
-static GbfProject*
+static IAnjutaProject*
 iproject_backend_new_project (IAnjutaProjectBackend* backend, GError** err)
 {
-	GbfProject *project;
-	
-	project = gbf_am_project_new ();
+	IAnjutaProject *project;
+	DEBUG_PRINT("create new amp project");	
+	project = (IAnjutaProject *)(g_object_new (AMP_TYPE_PROJECT, NULL));
 		
 	return project;
 }
 
+static gint
+iproject_backend_probe (IAnjutaProjectBackend* backend, GFile *directory, GError** err)
+{
+	DEBUG_PRINT("probe amp project");
+
+	return amp_project_probe (directory, err);
+}
+
 static void
 iproject_backend_iface_init(IAnjutaProjectBackendIface *iface)
 {
 	iface->new_project = iproject_backend_new_project;
+	iface->probe = iproject_backend_probe;
 }
 
 /* GObject functions
@@ -74,7 +83,7 @@ iproject_backend_iface_init(IAnjutaProjectBackendIface *iface)
 static gpointer parent_class;
 
 static void
-gbf_am_plugin_instance_init (GObject *obj)
+amp_plugin_instance_init (GObject *obj)
 {
 }
 
@@ -95,7 +104,7 @@ finalize (GObject *obj)
 }
 
 static void
-gbf_am_plugin_class_init (GObjectClass *klass) 
+amp_plugin_class_init (GObjectClass *klass) 
 {
 	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
 
@@ -110,13 +119,8 @@ gbf_am_plugin_class_init (GObjectClass *klass)
 /* AnjutaPlugin declaration
  *---------------------------------------------------------------------------*/
 
-ANJUTA_PLUGIN_BEGIN (GbfAmPlugin, gbf_am_plugin);
+ANJUTA_PLUGIN_BEGIN (AmpPlugin, amp_plugin);
 ANJUTA_PLUGIN_ADD_INTERFACE (iproject_backend, IANJUTA_TYPE_PROJECT_BACKEND);
 ANJUTA_PLUGIN_END;
 
-G_MODULE_EXPORT void
-anjuta_glue_register_components (GTypeModule *module)
-{
-	gbf_am_plugin_get_type (module);
-	gbf_am_project_get_type (module);
-}                     
+ANJUTA_SIMPLE_PLUGIN (AmpPlugin, amp_plugin);
diff --git a/plugins/gbf-mkfile/plugin.h b/plugins/am-project/plugin.h
similarity index 54%
rename from plugins/gbf-mkfile/plugin.h
rename to plugins/am-project/plugin.h
index b04aab1..d6a3fa7 100644
--- a/plugins/gbf-mkfile/plugin.h
+++ b/plugins/am-project/plugin.h
@@ -23,23 +23,23 @@
 
 #include <libanjuta/anjuta-plugin.h>
 
-extern GType gbf_mkfile_plugin_get_type (GTypeModule *module);
-#define GBF_TYPE_PLUGIN_MKFILE         (gbf_mkfile_plugin_get_type (NULL))
-#define GBF_PLUGIN_MKFILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GBF_TYPE_PLUGIN_MKFILE, GbfMkfilePlugin))
-#define GBF_PLUGIN_MKFILE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), GBF_TYPE_PLUGIN_MKFILE, GbfMkfilePluginClass))
-#define GBF_IS_PLUGIN_MKFILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GBF_TYPE_PLUGIN_MKFILE))
-#define GBF_IS_PLUGIN_MKFILE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GBF_TYPE_PLUGIN_MKFILE))
-#define GBF_PLUGIN_MKFILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GBF_TYPE_PLUGIN_MKFILE, GbfMkfilePluginClass))
-
-typedef struct _GbfMkfilePlugin GbfMkfilePlugin;
-typedef struct _GbfMkfilePluginClass GbfMkfilePluginClass;
-
-struct _GbfMkfilePlugin 
+extern GType amp_plugin_get_type (GTypeModule *module);
+#define ANJUTA_TYPE_PLUGIN_AMP         (amp_plugin_get_type (NULL))
+#define ANJUTA_PLUGIN_AMP(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), ANJUTA_TYPE_PLUGIN_AMP, AmpPlugin))
+#define ANJUTA_PLUGIN_AMP_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), ANJUTA_TYPE_PLUGIN_AMP, AmpPluginClass))
+#define ANJUTA_IS_PLUGIN_AMP(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), ANJUTA_TYPE_PLUGIN_AMP))
+#define ANJUTA_IS_PLUGIN_AMP_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), ANJUTA_TYPE_PLUGIN_AMP))
+#define ANJUTA_PLUGIN_AMP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ANJUTA_TYPE_PLUGIN_AMP, AmpPluginClass))
+
+typedef struct _AmpPlugin AmpPlugin;
+typedef struct _AmpPluginClass AmpPluginClass;
+
+struct _AmpPlugin 
 {
 	AnjutaPlugin parent;
 };
 
-struct _GbfMkfilePluginClass
+struct _AmpPluginClass
 {
 	AnjutaPluginClass parent_class;
 };
diff --git a/plugins/build-basic-autotools/executer.c b/plugins/build-basic-autotools/executer.c
index 45284ff..87bbcd2 100644
--- a/plugins/build-basic-autotools/executer.c
+++ b/plugins/build-basic-autotools/executer.c
@@ -64,8 +64,8 @@ get_program_parameters (BasicAutotoolsPlugin *plugin,
 		g_return_val_if_fail (pm != NULL, FALSE);
 		exec_targets =
 		ianjuta_project_manager_get_targets (pm, 
-							 IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE,
-											 NULL);
+							ANJUTA_TARGET_EXECUTABLE,
+                            NULL);
 		if (!exec_targets)
 		{
 			anjuta_util_dialog_error(GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
diff --git a/plugins/class-gen/plugin.c b/plugins/class-gen/plugin.c
index c1a8bf1..f178601 100644
--- a/plugins/class-gen/plugin.c
+++ b/plugins/class-gen/plugin.c
@@ -447,8 +447,8 @@ iwizard_activate (IAnjutaWizard *wiz, G_GNUC_UNUSED GError **err)
 	AnjutaClassGenPlugin *cg_plugin;
 	gchar *user_name;
 	gchar *user_email;
-	IAnjutaProjectManagerCapabilities caps =
-		IANJUTA_PROJECT_MANAGER_CAN_ADD_NONE;
+	IAnjutaProjectCapabilities caps =
+		IANJUTA_PROJECT_CAN_ADD_NONE;
 	
 	cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (wiz);
 
@@ -481,7 +481,7 @@ iwizard_activate (IAnjutaWizard *wiz, G_GNUC_UNUSED GError **err)
 			caps = ianjuta_project_manager_get_capabilities (manager, NULL);
 	}
 
-	if((caps & IANJUTA_PROJECT_MANAGER_CAN_ADD_SOURCE) == FALSE)
+	if((caps & IANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE)
 	{
 		cg_window_set_add_to_project (cg_plugin->window, FALSE);
 		cg_window_enable_add_to_project (cg_plugin->window, FALSE);
diff --git a/plugins/debug-manager/start.c b/plugins/debug-manager/start.c
index 82d0cd1..3fdf464 100644
--- a/plugins/debug-manager/start.c
+++ b/plugins/debug-manager/start.c
@@ -36,6 +36,7 @@
 /*#define DEBUG*/
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/resources.h>
+#include <libanjuta/anjuta-project.h>
 #include <libanjuta/interfaces/ianjuta-project-manager.h>
 #include <libanjuta/interfaces/ianjuta-document-manager.h>
 #include <libanjuta/interfaces/ianjuta-builder.h>
@@ -208,12 +209,12 @@ get_source_directories (AnjutaPlugin *plugin)
 		{
 			slibs_dirs =
 				ianjuta_project_manager_get_targets (pm,
-					IANJUTA_PROJECT_MANAGER_TARGET_SHAREDLIB,
-												  NULL);
+					ANJUTA_TARGET_SHAREDLIB,
+				    NULL);
 			libs_dirs =
 				ianjuta_project_manager_get_targets (pm,
-					IANJUTA_PROJECT_MANAGER_TARGET_STATICLIB,
-												  NULL);
+					ANJUTA_TARGET_STATICLIB,
+				    NULL);
 		}
 	}
 	slibs_dirs = g_list_reverse (slibs_dirs);
diff --git a/plugins/file-wizard/file.c b/plugins/file-wizard/file.c
index bc4b5d3..9d8d00a 100644
--- a/plugins/file-wizard/file.c
+++ b/plugins/file-wizard/file.c
@@ -36,6 +36,7 @@
 #include <libanjuta/interfaces/ianjuta-document-manager.h>
 #include <libanjuta/interfaces/ianjuta-macro.h>
 #include <libanjuta/interfaces/ianjuta-file.h>
+#include <libanjuta/interfaces/ianjuta-project.h>
 #include <libanjuta/interfaces/ianjuta-project-manager.h>
 #include <libanjuta/interfaces/ianjuta-vcs.h>
 
@@ -125,8 +126,8 @@ void
 display_new_file(AnjutaFileWizardPlugin *plugin,
 				 IAnjutaDocumentManager *docman)
 {
-	IAnjutaProjectManagerCapabilities caps =
-		IANJUTA_PROJECT_MANAGER_CAN_ADD_NONE;
+	IAnjutaProjectCapabilities caps =
+		IANJUTA_PROJECT_CAN_ADD_NONE;
 	
 	if (!nfg)
 		if (!create_new_file_dialog (docman))
@@ -147,7 +148,7 @@ display_new_file(AnjutaFileWizardPlugin *plugin,
 	                  G_CALLBACK(on_add_to_project_toggled),
 	                  nfg);
 	
-	if ((caps & IANJUTA_PROJECT_MANAGER_CAN_ADD_SOURCE) == FALSE) {
+	if ((caps & IANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE) {
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (nfg->add_to_project),
 									  FALSE);
 		gtk_widget_set_sensitive (nfg->add_to_project, FALSE);
diff --git a/plugins/glade/plugin.c b/plugins/glade/plugin.c
index 0bcf9be..c696ae6 100644
--- a/plugins/glade/plugin.c
+++ b/plugins/glade/plugin.c
@@ -316,9 +316,10 @@ value_added_pm_current_uri (AnjutaPlugin *plugin, const char *name,
 	ui = anjuta_shell_get_ui (plugin->shell, NULL);
 	action = anjuta_ui_get_action (ui, "ActionGroupGlade", "ActionSetDefaultTarget");
 	selected_id = ianjuta_project_manager_get_selected_id (projman,
-	                                                       IANJUTA_PROJECT_MANAGER_TARGET,
+	                                                       ANJUTA_PROJECT_TARGET,
 	                                                       NULL);
 	gtk_action_set_sensitive (action, selected_id != NULL);
+	g_free (selected_id);
 }
 
 static void
@@ -3871,7 +3872,7 @@ on_set_default_resource_target (GtkAction* action, GladePlugin* plugin)
 		anjuta_shell_get_interface (ANJUTA_PLUGIN(plugin)->shell,
 		                            IAnjutaProjectManager, NULL);
 
-	selected = ianjuta_project_manager_get_selected_id (projman, IANJUTA_PROJECT_MANAGER_TARGET, NULL);
+	selected = ianjuta_project_manager_get_selected_id (projman, ANJUTA_PROJECT_TARGET, NULL);
 	DEBUG_PRINT ("Selected element is %s", selected);
 	set_default_resource_target (selected, plugin);
 	g_free (selected);
diff --git a/plugins/gbf-mkfile/Makefile.am b/plugins/mk-project/Makefile.am
similarity index 54%
rename from plugins/gbf-mkfile/Makefile.am
rename to plugins/mk-project/Makefile.am
index 80befb7..bcd751b 100644
--- a/plugins/gbf-mkfile/Makefile.am
+++ b/plugins/mk-project/Makefile.am
@@ -4,18 +4,14 @@ plugin_ui_DATA =
 
 # Plugin glade file
 plugin_gladedir = $(anjuta_glade_dir)
-plugin_glade_DATA =
+plugin_glade_DATA = mk-project.ui
 
 # Plugin icon file
 plugin_pixmapsdir = $(anjuta_image_dir)
-plugin_pixmaps_DATA = gbf-mkfile-plugin-48.png
-
-# Plugin scripts
-scriptsdir = $(bindir)
-scripts_SCRIPTS = gbf-mkfile-parse
+plugin_pixmaps_DATA = mk-project-plugin-48.png
 
 # Plugin description file
-plugin_in_files = gbf-mkfile.plugin.in
+plugin_in_files = mk-project.plugin.in
 %.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
 plugindir = $(anjuta_plugin_dir)
@@ -26,37 +22,49 @@ AM_CPPFLAGS = 					\
 	$(DEPRECATED_FLAGS) \
 	$(GIO_CFLAGS) \
 	$(LIBANJUTA_CFLAGS) \
-	-DSCRIPTS_DIR=\"$(scriptsdir)\"
+	-DG_LOG_DOMAIN=\"mk-project\"
 
 plugin_LTLIBRARIES = \
-	libgbf-mkfile.la
+	libmk-project.la
 
-libgbf_mkfile_la_SOURCES = \
+libmk_project_la_SOURCES = \
 	plugin.c \
 	plugin.h \
-	gbf-mkfile-project.c \
-	gbf-mkfile-project.h \
-	gbf-mkfile-config.c \
-	gbf-mkfile-config.h \
-	gbf-mkfile-properties.c \
-	gbf-mkfile-properties.h 
+	mk-project.c \
+	mk-project.h \
+	mk-scanner.l \
+	mk-parser.y \
+	mk-scanner.h \
+	mk-rule.c \
+	mk-rule.h \
+	mk-project-private.h
 
-libgbf_mkfile_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
+libmk_project_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 
-libgbf_mkfile_la_LIBADD = \
+libmk_project_la_LIBADD = \
 	$(GIO_LIBS) \
 	$(LIBANJUTA_LIBS)
 
+AM_YFLAGS = -t -v -g -rall
+
+mk-scanner.c: $(srcdir)/mk-scanner.l mk-parser.c
+	$(LEXCOMPILE) -o $@ $<
+
+mk-parser.c: $(srcdir)/mk-parser.y
+	$(YACCCOMPILE) -o $@ $<
+
+mk-scanner.h: mk-parser.c
+
+
 EXTRA_DIST = \
 	$(plugin_in_files) \
 	$(plugin_DATA) \
 	$(plugin_ui_DATA) \
-	$(plugin_pixmaps_DATA)
+	$(plugin_pixmaps_DATA) \
+	$(plugin_glade_DATA) \
+	mk-parser.h
 
 DISTCLEANFILES = \
 	$(plugin_DATA)
 
-SUBDIRS = GBF
-
-
 -include $(top_srcdir)/git.mk
diff --git a/plugins/mk-project/mk-parser.y b/plugins/mk-project/mk-parser.y
new file mode 100644
index 0000000..31d1da0
--- /dev/null
+++ b/plugins/mk-project/mk-parser.y
@@ -0,0 +1,504 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * mk-parser.y
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 "mk-scanner.h"
+#include "mk-parser.h"
+
+#include <stdlib.h>
+
+#define YYDEBUG 1
+
+%}
+
+%token	EOL	'\n'
+%token	SPACE
+%token	TAB '\t'
+%token  HASH '#'
+%token	MACRO
+%token	VARIABLE
+%token  COMMA ','
+%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	MK_VARIABLE
+%token  _PHONY
+%token  _SUFFIXES
+%token  _DEFAULT
+%token  _PRECIOUS
+%token  _INTERMEDIATE
+%token  _SECONDARY
+%token  _SECONDEXPANSION
+%token  _DELETE_ON_ERROR
+%token  _IGNORE
+%token  _LOW_RESOLUTION_TIME
+%token  _SILENT
+%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"*/
+
+/*%glr-parser*/
+
+%parse-param {void* scanner}
+%lex-param   {void* scanner}
+
+%name-prefix="mkp_yy"
+
+%locations
+
+%expect 1
+
+%start file
+
+%debug
+
+%{
+
+//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);
+
+%}
+
+
+%%
+
+file:
+    statement
+    | file statement
+    ;
+
+statement:
+    end_of_line
+    | space end_of_line
+    | definition end_of_line
+    | rule  command_list {
+        if ($2 != NULL) $$ = anjuta_token_group ($1, $2);
+        mkp_scanner_add_rule (scanner, $$);
+    }
+	;
+
+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);
+        mkp_scanner_update_variable (scanner, $$);
+    }        
+    ;    
+
+rule:
+    depend_list  end_of_line {
+        $$ = anjuta_token_group ($1, $2);
+    }
+    | depend_list  SEMI_COLON  command_line  EOL {
+        $$ = anjuta_token_group ($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);
+        mkp_special_target ($1);
+        switch (anjuta_token_get_type ($2))
+        {
+        case COLON:
+            anjuta_token_set_type ($2, MK_TOKEN_COLON);
+            break;
+        case DOUBLE_COLON:
+            anjuta_token_set_type ($2, MK_TOKEN_DOUBLE_COLON);
+            break;
+        default:
+            break;
+        }
+        anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+    }
+    ;
+
+command_list:
+    /* empty */ {
+        $$ = NULL;
+    }
+	| command_list TAB command_line EOL {
+        $$ = $4;
+    }
+	;
+
+	
+/* Lists
+ *----------------------------------------------------------------------------*/
+
+end_of_line:
+    EOL
+    | comment
+    ;
+
+comment:
+    HASH not_eol_list EOL {
+        anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
+        anjuta_token_group ($1, $3);
+    }
+    ;
+
+not_eol_list:
+    /* empty */
+    | not_eol_list not_eol_token
+    ;
+
+value_list:
+    /* empty */ {
+        $$ = 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;
+    }
+    | 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);
+    }
+    ;
+
+prerequisite_list_body:
+	prerequisite
+	| prerequisite_list_body  space  prerequisite {
+        anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
+        $$ = $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);
+    }
+    ;
+
+head_list_body:
+    head
+    | head_list_body  space  head {
+        anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
+        $$ = $3;
+    }
+    ;
+
+command_line:
+    /* empty */
+    | command_line command_token
+    ;
+
+/* Items
+ *----------------------------------------------------------------------------*/
+
+optional_space:
+	/* empty */ {
+		$$ = NULL;
+	}
+	| space
+	;
+
+space:
+	space_token
+	| space space_token	{
+		anjuta_token_merge ($1, $2);
+	}
+	;
+
+head:
+    head_token {
+        $$ = anjuta_token_group_new (ANJUTA_TOKEN_NAME, $1);    
+    }
+    | head head_token {
+        anjuta_token_group ($$, $2);
+    }
+    ;
+
+value:
+    value_token {
+        $$ = anjuta_token_group_new (ANJUTA_TOKEN_VALUE, $1);
+    }
+    | value value_token {
+        anjuta_token_group ($$, $2);
+    }
+    ;     
+
+prerequisite:
+    prerequisite_token {
+        $$ = anjuta_token_group_new (mkp_special_prerequisite ($$), $1);
+    }
+    | prerequisite prerequisite_token {
+        $$ = anjuta_token_group ($1, $2);
+        anjuta_token_set_type ($$, ANJUTA_TOKEN_VALUE);
+    }
+    ;     
+
+/* Tokens
+ *----------------------------------------------------------------------------*/
+		
+not_eol_token:
+    word_token
+    | space_token
+    ;
+
+prerequisite_token:
+    name_token
+    | equal_token
+    | rule_token
+	;
+
+command_token:
+    name_token
+    | equal_token
+    | rule_token
+    | depend_token
+    | space_token
+    ;
+
+value_token:
+    name_token
+    | equal_token
+    | rule_token
+    | depend_token
+    ;
+
+head_token:
+    name_token
+    | depend_token
+    ;
+
+name_token:
+	VARIABLE {
+        anjuta_token_set_type ($$, MK_TOKEN_VARIABLE);
+    }
+	| NAME
+	| CHARACTER
+    | COMMA
+    | ORDER
+    | _PHONY
+    | _SUFFIXES
+    | _DEFAULT
+    | _PRECIOUS
+    | _INTERMEDIATE
+    | _SECONDARY
+    | _SECONDEXPANSION
+    | _DELETE_ON_ERROR
+    | _IGNORE
+    | _LOW_RESOLUTION_TIME
+    | _SILENT
+    | _EXPORT_ALL_VARIABLES
+    | _NOTPARALLEL
+    ;
+
+rule_token:
+	COLON
+	| DOUBLE_COLON
+	;
+
+depend_token:
+    SEMI_COLON
+    ;
+
+word_token:
+	VARIABLE
+	| NAME
+	| CHARACTER
+	| ORDER
+    | HASH
+    | COMMA
+    | COLON
+    | DOUBLE_COLON
+	| SEMI_COLON
+	| EQUAL
+	| IMMEDIATE_EQUAL
+	| CONDITIONAL_EQUAL
+	| APPEND
+    | _PHONY
+    | _SUFFIXES
+    | _DEFAULT
+    | _PRECIOUS
+    | _INTERMEDIATE
+    | _SECONDARY
+    | _SECONDEXPANSION
+    | _DELETE_ON_ERROR
+    | _IGNORE
+    | _LOW_RESOLUTION_TIME
+    | _SILENT
+    | _EXPORT_ALL_VARIABLES
+    | _NOTPARALLEL
+    ;
+		
+space_token:
+	SPACE
+	| TAB
+	;
+
+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);
+    }
+	;
+		
+%%
+
+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/gbf-mkfile/gbf-mkfile-plugin-48.png b/plugins/mk-project/mk-project-plugin-48.png
similarity index 100%
rename from plugins/gbf-mkfile/gbf-mkfile-plugin-48.png
rename to plugins/mk-project/mk-project-plugin-48.png
diff --git a/plugins/mk-project/mk-project-private.h b/plugins/mk-project/mk-project-private.h
new file mode 100644
index 0000000..b9bda25
--- /dev/null
+++ b/plugins/mk-project/mk-project-private.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* mk-project-private.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 _MK_PROJECT_PRIVATE_H_
+#define _MK_PROJECT_PRIVATE_H_
+
+#include "mk-project.h"
+
+G_BEGIN_DECLS
+
+struct _MkpProperty {
+	AnjutaToken *ac_init;				/* AC_INIT macro */
+	gchar *name;
+	gchar *version;
+	gchar *bug_report;
+	gchar *tarname;
+	gchar *url;
+};
+
+struct _MkpProject {
+	GObject         parent;
+
+	/* uri of the project; this can be a full uri, even though we
+	 * can only work with native local files */
+	GFile			*root_file;
+
+	/* project data */
+	AnjutaTokenFile		*make_file;		/* make file */
+
+	MkpProperty			*property;
+	
+	MkpGroup              *root_node;         	/* tree containing project data;
+								 * each GNode's data is a
+								 * AmpNode, and the root of
+								 * the tree is the root group. */
+
+	/* shortcut hash tables, mapping id -> GNode from the tree above */
+	GHashTable		*groups;
+	GHashTable		*files;
+	GHashTable		*variables;
+
+	GHashTable		*rules;
+	GHashTable		*suffix;
+	
+	/* project files monitors */
+	GHashTable         *monitors;
+
+	/* Keep list style */
+	AnjutaTokenStyle *space_list;
+	AnjutaTokenStyle *arg_list;
+};
+
+struct _MkpRule {
+	gchar *name;
+	const gchar *part;
+	gboolean phony;
+	gboolean pattern;
+	GList *prerequisite;
+	AnjutaToken *rule;
+};
+
+gchar *mkp_project_token_evaluate (MkpProject *project, AnjutaToken *token);
+
+MkpTarget* mkp_target_new (const gchar *name, AnjutaProjectTargetType type);
+void mkp_target_free (MkpTarget *node);
+void mkp_target_add_token (MkpGroup *node, AnjutaToken *token);
+MkpSource* mkp_source_new (GFile *file);
+
+G_END_DECLS
+
+#endif /* _MK_PROJECT_PRIVATE_H_ */
diff --git a/plugins/mk-project/mk-project.c b/plugins/mk-project/mk-project.c
new file mode 100644
index 0000000..d3e48cc
--- /dev/null
+++ b/plugins/mk-project/mk-project.c
@@ -0,0 +1,1460 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* mk-project.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 "mk-project.h"
+
+#include "mk-project-private.h"
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include "mk-scanner.h"
+
+
+#define UNIMPLEMENTED  G_STMT_START { g_warning (G_STRLOC": unimplemented"); } G_STMT_END
+
+/* Constant strings for parsing perl script error output */
+#define ERROR_PREFIX      "ERROR("
+#define WARNING_PREFIX    "WARNING("
+#define MESSAGE_DELIMITER ": "
+
+static const gchar *valid_makefiles[] = {"GNUmakefile", "makefile", "Makefile", NULL};
+
+/* convenient shortcut macro the get the MkpNode from a GNode */
+#define MKP_NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
+#define MKP_GROUP_DATA(node)  ((node) != NULL ? (MkpGroupData *)((node)->data) : NULL)
+#define MKP_TARGET_DATA(node)  ((node) != NULL ? (MkpTargetData *)((node)->data) : NULL)
+#define MKP_SOURCE_DATA(node)  ((node) != NULL ? (MkpSourceData *)((node)->data) : NULL)
+
+
+struct _MkpVariable {
+	gchar *name;
+	AnjutaTokenType assign;
+	AnjutaToken *value;
+};
+
+typedef enum {
+	AM_GROUP_TOKEN_CONFIGURE,
+	AM_GROUP_TOKEN_SUBDIRS,
+	AM_GROUP_TOKEN_DIST_SUBDIRS,
+	AM_GROUP_TARGET,
+	AM_GROUP_TOKEN_LAST
+} MkpGroupTokenCategory;
+
+typedef struct _MkpGroupData MkpGroupData;
+
+struct _MkpGroupData {
+	AnjutaProjectGroupData base;		/* Common node data */
+	gboolean dist_only;			/* TRUE if the group is distributed but not built */
+	GFile *makefile;				/* GFile corresponding to group makefile */
+	AnjutaTokenFile *tfile;		/* Corresponding Makefile */
+	GList *tokens[AM_GROUP_TOKEN_LAST];					/* List of token used by this group */
+};
+
+typedef enum _MkpTargetFlag
+{
+	AM_TARGET_CHECK = 1 << 0,
+	AM_TARGET_NOINST = 1 << 1,
+	AM_TARGET_DIST = 1 << 2,
+	AM_TARGET_NODIST = 1 << 3,
+	AM_TARGET_NOBASE = 1 << 4,
+	AM_TARGET_NOTRANS = 1 << 5,
+	AM_TARGET_MAN = 1 << 6,
+	AM_TARGET_MAN_SECTION = 31 << 7
+} MkpTargetFlag;
+
+typedef struct _MkpTargetData MkpTargetData;
+
+struct _MkpTargetData {
+	AnjutaProjectTargetData base;
+	gchar *install;
+	gint flags;
+	GList* tokens;
+};
+
+typedef struct _MkpSourceData MkpSourceData;
+
+struct _MkpSourceData {
+	AnjutaProjectSourceData base;
+	AnjutaToken* token;
+};
+
+typedef struct _MkpTargetInformation MkpTargetInformation;
+
+struct _MkpTargetInformation {
+	AnjutaProjectTargetInformation base;
+	AnjutaTokenType token;
+	const gchar *prefix;
+	const gchar *install;
+};
+
+/* Target types
+ *---------------------------------------------------------------------------*/
+
+static MkpTargetInformation MkpTargetTypes[] = {
+	{{N_("Unknown"), ANJUTA_TARGET_UNKNOWN,
+	"text/plain"},
+	ANJUTA_TOKEN_NONE,
+	NULL,
+	NULL},
+
+	{{NULL, ANJUTA_TARGET_UNKNOWN,
+	NULL},
+	ANJUTA_TOKEN_NONE,
+	NULL,
+	NULL}
+};
+
+
+/* ----- Standard GObject types and variables ----- */
+
+enum {
+	PROP_0,
+	PROP_PROJECT_DIR
+};
+
+static GObject *parent_class;
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+error_set (GError **error, gint code, const gchar *message)
+{
+        if (error != NULL) {
+                if (*error != NULL) {
+                        gchar *tmp;
+
+                        /* error already created, just change the code
+                         * and prepend the string */
+                        (*error)->code = code;
+                        tmp = (*error)->message;
+                        (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
+                        g_free (tmp);
+
+                } else {
+                        *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
+                                                      code,
+                                                      message);
+                }
+        }
+}
+
+/* Work even if file is not a descendant of parent */
+static gchar*
+get_relative_path (GFile *parent, GFile *file)
+{
+	gchar *relative;
+
+	relative = g_file_get_relative_path (parent, file);
+	if (relative == NULL)
+	{
+		if (g_file_equal (parent, file))
+		{
+			relative = g_strdup ("");
+		}
+		else
+		{
+			GFile *grand_parent = g_file_get_parent (parent);
+			gint level;
+			gchar *grand_relative;
+			gchar *ptr;
+			gsize len;
+			
+			
+			for (level = 1;  !g_file_has_prefix (file, grand_parent); level++)
+			{
+				GFile *next = g_file_get_parent (grand_parent);
+				
+				g_object_unref (grand_parent);
+				grand_parent = next;
+			}
+
+			grand_relative = g_file_get_relative_path (grand_parent, file);
+			g_object_unref (grand_parent);
+
+			len = strlen (grand_relative);
+			relative = g_new (gchar, len + level * 3 + 1);
+			ptr = relative;
+			for (; level; level--)
+			{
+				memcpy(ptr, ".." G_DIR_SEPARATOR_S, 3);
+				ptr += 3;
+			}
+			memcpy (ptr, grand_relative, len + 1);
+			g_free (grand_relative);
+		}
+	}
+
+	return relative;
+}
+
+static GFileType
+file_type (GFile *file, const gchar *filename)
+{
+	GFile *child;
+	GFileInfo *info;
+	GFileType type;
+
+	child = filename != NULL ? g_file_get_child (file, filename) : g_object_ref (file);
+
+	//g_message ("check file %s", g_file_get_path (child));
+	
+	info = g_file_query_info (child,
+	                          G_FILE_ATTRIBUTE_STANDARD_TYPE, 
+	                          G_FILE_QUERY_INFO_NONE,
+	                          NULL,
+	                          NULL);
+	if (info != NULL)
+	{
+		type = g_file_info_get_file_type (info);
+		g_object_unref (info);
+	}
+	else
+	{
+		type = G_FILE_TYPE_UNKNOWN;
+	}
+	
+	g_object_unref (child);
+	
+	return type;
+}
+
+/* Group objects
+ *---------------------------------------------------------------------------*/
+
+static void
+mkp_group_add_token (MkpGroup *node, AnjutaToken *token, MkpGroupTokenCategory category)
+{
+    MkpGroupData *group;
+	
+	g_return_if_fail ((node != NULL) && (node->data != NULL)); 
+
+ 	group = MKP_GROUP_DATA (node);
+	group->tokens[category] = g_list_prepend (group->tokens[category], token);
+}
+
+static GList *
+mkp_group_get_token (MkpGroup *node, MkpGroupTokenCategory category)
+{
+    MkpGroupData *group;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	group = MKP_GROUP_DATA (node);
+	return group->tokens[category];
+}
+
+static AnjutaTokenFile*
+mkp_group_set_makefile (MkpGroup *node, GFile *makefile)
+{
+    MkpGroupData *group;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	group = MKP_GROUP_DATA (node);
+	if (group->makefile != NULL) g_object_unref (group->makefile);
+	if (group->tfile != NULL) anjuta_token_file_free (group->tfile);
+	if (makefile != NULL)
+	{
+		group->makefile = g_object_ref (makefile);
+		group->tfile = anjuta_token_file_new (makefile);
+	}
+	else
+	{
+		group->makefile = NULL;
+		group->tfile = NULL;
+	}
+
+	return group->tfile;
+}
+
+static MkpGroup*
+mkp_group_new (GFile *file)
+{
+    MkpGroupData *group = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	
+	group = g_slice_new0(MkpGroupData); 
+	group->base.node.type = ANJUTA_PROJECT_GROUP;
+	group->base.directory = g_object_ref (file);
+
+    return g_node_new (group);
+}
+
+static void
+mkp_group_free (MkpGroup *node)
+{
+    MkpGroupData *group = (MkpGroupData *)node->data;
+	gint i;
+	
+	if (group->base.directory) g_object_unref (group->base.directory);
+	if (group->tfile) anjuta_token_file_free (group->tfile);
+	if (group->makefile) g_object_unref (group->makefile);
+	for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
+	{
+		if (group->tokens[i] != NULL) g_list_free (group->tokens[i]);
+	}
+    g_slice_free (MkpGroupData, group);
+
+	g_node_destroy (node);
+}
+
+/* Target objects
+ *---------------------------------------------------------------------------*/
+
+void
+mkp_target_add_token (MkpGroup *node, AnjutaToken *token)
+{
+    MkpTargetData *target;
+	
+	g_return_if_fail ((node != NULL) && (node->data != NULL)); 
+
+ 	target = MKP_TARGET_DATA (node);
+	target->tokens = g_list_prepend (target->tokens, token);
+}
+
+static GList *
+mkp_target_get_token (MkpGroup *node)
+{
+    MkpTargetData *target;
+	
+	g_return_val_if_fail ((node != NULL) && (node->data != NULL), NULL); 
+
+ 	target = MKP_TARGET_DATA (node);
+	return target->tokens;
+}
+
+
+MkpTarget*
+mkp_target_new (const gchar *name, AnjutaProjectTargetType type)
+{
+    MkpTargetData *target = NULL;
+
+	target = g_slice_new0(MkpTargetData);
+	target->base.node.type = ANJUTA_PROJECT_TARGET;
+	target->base.name = g_strdup (name);
+	if (type == NULL) type = (AnjutaProjectTargetType)&MkpTargetTypes[0];
+	target->base.type = type;
+
+    return g_node_new (target);
+}
+
+void
+mkp_target_free (MkpTarget *node)
+{
+    MkpTargetData *target = MKP_TARGET_DATA (node);
+	
+    g_free (target->base.name);
+    g_free (target->install);
+    g_slice_free (MkpTargetData, target);
+
+	g_node_destroy (node);
+}
+
+/* Source objects
+ *---------------------------------------------------------------------------*/
+
+MkpSource*
+mkp_source_new (GFile *file)
+{
+    MkpSourceData *source = NULL;
+
+	source = g_slice_new0(MkpSourceData); 
+	source->base.node.type = ANJUTA_PROJECT_SOURCE;
+	source->base.file = g_object_ref (file);
+
+    return g_node_new (source);
+}
+
+static void
+mkp_source_free (MkpSource *node)
+{
+    MkpSourceData *source = MKP_SOURCE_DATA (node);
+	
+    g_object_unref (source->base.file);
+    g_slice_free (MkpSourceData, source);
+
+	g_node_destroy (node);
+}
+
+/*
+ * File monitoring support --------------------------------
+ * FIXME: review these
+ */
+static void
+monitor_cb (GFileMonitor *monitor,
+			GFile *file,
+			GFile *other_file,
+			GFileMonitorEvent event_type,
+			gpointer data)
+{
+	MkpProject *project = data;
+
+	g_return_if_fail (project != NULL && MKP_IS_PROJECT (project));
+
+	switch (event_type) {
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		case G_FILE_MONITOR_EVENT_DELETED:
+			/* monitor will be removed here... is this safe? */
+			mkp_project_reload (project, NULL);
+			g_signal_emit_by_name (G_OBJECT (project), "project-updated");
+			break;
+		default:
+			break;
+	}
+}
+
+
+static void
+monitor_add (MkpProject *project, GFile *file)
+{
+	GFileMonitor *monitor = NULL;
+	
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (project->monitors != NULL);
+	
+	if (file == NULL)
+		return;
+	
+	monitor = g_hash_table_lookup (project->monitors, file);
+	if (!monitor) {
+		gboolean exists;
+		
+		/* FIXME clarify if uri is uri, path or both */
+		exists = g_file_query_exists (file, NULL);
+		
+		if (exists) {
+			monitor = g_file_monitor_file (file, 
+						       G_FILE_MONITOR_NONE,
+						       NULL,
+						       NULL);
+			if (monitor != NULL)
+			{
+				g_signal_connect (G_OBJECT (monitor),
+						  "changed",
+						  G_CALLBACK (monitor_cb),
+						  project);
+				g_hash_table_insert (project->monitors,
+						     g_object_ref (file),
+						     monitor);
+			}
+		}
+	}
+}
+
+static void
+monitors_remove (MkpProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	if (project->monitors)
+		g_hash_table_destroy (project->monitors);
+	project->monitors = NULL;
+}
+
+static void
+group_hash_foreach_monitor (gpointer key,
+			    gpointer value,
+			    gpointer user_data)
+{
+	MkpGroup *group_node = value;
+	MkpProject *project = user_data;
+
+	monitor_add (project, MKP_GROUP_DATA(group_node)->base.directory);
+}
+
+static void
+monitors_setup (MkpProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	monitors_remove (project);
+	
+	/* setup monitors hash */
+	project->monitors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+						   (GDestroyNotify) g_file_monitor_cancel);
+
+	//monitor_add (project, anjuta_token_file_get_file (project->make_file));
+	if (project->groups)
+		g_hash_table_foreach (project->groups, group_hash_foreach_monitor, project);
+}
+
+
+/*
+ * ---------------- Data structures managment
+ */
+
+static void
+mkp_dump_node (GNode *g_node)
+{
+	gchar *name = NULL;
+	
+	switch (MKP_NODE_DATA (g_node)->type) {
+		case ANJUTA_PROJECT_GROUP:
+			name = g_file_get_uri (MKP_GROUP_DATA (g_node)->base.directory);
+			DEBUG_PRINT ("GROUP: %s", name);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			name = g_strdup (MKP_TARGET_DATA (g_node)->base.name);
+			DEBUG_PRINT ("TARGET: %s", name);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			name = g_file_get_uri (MKP_SOURCE_DATA (g_node)->base.file);
+			DEBUG_PRINT ("SOURCE: %s", name);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+	g_free (name);
+}
+
+static gboolean 
+foreach_node_destroy (GNode    *g_node,
+		      gpointer  data)
+{
+	switch (MKP_NODE_DATA (g_node)->type) {
+		case ANJUTA_PROJECT_GROUP:
+			//g_hash_table_remove (project->groups, g_file_get_uri (MKP_GROUP_NODE (g_node)->file));
+			mkp_group_free (g_node);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			mkp_target_free (g_node);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			//g_hash_table_remove (project->sources, MKP_NODE (g_node)->id);
+			mkp_source_free (g_node);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+	
+
+	return FALSE;
+}
+
+static void
+project_node_destroy (MkpProject *project, GNode *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,
+				 foreach_node_destroy, project);
+
+		/* now destroy the tree itself */
+		//g_node_destroy (g_node);
+	}
+}
+
+static void
+find_target (GNode *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;
+
+			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)
+{
+	if (is_last_ref)
+	{
+		MkpProject *project = (MkpProject *)data;
+		g_hash_table_remove (project->files, anjuta_token_file_get_file (ANJUTA_TOKEN_FILE (object)));
+	}
+}
+
+static MkpGroup*
+project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GError **error)
+{
+	MkpScanner *scanner;
+	AnjutaToken *rule_tok;
+	AnjutaToken *arg;
+	AnjutaTokenFile *tfile;
+	gboolean found;
+	gboolean ok;
+	GError *err = NULL;
+
+	/* Parse makefile */	
+	DEBUG_PRINT ("Parse: %s", g_file_get_uri (file));
+	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);
+	scanner = mkp_scanner_new (project);
+	ok = mkp_scanner_parse (scanner, tfile, &err);
+	mkp_scanner_free (scanner);
+	if (!ok)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             	IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED,
+		    			err == NULL ? _("Unable to parse make file") : err->message);
+		if (err != NULL) g_error_free (err);
+
+		return NULL;
+	}
+
+	/* 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;
+}
+
+/* Project access functions
+ *---------------------------------------------------------------------------*/
+
+MkpGroup *
+mkp_project_get_root (MkpProject *project)
+{
+	MkpGroup *g_node = NULL;
+	
+	if (project->root_file != NULL)
+	{
+		gchar *id = g_file_get_uri (project->root_file);
+		g_node = (MkpGroup *)g_hash_table_lookup (project->groups, id);
+		g_free (id);
+	}
+
+	return g_node;
+}
+
+GList *
+mkp_project_list_variable (MkpProject *project)
+{
+	return g_hash_table_get_values (project->variables);
+}
+
+MkpVariable*
+mkp_project_get_variable (MkpProject *project, const gchar *name)
+{
+	MkpVariable *var;
+	
+	var = (MkpVariable *)g_hash_table_lookup (project->groups, name);
+
+	return var;
+}
+
+MkpGroup *
+mkp_project_get_group (MkpProject *project, const gchar *id)
+{
+	return (MkpGroup *)g_hash_table_lookup (project->groups, id);
+}
+
+MkpTarget *
+mkp_project_get_target (MkpProject *project, const gchar *id)
+{
+	MkpTarget **buffer;
+	MkpTarget *target;
+	gsize dummy;
+
+	buffer = (MkpTarget **)g_base64_decode (id, &dummy);
+	target = *buffer;
+	g_free (buffer);
+
+	return target;
+}
+
+MkpSource *
+mkp_project_get_source (MkpProject *project, const gchar *id)
+{
+	MkpSource **buffer;
+	MkpSource *source;
+	gsize dummy;
+
+	buffer = (MkpSource **)g_base64_decode (id, &dummy);
+	source = *buffer;
+	g_free (buffer);
+
+	return source;
+}
+
+gchar *
+mkp_project_get_node_id (MkpProject *project, const gchar *path)
+{
+	GNode *node = NULL;
+
+	if (path != NULL)
+	{
+		for (; *path != '\0';)
+		{
+			gchar *end;
+			guint child = g_ascii_strtoull (path, &end, 10);
+
+			if (end == path)
+			{
+				/* error */
+				return NULL;
+			}
+
+			if (node == NULL)
+			{
+				if (child == 0) node = project->root_node;
+			}
+			else
+			{
+				node = g_node_nth_child (node, child);
+			}
+			if (node == NULL)
+			{
+				/* no node */
+				return NULL;
+			}
+
+			if (*end == '\0') break;
+			path = end + 1;
+		}
+	}
+
+	switch (MKP_NODE_DATA (node)->type)
+	{
+		case ANJUTA_PROJECT_GROUP:
+			return g_file_get_uri (MKP_GROUP_DATA (node)->base.directory);
+		case ANJUTA_PROJECT_TARGET:
+		case ANJUTA_PROJECT_SOURCE:
+			return g_base64_encode ((guchar *)&node, sizeof (node));
+		default:
+			return NULL;
+	}
+}
+
+gchar *
+mkp_project_get_uri (MkpProject *project)
+{
+	g_return_val_if_fail (project != NULL, NULL);
+
+	return project->root_file != NULL ? g_file_get_uri (project->root_file) : NULL;
+}
+
+GFile*
+mkp_project_get_file (MkpProject *project)
+{
+	g_return_val_if_fail (project != NULL, NULL);
+
+	return project->root_file;
+}
+	
+GList *
+mkp_project_get_target_types (MkpProject *project, GError **error)
+{
+	MkpTargetInformation *targets = MkpTargetTypes; 
+	GList *types = NULL;
+
+	while (targets->base.name != NULL)
+	{
+		types = g_list_prepend (types, targets);
+		targets++;
+	}
+	types = g_list_reverse (types);
+
+	return types;
+}
+
+/* Group access functions
+ *---------------------------------------------------------------------------*/
+
+GFile*
+mkp_group_get_directory (MkpGroup *group)
+{
+	return MKP_GROUP_DATA (group)->base.directory;
+}
+
+GFile*
+mkp_group_get_makefile (MkpGroup *group)
+{
+	return MKP_GROUP_DATA (group)->makefile;
+}
+
+gchar *
+mkp_group_get_id (MkpGroup *group)
+{
+	return g_file_get_uri (MKP_GROUP_DATA (group)->base.directory);
+}
+
+/* Target access functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+mkp_target_get_name (MkpTarget *target)
+{
+	return MKP_TARGET_DATA (target)->base.name;
+}
+
+AnjutaProjectTargetType
+mkp_target_get_type (MkpTarget *target)
+{
+	return MKP_TARGET_DATA (target)->base.type;
+}
+
+gchar *
+mkp_target_get_id (MkpTarget *target)
+{
+	return g_base64_encode ((guchar *)&target, sizeof (target));
+}
+
+/* Source access functions
+ *---------------------------------------------------------------------------*/
+
+gchar *
+mkp_source_get_id (MkpSource *source)
+{
+	return g_base64_encode ((guchar *)&source, sizeof (source));
+}
+
+GFile*
+mkp_source_get_file (MkpSource *source)
+{
+	return MKP_SOURCE_DATA (source)->base.file;
+}
+
+/* Variable access functions
+ *---------------------------------------------------------------------------*/
+
+const gchar *
+mkp_variable_get_name (MkpVariable *variable)
+{
+	return variable->name;
+}
+
+gchar *
+mkp_variable_evaluate (MkpVariable *variable, AnjutaProjectNode *context)
+{
+	return anjuta_token_evaluate (variable->value);
+}
+
+static MkpVariable*
+mkp_variable_new (gchar *name, AnjutaTokenType assign, AnjutaToken *value)
+{
+    MkpVariable *variable = NULL;
+
+	g_return_val_if_fail (name != NULL, NULL);
+	
+	variable = g_slice_new0(MkpVariable); 
+	variable->name = g_strdup (name);
+	variable->assign = assign;
+	variable->value = value;
+
+	return variable;
+}
+
+static void
+mkp_variable_free (MkpVariable *variable)
+{
+	g_free (variable->name);
+	
+    g_slice_free (MkpVariable, variable);
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+static void
+mkp_project_token_evaluate_token (MkpProject *project, AnjutaToken *token, GString *value)
+{
+	if ((token != NULL) && (anjuta_token_get_length (token) != 0))
+	{
+		gint type = anjuta_token_get_type (token);
+		guint length;
+		const gchar *string;
+		gchar *name;
+		MkpVariable *var;
+		
+		switch (type)
+		{
+		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));
+		}
+	}
+}	
+
+static  void
+mkp_project_token_evaluate_child (MkpProject *project, AnjutaToken *token, GString *value)
+{
+	AnjutaToken *child;
+	
+	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);
+}
+
+gchar *mkp_project_token_evaluate (MkpProject *project, AnjutaToken *token)
+{
+	GString *value = g_string_new (NULL);
+	gchar *str;
+
+	if (token != NULL)
+	{
+		AnjutaToken *child;
+		
+		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);
+	}
+
+	str = g_string_free (value, FALSE);
+	return *str == '\0' ? NULL : str; 	
+}
+
+gboolean
+mkp_project_reload (MkpProject *project, GError **error) 
+{
+	GFile *root_file;
+	GFile *make_file;
+	const gchar **makefile;
+	MkpGroup *group;
+	gboolean ok = TRUE;
+
+	/* Unload current project */
+	root_file = g_object_ref (project->root_file);
+	mkp_project_unload (project);
+	project->root_file = root_file;
+	DEBUG_PRINT ("reload project %p root file %p", project, project->root_file);
+
+	/* 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);
+
+	/* 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);
+
+	/* Find make file */
+	for (makefile = valid_makefiles; *makefile != NULL; makefile++)
+	{
+		if (file_type (root_file, *makefile) == G_FILE_TYPE_REGULAR)
+		{
+			make_file = g_file_get_child (root_file, *makefile);
+			break;
+		}
+	}
+	if (make_file == NULL)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+
+		return FALSE;
+	}
+
+	/* Create group */
+	group = mkp_group_new (root_file);
+	g_hash_table_insert (project->groups, g_file_get_uri (root_file), group);
+	project->root_node = group;
+
+	
+	/* Parse make file */	
+	project_load_makefile (project, make_file, group, error);
+	g_object_unref (make_file);
+
+	monitors_setup (project);
+	
+	
+	return ok;
+}
+
+gboolean
+mkp_project_load (MkpProject  *project,
+    GFile *directory,
+	GError     **error)
+{
+	g_return_val_if_fail (directory != NULL, FALSE);
+
+	project->root_file = g_object_ref (directory);
+	if (!mkp_project_reload (project, error))
+	{
+		g_object_unref (project->root_file);
+		project->root_file = NULL;
+	}
+
+	return project->root_file != NULL;
+}
+
+void
+mkp_project_unload (MkpProject *project)
+{
+	monitors_remove (project);
+	
+	/* project data */
+	project_node_destroy (project, project->root_node);
+	project->root_node = NULL;
+
+	if (project->root_file) g_object_unref (project->root_file);
+	project->root_file = NULL;
+
+	/* shortcut hash tables */
+	if (project->groups) g_hash_table_destroy (project->groups);
+	project->groups = NULL;
+	if (project->files) g_hash_table_destroy (project->files);
+	project->files = NULL;
+	if (project->variables) g_hash_table_destroy (project->variables);
+	project->variables = NULL;
+
+	mkp_project_free_rules (project);
+	
+	/* List styles */
+	if (project->space_list) anjuta_token_style_free (project->space_list);
+	if (project->arg_list) anjuta_token_style_free (project->arg_list);
+}
+
+gint
+mkp_project_probe (GFile *directory,
+	    GError     **error)
+{
+	gboolean probe;
+	gboolean dir;
+	
+	dir = (file_type (directory, NULL) == G_FILE_TYPE_DIRECTORY);
+	if (!dir)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+	}
+	
+	probe =  dir;
+	if (probe)
+	{
+		const gchar **makefile;
+
+		/* Look for makefiles */
+		probe = FALSE;
+		for (makefile = valid_makefiles; *makefile != NULL; makefile++)
+		{
+			if (file_type (directory, *makefile) == G_FILE_TYPE_REGULAR)
+			{
+				probe = TRUE;
+				break;
+			}
+		}
+	}
+
+	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)
+{
+	gpointer key;
+	gpointer value;
+	GHashTableIter iter;
+
+	g_return_val_if_fail (project != NULL, FALSE);
+
+	g_hash_table_iter_init (&iter, project->files);
+	while (g_hash_table_iter_next (&iter, &key, &value))
+	{
+		GError *error = NULL;
+		AnjutaTokenFile *tfile = (AnjutaTokenFile *)value;
+		;
+		anjuta_token_file_save (tfile, &error);
+	}
+
+	return TRUE;
+}
+
+gboolean
+mkp_project_move (MkpProject *project, const gchar *path)
+{
+	GFile	*old_root_file;
+	GFile *new_file;
+	gchar *relative;
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
+	AnjutaTokenFile *tfile;
+	GHashTable* old_hash;
+
+	/* Change project root directory */
+	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))
+	{
+		MkpGroup *group = (MkpGroup *)value;
+		
+		relative = get_relative_path (old_root_file, MKP_GROUP_DATA (group)->base.directory);
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		g_object_unref (MKP_GROUP_DATA (group)->base.directory);
+		MKP_GROUP_DATA (group)->base.directory = new_file;
+
+		g_hash_table_insert (project->groups, g_file_get_uri (new_file), group);
+	}
+	g_hash_table_destroy (old_hash);
+
+	/* Change all files */
+	old_hash = project->files;
+	project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
+	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));
+		new_file = g_file_resolve_relative_path (project->root_file, relative);
+		g_free (relative);
+		anjuta_token_file_move (tfile, new_file);
+		
+		g_hash_table_insert (project->files, new_file, tfile);
+		g_object_unref (key);
+	}
+	g_hash_table_steal_all (old_hash);
+	g_hash_table_destroy (old_hash);
+
+	g_object_unref (old_root_file);
+
+	return TRUE;
+}
+
+MkpProject *
+mkp_project_new (void)
+{
+	return MKP_PROJECT (g_object_new (MKP_TYPE_PROJECT, NULL));
+}
+
+/* Implement IAnjutaProject
+ *---------------------------------------------------------------------------*/
+
+static AnjutaProjectGroup* 
+iproject_add_group (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name, GError **err)
+{
+	return NULL;
+}
+
+static AnjutaProjectSource* 
+iproject_add_source (IAnjutaProject *obj, AnjutaProjectTarget *parent,  GFile *file, GError **err)
+{
+	return NULL;
+}
+
+static AnjutaProjectTarget* 
+iproject_add_target (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name,  AnjutaProjectTargetType type, GError **err)
+{
+	return NULL;
+}
+
+static GtkWidget* 
+iproject_configure (IAnjutaProject *obj, GError **err)
+{
+	return NULL;
+}
+
+static guint 
+iproject_get_capabilities (IAnjutaProject *obj, GError **err)
+{
+	return IANJUTA_PROJECT_CAN_ADD_NONE;
+}
+
+static GList* 
+iproject_get_packages (IAnjutaProject *obj, GError **err)
+{
+	return NULL;
+}
+
+static AnjutaProjectGroup* 
+iproject_get_root (IAnjutaProject *obj, GError **err)
+{
+	return mkp_project_get_root (MKP_PROJECT (obj));
+}
+
+static GList* 
+iproject_get_target_types (IAnjutaProject *obj, GError **err)
+{
+	return mkp_project_get_target_types (MKP_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_load (IAnjutaProject *obj, GFile *file, GError **err)
+{
+	return mkp_project_load (MKP_PROJECT (obj), file, err);
+}
+
+static gboolean
+iproject_refresh (IAnjutaProject *obj, GError **err)
+{
+	return mkp_project_reload (MKP_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_remove_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+{
+	return TRUE;
+}
+
+static void
+iproject_iface_init(IAnjutaProjectIface* iface)
+{
+	iface->add_group = iproject_add_group;
+	iface->add_source = iproject_add_source;
+	iface->add_target = iproject_add_target;
+	iface->configure = iproject_configure;
+	iface->get_capabilities = iproject_get_capabilities;
+	iface->get_packages = iproject_get_packages;
+	iface->get_root = iproject_get_root;
+	iface->get_target_types = iproject_get_target_types;
+	iface->load = iproject_load;
+	iface->refresh = iproject_refresh;
+	iface->remove_node = iproject_remove_node;
+}
+
+/* GbfProject implementation
+ *---------------------------------------------------------------------------*/
+
+static void
+mkp_project_dispose (GObject *object)
+{
+	g_return_if_fail (MKP_IS_PROJECT (object));
+
+	mkp_project_unload (MKP_PROJECT (object));
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);	
+}
+
+static void
+mkp_project_instance_init (MkpProject *project)
+{
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (MKP_IS_PROJECT (project));
+	
+	/* project data */
+	project->root_file = NULL;
+	project->root_node = NULL;
+	project->property = NULL;
+	project->suffix = NULL;
+	project->rules = NULL;
+
+	project->space_list = NULL;
+	project->arg_list = NULL;
+}
+
+static void
+mkp_project_class_init (MkpProjectClass *klass)
+{
+	GObjectClass *object_class;
+	
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->dispose = mkp_project_dispose;
+}
+
+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
new file mode 100644
index 0000000..22c2fc0
--- /dev/null
+++ b/plugins/mk-project/mk-project.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* mk-project.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 _MK_PROJECT_H_
+#define _MK_PROJECT_H_
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+#include <libanjuta/anjuta-token-style.h>
+
+G_BEGIN_DECLS
+
+#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))
+#define MKP_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), MKP_TYPE_PROJECT, MkpProjectClass))
+#define MKP_IS_PROJECT(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), MKP_TYPE_PROJECT))
+#define MKP_IS_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), MKP_TYPE_PROJECT))
+
+#define MKP_GROUP(obj)		((MkpGroup *)obj)
+#define MKP_TARGET(obj)		((MkpTarget *)obj)
+#define MKP_SOURCE(obj)		((MkpSource *)obj)
+
+typedef struct _MkpProject        MkpProject;
+typedef struct _MkpProjectClass   MkpProjectClass;
+
+struct _MkpProjectClass {
+	GObjectClass parent_class;
+};
+
+typedef AnjutaProjectGroup MkpGroup;
+typedef AnjutaProjectTarget MkpTarget;
+typedef AnjutaProjectSource MkpSource;
+typedef struct _MkpProperty MkpProperty;
+typedef struct _MkpVariable MkpVariable;
+typedef struct _MkpRule MkpRule;
+
+typedef enum {
+	MKP_PROPERTY_NAME = 0,
+	MKP_PROPERTY_VERSION,
+	MKP_PROPERTY_BUG_REPORT,
+	MKP_PROPERTY_TARNAME,
+	MKP_PROPERTY_URL
+} MkpPropertyType;
+
+
+GType         mkp_project_get_type (void);
+MkpProject   *mkp_project_new      (void);
+
+
+gint mkp_project_probe (GFile *directory, GError     **error);
+gboolean mkp_project_load (MkpProject *project, GFile *directory, GError **error);
+gboolean mkp_project_reload (MkpProject *project, GError **error);
+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);
+
+MkpGroup *mkp_project_get_group (MkpProject *project, const gchar *id);
+MkpTarget *mkp_project_get_target (MkpProject *project, const gchar *id);
+MkpSource *mkp_project_get_source (MkpProject *project, const gchar *id);
+
+gboolean mkp_project_move (MkpProject *project, const gchar *path);
+gboolean mkp_project_save (MkpProject *project, GError **error);
+
+gchar * mkp_project_get_uri (MkpProject *project);
+GFile* mkp_project_get_file (MkpProject *project);
+
+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);
+
+MkpTarget* mkp_project_add_target (MkpProject  *project, MkpGroup *parent, const gchar *name, const gchar *type, GError **error);
+void mkp_project_remove_target (MkpProject  *project, MkpTarget *target, GError **error);
+
+MkpSource* mkp_project_add_source (MkpProject  *project, MkpTarget *target, const gchar *uri, GError **error);
+void mkp_project_remove_source (MkpProject  *project, MkpSource *source, GError **error);
+
+gchar * mkp_project_get_node_id (MkpProject *project, const gchar *path);
+
+GFile *mkp_group_get_directory (MkpGroup *group);
+GFile *mkp_group_get_makefile (MkpGroup *group);
+gchar *mkp_group_get_id (MkpGroup *group);
+
+const gchar *mkp_target_get_name (MkpTarget *target);
+AnjutaProjectTargetType amp_target_get_type (MkpTarget *target);
+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);
+const gchar* mkp_variable_get_name (MkpVariable *variable);
+
+G_END_DECLS
+
+#endif /* _MK_PROJECT_H_ */
diff --git a/plugins/gbf-mkfile/gbf-mkfile.plugin.in b/plugins/mk-project/mk-project.plugin.in
similarity index 78%
rename from plugins/gbf-mkfile/gbf-mkfile.plugin.in
rename to plugins/mk-project/mk-project.plugin.in
index d9aa4d5..543fc4c 100644
--- a/plugins/gbf-mkfile/gbf-mkfile.plugin.in
+++ b/plugins/mk-project/mk-project.plugin.in
@@ -1,8 +1,8 @@
 [Anjuta Plugin]
 _Name=Makefile backend
 _Description=Makefile backend for project manager
-Location=gbf-mkfile:GbfMkfilePlugin
-Icon=gbf-mkfile-plugin-48.png
+Location=mk-project:MkpPlugin
+Icon=mk-project-plugin-48.png
 Interfaces=IAnjutaProjectBackend
 Dependencies=anjuta-project-manager:ProjectManagerPlugin
 UserActivatable=no
diff --git a/plugins/mk-project/mk-project.ui b/plugins/mk-project/mk-project.ui
new file mode 100644
index 0000000..931f50b
--- /dev/null
+++ b/plugins/mk-project/mk-project.ui
@@ -0,0 +1,419 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="package_selection_dialog">
+    <property name="title" translatable="yes">Select package</property>
+    <property name="default_width">600</property>
+    <property name="default_height">500</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkVBox" id="vbox2">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkFrame" id="frame1">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment3">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="border_width">5</property>
+                        <property name="hscrollbar_policy">automatic</property>
+                        <property name="vscrollbar_policy">automatic</property>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="pkg_treeview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Select Package to add:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancelbutton1">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="okbutton1">
+                <property name="label">gtk-add</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">cancelbutton1</action-widget>
+      <action-widget response="-3">okbutton1</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkNotebook" id="top_level">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="border_width">6</property>
+    <child>
+      <object class="GtkTable" id="general_properties_table">
+        <property name="visible">True</property>
+        <property name="border_width">6</property>
+        <property name="n_rows">7</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">General</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="vbox1">
+        <property name="height_request">300</property>
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHButtonBox" id="hbuttonbox1">
+            <property name="visible">True</property>
+            <property name="border_width">5</property>
+            <property name="spacing">5</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="add_module_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox1">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image1">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-add</property>
+                            <property name="icon-size">4</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Add _module</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="add_package_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox2">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image2">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-add</property>
+                            <property name="icon-size">4</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Add _Package</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove_button">
+                <property name="label">gtk-remove</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">etched-in</property>
+            <child>
+              <object class="GtkTreeView" id="packages_treeview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label2">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Packages</property>
+      </object>
+      <packing>
+        <property name="position">1</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="vbox3">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHButtonBox" id="hbuttonbox2">
+            <property name="visible">True</property>
+            <property name="spacing">5</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="add_variable_button">
+                <property name="label">gtk-add</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove_variable_button">
+                <property name="label">gtk-remove</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow3">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTreeView" id="variables_treeview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label6">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Variables</property>
+      </object>
+      <packing>
+        <property name="position">2</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/mk-project/mk-rule.c b/plugins/mk-project/mk-rule.c
new file mode 100644
index 0000000..39422ad
--- /dev/null
+++ b/plugins/mk-project/mk-rule.c
@@ -0,0 +1,372 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* mk-rule.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 "mk-rule.h"
+
+#include "mk-project-private.h"
+#include "mk-scanner.h"
+
+#include <string.h>
+
+/* Rule object
+ *---------------------------------------------------------------------------*/
+
+/* Maximum level of dependencies when searching for source files */
+#define MAX_DEPENDENCIES	16
+
+/* Rule object
+ *---------------------------------------------------------------------------*/
+
+static MkpRule*
+mkp_rule_new (gchar *name, AnjutaToken *token)
+{
+    MkpRule *rule = NULL;
+
+	g_return_val_if_fail (name != NULL, NULL);
+	
+	rule = g_slice_new0(MkpRule); 
+	rule->name = g_strdup (name);
+	rule->rule = token;
+
+	return rule;
+}
+
+static void
+mkp_rule_free (MkpRule *rule)
+{
+	g_free (rule->name);
+	g_list_foreach (rule->prerequisite, (GFunc)g_free, NULL);
+	g_list_free (rule->prerequisite);
+	
+    g_slice_free (MkpRule, rule);
+}
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+/* Find a source for target checking pattern rule. If no source is found,
+ * return target, else free target and return a newly allocated source name */
+
+gchar *
+mkp_project_find_source (MkpProject *project, gchar *target, AnjutaProjectGroup *parent, guint backtrack)
+{
+	GFile *child;
+	gboolean exist;
+	GHashTableIter iter;
+	gchar *key;
+	MkpRule *rule;
+
+	/* Check pattern rules */
+	if (backtrack < MAX_DEPENDENCIES)
+	{
+		for (g_hash_table_iter_init (&iter, project->rules); g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&rule);)
+		{
+			if (rule->pattern)
+			{
+				gchar *source;
+				
+				if (rule->part == NULL)
+				{	
+					/* simple suffix rule */
+					source = g_strconcat (target, rule->name, NULL);
+				}
+				else
+				{
+					/* double suffix rule */
+					if (strcmp (target + strlen (target) - strlen (rule->part), rule->part) == 0)
+					{
+						gchar *suffix;
+
+						source = g_strconcat (target, rule->name, NULL);
+						suffix = source + strlen (target) - strlen (rule->part);
+
+						memcpy (suffix, rule->name, rule->part - rule->name);
+						*(suffix + (rule->part - rule->name)) = '\0';
+					}
+					else
+					{
+						continue;
+					}
+				}
+					
+				source = mkp_project_find_source (project, source, parent, backtrack + 1);
+
+				if (source != NULL)
+				{
+					g_free (target);
+
+					return source;
+				}
+			}
+		}
+	}
+		
+	child = g_file_get_child (anjuta_project_group_get_directory (parent), target);
+	exist = g_file_query_exists (child, NULL);
+	g_message ("target =%s= filename =%s=", target, g_file_get_parse_name (child));
+	g_object_unref (child);
+
+	if (!exist)
+	{
+		g_free (target);
+		return NULL;
+	}
+	else
+	{
+		return target;
+	}
+}
+
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+void
+mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
+{
+	AnjutaToken *targ;
+	AnjutaToken *dep;
+	AnjutaToken *arg;
+	gboolean double_colon = FALSE;
+
+	targ = anjuta_token_list_first (token);
+	arg = anjuta_token_list_next (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))
+	{
+		AnjutaToken *src;
+		gchar *target;
+		gboolean order = FALSE;
+		gboolean no_token = TRUE;
+		MkpRule *rule;
+
+		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))
+			{
+				if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
+				{
+					target = mkp_project_token_evaluate (project, src);
+					
+					rule = g_hash_table_lookup (project->rules, target);
+					if (rule == NULL)
+					{
+						rule = mkp_rule_new (target, NULL);
+						g_hash_table_insert (project->rules, rule->name, rule);
+					}
+					rule->phony = TRUE;
+					
+					g_message ("    with target %s", target);
+					if (target != NULL) g_free (target);
+				}
+			}
+			break;
+		case MK_TOKEN__SUFFIXES:
+			for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+			{
+				if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
+				{
+					gchar *suffix;
+
+					suffix = mkp_project_token_evaluate (project, 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);
+					g_message ("    with suffix %s", suffix);
+					no_token = FALSE;
+				}
+			}
+			if (no_token == TRUE)
+			{
+				/* Clear all suffix */
+				g_hash_table_remove_all (project->suffix);
+			}
+			break;
+		case MK_TOKEN__DEFAULT:
+		case MK_TOKEN__PRECIOUS:
+		case MK_TOKEN__INTERMEDIATE:
+		case MK_TOKEN__SECONDARY:
+		case MK_TOKEN__SECONDEXPANSION:
+		case MK_TOKEN__DELETE_ON_ERROR:
+		case MK_TOKEN__IGNORE:
+		case MK_TOKEN__LOW_RESOLUTION_TIME:
+		case MK_TOKEN__SILENT:
+		case MK_TOKEN__EXPORT_ALL_VARIABLES:
+		case MK_TOKEN__NOTPARALLEL:
+			/* Do nothing with these targets, just ignore them */
+			break;
+		default:
+			target = g_strstrip (mkp_project_token_evaluate (project, 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);
+				g_hash_table_insert (project->rules, rule->name, rule);
+			}
+			else
+			{
+				rule->rule = arg;
+			}
+				
+			for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (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)
+				{
+					order = TRUE;
+				}
+				rule->prerequisite = g_list_prepend (rule->prerequisite, src_name);
+			}
+
+			if (target != NULL) g_free (target);
+		}
+	}
+}
+
+void
+mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent)
+{
+	GHashTableIter iter;
+	gpointer key;
+	MkpRule *rule;
+
+	/* Check pattern rules */
+	for (g_hash_table_iter_init (&iter, project->rules); g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&rule);)
+	{
+		if (rule->phony) continue;
+
+		if (g_hash_table_lookup (project->suffix, rule->name))
+		{
+			/* Single suffix rule */
+			rule->pattern = TRUE;
+			rule->part = NULL;
+		}
+		else
+		{
+			GString *pattern = g_string_sized_new (16);
+			GList *suffix;
+			GList *src;
+			
+			/* Check double suffix rule */
+			suffix = g_hash_table_get_keys (project->suffix);
+			
+			for (src = g_list_first (suffix); src != NULL; src = g_list_next (src))
+			{
+				GList *obj;
+
+				for (obj = g_list_first (suffix); obj != NULL; obj = g_list_next (obj))
+				{
+					g_string_assign (pattern, src->data);
+					g_string_append (pattern, obj->data);
+
+					if (strcmp (pattern->str, rule->name) == 0)
+					{
+						rule->pattern = TRUE;
+						rule->part = rule->name + strlen (src->data);
+						break;
+					}
+				}
+				if (rule->pattern) break;
+			}
+
+			g_string_free (pattern, TRUE);
+			g_list_free (suffix);
+		}
+	}
+
+	/* Create new target */
+	for (g_hash_table_iter_init (&iter, project->rules); g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&rule);)
+	{
+		MkpTarget *target;
+		AnjutaToken *prerequisite;
+		AnjutaToken *arg;
+
+		g_message ("rule =%s=", rule->name);
+		if (rule->phony || rule->pattern) continue;
+		
+		/* Create target */
+		target = mkp_target_new (rule->name, NULL);
+		mkp_target_add_token (target, rule->rule);
+		g_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;
+			}
+		}
+		
+		/* Add prerequisite */
+		for (arg = anjuta_token_list_first (prerequisite); arg != NULL; arg = anjuta_token_list_next (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);
+
+			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);
+
+				g_free (name);
+			}
+		}
+		
+	}
+}
+
+void 
+mkp_project_init_rules (MkpProject *project)
+{
+	project->rules = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)mkp_rule_free);
+	project->suffix = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+}
+
+void 
+mkp_project_free_rules (MkpProject *project)
+{
+	if (project->rules) g_hash_table_destroy (project->rules);
+	project->rules = NULL;
+	if (project->suffix) g_hash_table_destroy (project->suffix);
+	project->suffix = NULL;
+}
+
diff --git a/plugins/mk-project/mk-rule.h b/plugins/mk-project/mk-rule.h
new file mode 100644
index 0000000..e02db66
--- /dev/null
+++ b/plugins/mk-project/mk-rule.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* mk-rule.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 _MK_RULE_H_
+#define _MK_RULE_H_
+
+#include <glib-object.h>
+
+#include "mk-project.h"
+
+
+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);
+
+G_END_DECLS
+
+#endif /* _MK_RULE_H_ */
diff --git a/plugins/mk-project/mk-scanner.h b/plugins/mk-project/mk-scanner.h
new file mode 100644
index 0000000..dd5ec57
--- /dev/null
+++ b/plugins/mk-project/mk-scanner.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * mk-scanner.h
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 _MK_SCANNER_H_
+#define _MK_SCANNER_H_
+
+#include "libanjuta/anjuta-token.h"
+#include "libanjuta/anjuta-token-file.h"
+#include "libanjuta/anjuta-token-style.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#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);
+
+void mkp_scanner_update_variable (MkpScanner *scanner, AnjutaToken *variable);
+void mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule);
+
+const gchar* mkp_scanner_get_filename (MkpScanner *scanner);
+
+typedef enum
+{
+	MK_TOKEN_RULE = ANJUTA_TOKEN_USER,
+	MK_TOKEN_EQUAL,
+	MK_TOKEN_IMMEDIATE_EQUAL,
+	MK_TOKEN_CONDITIONAL_EQUAL,
+	MK_TOKEN_APPEND,
+	MK_TOKEN_TARGET,
+	MK_TOKEN_PREREQUISITE,
+	MK_TOKEN_ORDER_PREREQUISITE,
+	MK_TOKEN_ORDER,
+	MK_TOKEN_COLON,
+	MK_TOKEN_DOUBLE_COLON,
+	MK_TOKEN_VARIABLE,
+	MK_TOKEN__PHONY,
+	MK_TOKEN__SUFFIXES,
+	MK_TOKEN__DEFAULT,
+	MK_TOKEN__PRECIOUS,
+	MK_TOKEN__INTERMEDIATE,
+	MK_TOKEN__SECONDARY,
+	MK_TOKEN__SECONDEXPANSION,
+	MK_TOKEN__DELETE_ON_ERROR,
+	MK_TOKEN__IGNORE,
+	MK_TOKEN__LOW_RESOLUTION_TIME,
+	MK_TOKEN__SILENT,
+	MK_TOKEN__EXPORT_ALL_VARIABLES,
+	MK_TOKEN__NOTPARALLEL,
+} MakeTokenType;
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/mk-project/mk-scanner.l b/plugins/mk-project/mk-scanner.l
new file mode 100644
index 0000000..972069d
--- /dev/null
+++ b/plugins/mk-project/mk-scanner.l
@@ -0,0 +1,294 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * mk-scanner.l
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ * 
+ * main.c 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.
+ * 
+ * main.c 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 <stdlib.h>
+#include <string.h>
+#include "mk-scanner.h"
+#include "mk-parser.h"
+
+#include "libanjuta/anjuta-debug.h"
+
+
+/* Eliminate warning */
+#define YY_NO_UNPUT 1 
+
+#define YY_INPUT(buf,result,the_max_size) \
+    result = 0;
+
+#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);
+
+
+#define RETURN(tok) *yylval = mkp_scanner_append_token (yyextra, tok); \
+                    return tok
+
+%}
+
+%option reentrant stack noyywrap yylineno
+
+%option prefix="mkp_mk_yy"
+
+/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
+ * not "lex.mkp_yy.c" 
+%option outfile="lex.yy.c"*/
+
+%option bison-bridge bison-locations
+
+%option never-interactive
+
+%option batch
+
+%option debug
+
+NAME          [^ \t\n\r:#=$"'`&@\\]*
+
+%%
+
+\n                          { RETURN (EOL); }
+
+
+([ ]|\\\n)([ \t]|\\\n)*     { RETURN (SPACE); }
+
+#                           { RETURN (HASH); }
+
+\t                          { RETURN (TAB); }
+
+\$\([^ \t\n\r:#=$)]+\)      { RETURN (VARIABLE); }
+
+\$\{[^ \t\n\r:#=$}]+\}      { RETURN (VARIABLE); }
+
+\$[^ \t\n\r\(\{]            { RETURN (VARIABLE); }
+
+,                           { RETURN (COMMA); }
+
+:                           { RETURN (COLON); }
+
+::                          { RETURN (DOUBLE_COLON); }
+
+;                           { RETURN (SEMI_COLON); }
+
+\|                          { RETURN (ORDER); }
+
+\=                          { RETURN (EQUAL); }
+
+:=                          { RETURN (IMMEDIATE_EQUAL); }
+
+\?=                         { RETURN (CONDITIONAL_EQUAL); }
+
+\+=                         { RETURN (APPEND); }
+
+\\[ ]                       { RETURN (CHARACTER); }
+
+\\:                         { RETURN (CHARACTER); }
+
+\\=                         { RETURN (CHARACTER); }
+
+\\#                         { RETURN (CHARACTER); }
+
+.PHONY                      { RETURN (_PHONY); }
+
+.SUFFIXES                   { RETURN (_SUFFIXES); }
+
+.DEFAULT                    { RETURN (_DEFAULT); }
+
+.PRECIOUS                   { RETURN (_PRECIOUS); }
+
+.INTERMEDIATE               { RETURN (_INTERMEDIATE); }
+    
+.SECONDARY                  { RETURN (_SECONDARY); }
+
+.SECONDEXPANSION            { RETURN (_SECONDEXPANSION); }
+
+.DELETE_ON_ERROR            { RETURN (_DELETE_ON_ERROR); }
+
+.IGNORE                     { RETURN (_IGNORE); }
+
+.LOW_RESOLUTION_TIME        { RETURN (_LOW_RESOLUTION_TIME); }
+
+.SILENT                     { RETURN (_SILENT); }
+
+.EXPORT_ALL_VARIABLES       { RETURN (_EXPORT_ALL_VARIABLES); }
+
+.NOTPARALLEL                { RETURN (_NOTPARALLEL); }
+
+{NAME}                      { RETURN (NAME);}
+
+.                           { RETURN (CHARACTER); }
+
+%%
+     
+struct _MkpScanner
+{
+    const gchar *pos;
+    yyscan_t scanner;
+    YY_BUFFER_STATE	 buffer;
+
+    AnjutaTokenFile *file;
+    gchar *filename;
+
+    MkpProject *project;
+
+	guint line_width;
+};
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static AnjutaToken*
+mkp_scanner_append_token (MkpScanner *scanner, gint token)
+{
+    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;
+}
+
+static void
+mkp_scanner_update_line_width (MkpScanner *scanner, YYLTYPE *loc)
+{
+	anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+}
+
+void
+mkp_scanner_update_variable (MkpScanner *scanner, AnjutaToken *variable)
+{
+    mkp_project_update_variable (scanner->project, variable);
+}
+
+void
+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)
+{
+	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;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+int
+mkp_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,MkpScanner *scanner)
+{
+    return mkp_mk_yylex (yylval_param, yylloc_param, scanner->scanner);
+}
+
+
+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
+ *---------------------------------------------------------------------------*/
+
+MkpScanner *
+mkp_scanner_new (MkpProject *project)
+{
+	MkpScanner *scanner;
+
+	scanner = g_new0 (MkpScanner, 1);
+
+    yylex_init(&scanner->scanner);
+    yyset_extra (scanner, scanner->scanner);
+
+    scanner->project = project;
+
+	return scanner;
+};
+
+void
+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/gbf-mkfile/plugin.c b/plugins/mk-project/plugin.c
similarity index 77%
rename from plugins/gbf-mkfile/plugin.c
rename to plugins/mk-project/plugin.c
index 4d0d60f..f4db9b4 100644
--- a/plugins/gbf-mkfile/plugin.c
+++ b/plugins/mk-project/plugin.c
@@ -18,17 +18,16 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#define DEBUG
 #include <config.h>
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/gbf-project.h>
 #include <libanjuta/interfaces/ianjuta-project-backend.h>
 
 #include "plugin.h"
-#include "gbf-mkfile-project.h"
+#include "mk-project.h"
 
 
-#define ICON_FILE "gbf-mkfile-plugin-48.png"
+#define ICON_FILE "mk-project-plugin-48.png"
 
 /* AnjutaPlugin functions
  *---------------------------------------------------------------------------*/
@@ -36,7 +35,7 @@
 static gboolean
 activate_plugin (AnjutaPlugin *plugin)
 {
-	DEBUG_PRINT ("GbfMkfilePlugin: Activating Gnome build makefile backend Plugin ...");
+	DEBUG_PRINT ("MkpPlugin: Activating Anjuta make backend Plugin ...");
 	
 	return TRUE;
 }
@@ -44,7 +43,7 @@ activate_plugin (AnjutaPlugin *plugin)
 static gboolean
 deactivate_plugin (AnjutaPlugin *plugin)
 {
-	DEBUG_PRINT ("GbfMkfilePlugin: Deactivating Gnome build makefile backend Plugin ...");
+	DEBUG_PRINT ("MkpPlugin: Deacctivating Anjuta make backend Plugin ...");
 	return TRUE;
 }
 
@@ -52,20 +51,29 @@ deactivate_plugin (AnjutaPlugin *plugin)
 /* IAnjutaProjectBackend implementation
  *---------------------------------------------------------------------------*/
 
-static GbfProject*
+static IAnjutaProject*
 iproject_backend_new_project (IAnjutaProjectBackend* backend, GError** err)
 {
-	GbfProject *project;
-	
-	project = gbf_mkfile_project_new ();
+	IAnjutaProject *project;
+	DEBUG_PRINT("create new mkp project");	
+	project = (IAnjutaProject *)(g_object_new (MKP_TYPE_PROJECT, NULL));
 		
 	return project;
 }
 
+static gint
+iproject_backend_probe (IAnjutaProjectBackend* backend, GFile *directory, GError** err)
+{
+	DEBUG_PRINT("probe mkp project");
+
+	return mkp_project_probe (directory, err);
+}
+
 static void
 iproject_backend_iface_init(IAnjutaProjectBackendIface *iface)
 {
 	iface->new_project = iproject_backend_new_project;
+	iface->probe = iproject_backend_probe;
 }
 
 /* GObject functions
@@ -75,7 +83,7 @@ iproject_backend_iface_init(IAnjutaProjectBackendIface *iface)
 static gpointer parent_class;
 
 static void
-gbf_mkfile_plugin_instance_init (GObject *obj)
+mkp_plugin_instance_init (GObject *obj)
 {
 }
 
@@ -96,7 +104,7 @@ finalize (GObject *obj)
 }
 
 static void
-gbf_mkfile_plugin_class_init (GObjectClass *klass) 
+mkp_plugin_class_init (GObjectClass *klass) 
 {
 	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
 
@@ -111,13 +119,8 @@ gbf_mkfile_plugin_class_init (GObjectClass *klass)
 /* AnjutaPlugin declaration
  *---------------------------------------------------------------------------*/
 
-ANJUTA_PLUGIN_BEGIN (GbfMkfilePlugin, gbf_mkfile_plugin);
+ANJUTA_PLUGIN_BEGIN (MkpPlugin, mkp_plugin);
 ANJUTA_PLUGIN_ADD_INTERFACE (iproject_backend, IANJUTA_TYPE_PROJECT_BACKEND);
 ANJUTA_PLUGIN_END;
 
-G_MODULE_EXPORT void
-anjuta_glue_register_components (GTypeModule *module)
-{
-	gbf_mkfile_plugin_get_type (module);
-        gbf_mkfile_project_get_type (module);
-}                     
+ANJUTA_SIMPLE_PLUGIN (MkpPlugin, mkp_plugin);
diff --git a/plugins/gbf-am/plugin.h b/plugins/mk-project/plugin.h
similarity index 56%
rename from plugins/gbf-am/plugin.h
rename to plugins/mk-project/plugin.h
index 100e980..0059cd0 100644
--- a/plugins/gbf-am/plugin.h
+++ b/plugins/mk-project/plugin.h
@@ -23,23 +23,23 @@
 
 #include <libanjuta/anjuta-plugin.h>
 
-extern GType gbf_am_plugin_get_type (GTypeModule *module);
-#define GBF_TYPE_PLUGIN_AM         (gbf_am_plugin_get_type (NULL))
-#define GBF_PLUGIN_AM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GBF_TYPE_PLUGIN_AM, GbfAmPlugin))
-#define GBF_PLUGIN_AM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), GBF_TYPE_PLUGIN_AM, GbfAmPluginClass))
-#define GBF_IS_PLUGIN_AM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GBF_TYPE_PLUGIN_AM))
-#define GBF_IS_PLUGIN_AM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GBF_TYPE_PLUGIN_AM))
-#define GBF_PLUGIN_AM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GBF_TYPE_PLUGIN_AM, GbfAmPluginClass))
-
-typedef struct _GbfAmPlugin GbfAmPlugin;
-typedef struct _GbfAmPluginClass GbfAmPluginClass;
-
-struct _GbfAmPlugin 
+extern GType amp_plugin_get_type (GTypeModule *module);
+#define ANJUTA_TYPE_PLUGIN_MKP         (mkp_plugin_get_type (NULL))
+#define ANJUTA_PLUGIN_MKP(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), ANJUTA_TYPE_PLUGIN_MKP, MkpPlugin))
+#define ANJUTA_PLUGIN_MKP_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), ANJUTA_TYPE_PLUGIN_MKP, MkpPluginClass))
+#define ANJUTA_IS_PLUGIN_MKP(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), ANJUTA_TYPE_PLUGIN_MKP))
+#define ANJUTA_IS_PLUGIN_MKP_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), ANJUTA_TYPE_PLUGIN_MKP))
+#define ANJUTA_PLUGIN_MKP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ANJUTA_TYPE_PLUGIN_MKP, MkPluginClass))
+
+typedef struct _MkpPlugin MkpPlugin;
+typedef struct _MkpPluginClass MkpPluginClass;
+
+struct _MkpPlugin 
 {
 	AnjutaPlugin parent;
 };
 
-struct _GbfAmPluginClass
+struct _MkpPluginClass
 {
 	AnjutaPluginClass parent_class;
 };
diff --git a/plugins/project-manager/gbf-project-model.c b/plugins/project-manager/gbf-project-model.c
index 5f63eb8..d9ede16 100644
--- a/plugins/project-manager/gbf-project-model.c
+++ b/plugins/project-manager/gbf-project-model.c
@@ -34,7 +34,7 @@
 
 
 struct _GbfProjectModelPrivate {
-	GbfProject          *proj;
+	IAnjutaProject      *proj;
 	gulong               project_updated_handler;
 	
 	GtkTreeRowReference *root_row;
@@ -57,7 +57,7 @@ static void     gbf_project_model_drag_source_init   (GtkTreeDragSourceIface *if
 static void     gbf_project_model_drag_dest_init     (GtkTreeDragDestIface   *iface);
 
 static void     load_project                         (GbfProjectModel        *model,
-						      GbfProject             *proj);
+						      IAnjutaProject         *proj);
 static void     insert_empty_node                    (GbfProjectModel        *model);
 static void     unload_project                       (GbfProjectModel        *model);
 
@@ -284,12 +284,12 @@ default_sort_func (GtkTreeModel *model,
 		/* special case: the order of shortcuts is
 		 * user customizable */
 		for (l = GBF_PROJECT_MODEL (model)->priv->shortcuts; l; l = l->next) {
-			if (!strcmp (l->data, data_a->id)) {
+			if (l->data == data_a->id) {
 				/* a comes first */
 				retval = -1;
 				break;
 			}
-			else if (!strcmp (l->data, data_b->id)) {
+			else if (l->data == data_b->id) {
 				/* b comes first */
 				retval = 1;
 				break;
@@ -322,16 +322,14 @@ default_sort_func (GtkTreeModel *model,
 
 
 static void 
-add_source (GbfProjectModel *model,
-	    const gchar     *source_id,
-	    GtkTreeIter     *parent)
+add_source (GbfProjectModel    	      *model,
+	    AnjutaProjectSource *source,
+	    GtkTreeIter               *parent)
 {
-	GbfProjectTargetSource *source;
 	GtkTreeIter iter;
 	GbfTreeData *data;
 	
-	source = gbf_project_get_source (model->priv->proj, source_id, NULL);
-	if (!source)
+	if ((!source) || (anjuta_project_node_get_type (source) != ANJUTA_PROJECT_SOURCE))
 		return;
 	
 	data = gbf_tree_data_new_source (model->priv->proj, source);
@@ -340,31 +338,28 @@ add_source (GbfProjectModel *model,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
 	gbf_tree_data_free (data);
-
-	gbf_project_target_source_free (source);
 }
 
 static GtkTreePath *
-find_shortcut (GbfProjectModel *model, const gchar *target_id)
+find_shortcut (GbfProjectModel *model, const AnjutaProjectTarget *target)
 {
 	GList *l;
 	gint i;
 	
 	for (l = model->priv->shortcuts, i = 0; l; l = l->next, i++) {
-		if (!strcmp (target_id, l->data))
+		if (target == l->data)
 			return gtk_tree_path_new_from_indices (i, -1);
 	}
 	return NULL;
 }
 
 static void
-remove_shortcut (GbfProjectModel *model, const gchar *target_id)
+remove_shortcut (GbfProjectModel *model, const AnjutaProjectTarget *target)
 {
 	GList *l;
 	
 	for (l = model->priv->shortcuts; l; l = l->next) {
-		if (!strcmp (target_id, l->data)) {
-			g_free (l->data);
+		if (target == l->data) {
 			model->priv->shortcuts = g_list_delete_link (
 				model->priv->shortcuts, l);
 			break;
@@ -374,18 +369,16 @@ remove_shortcut (GbfProjectModel *model, const gchar *target_id)
 
 static void 
 add_target_shortcut (GbfProjectModel *model,
-		     const gchar     *target_id,
+		     AnjutaProjectTarget *target,
 		     GtkTreePath     *before_path)
 {
-	GList *l;
+	AnjutaProjectNode *node;
 	GtkTreeIter iter, sibling;
-	GbfProjectTarget *target;
 	GtkTreePath *root_path, *old_path;
 	gint *path_indices, i;
 	GbfTreeData *data;
 	
-	target = gbf_project_get_target (model->priv->proj, target_id, NULL);
-	if (!target)
+	if ((!target) || (anjuta_project_node_get_type (target) != ANJUTA_PROJECT_SOURCE))
 		return;
 
 	root_path = gtk_tree_row_reference_get_path (model->priv->root_row);
@@ -406,9 +399,9 @@ add_target_shortcut (GbfProjectModel *model,
 	i = path_indices [0];
 
 	/* remove the old shortcut to make sorting actually work */
-	old_path = find_shortcut (model, target_id);
+	old_path = find_shortcut (model, target);
 	if (old_path) {
-		remove_shortcut (model, target_id);
+		remove_shortcut (model, target);
 		if (gtk_tree_path_compare (old_path, before_path) < 0) {
 			/* adjust shortcut insert position if the old
 			 * index was before the new site */
@@ -419,7 +412,7 @@ add_target_shortcut (GbfProjectModel *model,
 			
 	/* add entry to the shortcut list */
 	model->priv->shortcuts = g_list_insert (model->priv->shortcuts,
-						g_strdup (target->id), i);
+						target, i);
 	
 	data = gbf_tree_data_new_target (model->priv->proj, target);
 	data->is_shortcut = TRUE;
@@ -430,25 +423,22 @@ add_target_shortcut (GbfProjectModel *model,
 	gbf_tree_data_free (data);
 	
 	/* add sources */
-	for (l = target->sources; l; l = l->next)
-		add_source (model, l->data, &iter);
+	for (node = anjuta_project_node_first_child (target); node; node = anjuta_project_node_next_sibling (node))
+		add_source (model, node, &iter);
 
 	gtk_tree_path_free (root_path);
-	gbf_project_target_free (target);
 }
 
 static void 
-add_target (GbfProjectModel *model,
-	    const gchar     *target_id,
-	    GtkTreeIter     *parent)
+add_target (GbfProjectModel 		*model,
+	    AnjutaProjectTarget   *target,
+	    GtkTreeIter     	        *parent)
 {
-	GbfProjectTarget *target;
-	GList *l;
+	AnjutaProjectNode *l;
 	GtkTreeIter iter;	
 	GbfTreeData *data;
 	
-	target = gbf_project_get_target (model->priv->proj, target_id, NULL);
-	if (!target)
+	if ((!target) || (anjuta_project_node_get_type (target) != ANJUTA_PROJECT_TARGET))
 		return;
 	
 	data = gbf_tree_data_new_target (model->priv->proj, target);
@@ -459,39 +449,44 @@ add_target (GbfProjectModel *model,
 	gbf_tree_data_free (data);
 	
 	/* add sources */
-	for (l = target->sources; l; l = l->next)
-		add_source (model, l->data, &iter);
+	for (l = anjuta_project_node_first_child (target); l; l = anjuta_project_node_next_sibling (l))
+	{
+		add_source (model, l, &iter);
+	}
 
 	/* add a shortcut to the target if the target's type is a primary */
 	/* FIXME: this shouldn't be here.  We would rather provide a
 	 * set of public functions to add/remove shortcuts to save
 	 * this information in the project metadata (when that's
 	 * implemented) */
-	if (!strcmp (target->type, "program") ||
-	    !strcmp (target->type, "shared_lib") ||
-	    !strcmp (target->type, "static_lib") ||
-	    !strcmp (target->type, "java") ||
-	    !strcmp (target->type, "python")) {
-		add_target_shortcut (model, target->id, NULL);
+	switch (anjuta_project_target_type_class (anjuta_project_target_get_type (target)))
+	{
+		case ANJUTA_TARGET_SHAREDLIB:
+		case ANJUTA_TARGET_STATICLIB:
+		case ANJUTA_TARGET_EXECUTABLE:
+		case ANJUTA_TARGET_PYTHON:
+		case ANJUTA_TARGET_JAVA:
+			add_target_shortcut (model, target, NULL);
+			break;
+		default:
+			break;
 	}
-
-	gbf_project_target_free (target);
 }
 
 static void
-update_target (GbfProjectModel *model, const gchar *target_id, GtkTreeIter *iter)
+update_target (GbfProjectModel *model, AnjutaProjectTarget *target, GtkTreeIter *iter)
 {
 	GtkTreeModel *tree_model;
-	GbfProjectTarget *target;
 	GtkTreeIter child;
+	GList *sources;
 	GList *node;
 	
 	tree_model = GTK_TREE_MODEL (model);
-	target = gbf_project_get_target (model->priv->proj, target_id, NULL);
-	if (!target)
+	if ((!target) || (anjuta_project_node_get_type (target) != ANJUTA_PROJECT_TARGET))
 		return;
 	
 	/* update target data here */
+	sources = anjuta_project_node_all_child (target, ANJUTA_PROJECT_SOURCE);
 	
 	/* walk the tree target */
 	if (gtk_tree_model_iter_children (tree_model, &child, iter)) {
@@ -505,10 +500,9 @@ update_target (GbfProjectModel *model, const gchar *target_id, GtkTreeIter *iter
 
 			/* find the iterating id in the target's sources */
 			if (data->id) {
-				node = g_list_find_custom (target->sources,
-							   data->id, (GCompareFunc) strcmp);
+				node = g_list_find (sources, data->id);
 				if (node) {
-					target->sources = g_list_delete_link (target->sources, node);
+					sources = g_list_delete_link (sources, node);
 					valid = gtk_tree_model_iter_next (tree_model, &child);
 				} else {
 					valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
@@ -519,24 +513,22 @@ update_target (GbfProjectModel *model, const gchar *target_id, GtkTreeIter *iter
 	}
 
 	/* add the remaining sources */
-	for (node = target->sources; node; node = node->next)
-		add_source (model, node->data, iter);
-	
-	gbf_project_target_free (target);
+	for (node = sources; node; node = g_list_next (node))
+	{
+		add_source (model, (AnjutaProjectSource *)node->data, iter);
+	}
 }
 
 static void 
-add_target_group (GbfProjectModel *model,
-		  const gchar     *group_id,
-		  GtkTreeIter     *parent)
+add_target_group (GbfProjectModel 	*model,
+		  AnjutaProjectGroup	*group,
+		  GtkTreeIter     	*parent)
 {
-	GbfProjectGroup *group;
 	GtkTreeIter iter;
-	GList *l;
+	AnjutaProjectNode *node;
 	GbfTreeData *data;
 
-	group = gbf_project_get_group (model->priv->proj, group_id, NULL);
-	if (!group)
+	if ((!group) || (anjuta_project_node_get_type (group) != ANJUTA_PROJECT_GROUP))
 		return;
 	
 	data = gbf_tree_data_new_group (model->priv->proj, group);
@@ -557,28 +549,31 @@ add_target_group (GbfProjectModel *model,
 	}
 
 	/* add groups ... */
-	for (l = group->groups; l; l = l->next)
-		add_target_group (model, l->data, &iter);
-
+	for (node = anjuta_project_node_first_child (group); node; node = anjuta_project_node_next_sibling (node))
+		add_target_group (model, node, &iter);
+	
 	/* ... and targets */
-	for (l = group->targets; l; l = l->next)
-		add_target (model, l->data, &iter);
-
-	gbf_project_group_free (group);
+	for (node = anjuta_project_node_first_child (group); node; node = anjuta_project_node_next_sibling (node))
+		add_target (model, node, &iter);
 }
 
 static void
-update_group (GbfProjectModel *model, const gchar *group_id, GtkTreeIter *iter)
+update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *iter)
 {
 	GtkTreeModel *tree_model;
-	GbfProjectGroup *group;
 	GtkTreeIter child;
 	GList *node;
-	
+	GList *groups;
+	GList *targets;
+
+	if ((!group) || (anjuta_project_node_get_type (group) != ANJUTA_PROJECT_GROUP))
+		return;
+
 	tree_model = GTK_TREE_MODEL (model);
-	group = gbf_project_get_group (model->priv->proj, group_id, NULL);
 	
 	/* 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);
 
 	/* walk the tree group */
 	/* group can be NULL, but we iterate anyway to remove any
@@ -598,9 +593,8 @@ update_group (GbfProjectModel *model, const gchar *group_id, GtkTreeIter *iter)
 			if (data->type == GBF_TREE_NODE_GROUP) {
 				/* update recursively */
 				update_group (model, data->id, &child);
-				if (group && (node = g_list_find_custom (group->groups, data->id,
-									 (GCompareFunc) strcmp))) {
-					group->groups = g_list_delete_link (group->groups, node);
+				if (group && (node = g_list_find (groups, data->id))) {
+					groups = g_list_delete_link (groups, node);
 				} else {
 					remove_child = TRUE;
 				}
@@ -608,10 +602,8 @@ update_group (GbfProjectModel *model, const gchar *group_id, GtkTreeIter *iter)
 			} else if (data->type == GBF_TREE_NODE_TARGET) {
 				GtkTreePath *shortcut;
 
-				if (group && (node = g_list_find_custom (group->targets,
-									 data->id,
-									 (GCompareFunc) strcmp))) {
-					group->targets = g_list_delete_link (group->targets, node);
+				if (group && (node = g_list_find (targets, data->id))) {
+					targets = g_list_delete_link (targets, node);
 					/* update recursively */
 					update_target (model, data->id, &child);
 				} else {
@@ -646,34 +638,32 @@ update_group (GbfProjectModel *model, const gchar *group_id, GtkTreeIter *iter)
 
 	if (group) {
 		/* add the remaining targets and groups */
-		for (node = group->groups; node; node = node->next)
+		for (node = groups; node; node = node->next)
 			add_target_group (model, node->data, iter);
 		
-		for (node = group->targets; node; node = node->next)
+		for (node = targets; node; node = node->next)
 			add_target (model, node->data, iter);
-	
-		gbf_project_group_free (group);
 	}
 }
 
 static void
-project_updated_cb (GbfProject *project, GbfProjectModel *model)
+project_updated_cb (IAnjutaProject *project, GbfProjectModel *model)
 {
 	GtkTreePath *path;
 	GtkTreeIter iter;
 
 	path = gtk_tree_row_reference_get_path (model->priv->root_row);
 	if (path && gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
-		update_group (model, "/", &iter);
+		update_group (model, ianjuta_project_get_root (project, NULL), &iter);
 	else
-		add_target_group (model, "/", NULL);
+		add_target_group (model, ianjuta_project_get_root (project, NULL), NULL);
 			
 	if (path)
 		gtk_tree_path_free (path);
 }
 
 static void
-load_project (GbfProjectModel *model, GbfProject *proj)
+load_project (GbfProjectModel *model, IAnjutaProject *proj)
 {
 	model->priv->proj = proj;
 	g_object_ref (proj);
@@ -681,7 +671,7 @@ load_project (GbfProjectModel *model, GbfProject *proj)
 	/* to get rid of the empty node */
 	gtk_tree_store_clear (GTK_TREE_STORE (model));
 
-	add_target_group (model, "/", NULL);
+	add_target_group (model, ianjuta_project_get_root (proj, NULL), NULL);
 
 	model->priv->project_updated_handler =
 		g_signal_connect (model->priv->proj, "project-updated",
@@ -723,10 +713,10 @@ unload_project (GbfProjectModel *model)
 }
 
 static gboolean 
-recursive_find_id (GtkTreeModel    *model,
-		   GtkTreeIter     *iter,
-		   GbfTreeNodeType  type,
-		   const gchar     *id)
+recursive_find_id (GtkTreeModel   	*model,
+		   GtkTreeIter     	*iter,
+		   GbfTreeNodeType  	 type,
+		   AnjutaProjectNode	*id)
 {
 	GtkTreeIter tmp;
 	GbfTreeData *data;
@@ -739,7 +729,7 @@ recursive_find_id (GtkTreeModel    *model,
 		
 		gtk_tree_model_get (model, &tmp,
 				    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
-		if (data->type == type && !strcmp (id, data->id)) {
+		if (id == data->id) {
 			*iter = tmp;
 			retval = TRUE;
 		}
@@ -758,10 +748,10 @@ recursive_find_id (GtkTreeModel    *model,
 }
 
 gboolean 
-gbf_project_model_find_id (GbfProjectModel *model,
-			   GtkTreeIter     *iter,
-			   GbfTreeNodeType  type,
-			   const gchar     *id)
+gbf_project_model_find_id (GbfProjectModel 	*model,
+			   GtkTreeIter     	*iter,
+			   GbfTreeNodeType  	 type,
+			   AnjutaProjectNode   *id)
 {
 	GtkTreePath *root;
 	GtkTreeIter tmp_iter;
@@ -783,7 +773,7 @@ gbf_project_model_find_id (GbfProjectModel *model,
 }
 
 GbfProjectModel *
-gbf_project_model_new (GbfProject *project)
+gbf_project_model_new (IAnjutaProject *project)
 {
 	return GBF_PROJECT_MODEL (g_object_new (GBF_TYPE_PROJECT_MODEL,
 						"project", project,
@@ -791,10 +781,10 @@ gbf_project_model_new (GbfProject *project)
 }
 
 void 
-gbf_project_model_set_project (GbfProjectModel *model, GbfProject *project)
+gbf_project_model_set_project (GbfProjectModel *model, IAnjutaProject *project)
 {
 	g_return_if_fail (model != NULL && GBF_IS_PROJECT_MODEL (model));
-	g_return_if_fail (project == NULL || GBF_IS_PROJECT (project));
+	g_return_if_fail (project == NULL || IANJUTA_IS_PROJECT (project));
 	
 	if (model->priv->proj)
 		unload_project (model);
@@ -803,7 +793,7 @@ gbf_project_model_set_project (GbfProjectModel *model, GbfProject *project)
 		load_project (model, project);
 }
 
-GbfProject *
+IAnjutaProject *
 gbf_project_model_get_project (GbfProjectModel *model)
 {
 	g_return_val_if_fail (model != NULL && GBF_IS_PROJECT_MODEL (model), NULL);
diff --git a/plugins/project-manager/gbf-project-model.h b/plugins/project-manager/gbf-project-model.h
index 3129c2c..51484a8 100644
--- a/plugins/project-manager/gbf-project-model.h
+++ b/plugins/project-manager/gbf-project-model.h
@@ -25,7 +25,8 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <libanjuta/gbf-project.h>
+#include <libanjuta/interfaces/ianjuta-project.h>
+#include <libanjuta/anjuta-project.h>
 #include "gbf-tree-data.h"
 
 #define GBF_TYPE_PROJECT_MODEL            (gbf_project_model_get_type ())
@@ -53,16 +54,16 @@ struct _GbfProjectModelClass {
 };
 
 GType            gbf_project_model_get_type          (void); 
-GbfProjectModel *gbf_project_model_new               (GbfProject      *project);
+GbfProjectModel *gbf_project_model_new               (IAnjutaProject    *project);
 
-void             gbf_project_model_set_project       (GbfProjectModel *model,
-                                                      GbfProject      *project);
-GbfProject      *gbf_project_model_get_project       (GbfProjectModel *model);
+void             gbf_project_model_set_project       (GbfProjectModel   *model,
+                                                      IAnjutaProject    *project);
+IAnjutaProject  *gbf_project_model_get_project       (GbfProjectModel   *model);
 
-GtkTreePath     *gbf_project_model_get_project_root  (GbfProjectModel *model);
-gboolean         gbf_project_model_find_id           (GbfProjectModel *model,
-                                                      GtkTreeIter     *iter,
-                                                      GbfTreeNodeType  type,
-                                                      const gchar     *id);
+GtkTreePath     *gbf_project_model_get_project_root  (GbfProjectModel   *model);
+gboolean         gbf_project_model_find_id           (GbfProjectModel   *model,
+                                                      GtkTreeIter       *iter,
+                                                      GbfTreeNodeType    type,
+                                                      AnjutaProjectNode *id);
 
 #endif
diff --git a/plugins/project-manager/gbf-project-util.c b/plugins/project-manager/gbf-project-util.c
index c57d702..8cb178b 100644
--- a/plugins/project-manager/gbf-project-util.c
+++ b/plugins/project-manager/gbf-project-util.c
@@ -76,9 +76,9 @@ groups_filter_fn (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
 }
 
 static void 
-setup_groups_treeview (GbfProjectModel *model,
-                       GtkWidget       *view,
-                       const gchar     *select_group)
+setup_groups_treeview (GbfProjectModel    *model,
+                       GtkWidget          *view,
+                       AnjutaProjectGroup *select_group)
 {
     GtkTreeModel *filter;
     GtkTreePath *path;
@@ -163,19 +163,19 @@ entry_changed_cb (GtkEditable *editable, gpointer user_data)
     g_free (text);
 }
 
-gchar*
-gbf_project_util_new_group (GbfProjectModel *model,
-                            GtkWindow       *parent,
-                            const gchar     *default_group,
-                            const gchar     *default_group_name_to_add)
+AnjutaProjectGroup*
+gbf_project_util_new_group (GbfProjectModel    *model,
+                            GtkWindow          *parent,
+                            AnjutaProjectGroup *default_group,
+                            const gchar        *default_group_name_to_add)
 {
     GtkBuilder *gui;
     GtkWidget *dialog, *group_name_entry, *ok_button;
     GtkWidget *groups_view;
     gint response;
-    GbfProject *project;
+    IAnjutaProject *project;
     gboolean finished = FALSE;
-    gchar *new_group = NULL;
+    AnjutaProjectGroup *new_group = NULL;
 
     g_return_val_if_fail (model != NULL, NULL);
     
@@ -219,19 +219,18 @@ gbf_project_util_new_group (GbfProjectModel *model,
             {
                 GError *err = NULL;
                 GbfTreeData *data;
-                gchar *parent_id = NULL, *name;
+                gchar *name;
+                AnjutaProjectGroup *parent_node;
             
                 name = gtk_editable_get_chars (
                     GTK_EDITABLE (group_name_entry), 0, -1);
                 data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (groups_view),
                                                        GBF_TREE_NODE_GROUP);
                 if (data) {
-                    gchar *new_group = NULL;
-                    
-                    parent_id = g_strdup (data->id);
+                    parent_node = data->id;
                     gbf_tree_data_free (data);
 		    
-                    new_group = gbf_project_add_group (project, parent_id, name, &err);
+                    new_group = ianjuta_project_add_group (project, parent_node, name, &err);
                     if (err) {
                         error_dialog (parent, _("Cannot add group"), "%s",
                                       err->message);
@@ -239,7 +238,6 @@ gbf_project_util_new_group (GbfProjectModel *model,
                     } else {
 			finished = TRUE;
 		    }
-                    g_free (parent_id);
                 } else {
                     error_dialog (parent, _("Cannot add group"),
 				  "%s", _("No parent group selected"));
@@ -268,24 +266,24 @@ enum {
 
 /* create a tree model with the target types */
 static GtkListStore *
-build_types_store (GbfProject *project)
+build_types_store (IAnjutaProject *project)
 {
     GtkListStore *store;
     GtkTreeIter iter;
-    gchar **types;
-    gint i;
-    
-    types = gbf_project_get_types (project);
+    GList *types;
+    GList *node;
+
+    types = ianjuta_project_get_target_types (project, NULL);
     store = gtk_list_store_new (TARGET_TYPE_N_COLUMNS,
-                                G_TYPE_STRING,
+                                G_TYPE_POINTER,
                                 G_TYPE_STRING,
                                 GDK_TYPE_PIXBUF);
     
-    for (i = 0; types [i]; i++) {
+    for (node = g_list_first (types); node != NULL; node = g_list_next (node)) {
         GdkPixbuf *pixbuf;
         const gchar *name;
 
-        name = gbf_project_name_for_type (project, types [i]);
+        name = anjuta_project_target_type_name ((AnjutaProjectTargetType)node->data);
         pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
                                            GTK_STOCK_CONVERT,
                                            ICON_SIZE,
@@ -294,7 +292,7 @@ build_types_store (GbfProject *project)
 
         gtk_list_store_append (store, &iter);
         gtk_list_store_set (store, &iter,
-                            TARGET_TYPE_TYPE, types [i],
+                            TARGET_TYPE_TYPE, node->data,
                             TARGET_TYPE_NAME, name,
                             TARGET_TYPE_PIXBUF, pixbuf,
                             -1);
@@ -303,15 +301,15 @@ build_types_store (GbfProject *project)
             g_object_unref (pixbuf);
     }
 
-    g_strfreev (types);
+    g_list_free (types);
 
     return store;
 }
 
-gchar* 
+AnjutaProjectTarget* 
 gbf_project_util_new_target (GbfProjectModel *model,
                              GtkWindow       *parent,
-                             const gchar     *default_group,
+                             AnjutaProjectGroup *default_group,
                              const gchar     *default_target_name_to_add)
 {
     GtkBuilder *gui;
@@ -320,9 +318,9 @@ gbf_project_util_new_target (GbfProjectModel *model,
     GtkListStore *types_store;
     GtkCellRenderer *renderer;
     gint response;
-    GbfProject *project;
+    IAnjutaProject *project;
     gboolean finished = FALSE;
-    gchar *new_target = NULL;
+    AnjutaProjectTarget *new_target = NULL;
     
     g_return_val_if_fail (model != NULL, NULL);
     
@@ -394,7 +392,9 @@ gbf_project_util_new_target (GbfProjectModel *model,
                 GError *err = NULL;
                 GbfTreeData *data;
                 GtkTreeIter iter;
-                gchar *group_id = NULL, *name, *type = NULL;
+                AnjutaProjectGroup *group;
+                gchar *name;
+                AnjutaProjectTargetType type = NULL;
                 
                 name = gtk_editable_get_chars (
                     GTK_EDITABLE (target_name_entry), 0, -1);
@@ -409,10 +409,10 @@ gbf_project_util_new_target (GbfProjectModel *model,
                 }
                 
                 if (data && type) {
-                    group_id = g_strdup (data->id);
+                    group = data->id;
                     gbf_tree_data_free (data);
             
-                    new_target = gbf_project_add_target (project, group_id, name, type, &err);
+                    new_target = ianjuta_project_add_target (project, group, name, type, &err);
                     if (err) {
                         error_dialog (parent, _("Cannot add target"), "%s",
                                       err->message);
@@ -420,8 +420,6 @@ gbf_project_util_new_target (GbfProjectModel *model,
                     } else {
 			finished = TRUE;
 		    }
-		    g_free (group_id);
-                    g_free (type);
                 } else {
                     error_dialog (parent, _("Cannot add target"), "%s",
 				  _("No group selected"));
@@ -461,10 +459,10 @@ targets_filter_fn (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
 }
 
 static void 
-setup_targets_treeview (GbfProjectModel *model,
-                        GtkWidget       *view,
-                        const gchar     *select_target,
-                        const gchar     *select_group)
+setup_targets_treeview (GbfProjectModel     *model,
+                        GtkWidget           *view,
+                        AnjutaProjectTarget *select_target,
+                        AnjutaProjectGroup  *select_group)
 {
     GtkTreeModel *filter;
     GtkTreeIter iter, iter_filter;
@@ -590,12 +588,12 @@ on_row_changed(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpoint
 		gtk_widget_set_sensitive(button, FALSE);
 }
 
-gchar*
-gbf_project_util_add_source (GbfProjectModel *model,
-                             GtkWindow       *parent,
-                             const gchar     *default_target,
-                             const gchar     *default_group,
-                             const gchar     *default_uri)
+AnjutaProjectSource*
+gbf_project_util_add_source (GbfProjectModel     *model,
+                             GtkWindow           *parent,
+                             AnjutaProjectTarget *default_target,
+                             AnjutaProjectGroup  *default_group,
+                             const gchar         *default_uri)
 {
         GList* new_sources;
 	gchar* uri = NULL;
@@ -613,7 +611,7 @@ gbf_project_util_add_source (GbfProjectModel *model,
 	
 	if (new_sources && g_list_length (new_sources))
 	{
-		gchar* new_source = g_strdup (new_sources->data);
+		AnjutaProjectSource *new_source = new_sources->data;
                 g_list_foreach (new_sources, (GFunc) g_free, NULL);
 		g_list_free (new_sources);
 		return new_source;
@@ -623,18 +621,18 @@ gbf_project_util_add_source (GbfProjectModel *model,
 }
 
 GList* 
-gbf_project_util_add_source_multi (GbfProjectModel *model,
-				   GtkWindow       *parent,
-				   const gchar     *default_target,
-				   const gchar     *default_group,
-				   GList     *uris_to_add)
+gbf_project_util_add_source_multi (GbfProjectModel     *model,
+				   GtkWindow           *parent,
+                                   AnjutaProjectTarget *default_target,
+                                   AnjutaProjectGroup  *default_group,
+				   GList               *uris_to_add)
 {
     GtkBuilder *gui;
     GtkWidget *dialog, *source_file_tree;
     GtkWidget *ok_button, *browse_button;
     GtkWidget *targets_view;
     gint response;
-    GbfProject *project;
+    IAnjutaProject *project;
     gboolean finished = FALSE;
     gchar *project_root;
     GtkListStore* list;
@@ -724,7 +722,7 @@ gbf_project_util_add_source_multi (GbfProjectModel *model,
             case GTK_RESPONSE_OK: 
             {
                 GbfTreeData *data;
-                gchar *target_id = NULL;
+                AnjutaProjectTarget *target = NULL;
             
                 data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (targets_view),
                                                        GBF_TREE_NODE_TARGET);
@@ -732,7 +730,7 @@ gbf_project_util_add_source_multi (GbfProjectModel *model,
 		    GtkTreeIter iter;
 		    GString *err_mesg = g_string_new (NULL);
 		    
-		    target_id = g_strdup (data->id);
+		    target = data->id;
 		    gbf_tree_data_free (data);
 		    
 		    if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list),
@@ -741,18 +739,22 @@ gbf_project_util_add_source_multi (GbfProjectModel *model,
 		    do
 		    {
 			GError *err = NULL;
-			gchar* new_source;
-			gchar* source_file;
+			AnjutaProjectSource* new_source;
+			gchar* uri;
+                        GFile* source_file;
+
 			gtk_tree_model_get (GTK_TREE_MODEL(list), &iter,
-					    COLUMN_URI, &source_file, -1);
-			
-			new_source = gbf_project_add_source (project,
-							     target_id,
+					    COLUMN_URI, &uri, -1);
+
+                        source_file = g_file_new_for_uri (uri);
+			new_source = ianjuta_project_add_source (project,
+							     target,
 							     source_file,
 							     &err);
+                        g_object_unref (source_file);
 			if (err) {
 			    gchar *str = g_strdup_printf ("%s: %s\n",
-							  source_file,
+							  uri,
 							  err->message);
 			    g_string_append (err_mesg, str);
 			    g_error_free (err);
@@ -762,12 +764,10 @@ gbf_project_util_add_source_multi (GbfProjectModel *model,
 			    new_sources = g_list_append (new_sources,
 							 new_source);
 			
-			g_free (source_file);
+			g_free (uri);
 		    } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(list),
 						       &iter));
 		    
-                    g_free (target_id);
-		    
 		    if (err_mesg->str && strlen (err_mesg->str) > 0) {
 			error_dialog (parent, _("Cannot add source files"),
 				      "%s", err_mesg->str);
diff --git a/plugins/project-manager/gbf-project-util.h b/plugins/project-manager/gbf-project-util.h
index abc71e1..55f6a77 100644
--- a/plugins/project-manager/gbf-project-util.h
+++ b/plugins/project-manager/gbf-project-util.h
@@ -25,31 +25,32 @@
 
 #include <glib.h>
 #include <gtk/gtk.h>
+#include <libanjuta/anjuta-project.h>
 #include "gbf-project-model.h"
 
 G_BEGIN_DECLS
 
-gchar* gbf_project_util_new_group  (GbfProjectModel *model,
-				    GtkWindow       *parent,
-				    const gchar     *default_group,
-				    const gchar     *default_group_name_to_add);
-
-gchar* gbf_project_util_new_target (GbfProjectModel *model,
-				    GtkWindow       *parent,
-				    const gchar     *default_group,
-				    const gchar     *default_target_name_to_add);
-
-gchar* gbf_project_util_add_source (GbfProjectModel *model,
-				    GtkWindow       *parent,
-				    const gchar     *default_target,
-				    const gchar     *default_group,
-				    const gchar     *default_uri_to_add);
-
-GList* gbf_project_util_add_source_multi (GbfProjectModel *model,
-				    GtkWindow       *parent,
-				    const gchar     *default_target,
-				    const gchar     *default_group,
-				    GList     *uris_to_add);
+AnjutaProjectGroup* gbf_project_util_new_group  (GbfProjectModel   *model,
+				                GtkWindow          *parent,
+				                AnjutaProjectGroup *default_group,
+				                const gchar        *default_group_name_to_add);
+
+AnjutaProjectTarget* gbf_project_util_new_target (GbfProjectModel  *model,
+				                GtkWindow          *parent,
+				                AnjutaProjectGroup *default_group,
+				                const gchar        *default_target_name_to_add);
+
+AnjutaProjectSource* gbf_project_util_add_source (GbfProjectModel   *model,
+				                GtkWindow           *parent,
+				                AnjutaProjectTarget *default_target,
+				                AnjutaProjectGroup  *default_group,
+				                const gchar         *default_uri_to_add);
+
+GList* gbf_project_util_add_source_multi (GbfProjectModel   *model,
+				        GtkWindow           *parent,
+        		                AnjutaProjectTarget *default_target,
+				        AnjutaProjectGroup  *default_group,
+				        GList               *uris_to_add);
 				    
 				    
 				    
diff --git a/plugins/project-manager/gbf-project-view.c b/plugins/project-manager/gbf-project-view.c
index 2db6a70..e6c3ef3 100644
--- a/plugins/project-manager/gbf-project-view.c
+++ b/plugins/project-manager/gbf-project-view.c
@@ -309,8 +309,8 @@ gbf_project_view_class_init (GbfProjectViewClass *klass)
 			      G_STRUCT_OFFSET (GbfProjectViewClass,
 					       target_selected),
 			      NULL, NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1, G_TYPE_POINTER);
 	signals [GROUP_SELECTED] = 
 		g_signal_new ("group_selected",
 			      GBF_TYPE_PROJECT_VIEW,
@@ -318,8 +318,8 @@ gbf_project_view_class_init (GbfProjectViewClass *klass)
 			      G_STRUCT_OFFSET (GbfProjectViewClass,
 					       group_selected),
 			      NULL, NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1, G_TYPE_POINTER);
 }
 
 static void 
diff --git a/plugins/project-manager/gbf-project-view.h b/plugins/project-manager/gbf-project-view.h
index db62a24..9688cda 100644
--- a/plugins/project-manager/gbf-project-view.h
+++ b/plugins/project-manager/gbf-project-view.h
@@ -24,6 +24,7 @@
 #define _GBF_PROJECT_TREE_H_
 
 #include <gtk/gtk.h>
+#include <libanjuta/anjuta-project.h>
 #include "gbf-tree-data.h"
 
 G_BEGIN_DECLS
@@ -51,10 +52,10 @@ struct _GbfProjectViewClass {
 	void (* uri_activated)    (GbfProjectView *project_view,
 				   const char     *uri);
 
-	void (* target_selected)  (GbfProjectView *project_view,
-				   const gchar    *target_id);
-	void (* group_selected)  (GbfProjectView *project_view,
-				   const gchar    *group_id);
+	void (* target_selected)  (GbfProjectView      *project_view,
+				   AnjutaProjectTarget *target);
+	void (* group_selected)  (GbfProjectView       *project_view,
+				   AnjutaProjectGroup  *group);
 };
 
 GType                       gbf_project_view_get_type         (void);
diff --git a/plugins/project-manager/gbf-tree-data.c b/plugins/project-manager/gbf-tree-data.c
index 37ac2c8..c1f916a 100644
--- a/plugins/project-manager/gbf-tree-data.c
+++ b/plugins/project-manager/gbf-tree-data.c
@@ -53,60 +53,68 @@ gbf_tree_data_new_string (const gchar *string)
 }
 
 GbfTreeData *
-gbf_tree_data_new_group (GbfProject *project, const GbfProjectGroup *group)
+gbf_tree_data_new_group (IAnjutaProject *project, AnjutaProjectGroup *group)
 {
 	GbfTreeData *node = g_new0 (GbfTreeData, 1);
-	
+	GFileInfo *ginfo;
+
 	node->type = GBF_TREE_NODE_GROUP;
-	node->name = g_strdup (group->name);
-	node->id = g_strdup (group->id);
+	node->id = group;
+	
+	ginfo = g_file_query_info (anjuta_project_group_get_directory (group),
+	    G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+	    G_FILE_QUERY_INFO_NONE,
+	    NULL, NULL);
+	if (ginfo)
+	{
+		node->name = g_strdup (g_file_info_get_display_name (ginfo));
+	        g_object_unref(ginfo);
+	}
+	else
+	{
+		node->name = g_strdup ("?");
+	}
 
 	return node;
 }
 
 GbfTreeData *
-gbf_tree_data_new_target (GbfProject *project, const GbfProjectTarget *target)
+gbf_tree_data_new_target (IAnjutaProject *project, AnjutaProjectTarget *target)
 {
 	GbfTreeData *node = g_new0 (GbfTreeData, 1);
 	
 	node->type = GBF_TREE_NODE_TARGET;
-	node->name = g_strdup (target->name);
-	node->id = g_strdup (target->id);
-	node->mime_type = g_strdup (gbf_project_mimetype_for_type (project, target->type));
+	node->id = target;
+	
+	node->name = g_strdup (anjuta_project_target_get_name (target));
+	node->mime_type = g_strdup (anjuta_project_target_type_mime (anjuta_project_target_get_type (target)));
 	
 	return node;
 }
 
 GbfTreeData *
-gbf_tree_data_new_source (GbfProject *project, const GbfProjectTargetSource *source)
+gbf_tree_data_new_source (IAnjutaProject *project, AnjutaProjectSource *source)
 {
 	GbfTreeData *node = g_new0 (GbfTreeData, 1);
-	GFile *file;
-	GFileInfo *file_info;
+	GFileInfo *ginfo;
 	
 	node->type = GBF_TREE_NODE_TARGET_SOURCE;
-	node->id = g_strdup (source->id);
-	node->uri = g_strdup (source->source_uri);
-	node->name = NULL;
+	node->id = source;
 	
-	file = g_file_new_for_uri (source->source_uri);
-	node->name = g_file_get_basename (file);
-	if (g_file_query_exists (file, NULL))
+	node->uri = g_file_get_uri (anjuta_project_source_get_file (source));
+
+	ginfo = g_file_query_info (anjuta_project_source_get_file (source),
+	    G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+	    G_FILE_QUERY_INFO_NONE,
+	    NULL, NULL);
+	if (ginfo)
 	{
-		file_info = g_file_query_info (file, 
-			G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
-			G_FILE_QUERY_INFO_NONE,
-			NULL, NULL);
-		if (file_info)
-		{
-			node->name = g_strdup (g_file_info_get_display_name (file_info));
-		}
+		node->name = g_strdup (g_file_info_get_display_name (ginfo));
+	        g_object_unref(ginfo);
 	}
-	g_object_unref (file);
-
-	if (node->name == NULL)
+	else
 	{
-		node->name = g_file_get_basename (file);
+		node->name = g_strdup ("?");
 	}
 
 	return node;
@@ -120,7 +128,7 @@ gbf_tree_data_copy (GbfTreeData *src)
 	node = g_new (GbfTreeData, 1);
 	node->type = src->type;
 	node->name = g_strdup (src->name);
-	node->id = g_strdup (src->id);
+	node->id = src->id;
 	node->uri = g_strdup (src->uri);
 	node->is_shortcut = src->is_shortcut;
 	node->mime_type = g_strdup (src->mime_type);
@@ -133,7 +141,6 @@ gbf_tree_data_free (GbfTreeData *node)
 {
 	if (node) {
 		g_free (node->name);
-		g_free (node->id);
 		g_free (node->uri);
 		g_free (node->mime_type);
 		g_free (node);
diff --git a/plugins/project-manager/gbf-tree-data.h b/plugins/project-manager/gbf-tree-data.h
index 0c2075b..afbb09f 100644
--- a/plugins/project-manager/gbf-tree-data.h
+++ b/plugins/project-manager/gbf-tree-data.h
@@ -25,7 +25,8 @@
 #define _GBF_TREE_DATA_H_
 
 #include <glib-object.h>
-#include <libanjuta/gbf-project.h>
+#include <libanjuta/interfaces/ianjuta-project.h>
+#include <libanjuta/anjuta-project.h>
 
 G_BEGIN_DECLS
 
@@ -42,24 +43,24 @@ typedef enum {
 
 struct _GbfTreeData
 {
-	GbfTreeNodeType  type;
-	gchar           *name;
-	gchar           *id;
-	gchar           *uri;
-	gboolean         is_shortcut;
-	gchar           *mime_type;
+	GbfTreeNodeType  	type;
+	gchar           	*name;
+	AnjutaProjectNode	*id;
+	gchar           	*uri;
+	gboolean         	is_shortcut;
+	gchar           	*mime_type;
 };
 
 GType          gbf_tree_data_get_type            (void);
-GbfTreeData   *gbf_tree_data_new_string          (const gchar                  *string);
-GbfTreeData   *gbf_tree_data_new_group           (GbfProject                   *project,
-						  const GbfProjectGroup        *group);
-GbfTreeData   *gbf_tree_data_new_target          (GbfProject                   *project,
-						  const GbfProjectTarget       *target);
-GbfTreeData   *gbf_tree_data_new_source          (GbfProject                   *project,
-						  const GbfProjectTargetSource *source);
-GbfTreeData   *gbf_tree_data_copy                (GbfTreeData                  *data);
-void           gbf_tree_data_free                (GbfTreeData                  *data);
+GbfTreeData   *gbf_tree_data_new_string          (const gchar            *string);
+GbfTreeData   *gbf_tree_data_new_group           (IAnjutaProject         *project,
+						  AnjutaProjectGroup     *group);
+GbfTreeData   *gbf_tree_data_new_target          (IAnjutaProject         *project,
+						  AnjutaProjectTarget    *target);
+GbfTreeData   *gbf_tree_data_new_source          (IAnjutaProject         *project,
+						  AnjutaProjectSource    *source);
+GbfTreeData   *gbf_tree_data_copy                (GbfTreeData            *data);
+void           gbf_tree_data_free                (GbfTreeData            *data);
 
 
 G_END_DECLS
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 48492d2..1482116 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -27,9 +27,11 @@
 #include <libanjuta/interfaces/ianjuta-file-manager.h>
 #include <libanjuta/interfaces/ianjuta-builder.h>
 #include <libanjuta/interfaces/ianjuta-project-backend.h>
+#include <libanjuta/interfaces/ianjuta-project.h>
 #include <libanjuta/anjuta-profile-manager.h>
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-status.h>
+#include <libanjuta/anjuta-project.h>
 
 #include "gbf-project-util.h"
 
@@ -53,7 +55,7 @@ typedef enum _PmPropertiesType
 struct _PmPropertiesDialogInfo
 {
 	PmPropertiesType type;
-	const gchar* id;
+	AnjutaProjectNode* id;
 	GtkWidget* dialog;
 };
 
@@ -266,7 +268,7 @@ update_operation_end (ProjectManagerPlugin *plugin, gboolean emit_signal)
 		{
 			GList *post_update_sources =
 			ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-												  IANJUTA_PROJECT_MANAGER_SOURCE,
+												  ANJUTA_PROJECT_SOURCE,
 												  NULL);
 			update_operation_emit_signals (plugin, plugin->pre_update_sources,
 										   post_update_sources);
@@ -280,7 +282,7 @@ update_operation_end (ProjectManagerPlugin *plugin, gboolean emit_signal)
 		{
 			GList *post_update_targets =
 			ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-												  IANJUTA_PROJECT_MANAGER_TARGET,
+												  ANJUTA_PROJECT_TARGET,
 												  NULL);
 			update_operation_emit_signals (plugin, plugin->pre_update_targets,
 										   post_update_targets);
@@ -294,7 +296,7 @@ update_operation_end (ProjectManagerPlugin *plugin, gboolean emit_signal)
 		{
 			GList *post_update_groups =
 			ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-												  IANJUTA_PROJECT_MANAGER_GROUP,
+												  ANJUTA_PROJECT_GROUP,
 												  NULL);
 			update_operation_emit_signals (plugin, plugin->pre_update_groups,
 										   post_update_groups);
@@ -331,15 +333,15 @@ update_operation_begin (ProjectManagerPlugin *plugin)
 	update_operation_end (plugin, FALSE);
 	plugin->pre_update_sources =
 	ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-										  IANJUTA_PROJECT_MANAGER_SOURCE,
+										  ANJUTA_PROJECT_SOURCE,
 										  NULL);
 	plugin->pre_update_targets =
 	ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-										  IANJUTA_PROJECT_MANAGER_TARGET,
+										  ANJUTA_PROJECT_TARGET,
 										  NULL);
 	plugin->pre_update_groups =
 	ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
-										  IANJUTA_PROJECT_MANAGER_GROUP,
+										  ANJUTA_PROJECT_GROUP,
 										  NULL);
 }
 
@@ -366,7 +368,7 @@ compare_properties_id (PmPropertiesDialogInfo *info, PmPropertiesDialogInfo *inf
 	return (info->type == info1->type) &&
 			((info1->id == NULL) ||
 			 ((info->id != NULL) &&
-			  (strcmp(info->id, info1->id) == 0))) ? 0 : 1;
+			  (info->id == info1->id))) ? 0 : 1;
 }
 
 static void
@@ -395,7 +397,7 @@ on_properties_dialog_response (GtkDialog *win,
 static void
 project_manager_show_properties_dialog (ProjectManagerPlugin *plugin,
 										PmPropertiesType type,
-										const gchar *id)
+										AnjutaProjectNode *id)
 {
 	PmPropertiesDialogInfo info;
 	GList* prop;
@@ -421,16 +423,16 @@ project_manager_show_properties_dialog (ProjectManagerPlugin *plugin,
 		switch (type)
 		{
 			case PM_PROJECT_PROPERTIES:
-				properties = gbf_project_configure (plugin->project, NULL);
+				properties = ianjuta_project_configure (plugin->project, NULL);
 				title = _("Project properties");
 				break;
 			case PM_TARGET_PROPERTIES:		
-				properties = gbf_project_configure_target (plugin->project,
+				properties = ianjuta_project_configure_node (plugin->project,
 														   id, NULL);
 				title = _("Target properties");
 				break;
 			case PM_GROUP_PROPERTIES:
-				properties = gbf_project_configure_group (plugin->project,
+				properties = ianjuta_project_configure_node (plugin->project,
 														   id, NULL);
 				title = _("Group properties");
 				break;
@@ -478,7 +480,7 @@ on_refresh_idle (gpointer user_data)
 	anjuta_status_push (status, _("Refreshing symbol treeâ?¦"));
 	anjuta_status_busy_push (status);
 	
-	gbf_project_refresh (GBF_PROJECT (plugin->project), &err);
+	ianjuta_project_refresh (IANJUTA_PROJECT (plugin->project), &err);
 	if (err)
 	{
 		anjuta_util_dialog_error (get_plugin_parent_window (plugin),
@@ -587,8 +589,8 @@ static void
 on_popup_add_group (GtkAction *action, ProjectManagerPlugin *plugin)
 {
 	GbfTreeData *data;
-	const gchar *selected_group;
-	gchar *group_id;
+	AnjutaProjectGroup *selected_group;
+	AnjutaProjectGroup *new_group;
 	
 	update_operation_begin (plugin);
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
@@ -596,21 +598,20 @@ on_popup_add_group (GtkAction *action, ProjectManagerPlugin *plugin)
 	selected_group = NULL;
 	if (data)
 		selected_group = data->id;
-	group_id = gbf_project_util_new_group (plugin->model,
+	new_group = gbf_project_util_new_group (plugin->model,
 										   get_plugin_parent_window (plugin),
 										   selected_group, NULL);
 	if (data)
 		gbf_tree_data_free (data);
 	update_operation_end (plugin, TRUE);
-	g_free (group_id);
 }
 
 static void
 on_popup_add_target (GtkAction *action, ProjectManagerPlugin *plugin)
 {
 	GbfTreeData *data;
-	const gchar *selected_group;
-	gchar *target_id;
+	AnjutaProjectGroup *selected_group;
+	AnjutaProjectTarget *new_target;
 
 	update_operation_begin (plugin);
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
@@ -618,21 +619,20 @@ on_popup_add_target (GtkAction *action, ProjectManagerPlugin *plugin)
 	selected_group = NULL;
 	if (data)
 		selected_group = data->id;
-	target_id = gbf_project_util_new_target (plugin->model,
+	new_target = gbf_project_util_new_target (plugin->model,
 											 get_plugin_parent_window (plugin),
 											 selected_group, NULL);
 	if (data)
 		gbf_tree_data_free (data);
 	update_operation_end (plugin, TRUE);
-	g_free (target_id);
 }
 
 static void
 on_popup_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
 {
 	GbfTreeData *data;
-	const gchar *selected_target;
-	gchar *source_id;
+	AnjutaProjectTarget *selected_target;
+	AnjutaProjectSource *new_source;
 	
 	update_operation_begin (plugin);
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
@@ -640,13 +640,12 @@ on_popup_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
 	selected_target = NULL;
 	if (data)
 		selected_target = data->id;
-	source_id = gbf_project_util_add_source (plugin->model,
+	new_source = gbf_project_util_add_source (plugin->model,
 											 get_plugin_parent_window (plugin),
 											 selected_target, NULL, NULL);
 	if (data)
 		gbf_tree_data_free (data);
 	update_operation_end (plugin, TRUE);
-	g_free (source_id);
 }
 
 static gboolean
@@ -706,20 +705,7 @@ on_popup_remove (GtkAction *action, ProjectManagerPlugin *plugin)
 		{
 			GError *err = NULL;
 			update_operation_begin (plugin);
-			switch (data->type)
-			{
-				case GBF_TREE_NODE_GROUP:
-					gbf_project_remove_group (plugin->project, data->id, &err);
-					break;
-				case GBF_TREE_NODE_TARGET:
-					gbf_project_remove_target (plugin->project, data->id, &err);
-					break;
-				case GBF_TREE_NODE_TARGET_SOURCE:
-					gbf_project_remove_source (plugin->project, data->id, &err);
-					break;
-				default:
-					g_warning ("Should not reach here!!!");
-			}
+			ianjuta_project_remove_node (plugin->project, data->id, &err);
 			update_operation_end (plugin, TRUE);
 			if (err)
 			{
@@ -759,21 +745,21 @@ on_popup_add_to_project (GtkAction *action, ProjectManagerPlugin *plugin)
 		filename = g_path_get_basename (plugin->fm_current_uri);
 		if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
 		{
-			gchar *group_id =
+			gchar *new_uri =
 			ianjuta_project_manager_add_group (IANJUTA_PROJECT_MANAGER (plugin),
 											   filename, parent_directory,
 											   NULL);
-			g_free (group_id);
+			g_free (new_uri);
 		}
 		else
 		{
-			gchar *source_id =
+			gchar *new_uri =
 				ianjuta_project_manager_add_source (IANJUTA_PROJECT_MANAGER
 													(plugin),
 													plugin->fm_current_uri,
 													parent_directory,
 													NULL);
-			g_free(source_id);
+			g_free (new_uri);
 		}
 		g_object_unref (file_info);
 		g_free (filename);
@@ -893,10 +879,10 @@ update_ui (ProjectManagerPlugin *plugin)
 	AnjutaUI *ui;
 	gint j;
 	GtkAction *action;
-	GbfProjectCapabilities caps = GBF_PROJECT_CAN_ADD_NONE;
+	IAnjutaProjectCapabilities caps = IANJUTA_PROJECT_CAN_ADD_NONE;
 	
 	if (plugin->project)
-		caps = gbf_project_get_capabilities (plugin->project, NULL);
+		caps = ianjuta_project_get_capabilities (plugin->project, NULL);
 	
 	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
 	for (j = 0; j < G_N_ELEMENTS (pm_actions); j++)
@@ -917,19 +903,19 @@ update_ui (ProjectManagerPlugin *plugin)
 								   "ActionProjectAddGroup");
 	g_object_set (G_OBJECT (action), "sensitive",
 				  ((plugin->project != NULL) &&
-				   (caps & GBF_PROJECT_CAN_ADD_GROUP)), NULL);
+				   (caps & IANJUTA_PROJECT_CAN_ADD_GROUP)), NULL);
 	
 	action = anjuta_ui_get_action (ui, "ActionGroupProjectManager",
 								   "ActionProjectAddTarget");
 	g_object_set (G_OBJECT (action), "sensitive",
 				  ((plugin->project != NULL) &&
-				   (caps & GBF_PROJECT_CAN_ADD_TARGET)), NULL);
+				   (caps & IANJUTA_PROJECT_CAN_ADD_TARGET)), NULL);
 
 	action = anjuta_ui_get_action (ui, "ActionGroupProjectManager",
 								   "ActionProjectAddSource");
 	g_object_set (G_OBJECT (action), "sensitive",
 				  ((plugin->project != NULL) &&
-				   (caps & GBF_PROJECT_CAN_ADD_SOURCE)), NULL);
+				   (caps & IANJUTA_PROJECT_CAN_ADD_SOURCE)), NULL);
 
 	/* Popup menus */
 	for (j = 0; j < G_N_ELEMENTS (popup_actions); j++)
@@ -952,7 +938,7 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 	GtkAction *action;
 	GbfTreeData *data;
 	gchar *selected_uri;
-	GbfProjectCapabilities caps = GBF_PROJECT_CAN_ADD_NONE;
+	IAnjutaProjectCapabilities caps = IANJUTA_PROJECT_CAN_ADD_NONE;
 	
 	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
 	/* Popup menu */
@@ -970,12 +956,12 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 	g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
 	
 	if (plugin->project)
-		caps = gbf_project_get_capabilities (plugin->project, NULL);
+		caps = ianjuta_project_get_capabilities (plugin->project, NULL);
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 										   GBF_TREE_NODE_TARGET_SOURCE);
 	if (data && data->type == GBF_TREE_NODE_TARGET_SOURCE)
 	{
-		if (caps & GBF_PROJECT_CAN_ADD_SOURCE)
+		if (caps & IANJUTA_PROJECT_CAN_ADD_SOURCE)
 		{
 			action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
 										   "ActionPopupProjectAddSource");
@@ -993,7 +979,7 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 										   GBF_TREE_NODE_TARGET);
 	if (data && data->type == GBF_TREE_NODE_TARGET)
 	{
-		if (caps & GBF_PROJECT_CAN_ADD_SOURCE)
+		if (caps & IANJUTA_PROJECT_CAN_ADD_SOURCE)
 		{
 			action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
 										   "ActionPopupProjectAddSource");
@@ -1011,13 +997,13 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 										   GBF_TREE_NODE_GROUP);
 	if (data && data->type == GBF_TREE_NODE_GROUP)
 	{
-		if (caps & GBF_PROJECT_CAN_ADD_GROUP)
+		if (caps & IANJUTA_PROJECT_CAN_ADD_GROUP)
 		{
 			action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
 										   "ActionPopupProjectAddGroup");
 			g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
 		}
-		if (caps & GBF_PROJECT_CAN_ADD_TARGET)
+		if (caps & IANJUTA_PROJECT_CAN_ADD_TARGET)
 		{
 			action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
 										   "ActionPopupProjectAddTarget");
@@ -1183,15 +1169,18 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
 	AnjutaPluginManager *plugin_manager;
 	AnjutaStatus *status;
 	gchar *dirname;
+	GFile *dirfile;
 	gchar *basename;
 	const gchar *root_uri;
 	GError *error = NULL;
 	GList *descs = NULL;
 	GList *desc;
+	IAnjutaProjectBackend *backend;
 	
 	root_uri = pm_plugin->project_root_uri;
 	
 	dirname = anjuta_util_get_local_path_from_uri (root_uri);
+	dirfile = g_file_new_for_uri (root_uri);
 	
 	g_return_if_fail (dirname != NULL);
 	
@@ -1205,51 +1194,45 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
 										 "Interfaces",
 										 "IAnjutaProjectBackend",
 										 NULL);
+	backend = NULL;
 	for (desc = g_list_first (descs); desc != NULL; desc = g_list_next (desc)) {
-		AnjutaPluginDescription *backend;
-		IAnjutaProjectBackend *plugin;
+		AnjutaPluginDescription *backend_desc;
 		gchar *location = NULL;
-		
-		backend = (AnjutaPluginDescription *)desc->data;
-		anjuta_plugin_description_get_string (backend, "Anjuta Plugin", "Location", &location);
+		IAnjutaProjectBackend *plugin;
+				
+		backend_desc = (AnjutaPluginDescription *)desc->data;
+		anjuta_plugin_description_get_string (backend_desc, "Anjuta Plugin", "Location", &location);
 		plugin = (IAnjutaProjectBackend *)anjuta_plugin_manager_get_plugin_by_id (plugin_manager, location);
+		g_message ("search plugin %s", location);
 		g_free (location);
-			
-		pm_plugin->project = ianjuta_project_backend_new_project (plugin, NULL);
-		if (pm_plugin->project)
+
+		if (ianjuta_project_backend_probe (plugin, dirfile, NULL))
 		{
-			if (gbf_project_probe (pm_plugin->project, dirname, NULL))
-			{
-				/* Backend found */
-				break;
-			}
-			g_object_unref (pm_plugin->project);
-			pm_plugin->project = NULL;
-		}
-		/*
-		if (!strcmp (backend->id, "gbf-am:GbfAmProject"))
+			/* Backend found */;
+			backend = plugin;
+			g_message ("Find backend");
 			break;
-		*/
-		plugin = NULL;
+		}
 	}
 	g_list_free (descs);
 	
-	if (!pm_plugin->project)
+	if (!backend)
 	{
 		/* FIXME: Set err */
 		g_warning ("no backend available for this project\n");
 		g_free (dirname);
+		g_object_unref (dirfile);
 		return;
 	}
 	
 	DEBUG_PRINT ("%s", "Creating new gbf project\n");
-	
-	/* pm_plugin->project = gbf_backend_new_project (backend->id); */
+	pm_plugin->project = ianjuta_project_backend_new_project (backend, NULL);
 	if (!pm_plugin->project)
 	{
 		/* FIXME: Set err */
 		g_warning ("project creation failed\n");
 		g_free (dirname);
+		g_object_unref (dirfile);
 		return;
 	}
 	
@@ -1262,7 +1245,7 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
 	DEBUG_PRINT ("loading project %s\n\n", dirname);
 	/* FIXME: use the error parameter to determine if the project
 	 * was loaded successfully */
-	gbf_project_load (pm_plugin->project, dirname, &error);
+	ianjuta_project_load (pm_plugin->project, dirfile, &error);
 	
 	anjuta_status_progress_tick (status, NULL, _("Created project viewâ?¦"));
 	
@@ -1285,6 +1268,7 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
 		pm_plugin->project = NULL;
 		g_free (basename);
 		g_free (dirname);
+		g_object_unref (dirfile);
 		/* gtk_widget_destroy (progress_win); */
 		anjuta_status_pop (status);
 		anjuta_status_busy_pop (status);
@@ -1303,6 +1287,7 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
 	anjuta_status_busy_pop (status);
 	g_free (basename);
 	g_free (dirname);
+	g_object_unref (dirfile);
 }
 
 static void
@@ -1731,29 +1716,16 @@ uri_is_inside_project (ProjectManagerPlugin *plugin, const gchar *uri)
 }
 
 static gchar *
-get_element_uri_from_id (ProjectManagerPlugin *plugin, const gchar *id, const gchar *root)
+get_element_uri_from_id (ProjectManagerPlugin *plugin, AnjutaProjectNode *id, const gchar *root)
 {
-	gchar *path, *ptr;
-	gchar *uri;
 	const gchar *project_root = NULL;
+	GFile *file = NULL;
+	GFile *target_file = NULL;
+	gchar *uri;
 	
 	if (!id)
 		return NULL;
 	
-	path = g_strdup (id);
-	ptr = strrchr (path, ':');
-	if (ptr)
-	{
-		*ptr = '\0';
-		if (ptr[1] == '/')
-		{
-			 /* ID is source ID, extract source uri */
-			uri = strrchr (path, ':');		/* keep uri scheme */
-			*ptr = ':';
-			return g_strdup (uri+1);
-		}
-	}
-	
 	anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
 					  root, G_TYPE_STRING,
 					  &project_root, NULL);
@@ -1766,9 +1738,46 @@ get_element_uri_from_id (ProjectManagerPlugin *plugin, const gchar *id, const gc
 					  &project_root,
 					  NULL);
 	}
-	uri = g_build_filename (project_root, path, NULL);
-	/* DEBUG_PRINT ("Converting id: %s to %s", id, uri); */
-	g_free (path);
+
+	switch (anjuta_project_node_get_type (id))
+	{
+		case ANJUTA_PROJECT_GROUP:
+			file = anjuta_project_group_get_directory (id);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			file = anjuta_project_group_get_directory (anjuta_project_node_parent (id));
+			target_file = g_file_get_child (file, anjuta_project_target_get_name (id));
+			file = target_file;
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			file = anjuta_project_source_get_file (id);
+			break;
+		default:
+			file = NULL;
+	}
+
+	if ((file != NULL) && (project_root != NULL))
+	{
+		gchar *rel_path;
+		
+		rel_path = g_file_get_relative_path (anjuta_project_group_get_directory (ianjuta_project_get_root (plugin->project, NULL)), file);
+
+		if (rel_path)
+		{
+			GFile *node_file = NULL;
+			GFile *root_file = NULL;
+			root_file = g_file_new_for_uri (project_root);
+			node_file = g_file_get_child (root_file, rel_path);
+			g_object_unref (root_file);
+
+			uri = g_file_get_uri (node_file);
+			g_object_unref (node_file);
+			g_free (rel_path);
+		}
+	}
+		
+	if (target_file != NULL) g_object_unref (target_file);
+	
 	return uri;
 }
 
@@ -1808,293 +1817,199 @@ get_element_relative_path (ProjectManagerPlugin *plugin, const gchar *uri, const
 	return NULL;
 }
 
-static GbfProjectTarget*
-get_target_from_uri (ProjectManagerPlugin *plugin, const gchar *uri)
+static AnjutaProjectNode*
+get_node_from_file (AnjutaProjectNode *parent, GFile *file)
 {
-	GbfProjectTarget *data;
-	const gchar *rel_path;
-	gchar *test_id;
-	
-	rel_path = get_element_relative_path (plugin, uri, IANJUTA_BUILDER_ROOT_URI);
-	
-	if (!rel_path)
-		return NULL;
-	
-	/* FIXME: More target types should be handled */
-	/* Test for shared lib */
-	test_id = g_strconcat (rel_path, ":shared_lib", NULL);
-	data = gbf_project_get_target (GBF_PROJECT (plugin->project),
-								   test_id, NULL);
-	g_free (test_id);
-	
-	if (!data)
-	{
-		/* Test for static lib */
-		test_id = g_strconcat (rel_path, ":static_lib", NULL);
-		data = gbf_project_get_target (GBF_PROJECT (plugin->project),
-									   test_id, NULL);
-		g_free (test_id);
-	}
-	if (!data)
+	AnjutaProjectNode *node;
+	GFile *target_file = NULL;
+
+	for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
 	{
-		/* Test for program */
-		test_id = g_strconcat (rel_path, ":program", NULL);
-		data = gbf_project_get_target (GBF_PROJECT (plugin->project),
-									   test_id, NULL);
-		g_free (test_id);
+		switch (anjuta_project_node_get_type (node))
+		{
+		case ANJUTA_PROJECT_GROUP:
+			if (g_file_equal (anjuta_project_group_get_directory (node), file))
+			{
+				return node;
+			}
+			else
+			{
+				return get_node_from_file (node, file);
+			}
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			target_file = g_file_get_child (anjuta_project_group_get_directory (parent), anjuta_project_target_get_name (node));
+			if (g_file_equal (target_file, file))
+			{
+				g_object_unref (target_file);
+				return node;
+			}
+			g_object_unref (target_file);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			if (g_file_equal (anjuta_project_source_get_file (node), file))
+			{
+				return node;
+			}
+			break;
+		default:
+			break;
+		}
 	}
-	return data;
+				
+	return NULL;		
 }
 
-static gchar *
+static AnjutaProjectNode*
 get_element_id_from_uri (ProjectManagerPlugin *plugin, const gchar *uri)
 {
-	GbfProjectTarget *target;
-	gchar *id;
+	AnjutaProjectNode *node;
+	GFile *file;
 	
 	if (!uri_is_inside_project (plugin, uri))
 		return NULL;
-	
-	target = get_target_from_uri (plugin, uri);
-	if (target)
+
+	file = g_file_new_for_uri (uri);
+	node = ianjuta_project_get_root (plugin->project, NULL);
+	if (g_file_equal (anjuta_project_group_get_directory (node), file))
 	{
-		id = g_strdup (target->id);
-		gbf_project_target_free (target);
+		return node;
 	}
-	else if (get_uri_vfs_type (uri) | G_FILE_TYPE_DIRECTORY)
+	else
 	{
-		id = g_strconcat (get_element_relative_path (plugin, uri, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI), "/", NULL);
+		return get_node_from_file (node, file);
+	}
+}
+
+static AnjutaProjectTarget*
+get_target_from_uri (ProjectManagerPlugin *plugin, const gchar *uri)
+{
+	AnjutaProjectNode *node;
+
+	node = get_element_id_from_uri (plugin, uri);
+
+	if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_TARGET)
+	{
+		return (AnjutaProjectTarget *)node;
 	}
 	else
 	{
-		id = strdup (get_element_relative_path (plugin, uri, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
+		return NULL;
 	}
-	return id;
 }
 
-static IAnjutaProjectManagerElementType
+static AnjutaProjectNodeType
 iproject_manager_get_element_type (IAnjutaProjectManager *project_manager,
 								   const gchar *element_uri,
 								   GError **err)
 {
-	GFileType ftype;
+	AnjutaProjectNode *node;
 	ProjectManagerPlugin *plugin;
-	
+
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
-						  IANJUTA_PROJECT_MANAGER_UNKNOWN);
+						  ANJUTA_PROJECT_UNKNOWN);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project),
-						  IANJUTA_PROJECT_MANAGER_UNKNOWN);
-	g_return_val_if_fail (uri_is_inside_project (plugin, element_uri),
-						  IANJUTA_PROJECT_MANAGER_UNKNOWN);
-	
-	ftype = get_uri_vfs_type (element_uri);
-	if (ftype | G_FILE_TYPE_DIRECTORY)
-	{
-		return IANJUTA_PROJECT_MANAGER_GROUP;
-	}
-	else if (ianjuta_project_manager_get_target_type (project_manager,
-													  element_uri, NULL) !=
-				IANJUTA_PROJECT_MANAGER_TARGET_UNKNOWN)
-	{
-		return IANJUTA_PROJECT_MANAGER_TARGET;
-	}
-	else if (ftype | G_FILE_TYPE_REGULAR)
-	{
-		return IANJUTA_PROJECT_MANAGER_SOURCE;
-	}
-	return IANJUTA_PROJECT_MANAGER_UNKNOWN;
+
+	node = get_element_id_from_uri (plugin, element_uri);
+
+	return node == NULL ? ANJUTA_PROJECT_UNKNOWN : anjuta_project_node_get_type (node);
 }
 
 static GList*
 iproject_manager_get_elements (IAnjutaProjectManager *project_manager,
-							   IAnjutaProjectManagerElementType element_type,
+							   AnjutaProjectNodeType element_type,
 							   GError **err)
 {
-	GList *elements;
 	ProjectManagerPlugin *plugin;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
-	
-	elements = NULL;
-	switch (element_type)
-	{
-		case IANJUTA_PROJECT_MANAGER_SOURCE:
-		{
-			GList *sources, *node;
-			GbfProjectTargetSource *source;
-			sources = gbf_project_get_all_sources (plugin->project, NULL);
-			node = sources;
-			while (node)
-			{
-				source = gbf_project_get_source (plugin->project,
-												 (const gchar *) node->data,
-												 NULL);
-				if (source)
-					elements = g_list_prepend (elements,
-											   g_strdup (source->source_uri));
-				gbf_project_target_source_free (source);
-				g_free (node->data);
-				node = node->next;
-			}
-			g_list_free (sources);
-			break;
-		}
-		case IANJUTA_PROJECT_MANAGER_TARGET:
-		{
-			GList *targets, *node;
-			targets = gbf_project_get_all_targets (plugin->project, NULL);
-			node = targets;
-			while (node)
-			{
-				elements = g_list_prepend (elements,
-										   get_element_uri_from_id (plugin,
-												(const gchar *)node->data,
-												IANJUTA_BUILDER_ROOT_URI));
-				g_free (node->data);
-				node = node->next;
-			}
-			g_list_free (targets);
-			break;
-		}
-		case IANJUTA_PROJECT_MANAGER_GROUP:
-		{
-			GList *groups, *node;
-			groups = gbf_project_get_all_groups (plugin->project, NULL);
-			node = groups;
-			while (node)
-			{
-				elements = g_list_prepend (elements,
-										   get_element_uri_from_id (plugin,
-												(const gchar *)node->data,
-										        IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
-				g_free (node->data);
-				node = node->next;
-			}
-			g_list_free (groups);
-			break;
-		}
-		default:
-			elements = NULL;
-	}
-	return g_list_reverse (elements);
+	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); 
 }
 
-static IAnjutaProjectManagerTargetType
+static AnjutaProjectTargetClass
 iproject_manager_get_target_type (IAnjutaProjectManager *project_manager,
 								   const gchar *target_uri,
 								   GError **err)
 {
-	IAnjutaProjectManagerElementType element_type;
-	IAnjutaProjectManagerTargetType target_type;
 	ProjectManagerPlugin *plugin;
-	GbfProjectTarget *data;
+	AnjutaProjectTarget *target;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
-						  IANJUTA_PROJECT_MANAGER_TARGET_UNKNOWN);
+						  ANJUTA_TARGET_UNKNOWN);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project),
-						  IANJUTA_PROJECT_MANAGER_TARGET_UNKNOWN);
-	
-	element_type = ianjuta_project_manager_get_element_type (project_manager,
-															 target_uri, NULL);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project),
+						  ANJUTA_TARGET_UNKNOWN);
 	
 	g_return_val_if_fail (uri_is_inside_project (plugin, target_uri),
-						  IANJUTA_PROJECT_MANAGER_TARGET_UNKNOWN);
-	
-	data = get_target_from_uri (plugin, target_uri);
+						  ANJUTA_TARGET_UNKNOWN);
 	
-	if (data && data->type && strcmp (data->type, "shared_lib") == 0)
-	{
-		target_type = IANJUTA_PROJECT_MANAGER_TARGET_SHAREDLIB;
-	}
-	else if (data && data->type && strcmp (data->type, "static_lib") == 0)
-	{
-		target_type = IANJUTA_PROJECT_MANAGER_TARGET_STATICLIB;
-	}
-	else if (data && data->type && strcmp (data->type, "program") == 0)
+	target = get_target_from_uri (plugin, target_uri);
+
+	if (target != NULL)
 	{
-		target_type = IANJUTA_PROJECT_MANAGER_TARGET_STATICLIB;
+		AnjutaProjectTargetType type = anjuta_project_target_get_type (target);
+
+		return anjuta_project_target_type_class (type);
 	}
 	else
 	{
-		target_type = IANJUTA_PROJECT_MANAGER_TARGET_UNKNOWN;
+		return ANJUTA_TARGET_UNKNOWN;
 	}
-	if (data)
-		gbf_project_target_free (data);
-	return target_type;
 }
 
 static GList*
 iproject_manager_get_targets (IAnjutaProjectManager *project_manager,
-							  IAnjutaProjectManagerTargetType target_type,
+							  AnjutaProjectTargetClass target_type,
 							  GError **err)
 {
 	GList *targets, *node;
-	const gchar *target_id;
-	GList *elements;
 	ProjectManagerPlugin *plugin;
-	GList *target_types = NULL;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
-	
-	switch (target_type)
-	{
-		case IANJUTA_PROJECT_MANAGER_TARGET_SHAREDLIB:
-			target_types = g_list_append(target_types, "shared_lib");
-			break;
-		case IANJUTA_PROJECT_MANAGER_TARGET_STATICLIB:
-			target_types = g_list_append(target_types, "static_lib");
-			break;
-		case IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE:
-			target_types = g_list_append(target_types, "program");
-			target_types = g_list_append(target_types, "script");
-			break;
-		default:
-			/* FIXME: there are some more target types */
-			g_warning ("Unsupported target type");
-			return NULL;
-	}
-	
-	elements = NULL;
-	targets = gbf_project_get_all_targets (plugin->project, NULL);
-	node = targets;
-	while (node)
+	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);
+
+	/* Remove all targets not in specified class */
+	for (node = g_list_first (targets); node != NULL;)
 	{
-		const gchar *t_type;
-		
-		target_id = (const gchar*) node->data;
-		
-		t_type = strrchr (target_id, ':');
-		if (t_type && strlen (t_type) > 2)
+		AnjutaProjectTargetType type;
+
+		type = anjuta_project_target_get_type (node->data);
+		if (anjuta_project_target_type_class (type) != target_type)
 		{
-			GList* type_node;
-			t_type++;
-			for (type_node = target_types; type_node != NULL;
-				 type_node = type_node->next)
-			{
-				if (strcmp (t_type, type_node->data) == 0)
-				{
-					gchar *target_uri = get_element_uri_from_id (plugin,
-																 target_id,
-																 IANJUTA_BUILDER_ROOT_URI);
-					elements = g_list_prepend (elements, target_uri);
-				}
-			}
+			GList *next = g_list_next (node);
+			targets = g_list_delete_link (targets, node);
+			node = next;
+		}
+		else
+		{
+			node = g_list_next (node);
 		}
-		g_free (node->data);
-		node = node->next;
 	}
-	g_list_free (targets);
-	return g_list_reverse (elements);
+
+	/* Replace all targets by their corresponding URI */
+	for (node = g_list_first (targets); node != NULL; node = g_list_next (node))
+	{
+		AnjutaProjectTarget *target = (AnjutaProjectTarget *)node->data;
+		AnjutaProjectGroup *parent = anjuta_project_node_parent (target);
+		GFile *file;
+
+		file = g_file_get_child (anjuta_project_group_get_directory (parent), anjuta_project_target_get_name (target));
+		node->data = g_file_get_uri (file);
+		g_object_unref (file);
+	}
+
+	return targets;
 }
 
 static gchar*
@@ -2102,13 +2017,13 @@ iproject_manager_get_parent (IAnjutaProjectManager *project_manager,
 							 const gchar *element_uri,
 							 GError **err)
 {
-	IAnjutaProjectManagerElementType type;
+	AnjutaProjectNodeType type;
 	ProjectManagerPlugin *plugin;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 	
 	type = ianjuta_project_manager_get_element_type (project_manager,
 													 element_uri, NULL);
@@ -2126,7 +2041,7 @@ iproject_manager_get_children (IAnjutaProjectManager *project_manager,
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 	/* FIXME: */
 	return NULL;
 }
@@ -2144,7 +2059,7 @@ iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	if (plugin->project == NULL) return NULL;
 	
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 	
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 										   GBF_TREE_NODE_TARGET_SOURCE);
@@ -2162,7 +2077,7 @@ iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
 										   GBF_TREE_NODE_TARGET);
 	if (data && data->type == GBF_TREE_NODE_TARGET)
 	{
-		uri = get_element_uri_from_id (plugin, data->id, IANJUTA_BUILDER_ROOT_URI);
+		uri = get_element_uri_from_id (plugin, (AnjutaProjectNode *)data->id, IANJUTA_BUILDER_ROOT_URI);
 		gbf_tree_data_free (data);
 		return uri;
 	}
@@ -2185,79 +2100,94 @@ iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
 	return NULL;
 }
 
-static gchar *
+static gchar*
 iproject_manager_get_selected_id (IAnjutaProjectManager *project_manager,
-								  IAnjutaProjectManagerElementType element_type,
+								  AnjutaProjectNodeType element_type,
 								  GError **err)
 {
 	GbfTreeData *data;
 	ProjectManagerPlugin *plugin;
-	gchar *id = NULL;
+	AnjutaProjectNode *node = NULL;
+	gchar *uri;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), NULL);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 
-	if (element_type == IANJUTA_PROJECT_MANAGER_UNKNOWN ||
-		element_type == IANJUTA_PROJECT_MANAGER_SOURCE)
+	if (element_type == ANJUTA_PROJECT_UNKNOWN ||
+		element_type == ANJUTA_PROJECT_SOURCE)
 	{
 		data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 		                                       GBF_TREE_NODE_TARGET_SOURCE);
 		if (data && data->type == GBF_TREE_NODE_TARGET_SOURCE)
-			id = g_strdup (data->id);
+			node = data->id;
 
 		if (data)
 			gbf_tree_data_free (data);
 
-		if (id)
-			return id;
+		if (node)
+		{
+			uri = get_element_uri_from_id (plugin, node, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
+			return uri;
+		}
 	}
 
-	if (element_type == IANJUTA_PROJECT_MANAGER_UNKNOWN ||
-		element_type == IANJUTA_PROJECT_MANAGER_TARGET)
+	if (element_type == ANJUTA_PROJECT_UNKNOWN ||
+		element_type == ANJUTA_PROJECT_TARGET)
 	{
 		data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 											   GBF_TREE_NODE_TARGET);
 		if (data && data->type == GBF_TREE_NODE_TARGET)
-			id = g_strdup (data->id);
+			node = data->id;
 		
 		if (data)
 			gbf_tree_data_free (data);
 
-		if (id)
-			return id;
+		if (node)
+		{
+			uri = get_element_uri_from_id (plugin, node, IANJUTA_BUILDER_ROOT_URI);
+			return uri;
+		}
 	}
 
-	if (element_type == IANJUTA_PROJECT_MANAGER_UNKNOWN ||
-		element_type == IANJUTA_PROJECT_MANAGER_GROUP)
+	if (element_type == ANJUTA_PROJECT_UNKNOWN ||
+		element_type == ANJUTA_PROJECT_GROUP)
 	{
 		data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 											   GBF_TREE_NODE_GROUP);
 		if (data && data->type == GBF_TREE_NODE_GROUP)
-			id = g_strdup (data->id);
+			node = data->id;
 
 		if (data)
 			gbf_tree_data_free (data);
 
-		if (id)
-			return id;
+		if (node)
+		{
+			uri = get_element_uri_from_id (plugin, node, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
+			return uri;
+		}
 	}
 
-	return id;
+	if (node)
+	{
+		uri = get_element_uri_from_id (plugin, node, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
+		return uri;
+	}
+	return NULL;
 }
 
-static IAnjutaProjectManagerCapabilities
+static IAnjutaProjectCapabilities
 iproject_manager_get_capabilities (IAnjutaProjectManager *project_manager,
 								   GError **err)
 {
 	ProjectManagerPlugin *plugin;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
-						  IANJUTA_PROJECT_MANAGER_CAN_ADD_NONE);
+						  IANJUTA_PROJECT_CAN_ADD_NONE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	return gbf_project_get_capabilities (plugin->project, NULL);
+	return ianjuta_project_get_capabilities (plugin->project, NULL);
 }
 
 static gchar*
@@ -2267,20 +2197,20 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 							 GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	IAnjutaProjectManagerElementType default_location_type;
-	gchar *location_id = NULL;
-	gchar* source_id;
+	AnjutaProjectNodeType default_location_type;
+	AnjutaProjectNode *location_id = NULL;
+	AnjutaProjectSource *source_id;
 	gchar* source_uri;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), FALSE);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	update_operation_begin (plugin);
 	if (default_location_uri == NULL)
 	{
-		default_location_type = IANJUTA_PROJECT_MANAGER_UNKNOWN;
+		default_location_type = ANJUTA_PROJECT_UNKNOWN;
 	}
 	else
 	{
@@ -2289,14 +2219,14 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 													  default_location_uri, NULL);
 		location_id = get_element_id_from_uri (plugin, default_location_uri);
 	}
-	if (default_location_type == IANJUTA_PROJECT_MANAGER_GROUP)
+	if (default_location_type == ANJUTA_PROJECT_GROUP)
 	{
 		source_id = gbf_project_util_add_source (plugin->model,
 											get_plugin_parent_window (plugin),
 												 NULL, location_id,
 												 source_uri_to_add);
 	}
-	else if (default_location_type == IANJUTA_PROJECT_MANAGER_TARGET)
+	else if (default_location_type == ANJUTA_PROJECT_TARGET)
 	{
 		source_id = gbf_project_util_add_source (plugin->model,
 											 get_plugin_parent_window (plugin),
@@ -2313,7 +2243,6 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 	update_operation_end (plugin, TRUE);
 	
 	source_uri = get_element_uri_from_id(plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
-	g_free(source_id);
 	
 	return source_uri;
 }
@@ -2325,21 +2254,26 @@ iproject_manager_add_source_quiet (IAnjutaProjectManager *project_manager,
 								   GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	gchar* source_id;
+	AnjutaProjectSource *source_id;
+	GFile *source_file;
+	AnjutaProjectTarget *target;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), FALSE);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
+	target = get_element_id_from_uri (plugin, location_uri);
+	source_file = g_file_new_for_uri (source_uri_to_add);
 	update_operation_begin (plugin);
-	source_id = gbf_project_add_source (plugin->project,
-										source_uri_to_add,
-										location_uri,
+	source_id = ianjuta_project_add_source (plugin->project,
+	    								target,
+	    								source_file,
 										err);
 	update_operation_end (plugin, TRUE);
+	g_object_unref (source_file);
 	
-	return source_id;
+	return get_element_uri_from_id (plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
 }
 
 static GList*
@@ -2349,20 +2283,20 @@ iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
 							 GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	IAnjutaProjectManagerElementType default_location_type;
-	gchar *location_id = NULL;
+	AnjutaProjectNodeType default_location_type;
+	AnjutaProjectNode *location_id = NULL;
 	GList* source_ids;
 	GList* source_uris = NULL;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), FALSE);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	update_operation_begin (plugin);
 	if (default_location_uri == NULL)
 	{
-		default_location_type = IANJUTA_PROJECT_MANAGER_UNKNOWN;
+		default_location_type = ANJUTA_PROJECT_UNKNOWN;
 	}
 	else
 	{
@@ -2371,14 +2305,14 @@ iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
 													  default_location_uri, NULL);
 		location_id = get_element_id_from_uri (plugin, default_location_uri);
 	}
-	if (default_location_type == IANJUTA_PROJECT_MANAGER_GROUP)
+	if (default_location_type == ANJUTA_PROJECT_GROUP)
 	{
 		source_ids = gbf_project_util_add_source_multi (plugin->model,
 											 get_plugin_parent_window (plugin),
 												 NULL, location_id,
 												 source_add_uris);
 	}
-	else if (default_location_type == IANJUTA_PROJECT_MANAGER_TARGET)
+	else if (default_location_type == ANJUTA_PROJECT_TARGET)
 	{
 		source_ids =
 			gbf_project_util_add_source_multi (plugin->model,
@@ -2416,13 +2350,15 @@ iproject_manager_add_target (IAnjutaProjectManager *project_manager,
 							 GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	gchar *default_group_id, *target_id, *target_uri = NULL;
+	gchar *target_uri = NULL;
+	AnjutaProjectTarget *target_id;
+	AnjutaProjectGroup *default_group_id;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), FALSE);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	default_group_id = get_element_id_from_uri (plugin, default_group_uri);
 	
@@ -2434,7 +2370,6 @@ iproject_manager_add_target (IAnjutaProjectManager *project_manager,
 	update_operation_end (plugin, TRUE);
 	target_uri = get_element_uri_from_id (plugin, target_id, IANJUTA_BUILDER_ROOT_URI);
 	g_free (target_id);
-	g_free (default_group_id);
 	return target_uri;
 }
 
@@ -2445,13 +2380,14 @@ iproject_manager_add_group (IAnjutaProjectManager *project_manager,
 							GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	gchar *group_id, *group_uri = NULL;
-	gchar *default_group_id;
+	gchar *group_uri = NULL;
+	AnjutaProjectGroup *group_id;
+	AnjutaProjectGroup *default_group_id;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
-	g_return_val_if_fail (GBF_IS_PROJECT (plugin->project), FALSE);
+	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	default_group_id = get_element_id_from_uri (plugin, default_group_uri);
 	
@@ -2463,7 +2399,7 @@ iproject_manager_add_group (IAnjutaProjectManager *project_manager,
 	update_operation_end (plugin, TRUE);
 	group_uri = get_element_uri_from_id (plugin, group_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
 	g_free (group_id);
-	g_free (default_group_id);
+	
 	return group_uri;
 }
 
@@ -2474,32 +2410,20 @@ iproject_manager_is_open (IAnjutaProjectManager *project_manager, GError **err)
 
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 
-	return GBF_IS_PROJECT (plugin->project);
+	return IANJUTA_IS_PROJECT (plugin->project);
 }
 
 static GList*
 iproject_manager_get_packages (IAnjutaProjectManager *project_manager, GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	GList *modules = NULL;
-	GList *packages = NULL;
-	GList* node;
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	
 	/* Check if a current project is opened */
 	if (plugin->project == NULL) return NULL;
-	
-	modules = gbf_project_get_config_modules (plugin->project, NULL);
-	for (node = modules; node != NULL; node = g_list_next (node))
-	{
-		GList* mod_pkgs = gbf_project_get_config_packages (plugin->project,
-														   node->data, NULL);
-		packages = g_list_concat (packages, mod_pkgs);
-	}
-	g_list_foreach (modules, (GFunc)g_free, NULL);
-	g_list_free (modules);
-	return packages;
+
+	return ianjuta_project_get_packages (plugin->project, NULL);
 }
 
 static void
diff --git a/plugins/project-manager/plugin.h b/plugins/project-manager/plugin.h
index 7490a02..1e58763 100644
--- a/plugins/project-manager/plugin.h
+++ b/plugins/project-manager/plugin.h
@@ -22,7 +22,8 @@
 #define _PROJECT_MANAGER_PLUGIN_H_
 
 #include <libanjuta/anjuta-plugin.h>
-#include <libanjuta/gbf-project.h>
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/interfaces/ianjuta-project.h>
 #include "gbf-project-model.h"
 #include "gbf-project-view.h"
 
@@ -42,7 +43,7 @@ struct _ProjectManagerPlugin{
 	
 	AnjutaUI *ui;
 	AnjutaPreferences *prefs;
-	GbfProject *project;
+	IAnjutaProject *project;
 	GtkWidget *view;
 	GbfProjectModel *model;
 	GtkWidget *scrolledwindow;
diff --git a/plugins/run-program/parameters.c b/plugins/run-program/parameters.c
index 2f7c6d9..9a31567 100644
--- a/plugins/run-program/parameters.c
+++ b/plugins/run-program/parameters.c
@@ -677,7 +677,7 @@ run_dialog_init (RunDialog *dlg, RunProgramPlugin *plugin)
 		if (pm != NULL)
 		{
 			exec_targets = ianjuta_project_manager_get_targets (pm,
-							 IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE,
+							 ANJUTA_TARGET_EXECUTABLE,
 							 NULL);
 		}
 		if (exec_targets != NULL)
diff --git a/plugins/search/search-replace_backend.c b/plugins/search/search-replace_backend.c
index 8b1fa17..b67fbeb 100644
--- a/plugins/search/search-replace_backend.c
+++ b/plugins/search/search-replace_backend.c
@@ -300,7 +300,7 @@ get_project_file_list(void)
 											IAnjutaProjectManager , NULL);
 		
 		list = ianjuta_project_manager_get_elements (prjman,
-													 IANJUTA_PROJECT_MANAGER_SOURCE,
+													 ANJUTA_PROJECT_SOURCE,
 													 NULL);
 		if (list)
 		{
diff --git a/plugins/symbol-db/plugin.c b/plugins/symbol-db/plugin.c
index 87666a8..fe8d105 100644
--- a/plugins/symbol-db/plugin.c
+++ b/plugins/symbol-db/plugin.c
@@ -1413,7 +1413,7 @@ do_import_project_sources (AnjutaPlugin *plugin, IAnjutaProjectManager *pm,
 	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);	
 
 	prj_elements_list = ianjuta_project_manager_get_elements (pm,
-					   IANJUTA_PROJECT_MANAGER_SOURCE,
+					   ANJUTA_PROJECT_SOURCE,
 					   NULL);
 	
 	if (prj_elements_list == NULL)
@@ -1579,7 +1579,7 @@ do_check_offline_files_changed (SymbolDBPlugin *sdb_plugin)
 									 IAnjutaProjectManager, NULL);	
 
 	prj_elements_list = ianjuta_project_manager_get_elements (pm,
-		   IANJUTA_PROJECT_MANAGER_SOURCE,
+		   ANJUTA_PROJECT_SOURCE,
 		   NULL);
 	
 	/* fill an hash table with all the items of the list just taken. 



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