diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 59757878a3c1deb17b554d322eb9c2776225c023..1dc1f603633a6bf993f894b113adb7c9f626ab6b 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -122,7 +122,10 @@ libcommon_la_SOURCES = 			\
 	proc_args.c proc_args.h		\
 	slurm_strcasestr.c slurm_strcasestr.h \
 	node_conf.h node_conf.c		\
-	gres.h gres.c
+	gres.h gres.c			\
+	entity.h entity.c		\
+	layout.h layout.c		\
+	layouts_mgr.h layouts_mgr.c
 
 EXTRA_libcommon_la_SOURCES = 		\
 	$(extra_unsetenv_src)		\
diff --git a/src/common/Makefile.in b/src/common/Makefile.in
index ebdcd7650528786106a5e4e2f50d876aa3f48c65..9182a82c47012e324525a99d2c9c9d80e803cbc5 100644
--- a/src/common/Makefile.in
+++ b/src/common/Makefile.in
@@ -186,7 +186,8 @@ am__libcommon_la_SOURCES_DIST = cpu_frequency.c cpu_frequency.h \
 	global_defaults.c timers.c timers.h slurm_xlator.h stepd_api.c \
 	stepd_api.h write_labelled_message.c write_labelled_message.h \
 	proc_args.c proc_args.h slurm_strcasestr.c slurm_strcasestr.h \
-	node_conf.h node_conf.c gres.h gres.c
+	node_conf.h node_conf.c gres.h gres.c entity.h entity.c \
+	layout.h layout.c layouts_mgr.h layouts_mgr.c
 @HAVE_UNSETENV_FALSE@am__objects_1 = unsetenv.lo
 am_libcommon_la_OBJECTS = cpu_frequency.lo assoc_mgr.lo xmalloc.lo \
 	xassert.lo xstring.lo xsignal.lo strnatcmp.lo forward.lo \
@@ -210,7 +211,8 @@ am_libcommon_la_OBJECTS = cpu_frequency.lo assoc_mgr.lo xmalloc.lo \
 	slurm_step_layout.lo checkpoint.lo job_resources.lo \
 	parse_time.lo job_options.lo global_defaults.lo timers.lo \
 	stepd_api.lo write_labelled_message.lo proc_args.lo \
-	slurm_strcasestr.lo node_conf.lo gres.lo
+	slurm_strcasestr.lo node_conf.lo gres.lo entity.lo layout.lo \
+	layouts_mgr.lo
 am__EXTRA_libcommon_la_SOURCES_DIST = unsetenv.c unsetenv.h \
 	uthash/LICENSE uthash/README uthash/uthash.h
 libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
@@ -649,7 +651,10 @@ libcommon_la_SOURCES = \
 	proc_args.c proc_args.h		\
 	slurm_strcasestr.c slurm_strcasestr.h \
 	node_conf.h node_conf.c		\
-	gres.h gres.c
+	gres.h gres.c			\
+	entity.h entity.c		\
+	layout.h layout.c		\
+	layouts_mgr.h layouts_mgr.c
 
 EXTRA_libcommon_la_SOURCES = \
 	$(extra_unsetenv_src)		\
@@ -764,6 +769,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu_frequency.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemonize.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entity.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forward.Plo@am__quote@
@@ -775,6 +781,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_hdr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job_options.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job_resources.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layout.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layouts_mgr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@
diff --git a/src/common/entity.c b/src/common/entity.c
new file mode 100644
index 0000000000000000000000000000000000000000..aeefad11f752aa1dd724d6518b8ba6e68df8556a
--- /dev/null
+++ b/src/common/entity.c
@@ -0,0 +1,208 @@
+/*****************************************************************************\
+ *  entity.c - layouts entities data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#include "src/common/entity.h"
+#include "src/common/layout.h"
+#include "src/common/xmalloc.h"
+#include "src/common/xstring.h"
+#include "src/common/xtree.h"
+
+
+/*****************************************************************************\
+ *                                 FUNCTIONS                                 *
+\*****************************************************************************/
+
+static const char* _entity_data_identify(void* item)
+{
+	entity_data_t* data_item = (entity_data_t*)item;
+	return data_item->key;
+}
+
+void entity_init(entity_t* entity, const char* name, const char* type)
+{
+	entity->name = xstrdup(name);
+	entity->type = xstrdup(type);
+	entity->data = xhash_init(_entity_data_identify, NULL, NULL, 0);
+	entity->nodes = list_create(NULL);
+	entity->ptr = NULL;
+}
+
+void entity_free(entity_t* entity)
+{
+	if (entity) {
+		xfree(entity->name);
+		xfree(entity->type);
+		xhash_free(entity->data);
+		list_destroy(entity->nodes);
+	}
+}
+
+const char* entity_get_name(const entity_t* entity)
+{
+	return entity->name;
+}
+
+const char* entity_get_type(const entity_t* entity)
+{
+	return entity->type;
+}
+
+void** entity_get_data(const entity_t* entity, const char* key)
+{
+	entity_data_t* data = (entity_data_t*)xhash_get(entity->data, key);
+	if (data) {
+		return &data->value;
+	}
+	return NULL;
+}
+
+int entity_add_data(entity_t* entity, const char* key, void* value,
+		    void (*_free)(void*))
+{
+	entity_data_t* result;
+	entity_data_t* new_data_item;
+	if (!key || !*key || !value)
+		return 0;
+	result = (entity_data_t*)xhash_get(entity->data, key);
+	if (result != NULL) {
+		if (_free)
+			_free(result->value);
+		result->value = value;
+		return 1;
+	}
+	new_data_item = (entity_data_t*)xmalloc(sizeof(entity_data_t));
+	new_data_item->key = key;
+	new_data_item->value = value;
+	result = xhash_add(entity->data, new_data_item);
+	if (result == NULL) {
+		xfree(new_data_item);
+		return 0;
+	}
+	return 1;
+}
+
+void entity_delete_data(entity_t* entity, const char* key)
+{
+	xhash_delete(entity->data, key);
+}
+
+void entity_clear_data(entity_t* entity)
+{
+	xhash_clear(entity->data);
+}
+
+void entity_add_node(entity_t* entity, layout_t* layout, void* node)
+{
+
+	entity_node_t* entity_node = (entity_node_t*)xmalloc(
+		sizeof(entity_node_t));
+	entity_node->layout = layout;
+	entity_node->node = node;
+	list_append(entity->nodes, entity_node);
+}
+
+static int _entity_node_find(void* x, void* key)
+{
+	entity_node_t* entity_node = (entity_node_t*)x;
+	return entity_node->node == key;
+}
+
+void entity_delete_node(entity_t* entity, void* node)
+{
+	ListIterator i;
+	void* result;
+	i = list_iterator_create(entity->nodes);
+	list_iterator_reset(i);
+	result = list_find(i, _entity_node_find, node);
+	do {
+		if (result == NULL)
+			break;
+		list_delete_item(i);
+		xfree(result);
+	} while(0);
+	list_iterator_destroy(i);
+}
+
+void entity_clear_nodes(entity_t* entity)
+{
+	list_flush(entity->nodes);
+}
+
+int entity_has_node(entity_t* entity, void* node)
+{
+	ListIterator i;
+	void* result;
+	i = list_iterator_create(entity->nodes);
+	list_iterator_reset(i);
+	result = list_find(i, _entity_node_find, node);
+	list_iterator_destroy(i);
+	return result != NULL;
+}
+
+typedef struct _entity_nodes_walkstruct_st {
+	void (*callback)(layout_t* layout, void* node, void* arg);
+	void* arg;
+} _entity_nodes_walkstruct_t;
+
+static int _entity_nodes_walkfunc(void* x, void* arg)
+{
+	entity_node_t* entity_node = (entity_node_t*)x;
+	_entity_nodes_walkstruct_t* real_arg =
+		(_entity_nodes_walkstruct_t*)arg;
+	real_arg->callback(entity_node->layout,
+			   entity_node->node,
+			   real_arg->arg);
+	return 0;
+}
+
+void entity_nodes_walk(entity_t* entity,
+		       void (*callback)(layout_t* layout,
+					void* node,
+					void* arg),
+		       void* arg)
+{
+	_entity_nodes_walkstruct_t real_arg;
+	real_arg.callback = callback;
+	real_arg.arg = arg;
+	list_for_each(entity->nodes, _entity_nodes_walkfunc, &real_arg);
+}
+
+const char* entity_hashable_identify(void* item)
+{
+	entity_t* entity = (entity_t*)item;
+	return entity->name;
+}
diff --git a/src/common/entity.h b/src/common/entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..03650a6af2af62143dbbfe65b4f7e515e3306d29
--- /dev/null
+++ b/src/common/entity.h
@@ -0,0 +1,228 @@
+/*****************************************************************************\
+ *  entity.h - layouts entities data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#ifndef __ENTITY_GDBZJYZL_INC__
+#define __ENTITY_GDBZJYZL_INC__
+
+#include "src/common/list.h"
+#include "src/common/xhash.h"
+#include "src/common/xtree.h"
+#include "src/common/layout.h"
+
+/*****************************************************************************\
+ *                                 STRUCTURES                                *
+\*****************************************************************************/
+
+/* definition of the entity itself, main structure of this file. */
+typedef struct entity_st {
+	char* name;     /* unique name of this entity */
+	char* type;     /* basic type of entity */
+	xhash_t* data;  /* data table, stores data items */
+	List nodes;     /* list of nodes where this entity
+			   appears */
+	void *ptr;      /* private data for arbitraty ptr */
+} entity_t;
+
+/* definition of the key-value structure used internaly by entities */
+typedef struct entity_data_st {
+	const char* key; /* memory not owned, see layouts_keydef */
+	void* value;
+} entity_data_t;
+
+/* definition of the entity node structure used internaly by entities
+ * to represent the layout nodes that are linked to them */
+typedef struct entity_node_st {
+	layout_t* layout; /* layout containing a relationnal structure holding
+			   * a reference to this entity */
+	void* node;       /* pointer to the relational node referencing
+			     this entity */
+} entity_node_t;
+
+/*****************************************************************************\
+ *                                 FUNCTIONS                                 *
+\*****************************************************************************/
+
+/*
+ * entity_init - initialize an entity
+ *
+ * IN entity - the entity struct to initialize
+ * IN name - the name of the entity
+ * IN type - the type of the entity
+ */
+void entity_init(entity_t* entity, const char* name, const char* type);
+
+/*
+ * entity_free - free entity internals
+ *
+ * IN entity - the entity struct to fee internals from
+ */
+void entity_free(entity_t* entity);
+
+/*
+ * entity_get_name - get the name of an entity
+ *
+ * IN entity - the entity struct to use
+ *
+ * Return value is the name of the entity
+ */
+const char* entity_get_name(const entity_t* entity);
+
+/*
+ * entity_get_type - get the type of an entity
+ *
+ * IN entity - the entity struct to use
+ *
+ * Return value is the type of the entity
+ */
+const char* entity_get_type(const entity_t* entity);
+
+/*
+ * entity_get_data - get the address of the pointer to the data associated
+ *       with a particular key of an entity
+ *
+ * IN entity - the entity struct to use
+ * IN key - the targeted key
+ *
+ * Return value is the address of the (void*) pointer to the data associated to
+ *       the key or NULL in case of error
+ */
+void** entity_get_data(const entity_t* entity, const char* key);
+
+/*
+ * entity_add_data - associate data to a particular key of an entity
+ *
+ * IN entity - the entity struct to use
+ * IN key - the key the data must be associated to
+ * IN value - the data to associate with the key (potentially overriding
+ *       previous value)
+ * IN _free - a function to apply on the former value in case it exists
+ *       before overriding
+ *
+ * Return 1 if the value was successfully associated or 0 otherwise
+ */
+int entity_add_data(entity_t* entity, const char* key, void* value,
+		    void (*_free)(void*));
+
+/*
+ * entity_delete_data - delete the data associated with a particular key
+ *       of an entity
+ *
+ * IN entity - the entity struct to use
+ * IN key - the key the data must be deleted from
+ */
+void entity_delete_data(entity_t* entity, const char* key);
+
+/*
+ * entity_clear_data - removes all the entity key/value pairs
+ *
+ * IN entity - the entity struct to use
+ *
+ * Notes: does not free value, user is responsible for it, if the data_freefunc
+ *       is null.
+ */
+void entity_clear_data(entity_t* entity);
+
+/*
+ * entity_add_node - add a relational node to the list of nodes referring to
+ *       this entity
+ *
+ * IN entity - the entity struct to use
+ * IN layout - the layout having a node referring to this entity
+ * IN node - the node referring to it
+ *
+ * Notes: the entity does not own the memory of the relationnal nodes.
+ */
+void entity_add_node(entity_t* entity, layout_t* layout, void* node);
+
+/*
+ * entity_delete_node - remove a relational node from the list of nodes
+ *       referring to this entity
+ *
+ * IN entity - the entity struct to use
+ * IN node - the node referring to it
+ *
+ * Notes: the memory of the node data is not freed.
+ */
+void entity_delete_node(entity_t* entity, void* node);
+
+/*
+ * entity_clear_nodes - remove all the relational node from the list of nodes
+ *       referring to this entity
+ *
+ * IN entity - the entity struct to use
+ *
+ * Notes: the memory of the nodes data is not freed.
+ */
+void entity_clear_nodes(entity_t* entity);
+
+/*
+ * entity_has_node - check wether or not a relational node is in the
+ *       list of nodes referring to this entity
+ *
+ * IN entity - the entity struct to use
+ * IN node - the node to check for
+ *
+ * Return 1 if found, 0 otherwise
+ */
+int entity_has_node(entity_t* entity, void* node);
+
+/*
+ * entity_nodes_walk - iterate over the nodes referring to this entity
+ *       applying a particular callback with a particular arg. It can be
+ *       used to search, compare, and do other general operation on each nodes
+ *       associated with an entity.
+ *
+ * IN entity - the entity struct to use
+ * IN callback - the callback function to use. The first arg will receive the
+ *       layout of the node being processed, the second will be the node itself
+ *       and the third one will be the arg passed to the function.
+ * IN arg - the arg to pass to the callback function for every node.
+ */
+void entity_nodes_walk(entity_t* entity,
+		       void (*callback)(layout_t*, void*, void*),
+		       void* arg);
+
+/*
+ * entity_hashable_identify - defines a hashable identifying function to
+ *      use with xhash.
+ *
+ * Note: it currently just returns the name of the entity
+ */
+const char* entity_hashable_identify(void* item);
+
+#endif /* end of include guard: __ENTITY_GDBZJYZL_INC__ */
+
diff --git a/src/common/layout.c b/src/common/layout.c
new file mode 100644
index 0000000000000000000000000000000000000000..d4d4bb2f04b487feabc2407c62b8dda843d57f49
--- /dev/null
+++ b/src/common/layout.c
@@ -0,0 +1,110 @@
+/*****************************************************************************\
+ *  layout.c - layout data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#include "src/common/layout.h"
+#include "src/common/xstring.h"
+#include "src/common/xmalloc.h"
+
+void layout_init(layout_t* layout, const char* name, const char* type,
+		 uint32_t priority, int struct_type)
+{
+	layout->name = xstrdup(name);
+	layout->type = xstrdup(type);
+	layout->priority = priority;
+	layout->struct_type = struct_type;
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		layout->tree = (xtree_t*)xmalloc(sizeof(xtree_t));
+		xtree_init(layout->tree, NULL);
+		break;
+	}
+}
+
+void layout_free(layout_t* layout)
+{
+	xfree(layout->name);
+	xfree(layout->type);
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		xtree_free(layout->tree);
+		xfree(layout->tree);
+		break;
+	}
+}
+
+const char* layout_get_name(const layout_t* layout)
+{
+	return layout->name;
+}
+
+const char* layout_get_type(const layout_t* layout)
+{
+	return layout->type;
+}
+
+uint32_t layout_get_priority(const layout_t* layout)
+{
+	return layout->priority;
+}
+
+void layout_node_delete(layout_t* layout, void* node)
+{
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		xtree_delete(layout->tree, (xtree_node_t*)node);
+		break;
+	}
+}
+
+xtree_t* layout_get_tree(layout_t* layout)
+{
+	if (layout->struct_type == LAYOUT_STRUCT_TREE) {
+		return layout->tree;
+	}
+	fatal("layout has unknown relationnal structure type");
+	return NULL;
+}
+
+const char* layout_hashable_identify(void* item) {
+	layout_t* l = (layout_t*)item;
+	return l->name;
+}
+
+const char* layout_hashable_identify_by_type(void* item) {
+	layout_t* l = (layout_t*)item;
+	return l->type;
+}
diff --git a/src/common/layout.h b/src/common/layout.h
new file mode 100644
index 0000000000000000000000000000000000000000..1203a83a59a394da4328846121f54c86763afed1
--- /dev/null
+++ b/src/common/layout.h
@@ -0,0 +1,145 @@
+/*****************************************************************************\
+ *  layout.h - layout data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#ifndef __LAYOUT_DGR6BCQ2_INC__
+#define __LAYOUT_DGR6BCQ2_INC__
+
+#include "src/common/xtree.h"
+
+/*
+ * NOTE FOR ADDING RELATIONNAL STRUCTURES:
+ *
+ * When adding a relationnal structure you must :
+ * - add definition to layout_st
+ * - add the LAYOUT_STRUCT_RELTYPE constant
+ * and then add logics in 3 functions:
+ * - layout_init
+ * - layout_free
+ * - layout_node_delete
+ *
+ */
+#define LAYOUT_STRUCT_TREE 1
+
+typedef struct layout_st {
+	char* name;        /* the name of the layout */
+	uint32_t priority; /* the priority of the layout among the others,
+			    * might be useful for selecting resources
+			    * refining the results through a list of layouts */
+	int struct_type;   /* type of relational structure (@see entity.h) */
+	char* type;        /* the type of the layout, exp: racking, power...*/
+	union {	           /* relational structure used by the layout */
+		xtree_t* tree;
+	};
+} layout_t;
+
+/*
+ * layout_init - initialize a particular layout struct 
+ * IN layout - the layout struct to initialize
+ * IN name - the layout struct to initialize
+ * IN type - the layout struct to initialize
+ * IN priority - the layout priority value among the other layouts
+ * IN struct_type - the type of relational structure to use to connect
+ *      the entities managed by this layout (tree structure is the only
+ *      relational structure supported for now)
+ */
+void layout_init(layout_t* layout, const char* name, const char* type,
+		 uint32_t priority, int struct_type);
+
+/*
+ * layout_free - destroy a particular layout struct 
+ * IN layout - the layout struct to free
+ */
+void layout_free(layout_t* layout);
+
+/*
+ * layout_get_name - return the name of a layout
+ * IN layout - the layout struct to use
+ *
+ * Return value is the name of the layout
+ */
+const char* layout_get_name(const layout_t* layout);
+
+/*
+ * layout_get_type - return the type of a layout
+ * IN layout - the layout struct to use
+ *
+ * Return value is the type of the layout
+ */
+const char* layout_get_type(const layout_t* layout);
+
+/*
+ * layout_get_priority - return the numeric priority of a layout
+ * IN layout - the layout struct to use
+ *
+ * Return value is the priority of the layout
+ */
+uint32_t layout_get_priority(const layout_t* layout);
+
+
+/*
+ * layout_node_delete - remove a particular node from the relational
+ *      structure of the layout
+ * IN layout - the layout struct to use
+ * IN node - a (void*) pointer to the relational struct node to remove
+ */
+void layout_node_delete(layout_t* layout, void* node);
+
+
+/*
+ * layout_get_tree - get the tree relational structure associated to a layout
+ * IN layout - the layout struct to use
+ *
+ * Return value is a pointer to the xtree_t struct or NULL if not available
+ */
+xtree_t* layout_get_tree(layout_t* layout);
+
+/*
+ * layout_hashable_identify - defines a hashable identifying function to
+ *      use with xhash.
+ *
+ * Note: it currently just returns the name of the layout
+ */
+const char* layout_hashable_identify(void* item);
+
+/* layout_hashable_identify_by_type - defines a per-type hashable identifying
+ *      function to use with xhash.
+ *
+ * Note: it currently just returns the type of the layout
+ */
+const char* layout_hashable_identify_by_type(void* item);
+
+#endif /* end of include guard: __LAYOUT_DGR6BCQ2_INC__ */
diff --git a/src/common/layouts_mgr.c b/src/common/layouts_mgr.c
new file mode 100644
index 0000000000000000000000000000000000000000..95eaf5583768bbbf03aaeb502d798b628703d9b4
--- /dev/null
+++ b/src/common/layouts_mgr.c
@@ -0,0 +1,1278 @@
+/*****************************************************************************\
+ *  layouts_mgr.c - layouts manager data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#include <pthread.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+
+#include "layouts_mgr.h"
+
+#include "src/common/entity.h"
+#include "src/common/layout.h"
+
+#include "slurm/slurm.h"
+#include "slurm/slurm_errno.h"
+#include "src/common/list.h"
+#include "src/common/xtree.h"
+#include "src/common/xmalloc.h"
+#include "src/common/plugin.h"
+#include "src/common/xstring.h"
+#include "src/common/slurm_protocol_api.h"
+#include "src/common/read_config.h"
+#include "src/common/node_conf.h"
+#include "src/common/hostlist.h"
+
+#define PATHLEN 256
+
+/*****************************************************************************\
+ *                            STRUCTURES AND TYPES                           *
+\*****************************************************************************/
+
+void free(void*);
+
+/*
+ * layouts_conf_spec_t - structure used to keep track of layouts conf details
+ */
+typedef struct layouts_conf_spec_st {
+	char* whole_name;
+	char* name;
+	char* type;
+} layouts_conf_spec_t;
+
+static void layouts_conf_spec_free(void* x)
+{
+	layouts_conf_spec_t* spec = (layouts_conf_spec_t*)x;
+	xfree(spec->whole_name);
+	xfree(spec->type);
+	xfree(spec->name);
+	xfree(spec);
+}
+
+/*
+ * layout ops - operations associated to layout plugins
+ *
+ * This struct is populated while opening the plugin and linking the 
+ * associated symbols. See layout_syms description for the name of the "public"
+ * symbols associated to this structure fields.
+ *
+ * Notes : the layouts plugins are able to access the entities hashtable in order
+ * to read/create/modify entities as necessary during the load_entities and 
+ * build_layout API calls.
+ *
+ */
+typedef struct layout_ops_st {
+	layouts_plugin_spec_t*	spec;
+	int (*conf_done) (xhash_t* entities, layout_t* layout,
+			  s_p_hashtbl_t* tbl);
+	void (*entity_parsing) (entity_t* e, s_p_hashtbl_t* etbl,
+				layout_t* layout);
+} layout_ops_t;
+
+/*
+ * layout plugin symbols - must be synchronized with ops structure definition
+ *        as previously detailed, that's why though being a global constant,
+ *        it is placed in this section.
+ */
+const char *layout_syms[] = {
+	"plugin_spec",             /* holds constants, definitions, ... */
+	"layouts_p_conf_done",     /* */
+	"layouts_p_entity_parsing",
+};
+
+/*
+ * layout_plugin_t - it is the structure holding the plugin context of the
+ *        associated layout plugin as well as the ptr to the dlsymed calls.
+ *        It is used by the layouts manager to operate on the different layouts
+ *        loaded during the layouts framework initialization
+ */
+typedef struct layout_plugin_st {
+	plugin_context_t* context;
+	layout_t* layout;
+	char* name;
+	layout_ops_t* ops;
+} layout_plugin_t;
+
+static void _layout_plugins_destroy(layout_plugin_t *lp) {
+	plugin_context_destroy(lp->context);
+	/* it might be interesting to also dlclose the ops here */
+	layout_free(lp->layout);
+	xfree(lp->name);
+	xfree(lp->ops);
+	xfree(lp->layout);
+}
+/*
+ * layouts_keydef_t - entities similar keys share a same key definition
+ *       in order to avoid loosing too much memory duplicating similar data
+ *       like the key str itself and custom destroy/dump functions.
+ *
+ * The layouts manager keeps an hash table of the various keydefs and use
+ * the factorized details while parsing the configuration and creating the 
+ * entity_data_t structs associated to the entities.
+ *
+ * Note custom_* functions are used if they are not NULL* and type equals 
+ * L_T_CUSTOM
+ */
+typedef struct layouts_keydef_st {
+	char*			key; /* normalize to lower or upper case */
+	layouts_keydef_types_t	type;
+	void			(*custom_destroy)(void* value);
+	char*			(*custom_dump)(void* value);
+	layout_plugin_t*	plugin;
+} layouts_keydef_t;
+
+/*
+ * layouts_keydef_idfunc - identity function to build an hash table of
+ *        layouts_keydef_t
+ */
+static const char* layouts_keydef_idfunc(void* item)
+{
+	layouts_keydef_t* keydef = (layouts_keydef_t*)item;
+	return keydef->key;
+}
+
+/*
+ * layouts_mgr_t - the main structure holding all the layouts, entities and 
+ *        shared keydefs as well as conf elements and plugins details.
+ */
+typedef struct layouts_mgr_st {
+	pthread_mutex_t lock;
+	layout_plugin_t *plugins;
+	uint32_t plugins_count;
+	List    layouts_desc;  /* list of the layouts requested in conf */
+	xhash_t *layouts;      /* hash tbl of loaded layout structs (by type) */
+	xhash_t *entities;     /* hash tbl of loaded entity structs (by name) */
+	xhash_t *keydefs;      /* info on key types, how to free them etc */
+} layouts_mgr_t;
+
+/*****************************************************************************\
+ *                                  GLOBALS                                  *
+\*****************************************************************************/
+
+/** global structure holding layouts and entities */
+static layouts_mgr_t layouts_mgr = {PTHREAD_MUTEX_INITIALIZER};
+static layouts_mgr_t* mgr = &layouts_mgr;
+
+/*****************************************************************************\
+ *                                  HELPERS                                  *
+\*****************************************************************************/
+
+/* entities added to the layouts mgr hash table come from the heap,
+ * this funciton will help to free them while freeing the hash table */
+static void _entity_free(void* item)
+{
+	entity_t* entity = (entity_t*) item;
+	entity_free(entity);
+	xfree(entity);
+}
+
+/* layouts added to the layouts mgr hash table come from the heap,
+ * this funciton will help to free them while freeing the hash table */
+static void _layout_free(void* item)
+{
+	layout_t* layout = (layout_t*) item;
+	layout_free(layout);
+	xfree(layout);
+}
+
+/* keydef added to the layouts mgr hash table come from the heap,
+ * this funciton will help to free them while freeing the hash table */
+static void _layouts_keydef_free(void* x)
+{
+	layouts_keydef_t* keydef = (layouts_keydef_t*)x;
+	xfree(keydef->key);
+	xfree(keydef);
+}
+
+/* generic xfree callback */
+static void xfree_as_callback(void* p)
+{
+	xfree(p);
+}
+
+/* safer behavior than plain strncat */
+static char* _cat(char* dest, const char* src, size_t n)
+{
+	size_t len;
+	char* r;
+	if (n == 0) return dest;
+	len = strlen(dest);
+	if (n - len - 1 <= 0) {
+		dest[n - 1] = 0;
+		return dest;
+	}
+	r = strncat(dest, src, n - len - 1);
+	dest[n - 1] = 0;
+	return r;
+}
+
+/* safer behavior than plain strncpy */
+static char* _cpy(char* dest, const char* src, size_t n)
+{
+	char* r;
+	if (n == 0) return dest;
+	r = strncpy(dest, src, n - 1);
+	dest[n - 1] = 0;
+	return r;
+}
+
+static char* trim(char* str)
+{
+	char* str_modifier;
+	if (!str) return str;
+	while (*str && isspace(*str)) ++str;
+	str_modifier = str + strlen(str) - 1;
+	while (str_modifier >= str && isspace(*str_modifier)) {
+		*str_modifier = '\0';
+		--str_modifier;
+	}
+	return str;
+}
+
+/* check if str is in strings (null terminated string array) */
+/* TODO: replace this with a xhash instead for next modification */
+static int _string_in_array(const char* str, const char** strings)
+{
+	xassert(strings); /* if etypes no specified in plugin, no new entity
+			     should be created */
+	for (; *strings; ++strings) {
+		if (!strcmp(str, *strings))
+			return 1;
+	}
+	return 0;
+}
+
+static void _normalize_keydef_keycore(char* buffer, uint32_t size,
+				      const char* key, const char* plugtype,
+				      bool cat)
+{
+	int i;
+	char keytmp[PATHLEN];
+
+	for (i = 0; plugtype[i] && i < PATHLEN - 1; ++i) {
+		keytmp[i] = tolower(plugtype[i]);
+	}
+	keytmp[i] = 0;
+	if (cat) {
+		_cat(buffer, keytmp, size);
+	} else {
+		_cpy(buffer, keytmp, size);
+	}
+	_cat(buffer, ".", size);
+	for (i = 0; key[i] && i < PATHLEN - 1; ++i) {
+		keytmp[i] = tolower(key[i]);
+	}
+	keytmp[i] = 0;
+	_cat(buffer, keytmp, size);
+}
+
+static void _normalize_keydef_key(char* buffer, uint32_t size,
+				  const char* key, const char* plugtype)
+{
+	_normalize_keydef_keycore(buffer, size, key, plugtype, false);
+}
+
+static void _normalize_keydef_mgrkey(char* buffer, uint32_t size,
+				     const char* key, const char* plugtype)
+{
+	_cpy(buffer, "mgr.", size);
+	_normalize_keydef_keycore(buffer, size, key, plugtype, true);
+}
+
+static void _entity_add_data(entity_t* e, const char* key, void* data)
+{
+	int rc;
+	layouts_keydef_t* hkey = xhash_get(mgr->keydefs, key);
+	xassert(hkey);
+	void (*freefunc)(void* p) = xfree_as_callback;
+	if (hkey->type == L_T_CUSTOM) {
+		freefunc = hkey->custom_destroy;
+	}
+	rc = entity_add_data(e, hkey->key, data, freefunc);
+	xassert(rc);
+}
+
+/*****************************************************************************\
+ *                                MANAGER INIT                               *
+\*****************************************************************************/
+
+static void _slurm_layouts_init_keydef(xhash_t* keydefs,
+				       const layouts_keyspec_t* plugin_keyspec,
+				       layout_plugin_t* plugin)
+{
+	char keytmp[PATHLEN];
+
+	const layouts_keyspec_t* current;
+	layouts_keydef_t* nkeydef;
+
+	/* A layout plugin may have no data to store to entities but still
+	 * being valid. */
+	if (!plugin_keyspec)
+		return;
+
+	/* iterate over the keys of the plugin */
+	for (current = plugin_keyspec; current->key; ++current) {
+		/* if not end of list, a keyspec key is mandatory */
+		_normalize_keydef_key(keytmp, PATHLEN, current->key,
+				      plugin->layout->type);
+		xassert(xhash_get(keydefs, keytmp) == NULL);
+		nkeydef = (layouts_keydef_t*)
+			xmalloc(sizeof(layouts_keydef_t));
+		nkeydef->key = xstrdup(keytmp);
+		nkeydef->type = current->type;
+		nkeydef->custom_destroy = current->custom_destroy;
+		nkeydef->custom_dump = current->custom_dump;
+		nkeydef->plugin = plugin;
+		xhash_add(keydefs, nkeydef);
+	}
+
+	/* then add keys managed by the layouts_mgr directly */
+	switch(plugin->layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		_normalize_keydef_mgrkey(keytmp, PATHLEN, "enclosed",
+					 plugin->layout->type);
+		xassert(xhash_get(keydefs, keytmp) == NULL);
+		nkeydef = (layouts_keydef_t*)
+			xmalloc(sizeof(layouts_keydef_t));
+		nkeydef->key = xstrdup(keytmp);
+		nkeydef->type = L_T_STRING;
+		nkeydef->plugin = plugin;
+		xhash_add(keydefs, nkeydef);
+		break;
+	}
+}
+
+static int _slurm_layouts_init_layouts_walk_helper(void* x, void* arg)
+{
+	layouts_conf_spec_t* spec = (layouts_conf_spec_t*)x;
+	int* i = (int*)arg;
+	layout_plugin_t* plugin = &mgr->plugins[*i];
+	const char* plugin_type = "layouts";
+	char plugin_name[PATHLEN];
+	void* inserted_item;
+	plugin_context_t* plugin_context;
+	snprintf(plugin_name, PATHLEN,
+		 "layouts/%s_%s", spec->type, spec->name);
+	plugin->ops = (layout_ops_t*)xmalloc(sizeof(layout_ops_t));
+	debug2("layouts: loading %s...", spec->whole_name);
+	plugin->context = plugin_context = plugin_context_create(
+		plugin_type,
+		plugin_name,
+		(void**)plugin->ops,
+		layout_syms,
+		sizeof(layout_syms));
+	if (!plugin_context) {
+		error("layouts: error loading %s.", plugin_name);
+		return SLURM_ERROR;
+	}
+	if (!plugin->ops->spec) {
+		error("layouts: plugin_spec must be valid (%s plugin).",
+		      plugin_name);
+		return SLURM_ERROR;
+
+	}
+	plugin->name = xstrdup(spec->whole_name);
+	plugin->layout = (layout_t*)xmalloc(sizeof(layout_t));
+	layout_init(plugin->layout, spec->name, spec->type, 0,
+		    plugin->ops->spec->struct_type);
+	inserted_item = xhash_add(mgr->layouts, plugin->layout);
+	xassert(inserted_item == plugin->layout);
+	_slurm_layouts_init_keydef(mgr->keydefs,
+				   plugin->ops->spec->keyspec,
+				   plugin);
+	++*i;
+	return SLURM_SUCCESS;
+}
+
+static void _layouts_mgr_parse_global_conf(layouts_mgr_t* mgr)
+{
+	char* layouts;
+	char* parser;
+	char* saveptr;
+	char* slash;
+	layouts_conf_spec_t* nspec;
+
+	mgr->layouts_desc = list_create(layouts_conf_spec_free);
+	layouts = slurm_get_layouts();
+	parser = strtok_r(layouts, ",", &saveptr);
+	while (parser) {
+		nspec = (layouts_conf_spec_t*)xmalloc(
+			sizeof(layouts_conf_spec_t));
+		nspec->whole_name = xstrdup(trim(parser));
+		slash = strchr(parser, '/');
+		if (slash) {
+			*slash = 0;
+			nspec->type = xstrdup(trim(parser));
+			nspec->name = xstrdup(trim(slash+1));
+		} else {
+			nspec->type = xstrdup(trim(parser));
+			nspec->name = xstrdup("default");
+		}
+		list_append(mgr->layouts_desc, nspec);
+		parser = strtok_r(NULL, ",", &saveptr);
+	}
+	xfree(layouts);
+}
+
+static void layouts_mgr_init(layouts_mgr_t* mgr)
+{
+	_layouts_mgr_parse_global_conf(mgr);
+
+	mgr->layouts = xhash_init(layout_hashable_identify_by_type,
+				  (xhash_freefunc_t)_layout_free, NULL, 0);
+	mgr->entities = xhash_init(entity_hashable_identify,
+				   (xhash_freefunc_t)_entity_free, NULL, 0);
+	mgr->keydefs = xhash_init(layouts_keydef_idfunc,
+				  _layouts_keydef_free, NULL, 0);
+}
+
+static void layouts_mgr_free(layouts_mgr_t* mgr)
+{
+	/* free the configuration details */
+	list_destroy(mgr->layouts_desc);
+
+	/* FIXME: can we do a faster free here ? since each node removal will
+	 * modify either the entities or layouts for back (or forward)
+	 * references. */
+	xhash_free(mgr->layouts);
+	xhash_free(mgr->entities);
+	xhash_free(mgr->keydefs);
+}
+
+/*****************************************************************************\
+ *                               CONFIGURATION                               *
+\*****************************************************************************/
+
+static char* _conf_get_filename(const char* type)
+{
+	char path[PATHLEN];
+	char* final_path;
+	_cpy(path, "layouts.d/", PATHLEN);
+	_cat(path, type, PATHLEN);
+	_cat(path, ".conf", PATHLEN);
+	final_path = get_extra_conf_path(path);
+	return final_path;
+}
+
+static s_p_hashtbl_t* _conf_make_hashtbl(int struct_type,
+					 const s_p_options_t* layout_options)
+{
+	s_p_hashtbl_t* tbl = NULL;
+	s_p_hashtbl_t* tbl_relational = NULL;
+	s_p_hashtbl_t* tbl_layout = NULL;
+	s_p_options_t* relational_options = NULL;
+
+	/* generic line option */
+	static s_p_options_t global_options_entity[] = {
+		{"Entity", S_P_STRING},
+		{"Type", S_P_STRING},
+		{NULL}
+	};
+	static s_p_options_t global_options[] = {
+		{"Priority", S_P_UINT32},
+		{"Entity", S_P_EXPLINE, NULL, NULL, global_options_entity},
+		{NULL}
+	};
+
+	/* available for constructing a tree */
+	static s_p_options_t tree_options_entity[] = {
+		{"Enclosed", S_P_PLAIN_STRING},
+		{NULL}
+	};
+	static s_p_options_t tree_options[] = {
+		{"Root", S_P_STRING},
+		{"Entity", S_P_EXPLINE, NULL, NULL, tree_options_entity},
+		{NULL}
+	};
+
+	xassert(layout_options);
+
+	switch(struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		relational_options = tree_options;
+		break;
+	default:
+		fatal("layouts: does not know what relation structure to"
+		      "use.");
+	}
+
+	tbl = s_p_hashtbl_create(global_options);
+	tbl_relational = s_p_hashtbl_create(relational_options);
+	tbl_layout = s_p_hashtbl_create(layout_options);
+
+	s_p_hashtbl_merge_keys(tbl, tbl_relational);
+	s_p_hashtbl_merge_keys(tbl, tbl_layout);
+
+	s_p_hashtbl_destroy(tbl_relational);
+	s_p_hashtbl_destroy(tbl_layout);
+
+	return tbl;
+}
+
+#define _layouts_load_merge(type_t, s_p_get_type) { \
+	type_t newvalue; \
+	type_t** oldvalue; \
+	if (!s_p_get_type(&newvalue, option_key, etbl)) { \
+		/* no value to merge/create */ \
+		continue; \
+	} \
+	oldvalue = (type_t**)entity_get_data(e, key_keydef); \
+	if (oldvalue) { \
+		**oldvalue = newvalue; \
+	} else { \
+		type_t* newalloc = (type_t*)xmalloc(sizeof(type_t)); \
+		*newalloc = newvalue; \
+		_entity_add_data(e, key_keydef, newalloc); \
+	} \
+}
+
+#define _layouts_merge_check(type1, type2) \
+	(entity_option->type == type1 && keydef->type == type2)
+
+static void _layouts_load_automerge(layout_plugin_t* plugin, entity_t* e,
+		s_p_hashtbl_t* etbl)
+{
+	const s_p_options_t* layout_option;
+	const s_p_options_t* entity_option;
+	layouts_keydef_t* keydef;
+	char key_keydef[PATHLEN];
+	char* option_key;
+
+	for (layout_option = plugin->ops->spec->options;
+		layout_option && strcasecmp("Entity", layout_option->key);
+		++layout_option);
+	xassert(layout_option);
+
+	for (entity_option = layout_option->line_options;
+			entity_option->key;
+			++entity_option) {
+		option_key = entity_option->key;
+		_normalize_keydef_key(key_keydef, PATHLEN, option_key,
+				plugin->layout->type);
+		keydef = xhash_get(mgr->keydefs, key_keydef);
+		if (!keydef) {
+			/* key is not meant to be automatically handled,
+			 * ignore it for this function */
+			continue;
+		}
+		if (_layouts_merge_check(S_P_LONG, L_T_LONG)) {
+			_layouts_load_merge(long, s_p_get_long);
+		} else if (_layouts_merge_check(S_P_UINT16, L_T_UINT16)) {
+			_layouts_load_merge(uint16_t, s_p_get_uint16);
+		} else if (_layouts_merge_check(S_P_UINT32, L_T_UINT32)) {
+			_layouts_load_merge(uint32_t, s_p_get_uint32);
+		} else if (_layouts_merge_check(S_P_BOOLEAN, L_T_BOOLEAN)) {
+			_layouts_load_merge(bool, s_p_get_boolean);
+		} else if (_layouts_merge_check(S_P_LONG, L_T_LONG)) {
+			_layouts_load_merge(long, s_p_get_long);
+		} else if (_layouts_merge_check(S_P_STRING, L_T_STRING)) {
+			char* newvalue;
+			if (s_p_get_string(&newvalue, option_key, etbl)) {
+				_entity_add_data(e, key_keydef, newvalue);
+			}
+		}
+	}
+}
+
+/* extract Enlosed= attributes providing the relational structures info */
+static void _layouts_parse_relations(layout_plugin_t* plugin, entity_t* e,
+				     s_p_hashtbl_t* entity_tbl)
+{
+	char* e_enclosed;
+	char** e_already_enclosed;
+	char key[PATHLEN];
+	switch(plugin->layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		if (s_p_get_string(&e_enclosed, "Enclosed", entity_tbl)) {
+			_normalize_keydef_mgrkey(key, PATHLEN, "enclosed",
+					plugin->layout->type);
+			e_already_enclosed = (char**)entity_get_data(e, key);
+			if (e_already_enclosed) {
+				/* FC expressed warnings about that section,
+				 * should be checked more */
+				*e_already_enclosed = xrealloc(
+						*e_already_enclosed,
+						strlen(*e_already_enclosed) +
+						strlen(e_enclosed) + 2);
+				strcat(*e_already_enclosed, ",");
+				strcat(*e_already_enclosed, e_enclosed);
+				xfree(e_enclosed);
+			} else {
+				_entity_add_data(e, key, e_enclosed);
+			}
+		}
+		break;
+	}
+}
+
+static int _layouts_read_config_post(layout_plugin_t* plugin,
+		s_p_hashtbl_t* tbl)
+{
+	char* root_nodename;
+	entity_t* e;
+	xtree_node_t* root_node,* inserted_node;
+	xtree_t* tree;
+	switch(plugin->layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		tree = layout_get_tree(plugin->layout);
+		xassert(tree);
+		if (!s_p_get_string(&root_nodename, "Root", tbl)) {
+			error("layouts: unable to construct the layout tree, "
+			      "no root node specified");
+			xfree(root_nodename);
+			return SLURM_ERROR;
+		}
+		e = xhash_get(mgr->entities, trim(root_nodename));
+		if (!e) {
+			error("layouts: unable to find specified root "
+			      "entity `%s'", trim(root_nodename));
+			xfree(root_nodename);
+			return SLURM_ERROR;
+		}
+		xfree(root_nodename);
+		root_node = xtree_add_child(tree, NULL, e, XTREE_APPEND);
+		xassert(root_node);
+		inserted_node = list_append(e->nodes, root_node);
+		xassert(inserted_node == root_node);
+		break;
+	}
+	return SLURM_SUCCESS;
+}
+
+/*
+ * _layouts_read_config - called after base entities are loaded successfully
+ *
+ * This function is the stage 1 of the layouts loading stage, where we collect
+ * info on all the entities and store them in a global hash table.
+ * Entities that do not already exist are created, otherwise updated.
+ *
+ * Information concerning the relations among entities provided by the
+ * 'Enclosed' conf pragma are also extracted here for further usage in stage 2.
+ *
+ * When layout plugins callbacks are called, relational structures among
+ * entities are not yet built.
+ */
+static int _layouts_read_config(layout_plugin_t* plugin)
+{
+	s_p_hashtbl_t* tbl = NULL;
+	s_p_hashtbl_t** entities_tbl = NULL;
+	s_p_hashtbl_t* entity_tbl = NULL;
+	int entities_tbl_count = 0, i;
+	int rc = SLURM_ERROR;
+	char* filename = NULL;
+
+	uint32_t l_priority;
+
+	entity_t* e;
+	char* e_name = NULL;
+	char* e_type = NULL;
+
+	if (!plugin->ops->spec->options) {
+		/* no option in this layout plugin, nothing to parse */
+		return SLURM_SUCCESS;
+	}
+
+	tbl = _conf_make_hashtbl(plugin->layout->struct_type,
+				 plugin->ops->spec->options);
+	filename = _conf_get_filename(plugin->layout->type);
+	if (!filename) {
+		fatal("layouts: cannot find configuration file for "
+		      "required layout '%s'", plugin->name);
+	}
+	if (s_p_parse_file(tbl, NULL, filename, false) == SLURM_ERROR) {
+		fatal("layouts: something went wrong when opening/reading "
+		      "'%s': %m", filename);
+	}
+	debug3("layouts: configuration file '%s' is loaded", filename);
+
+	if (s_p_get_uint32(&l_priority, "Priority", tbl)) {
+		plugin->layout->priority = l_priority;
+	}
+
+	/* get the config hash tables of the defined entities */
+	if (!s_p_get_expline(&entities_tbl, &entities_tbl_count,
+				"Entity", tbl)) {
+		error("layouts: no valid Entity found, can not append any "
+		      "information nor construct relations for %s/%s",
+		      plugin->layout->type, plugin->layout->name);
+		goto cleanup;
+	}
+
+	/* stage 1: create the described entities or update them */
+	for (i = 0; i < entities_tbl_count; ++i) {
+		entity_tbl = entities_tbl[i];
+		xfree(e_name);
+		xfree(e_type);
+		if (!s_p_get_string(&e_name, "Entity", entity_tbl)) {
+			error("layouts: no name associated to entity[%d], "
+			      "skipping...", i);
+			continue;
+		}
+		
+		/* look for the entity in the entities hash table*/
+		e = xhash_get(mgr->entities, e_name);
+		if (!e) {
+			/* if the entity does not already exists, create it */
+			if (!s_p_get_string(&e_type, "Type", entity_tbl)) {
+				error("layouts: entity '%s' does not already "
+				      "exists and no type was specified, "
+				      "skipping", e_name);
+				continue;
+			}
+			if (!_string_in_array(e_type,
+					      plugin->ops->spec->etypes)) {
+				error("layouts: entity '%s' type (%s) is "
+				      "invalid, skipping", e_name, e_type);
+				continue;
+			}
+
+			e = (entity_t*)xmalloc(sizeof(entity_t));
+			entity_init(e, e_name, e_type);
+			xhash_add(mgr->entities, e);
+
+		} else if (s_p_get_string(&e_type, "Type", entity_tbl)) {
+			/* if defined, check that the type is consistent */
+			if (!_string_in_array(e_type,
+					      plugin->ops->spec->etypes)) {
+				error("layouts: entity '%s' type (%s) is "
+				      "invalid, skipping", e_name, e_type);
+				continue;
+			}
+			if (!strcmp(e_type, e->type)) {
+				error("layouts: entity '%s' type (%s) differs "
+				      "from already registered entity type (%s)"
+				      "skipping", e_name, e_type, e->type);
+				continue;
+			}
+		}
+
+		/* look for "Enclosed" pragmas identifying the relations
+		 * among entities and kep that along with the entity for
+		 * stage 2 */
+		_layouts_parse_relations(plugin, e, entity_tbl);
+
+		/*
+		 * if the layout plugin requests automerge, try to automatically
+		 * parse the conf hash table using the s_p_option_t description
+		 * of the plugin, creating the key/vlaue with the right value
+		 * type and adding them to the entity key hash table.
+		 */
+		if (plugin->ops->spec->automerge) {
+			_layouts_load_automerge(plugin, e, entity_tbl);
+		}
+
+		/*
+		 * in case the automerge was not sufficient, the layout parsing
+		 * callback is called for further actions.
+		 */
+		if (plugin->ops->entity_parsing) {
+			plugin->ops->entity_parsing(e, entity_tbl,
+						    plugin->layout);
+		}
+	}
+
+	/* post-read-and-build (post stage 1)
+	 * ensure that a Root entity was defined and set it as the root of
+	 * the relational structure of the layout.
+	 * fails in case of error as a root is mandatory to walk the relational
+	 * structure of the layout */
+	if (_layouts_read_config_post(plugin, tbl) != SLURM_SUCCESS) {
+		goto cleanup;
+	}
+
+	/*
+	 * call the layout plugin conf_done callback for further
+	 * layout specific actions.
+	 */
+	if (plugin->ops->conf_done) {
+		if (!plugin->ops->conf_done(mgr->entities, plugin->layout,
+					    tbl)) {
+			error("layouts: plugin %s/%s has an error parsing its"
+			      " configuration", plugin->layout->type,
+			      plugin->layout->name);
+			goto cleanup;
+		}
+	}
+	
+	rc = SLURM_SUCCESS;
+
+cleanup:
+	s_p_hashtbl_destroy(tbl);
+	xfree(filename);
+
+	return rc;
+}
+
+typedef struct _layouts_build_xtree_walk_st {
+	char* enclosed_key;
+	xtree_t* tree;
+} _layouts_build_xtree_walk_t;
+
+uint8_t _layouts_build_xtree_walk(xtree_node_t* node,
+					 uint8_t which,
+					 uint32_t level,
+					 void* arg)
+{
+	_layouts_build_xtree_walk_t* p = (_layouts_build_xtree_walk_t*)arg;
+	entity_t* e;
+	char** enclosed_str;
+	char* enclosed_name;
+	hostlist_t enclosed_hostlist;
+	entity_t* enclosed_e;
+	xtree_node_t* enclosed_node,* inserted_node;
+
+	xassert(arg);
+
+	e = xtree_node_get_data(node);
+	xassert(e);
+
+	/*
+	 * FIXME: something goes wrong with the order...
+	 * after a first growing, the first new child is called with preorder.
+	 *
+	 * for now, testing each time and use enclosed_str to know if it has
+	 * been processed.
+	 */
+	if (which != XTREE_GROWING && which != XTREE_PREORDER)
+		return 1;
+
+	enclosed_str = (char**)entity_get_data(e, p->enclosed_key);
+
+	if (enclosed_str) {
+		enclosed_hostlist = hostlist_create(*enclosed_str);
+		xfree(*enclosed_str);
+		entity_delete_data(e, p->enclosed_key);
+		while ((enclosed_name = hostlist_shift(enclosed_hostlist))) {
+			enclosed_e = xhash_get(mgr->entities, enclosed_name);
+			if (!enclosed_e) {
+				error("layouts: entity '%s' specified in "
+				      "enclosed entities of entity '%s' "
+				      "not found, ignoring.",
+				      enclosed_name, e->name);
+				free(enclosed_name);
+				continue;
+			}
+			free(enclosed_name);
+			enclosed_node = xtree_add_child(p->tree, node,
+							enclosed_e, 
+							XTREE_APPEND);
+			xassert(enclosed_node);
+			inserted_node = list_append(enclosed_e->nodes,
+						    enclosed_node);
+			xassert(inserted_node == enclosed_node);
+		}
+		hostlist_destroy(enclosed_hostlist);
+	}
+
+	return 1;
+}
+
+/*
+ * _layouts_build_relations - called after _layouts_read_config to create the
+ *        relational structure of the layout according to the topological
+ *        details parsed in stage 1. This is the stage 2 of the layouts
+ *        configuration load.
+ *
+ * This function is the stage 2 of the layouts loading stage, where we use
+ * the relational details extracted from the parsing stage (Enclosed pragmas
+ * and Root entity) to build the relational structure of the layout.
+ *
+ */
+static int _layouts_build_relations(layout_plugin_t* plugin)
+{
+	xtree_t* tree;
+	xtree_node_t* root_node;
+	char key[PATHLEN];
+	switch(plugin->layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		tree = layout_get_tree(plugin->layout);
+		xassert(tree);
+		root_node = xtree_get_root(tree);
+		_normalize_keydef_mgrkey(key, PATHLEN, "enclosed",
+					 plugin->layout->type);
+		_layouts_build_xtree_walk_t p = {
+			key,
+			tree
+		};
+		xtree_walk(tree,
+			   root_node,
+			   0,
+			   XTREE_LEVEL_MAX,
+			   _layouts_build_xtree_walk,
+			   &p);
+		break;
+	}
+	return SLURM_SUCCESS;
+}
+
+/*
+ * For debug purposes, dump functions helping to print the layout mgr
+ * internal states in a file after the load.
+ */
+#if 0
+static char* _dump_data_key(layouts_keydef_t* keydef, void* value)
+{
+	char val;
+	if (!keydef) {
+		return xstrdup("ERROR_bad_keydef");
+	}
+	switch(keydef->type) {
+	case L_T_ERROR:
+		return xstrdup("ERROR_keytype!");
+	case L_T_STRING:
+		return xstrdup((char*)value);
+	case L_T_LONG:
+		return xstrdup_printf("%ld", *(long*)value);
+	case L_T_UINT16:
+		return xstrdup_printf("%u", *(uint16_t*)value);
+	case L_T_UINT32:
+		return xstrdup_printf("%ul", *(uint32_t*)value);
+	case L_T_BOOLEAN:
+		val = *(bool*)value;
+		return xstrdup_printf("%s", val ? "true" : "false");
+	case L_T_FLOAT:
+		return xstrdup_printf("%f", *(float*)value);
+	case L_T_DOUBLE:
+		return xstrdup_printf("%f", *(double*)value);
+	case L_T_LONG_DOUBLE:
+		return xstrdup_printf("%Lf", *(long double*)value);
+	case L_T_CUSTOM:
+		if (keydef->custom_dump) {
+			return keydef->custom_dump(value);
+		}
+		return xstrdup_printf("custom_ptr(%p)", value);
+	}
+	return NULL;
+}
+
+static void _dump_entity_data(void* item, void* arg)
+{
+	entity_data_t* data = (entity_data_t*)item;
+	FILE* fdump = (FILE*)arg;
+	layouts_keydef_t* keydef;
+	char* data_dump;
+
+	xassert(data);
+	keydef = xhash_get(mgr->keydefs, data->key);
+	xassert(keydef);
+	data_dump = _dump_data_key(keydef, data->value);
+
+	fprintf(fdump, "data %s (type: %d): %s\n",
+		data->key, keydef->type, data_dump);
+
+	xfree(data_dump);
+}
+
+static void _dump_entities(void* item, void* arg)
+{
+	entity_t* entity = (entity_t*)item;
+	FILE* fdump = (FILE*)arg;
+	fprintf(fdump, "-- entity %s --\n", entity->name);
+	fprintf(fdump, "type: %s\nnode count: %d\nptr: %p\n",
+		entity->type, list_count(entity->nodes), entity->ptr);
+	xhash_walk(entity->data, _dump_entity_data, fdump);
+}
+
+static uint8_t _dump_layout_tree(xtree_node_t* node, uint8_t which,
+				 uint32_t level, void* arg)
+{
+	FILE* fdump = (FILE*)arg;
+	entity_t* e;
+	if (which != XTREE_PREORDER && which != XTREE_LEAF) {
+		return 1;
+	}
+	e = xtree_node_get_data(node);
+	if (!e) {
+		fprintf(fdump, "NULL_entity\n");
+	}
+	else {
+		fprintf(fdump, "%*s%s\n", level, " ", e->name);
+	}
+	return 1;
+}
+
+static void _dump_layouts(void* item, void* arg)
+{
+	layout_t* layout = (layout_t*)item;
+	FILE* fdump = (FILE*)arg;
+	fprintf(fdump, "-- layout %s --\n"
+		"type: %s\n"
+		"priority: %u\n"
+		"struct_type: %d\n"
+		"relational ptr: %p\n",
+		layout->name,
+		layout->type,
+		layout->priority,
+		layout->struct_type,
+		layout->tree);
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		fprintf(fdump, "struct_type(string): tree, count: %d\n"
+			"entities list:\n",
+			xtree_get_count(layout->tree));
+		xtree_walk(layout->tree, NULL, 0, XTREE_LEVEL_MAX,
+			   _dump_layout_tree, fdump);
+		break;
+	}
+}
+#endif
+
+/*****************************************************************************\
+ *                             SLURM LAYOUTS API                             *
+\*****************************************************************************/
+
+int slurm_layouts_init()
+{
+	int i = 0;
+	uint32_t layouts_count;
+
+	debug3("layouts: slurm_layouts_init()...");
+
+	if (mgr->plugins) {
+		return SLURM_SUCCESS;
+	}
+
+	slurm_mutex_lock(&layouts_mgr.lock);
+
+	layouts_mgr_init(&layouts_mgr);
+	layouts_count = list_count(layouts_mgr.layouts_desc);
+	if (layouts_count == 0)
+		info("layouts: no layout to initialize");
+	else
+		info("layouts: %d layout(s) to initialize", layouts_count);
+
+	mgr->plugins = xmalloc(sizeof(layout_plugin_t) * layouts_count);
+	list_for_each(layouts_mgr.layouts_desc,
+			_slurm_layouts_init_layouts_walk_helper,
+			&i);
+	mgr->plugins_count = i;
+
+	if (mgr->plugins_count != layouts_count) {
+		error("layouts: only %d/%d layouts loaded, aborting...",
+		      mgr->plugins_count, layouts_count);
+		for (i = 0; i < mgr->plugins_count; i++) {
+			_layout_plugins_destroy(&mgr->plugins[i]);
+		}
+		xfree(mgr->plugins);
+		mgr->plugins = NULL;
+	} else if (layouts_count > 0) {
+		info("layouts: slurm_layouts_init done : %d layout(s) "
+		     "initialized", layouts_count);
+	}
+
+	slurm_mutex_unlock(&layouts_mgr.lock);
+
+	return mgr->plugins_count == layouts_count ?
+		SLURM_SUCCESS : SLURM_ERROR;
+}
+
+int slurm_layouts_fini()
+{
+	int i;
+
+	debug3("layouts: slurm_layouts_fini()...");
+
+	slurm_mutex_lock(&mgr->lock);
+
+	for (i = 0; i < mgr->plugins_count; i++) {
+		_layout_plugins_destroy(&mgr->plugins[i]);
+	}
+	xfree(mgr->plugins);
+	mgr->plugins = NULL;
+
+	layouts_mgr_free(mgr);
+
+	slurm_mutex_unlock(&mgr->lock);
+
+	info("layouts: all layouts are now unloaded.");
+
+	return SLURM_SUCCESS;
+}
+
+int slurm_layouts_load_config()
+{
+	int i, rc, inx;
+	struct node_record *node_ptr;
+	layout_t *layout;
+	uint32_t layouts_count;
+	entity_t *entity;
+	void *ptr;
+
+	info("layouts: loading entities/relations information");
+	rc = SLURM_SUCCESS;
+
+	slurm_mutex_lock(&mgr->lock);
+
+	/*
+	 * create a base layout to contain the configured nodes
+	 * Notes : it might be moved to its own external layout in the
+	 * slurm source layouts directory.
+	 */
+	layout = (layout_t*) xmalloc(sizeof(layout_t));
+	layout_init(layout, "slurm", "base", 0, LAYOUT_STRUCT_TREE);
+	if (xtree_add_child(layout->tree, NULL, NULL, XTREE_APPEND) == NULL) {
+		error("layouts: unable to create base layout tree root"
+		      ", aborting");
+		goto exit;
+	}
+
+	/*
+	 * generate and store the slurm node entities,
+	 * add them to the base layout at the same time
+	 */
+	for (inx = 0, node_ptr = node_record_table_ptr; inx < node_record_count;
+	     inx++, node_ptr++) {
+		xassert (node_ptr->magic == NODE_MAGIC);
+		xassert (node_ptr->config_ptr->magic == CONFIG_MAGIC);
+		debug("layouts: loading node %s",node_ptr->name);
+
+		/* init entity structure on the heap */
+		entity = (entity_t*) xmalloc(sizeof(struct entity_st));
+		entity_init(entity, node_ptr->name, 0); 
+		entity->ptr = node_ptr;
+
+		/* add to mgr entity hashtable */
+		if (xhash_add(layouts_mgr.entities,(void*)entity) == NULL) {
+			error("layouts: unable to add entity of node %s"
+			      "in the hashtable, aborting", node_ptr->name);
+			entity_free(entity);
+			xfree(entity);
+			rc = SLURM_ERROR;
+			break;
+		}
+
+		/* add to the base layout (storing a callback ref to the
+		   layout node pointing to it) */
+		ptr = xtree_add_child(layout->tree, layout->tree->root,
+				      (void*)entity, XTREE_APPEND);
+		if (!ptr) {
+			error("layouts: unable to add entity of node %s"
+			      "in the hashtable, aborting", node_ptr->name);
+			entity_free(entity);
+			xfree(entity);
+			rc = SLURM_ERROR;
+			break;
+		} else
+			entity_add_node(entity, layout, ptr);
+
+	}
+	debug("layouts: %d/%d nodes in hash table, rc=%d", 
+	      xhash_count(layouts_mgr.entities), node_record_count, rc);
+
+	if (rc != SLURM_SUCCESS)
+		goto exit;
+
+	/* add the base layout to the layouts manager dedicated hashtable */
+	if (xhash_add(layouts_mgr.layouts, (void*)layout) == NULL) {
+		error("layouts: unable to add base layout into the hashtable");
+		layout_free(layout);
+		rc = SLURM_ERROR;
+	}
+
+	/* check that we get as many layouts as initiliazed plugins
+	 * as layouts are added and referenced by type.
+	 * do +1 in the operation as the base layout is currently managed
+	 * separately.
+	 * If this base layout is moved to a dedicated plugin and automatically
+	 * added to the mgr layouts_desc at init, the +1 will have to be
+	 * removed here as it will be counted as the other plugins in the sum
+	 */
+	layouts_count = xhash_count(layouts_mgr.layouts);
+	if ( layouts_count != mgr->plugins_count + 1) {
+		error("layouts: %d/%d layouts added to hashtable, aborting",
+		      layouts_count,mgr->plugins_count+1);
+		rc = SLURM_ERROR;
+	}
+
+exit:
+	if (rc != SLURM_SUCCESS) {
+		layout_free(layout);
+		xfree(layout);
+	} else {
+		debug("layouts: loading stage 1");
+		for (i = 0; i < mgr->plugins_count; ++i) {
+			debug3("layouts: reading config for %s",
+			       mgr->plugins[i].name);
+			if (_layouts_read_config(&mgr->plugins[i]) !=
+			    SLURM_SUCCESS) {
+				rc = SLURM_ERROR;
+				break;
+			}
+		}
+		debug("layouts: loading stage 2");
+		for (i = 0; i < mgr->plugins_count; ++i) {
+			debug3("layouts: creating relations for %s",
+			       mgr->plugins[i].name);
+			if (_layouts_build_relations(&mgr->plugins[i]) !=
+			    SLURM_SUCCESS) {
+				rc = SLURM_ERROR;
+				break;
+			}
+		}
+	}
+
+/*
+ * For debug purposes, print the layout mgr internal states
+ * in a file after the load.
+ */
+#if 0
+	/* temporary section to test layouts */
+	FILE* fdump = fopen("/tmp/slurm-layouts-dump.txt", "wb");
+
+	xhash_walk(mgr->entities, _dump_entities, fdump);
+	xhash_walk(mgr->layouts,  _dump_layouts,  fdump);
+
+	if (fdump)
+		fclose(fdump);
+#endif
+
+	slurm_mutex_unlock(&mgr->lock);
+
+	return rc;
+}
+
+layout_t* slurm_layouts_get_layout(const char* type)
+{
+	layout_t* layout = (layout_t*)xhash_get(mgr->layouts, type);
+	return layout;
+}
+
+entity_t* slurm_layouts_get_entity(const char* name)
+{
+	entity_t* e = (entity_t*)xhash_get(mgr->entities, name);
+	return e;
+}
diff --git a/src/common/layouts_mgr.h b/src/common/layouts_mgr.h
new file mode 100644
index 0000000000000000000000000000000000000000..51d997e3bbed2cab2de9e861ea6f09772c056860
--- /dev/null
+++ b/src/common/layouts_mgr.h
@@ -0,0 +1,151 @@
+/*****************************************************************************\
+ *  layouts_mgr.h - layouts manager data structures and main functions
+ *****************************************************************************
+ *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
+ *  at Bull for slurm-2.6.
+ *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://slurm.schedmd.com/>.
+ *  Please also read the included file: DISCLAIMER.
+ *
+ *  SLURM 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.
+ *
+ *  In addition, as a special exception, the copyright holders give permission
+ *  to link the code of portions of this program with the OpenSSL library under
+ *  certain conditions as described in each individual source file, and
+ *  distribute linked combinations including the two. You must obey the GNU
+ *  General Public License in all respects for all of the code used other than
+ *  OpenSSL. If you modify file(s) with this exception, you may extend this
+ *  exception to your version of the file(s), but you are not obligated to do
+ *  so. If you do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source files in
+ *  the program, then also delete it here.
+ *
+ *  SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+
+#ifndef __LAYOUTS_MGR_1NRINRSD__INC__
+#define __LAYOUTS_MGR_1NRINRSD__INC__
+
+#include "src/common/list.h"
+#include "src/common/xhash.h"
+#include "src/common/xtree.h"
+#include "src/common/parse_config.h"
+
+#include "src/common/layout.h"
+#include "src/common/entity.h"
+
+/*
+ * Layouts are managed through a "layouts manager" of type layouts_mgr_t.
+ *
+ * The layouts_mgr_t manages the layouts and entities loaded through the list
+ * of layouts specified in the Slurm configuration file (slurm.conf)
+ *
+ * At startup, Slurm initialize one layouts_mgr_t using slurm_layouts_init()
+ * and then load the required layouts defined in the configuration using
+ * slurm_layouts_load_config().
+ *
+ * The different layouts and entities can then be queried using either
+ * slurm_layouts_get_layout() and slurm_layouts_get_entity().
+ *
+ * Note that each entity contains a list of nodes appearing inside the
+ * associated layouts.
+ */
+
+/*
+ * Potential enhancement to complete: agregate specified plugin etypes in a
+ *      xhash in the mgr, avoiding same string to be duplicated again and again.
+ *      (in short: apply the same logic for etypes as for entity data keys.)
+ */
+
+typedef enum layouts_keydef_types_en {
+	L_T_ERROR = 0,
+	L_T_STRING,
+	L_T_LONG,
+	L_T_UINT16,
+	L_T_UINT32,
+	L_T_BOOLEAN,
+	L_T_FLOAT,
+	L_T_DOUBLE,
+	L_T_LONG_DOUBLE,
+	L_T_CUSTOM,
+} layouts_keydef_types_t;
+
+typedef struct layouts_keyspec_st {
+	char*			key;
+	layouts_keydef_types_t	type;
+	void			(*custom_destroy)(void*);
+	char*			(*custom_dump)(void*);
+} layouts_keyspec_t;
+
+typedef struct layouts_plugin_spec_st {
+	const s_p_options_t*		options;
+	const layouts_keyspec_t*	keyspec;
+	int				struct_type;
+	const char**			etypes;
+	bool				automerge;
+} layouts_plugin_spec_t;
+
+/*****************************************************************************\
+ *                             PLUGIN FUNCTIONS                              *
+\*****************************************************************************/
+
+/*
+ * slurm_layouts_init - intialize the layouts mgr, load the required plugins
+ *        and initialize the internal hash tables for entities, keydefs and
+ *        layouts.
+ *
+ * Return SLURM_SUCCESS or SLURM_ERROR if all the required layouts were not
+ * loaded correctly.
+ *
+ * Notes: this call do not try to read and parse the layouts configuration
+ * files. It only loads the layouts plugins, dlsym the layout API and conf
+ * elements to prepare the reading and parsing performed in the adhoc call
+ * slurm_layouts_load_config()
+ *
+ */
+int slurm_layouts_init();
+
+/*
+ * slurm_layouts_fini - uninitialize the layouts mgr and free the internal
+ *        hash tables.
+ */
+int slurm_layouts_fini();
+
+/*
+ * slurm_layouts_load_config - use the layouts plugins details loaded during
+ *        slurm_layouts_init() and read+parse the different layouts
+ *        configuration files, creating the entities and the relational
+ *        structures associated the eaf of them.
+ *
+ * Return SLURM_SUCCESS or SLURM_ERROR if all the required layouts were not
+ * loaded correctly.
+ */
+int slurm_layouts_load_config();
+
+/*
+ * slurm_layouts_get_layout - return the layout from a given type
+ *
+ * Return a pointer to the layout_t struct of the layout or NULL if not found
+ */
+layout_t* slurm_layouts_get_layout(const char* type);
+
+/*
+ * slurm_layouts_get_entity - return the entity from a given name
+ *
+ * Return a pointer to the entity_t struct of the entity or NULL if not found
+ */
+entity_t* slurm_layouts_get_entity(const char* name);
+
+#endif /* end of include guard: __LAYOUTS_MGR_1NRINRSD__INC__ */