configurationengine/source/cone/public/api.py
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/api.py	Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3020 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+"""
+Cone public API.
+The core interface to the ConE functionality.
+"""
+
+import os
+import re
+import sys
+import logging
+import copy
+import sets
+
+import exceptions, utils, container, mapping
+
+class Base(container.ObjectContainer):
+    """
+    The Base class is intended for capturing same kind of naming scheme.
+    """
+    
+    
+    def __init__(self, ref="", **kwargs):
+        if len(utils.dottedref.split_ref(ref)) > 1:
+            raise exceptions.InvalidRef("Invalid reference for Base object %s!" % ref)
+        self.ref = ref
+        container.ObjectContainer.__init__(self, ref)
+        for arg in kwargs.keys():
+            if kwargs.get(arg) != None:
+                setattr(self, arg, kwargs.get(arg))
+
+    def __repr__(self):
+        dict = self._dict()
+        return "%s(%s)" % (self.__class__.__name__, dict)
+
+    def _get_mapper(self,modelname):
+        """
+        Return a instance of appropriate mapper for given model.
+        """
+        return mapping.BaseMapper()
+
+    def _compare(self, other, dict_keys=None):
+        """ 
+        Compare the attributes of elements 
+        """
+        if isinstance(other, Base):
+            keys = dict_keys or self._dict().keys() 
+            for key in keys:
+                self_attr = None
+                other_attr = None
+                try:
+                    self_attr = getattr(self, key)
+                    other_attr = getattr(other, key)
+                except AttributeError:
+                    # If the attribute is not found from either elements
+                    # ignore it entirely
+                    if self_attr == None and other_attr == None: 
+                        continue
+                if  self_attr != other_attr:
+                    return False
+            # If all given keys match report this as as similar element
+            return True
+        else:
+            return False
+
+    def _clone(self, **kwargs):
+        """
+        A generic implementation for cloning the object.
+        Copies all (public) members in dictionary.
+        To clone objects recursively set the recursion level with recursion param.
+        @param recursion: Boolean to define recursion on or off
+        @param recursion_depth: positive integer to define recursion depth. default is -1 which will 
+        perform recursion to all objects.
+        """
+        dict = self._dict()
+        if kwargs.get('class_instance'):
+            class_instance = kwargs.get('class_instance')
+            del kwargs['class_instance']
+        else:
+            class_instance = self.__class__
+        obj = class_instance(**dict)
+        # Remove all children created at the construction phase 
+        # This is needed when the recursion adds children to the object so that there are not duplicates
+        obj._order = []
+        obj._children = {}
+        
+        # handle the recursion argument
+        recursion = kwargs.get('recursion', False)
+        if recursion:
+            recursion_depth = kwargs.get('recursion_depth', -1)
+            if recursion_depth < 0 or recursion_depth > 0:
+                # decrease the recursion
+                kwargs['recursion_depth'] = recursion_depth - 1 
+                for child in self._objects():
+                    obj._add(child._clone(**kwargs), container.APPEND)
+        return obj
+
+    def _dict(self):
+        """
+        Return the public variables in a dictionary
+        """
+        dict = {}
+        for key in self.__dict__.keys():
+            if key.startswith('_'):
+                continue
+            else:
+                dict[key] = self.__dict__[key]
+        return dict
+
+    def _default_object(self, name):
+        return Base(name)
+
+    @property
+    def fqr(self):
+        """
+        Return a Fully Qualified Ref, which is the full name of the reference. 
+        Joins the namespace and ref to one string.
+        @return: A string 
+        """
+        return utils.dottedref.join_refs([self.namespace, self.get_ref()])
+
+    @property
+    def namespace(self):
+        """
+        @return: The namespace of the object.
+        """
+        containerpath = ""
+        path = ""
+        parentcontainer = self.find_parent(container=True)
+        parent = self.find_parent(type=Base)
+        paths = []
+        while parent and parent != parentcontainer:
+            """ Skip the element if it is supposed to be hidden. Begins with _. """
+            if not parent.get_ref().startswith('_'):
+                paths.append(parent.get_ref())
+            parent = parent._get_parent()
+        if parentcontainer:
+            paths.append(parentcontainer.namespace)
+        paths.reverse()
+        return utils.dottedref.join_refs(paths)
+
+    def get_fullref(self):
+        """
+        Return a full reference, reference including a 
+        possible index of the object in list. 
+        e.g. ref can be bar[1] or just the normal bar. 
+        
+        @return: The full reference of the object.
+        """
+        if self.parent and utils.is_list(self.parent._get(self.ref)):
+            return "%s[%s]" % (self.ref, self.get_index())
+        else:
+            return self.ref
+
+    def get_fullfqr(self):
+        """
+        Return a full reference, reference including a 
+        possible index of the object in list. 
+        ref and adds index.
+        @return: A string 
+        """
+        return utils.dottedref.join_refs([self.get_fullnamespace(), self.get_fullref()])
+
+    def get_fullnamespace(self):
+        """
+        @return: The full namespace of the object with possible indexes of the parent objects
+        """
+        containerpath = ""
+        path = ""
+        parentcontainer = self.find_parent(container=True)
+        parent = self.find_parent(type=Base)
+        paths = []
+        while parent and parent != parentcontainer:
+            paths.append(parent.get_fullref())
+            parent = parent.parent
+        if parentcontainer:
+            paths.append(parentcontainer.namespace)
+        paths.reverse()
+        return utils.dottedref.join_refs(paths)
+
+    def get_storage(self):
+        """
+        Get the root storage from the root object.
+        """
+        if self._find_parent():
+            return self._find_parent().get_storage()
+        else:
+            raise exceptions.StorageException("Storage is not found from root!")
+
+    def get_project(self):
+        """
+        Get the root project from the root object.
+        """
+        if isinstance(self, Project):
+                return self
+        elif self._find_parent():
+            return self._find_parent().get_project()
+        else:
+            raise exceptions.NotFound("Project not found!!")
+
+    def get_default_view(self):
+        """
+        Get the default view from the root object.
+        """
+        try:
+            return self._find_parent().get_default_view()
+        except exceptions.NotFound:
+            raise exceptions.NotFound("Default View is not found! No root configuration?")
+
+    def get_root(self):
+        """
+        Get the root object
+        """
+        try:
+            return self._find_parent().get_root()
+        except exceptions.NotFound:
+            return self
+
+    def get_root_configuration(self):
+        """
+        Get the root object
+        """
+        if self.find_parent(type=Configuration):
+            return self.find_parent(type=Configuration).get_root_configuration()
+        elif isinstance(self, Configuration):
+            return self
+        else:
+            return None
+
+    def get_index(self):
+        """
+        @return : the index of the data element for sequential data defined inside the same configuration.
+        0 for normal data.
+        """
+        # Get the list of items from parent which contains this element and ask my own index
+        # Make sure that the returned element is a list with get_list
+        selflist = utils.get_list(self._get_parent()._get(self.get_ref()))
+        return selflist.index(self)
+
+    def find_parent(self, **kwargs):
+        """
+        find the closest parent object of given type.
+        e.g. find_parent(type=Configuration) returns the closest parent 
+        Configuration parent instance
+        @param type: class definitiob
+        """
+        type = kwargs.get('type', None)
+        container = kwargs.get('container', False)
+        try:
+            parent = self._find_parent()
+            if type and isinstance(parent, type):
+                    return parent
+            elif container and hasattr(parent, 'container'):
+                    return parent
+            else:
+                return parent.find_parent(**kwargs)
+        except exceptions.NotFound:
+            return None
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        raise exceptions.NotSupportedException("Cannot add %s object to %s" % (child, self))
+
+    def get_elem(self, fqr):
+        """
+        A generic get function to get child objects and members. The function uses getattr
+        to traverse downwards the the object tree. The returned object is the final object or attribute 
+        if it is found. Raises AttributeError if the child is not found.
+        
+        Example: obj.get('test.bar'), returns child obj.test.bar
+        @param fqr: the fully qualified ref to the object
+        @raise AttributeError: if the given ref is not found.  
+        """
+        return None
+
+
+class Project(Base):
+    """
+    A project is a container that can hold several Configuration objects.
+    """
+
+    def __init__(self, storage, **kwargs):
+        """
+        Project constructor
+        """
+        Base.__init__(self, "")
+        """ Try to set the model and tet the actual configuration class """
+        try:
+            self._model = storage.persistentmodule.MODEL
+        except AttributeError:
+            self._model = None
+        
+        self.set_storage(storage)
+        self.update()
+        self.loaded = {}
+
+    def __add_loaded__(self, ref, obj):
+        """
+        Add the object to loaded 
+        """
+        self.loaded[ref] = {'counter': 0, 'obj': obj}
+
+    def __get_loaded__(self, ref):
+        """
+        Get a loaded object if it is existing and increase the reference counter
+        @param ref: 
+        @return: The loaded object if it exists. None if it does not. 
+        """
+        if self.loaded.has_key(ref):
+            return self.loaded[ref]['obj']
+        else:
+            return None
+
+    def __loaded__(self, ref):
+        """
+        Get a loaded object if it is existing and increase the reference counter
+        @param ref: 
+        @return: The loaded object if it exists. None if it does not. 
+        """
+        if self.loaded.has_key(ref):
+            self.loaded[ref]['counter'] += 1
+        else:
+            raise exceptions.NotFound("ref %s is not found from loaded!" % ref)
+
+    def __unloaded__(self, ref):
+        """
+        returns True when the reference count is zero and object can be released.
+        """
+        if self.loaded.has_key(ref):
+            self.loaded[ref]['counter'] -= 1
+            if self.loaded[ref]['counter'] == 0:
+                del self.loaded[ref]
+                return True
+            else: 
+                return False
+        else: 
+            return True
+        
+    def _supported_type(self, obj):
+        if isinstance(obj, Configuration) \
+        or isinstance(obj, ConfigurationProxy): 
+            return True
+        else:
+            return False
+
+
+    def update(self):
+        """
+        update the root confml files as configurations
+        """
+        root_confmls = self.get_storage().list_resources(".")
+        root_confmls = utils.resourceref.filter_resources(root_confmls, "\.confml")
+        for rootml in root_confmls:
+            self._add(ConfigurationProxy(rootml))
+    
+    def get_storage(self):
+        """
+        Get the Storage instance of this Project.
+        """
+        return self.storage
+
+    def set_storage(self, storage):
+        """
+        Set the Storage instance of this Project.
+        """
+        if isinstance(storage, Storage):
+            self.storage = storage
+        else:
+            raise exceptions.StorageException("The given storage is not a instance of Storage!")
+
+    def list_configurations(self, filter_or_filters=None):
+        """
+        List the direct child objects of the project (Root configurations)
+        @param filter_or_filters: A regular expression or list of regular expressions
+            used for filtering the configuration paths. If None, all configurations are
+            returned.
+        @return: a list for configuration file paths
+        """
+        filters = None
+        if isinstance(filter_or_filters, basestring):   filters = [filter_or_filters]
+        elif filter_or_filters is not None:             filters = filter_or_filters
+        
+        configs = [obj.get_path() for obj in self._objects()]
+        
+        if filters is not None:
+            result = []
+            for config in configs:
+                for filter in filters:
+                    if re.match(filter, config) is not None:
+                        result.append(config)
+                        break
+            return result
+        else:
+            return configs
+
+    def list_all_configurations(self):
+        """
+        List all configuration objects of the project (all configurations)
+        @return: a list for configuration file paths
+        """
+        return [obj.get_path() for obj in self._traverse(type=(Configuration, ConfigurationProxy))]
+
+    def get_configuration(self, path):
+        """
+        Get a configuration object from the given path
+        @param path: path to configuration 
+        @return: a instance of Configuration.
+        """
+        # Load the configuration object if it is not already loaded
+        try:
+            return self._get(utils.resourceref.to_objref(utils.resourceref.norm(path)))
+        except exceptions.NotFound, e:
+            if self.storage.is_resource(utils.resourceref.norm(path)):
+                proxy = ConfigurationProxy(utils.resourceref.norm(path))
+                proxy._set_parent(self)
+                return proxy
+            else:
+                raise e
+
+    def is_configuration(self, path):
+        """
+        Return true if the given path is a configuration object in this Project.
+        @param path: path to configuration 
+        @return: Boolean return value.
+        """
+        # Changed from list_all_configurations to list_configurations
+        # (list_all_configurations causes a insane performance problem with _traverse)
+        return path in self.list_configurations()
+
+    def add_configuration(self, config):
+        """
+        Add a Configuration object to this project
+        """
+        if isinstance(config, Configuration):
+            if self.is_configuration(config.get_path()):
+                raise exceptions.AlreadyExists("%s" % config.get_path())
+            self._add(config)
+            self.__add_loaded__(config.get_path(), config)
+            self.__loaded__(config.get_path())
+        else:
+            raise exceptions.IncorrectClassError("Only Configuration instance can be added to Project!")
+
+    def create_configuration(self, path, namespace=""):
+        """
+        Create a Configuration object to this project
+        """
+        config = self.get_configuration_class()(utils.resourceref.norm(path), namespace=namespace)
+        self.add_configuration(config)
+        return config
+
+    def remove_configuration(self, path):
+        """
+        Remove a Configuration by its reference
+        """
+        # remove configuration as an object and try to remove it from the storage
+        self._remove(utils.resourceref.to_objref(path))
+        try:
+            self.storage.delete_resource(path)
+        except exceptions.NotSupportedException:
+            pass
+        return
+
+    def import_configuration(self, configuration):  
+        """
+        Import a configuration object from another storage
+        """
+        self.storage.import_resources(configuration.list_resources(), configuration.get_storage())
+        return
+
+    def export_configuration(self, configuration, export_storage, empty_folders=False):
+        """
+        Export a configuration object to another storage
+        """
+        # First clone the configuration and then import the rest of the configuration resources
+        if isinstance(configuration, ConfigurationProxy):
+            configuration = configuration._get_obj()
+        
+        export_storage.unload(configuration.get_full_path(),configuration)
+        for child in configuration._traverse(type=Configuration):
+            export_storage.unload(child.get_full_path(),child)
+        
+        #If the configuration is not in the root of the project adding the path 
+        #to final exporting source path.
+        #l = []
+        cpath = utils.resourceref.get_path(configuration.get_path()) 
+        resr = [utils.resourceref.join_refs([cpath,related]) \
+                for related in configuration.get_layer().list_all_related(empty_folders)]        
+        self.storage.export_resources(resr ,export_storage, empty_folders)
+        return
+
+    def get_configuration_class(self):
+        """
+        return the default configuration class that is used with the model. 
+        """
+        return utils.get_class(self._model, Configuration)
+
+    def save(self):
+        """
+        Save the object to the permanent Storage object. Calls the save operation for 
+        all the children and also for the Storage.
+        """
+        for child in self._objects():
+            if isinstance(child, (Configuration, ConfigurationProxy)):
+                child.save()
+        self.storage.save()
+
+    def close(self):
+        """
+        Close the Project.
+        """
+        for child in self._objects():
+            if isinstance(child, (Configuration, ConfigurationProxy)):
+                child.close()
+        self.storage.close()
+
+    def load(self, path):
+        """
+        Load an object from a reference. The given reference is loaded once from storage
+        and stored as a loaded object to the Project. Sequential loads to the same ref will
+        return the same object.
+        @param path: The reference where to load the object 
+        @raise StorageException: if the given object cannot be loaded as an 
+        object from this storage 
+        """
+        if not self.__get_loaded__(path):
+            configuration = self.get_storage().load(path)
+            if configuration.get_ref() == 'unknown':
+                 configuration.set_ref(utils.resourceref.to_dref(path))
+            self.__add_loaded__(path, configuration)
+        """ increase the ref counter """
+        self.__loaded__(path)
+        return self.__get_loaded__(path)
+
+    def unload(self, path, object):
+        """
+        Release the given ref, which decreases the reference counter of the given ref.
+        @param path: The reference where to store the object 
+        @param object: The object instance to dump 
+        @raise StorageException: if the given object cannot be dumped to this storage 
+        """
+        if self.__unloaded__(path):
+            self.get_storage().unload(path, object)
+
+    def get_path(self):
+        """
+        Return the path of the project, which is always root
+        """
+        return ""
+
+
+class CompositeConfiguration(Base):
+    """
+    A base class for composite Configuration objects.  
+    """
+    def __init__(self, ref="", **kwargs):
+#        self.meta       = {}
+#        self.desc       = ""
+        super(CompositeConfiguration, self).__init__(ref, **kwargs)
+        self.container = True
+
+    def add_configuration(self, config):
+        """
+        Add an existing Configuration to this configuration
+        @param config: A Configuration instance:
+        @return: None 
+        """
+        """
+        Merge the default view features from added config to this configs _default_view.
+        """
+        self._add(config)
+
+    def include_configuration(self, configref):
+        """
+        Add an existing Configuration to this configuration by its resource reference
+        @param config: A Configuration instance:
+        @return: None 
+        """
+        # add the configuration load proxy to this configuration instead 
+        # adding the configuration directly
+        self._add(ConfigurationProxy(configref))
+
+    def create_configuration(self, path):
+        """
+        Create a new configuration by its name to the Configuration. 
+        1. Create new Configuration object
+        2. Create new ConfigurationProxy 
+        3. Add proxy to this object
+        4. Set proxy to point to the created Configuration object
+        @param path: The reference of the configuration to create
+        @return: The new configuration object.
+        """
+        # normalise the path
+        normpath = utils.resourceref.norm(path)
+        cklass = self.get_configuration_class()
+        conf = cklass(normpath, namespace=self.namespace)
+        proxy = ConfigurationProxy(normpath)
+        self.add_configuration(proxy)
+        proxy._set_obj(conf)
+        return conf
+
+    def remove_configuration(self, path):
+        """
+        Remove a Layer object from the Configuration by its reference.
+        """
+        self._remove(utils.resourceref.to_objref(path))
+
+    def list_configurations(self):
+        """
+        List all Layer objects in the Configuration
+        @return: a copy array of layer references.
+        """
+        return [config.get_path() for config in self._objects(type=(Configuration, ConfigurationProxy))] 
+
+    def list_all_configurations(self):
+        """
+        List all Layer objects in the Configuration
+        @return: a copy array of layer references.
+        """
+        # TODO
+        # huge performance problem 
+        return [config.get_path() for config in self._traverse(type=(Configuration, ConfigurationProxy))] 
+
+    def get_configuration(self, path):
+        """
+        Get a Layer object by if path
+        @return: a Layer object
+        """
+        return self._get(utils.resourceref.to_objref(path))
+
+    def get_configuration_by_index(self, index):
+        """
+        Get a Layer object by if indexing number
+        @return: a Layer object
+        """
+        configs = self._objects(type=(Configuration, ConfigurationProxy))
+        return configs[index]
+
+    def get_last_configuration(self):
+        """
+        Get the last Layer object from this configuration hierarchy.
+        @return: a Layer object
+        """
+        last_config = self
+        try: 
+            last_config = last_config.get_configuration_by_index(-1)
+            return last_config.get_last_configuration()
+        except IndexError:
+            return self 
+
+    def get_configuration_class(self):
+        """
+        return the default configuration class retrieved from the project if it is found.
+        Otherwise return cone.public.api.Configuration. 
+        """
+        try:
+            return self.get_project().get_configuration_class()
+        # catch the Parent/Project NotFound exception
+        except exceptions.NotFound:
+            return Configuration
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, Configuration):
+            self.add_configuration(child)
+        elif isinstance(child, ConfigurationProxy):
+            self.add_configuration(child)
+        elif isinstance(child, Base):
+            self._add(child)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+    def layered_content(self, layers=None):
+        """
+        fetch content from first to last and override content 
+        if it is found from a later layer 
+        Create an array of the layers based on the layer indexes.
+        """
+        configuration_array = []
+        if layers == None:
+            configuration_array = self.list_configurations()
+        else:
+            all = self.list_configurations()
+            for i in layers:
+                configuration_array.append(all[i])
+
+        content = container.DataContainer()
+        for configuration_path in configuration_array:
+            content_folder = self.get_configuration(configuration_path).get_layer().content_folder()
+            content_path = content_folder.get_current_path()
+            for content_file in content_folder.list_resources("", True):
+                source_file = utils.resourceref.join_refs([content_path, content_file])
+                content.add_value(content_file, source_file)
+                
+        return content
+
+
+class Configuration(CompositeConfiguration):
+    """
+    A Configuration is a container that can hold several Layer objects.
+    """
+
+    def __init__(self, ref="", **kwargs):
+        self.path = kwargs.get('path') or ref
+        self.namespace = kwargs.get('namespace', '')
+        self.name = utils.resourceref.to_objref(self.path)
+        super(Configuration, self).__init__(utils.resourceref.to_objref(self.path))
+        self.container = True
+
+    def _default_object(self, name):
+        return Feature(name)
+
+    def _supported_type(self, obj):
+        if isinstance(obj, Configuration) \
+        or isinstance(obj, Feature) \
+        or isinstance(obj, Data) \
+        or isinstance(obj, ConfigurationProxy) \
+        or isinstance(obj, View) \
+        or isinstance(obj, Base): 
+            return True
+        else:
+            return False
+
+    def _dict(self):
+        """
+        Return the public variables in a dictionary
+        """
+        dict = {}
+        for key in self.__dict__.keys():
+            if key.startswith('_'):
+                continue
+            else:
+                dict[key] = self.__dict__[key]
+        dict['namespace'] = self.namespace
+        return dict
+    
+    def get_name(self):
+        """
+        Return the name of the configuration
+        """
+        return self.name
+
+    def set_name(self, name):
+        """
+        Set the name
+        """
+        self.name = name
+
+    def get_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        return self.path
+
+    def set_path(self, path):
+        """
+        Set the path of the configuration resource, and update the name and ref to correspond
+        """
+        self.path = path
+        #self.name = utils.resourceref.to_objref(self.path)
+        self.set_ref(utils.resourceref.to_objref(self.path))
+
+    #@property
+    def get_full_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        try:
+            parentconfig = self._find_parent(type=Configuration)
+            parent_path = utils.resourceref.get_path(parentconfig.get_path()) 
+        except exceptions.NotFound:
+            parent_path = ""
+
+        return utils.resourceref.join_refs([parent_path, self.path])
+
+    def get_layer(self):
+        """
+        Get the layer object where this Configuration is located. 
+        """
+        if not hasattr(self, "layer"):
+            layerpath = utils.resourceref.get_path(self.get_path())
+            # hardcoded removal of confml folder from the layer path it is there
+            layerpath = utils.resourceref.remove_end(layerpath, '/confml')
+            self.layer = Layer(self.get_storage(), layerpath)
+            """ Add the sublayers to this layer if they are different from this configuration """
+            for configpath in self.list_configurations():
+                sublayer_path = utils.resourceref.get_path(self.get_configuration(configpath).get_full_path())
+                sublayer_path = utils.resourceref.remove_end(sublayer_path, '/confml')
+                if sublayer_path != utils.resourceref.get_path(self.get_path()):
+                    self.layer.add_layer(self.get_configuration(configpath).get_layer())
+        return self.layer
+
+    def set_namespace(self, namespace):
+        """
+        @param namespace: The new namespace of the object
+        """
+        self._namespace =  namespace
+        #self.root.set_namespace(namespace)
+
+    def get_namespace(self):
+        """
+        @return: The reference of the object.
+        """
+        return self._namespace
+
+    def del_namespace(self):
+        """
+        @return: The reference of the object.
+        """
+        self._namespace = None
+    namespace = property(get_namespace, set_namespace, del_namespace)
+
+    def list_resources(self, empty_folders=False):
+        """
+        List all resources used in this configuration
+        """
+        """
+        1. First ensure that all configuration resource files are added 
+        2. Then add all layer resources 
+        3. Make the list distinct
+        """
+        
+        
+        resources = [self.get_full_path()]
+        for config in self._traverse(type=Configuration):
+            resources.append(config.get_full_path())
+        layer = self.get_layer()
+        for resref in layer.list_all_resources(empty_folders):
+            resources.append(utils.resourceref.join_refs([layer.get_current_path(), resref]))
+    
+        return utils.distinct_array(resources)
+
+    def get_resource(self, ref, mode="r"):
+        """
+        Get the given resource as a Resource object. The resource is searched relative to the 
+        Configuration path, e.g. Configuration('test/foo/root.confml') => searches from 'test/foo'.
+        @param ref: the reference path to the requested resource
+        @return: a instance of Resource. 
+        """
+        mypath = utils.resourceref.get_path(self.path)
+        myref = utils.resourceref.join_refs([mypath, ref])
+        return self.get_storage().open_resource(myref, mode)
+
+    def get_all_resources(self):
+        """
+        Get all resources in resource list of Resource objects
+        """
+        resources = []
+        res_list = self.list_resources()
+        for res in res_list:
+            resources.append(self.get_storage().open_resource(res))
+        return resources
+
+    def get_root_resource(self):
+        """
+        Get the configuration reference resource.
+        """
+        return self.get_storage().open_resource(self.get_path())
+
+    def get_feature(self, ref):
+        """
+        Get a feature object by its reference.
+        @param ref: The reference to the feature object.
+        @return: A Feature object
+        """
+        return self._get(ref)
+
+    def add_feature(self, feature, namespace=""):
+        """
+        Add a feature object to the configuration.
+        @param feature: The Feature object to add.
+        @param namespace: The sub namespace for the feature. 
+        e.g. to add fea2 under fea1 add_feature(fea2, 'fea1')
+        @return: None
+        """
+        self._add_to_path(namespace, feature)
+
+    def remove_feature(self, ref):
+        """
+        remove feature by its reference
+        @param ref: 
+        """
+        self._remove(ref)
+
+    def list_features(self):
+        """
+        List immediate features found under the this configuration (the top nodes). 
+        The features are also available via the _default_view of the configuration.
+        @return: a list of feature references. 
+        """
+        return [fea.get_ref() for fea in self._objects(type=Feature)]
+
+    def list_all_features(self):
+        """
+        List all features found under the this configuration. The features are also 
+        available via the _default_view of the configuration.
+        @return: a list of feature references. 
+        """
+        return [fea.fqr for fea in self._traverse(type=Feature)]
+
+    def add_data(self, data, policy=container.REPLACE):
+        """
+        Add a data object to this configuration object.
+        @param data: The Data object to add.
+        @return: None
+        """ 
+        if not self._has(data.attr):
+            self._add(DataContainer(data.attr, container=True))
+        (namespace, name) = utils.dottedref.psplit_ref(data.get_fearef())
+        self._get(data.attr)._add_to_path(namespace, data, policy)
+
+    def get_data(self, ref):
+        """
+        Get a data object by its reference.
+        @param ref: The reference to the data object.
+        @return: A Data object
+        """
+        return self.data._get(ref)
+
+    def remove_data(self, ref):
+        """
+        remove feature by its reference
+        @param ref: 
+        """
+        self.data._remove(ref)
+
+    def list_datas(self):
+        """
+        List all datas found under the this configuration. 
+        @return: a list of Data references. 
+        """
+        if self._has('data'):
+            return [dataelem.fqr for dataelem in self.data._objects(type=Data)]
+        else:
+            return []
+
+    def get_datas(self):
+        """
+        List immediate datas found under the this configuration (the top nodes). 
+        @return: a list of Data references. 
+        """
+        if self._has('data'):
+            return [dataelem for dataelem in self.data._objects(type=Data)]
+        else:
+            return []
+
+    def list_all_datas(self):
+        """
+        List all Data elements found under the this configuration (or subconfigurations). 
+        @return: a list of Data references. 
+        """
+        return [dataelem.fqr for dataelem in self._traverse(type=Data)]
+
+    def get_all_datas(self):
+        """
+        List all Data elements found under the this configuration (or subconfigurations). 
+        @return: a list of Data references. 
+        """
+        return [dataelem for dataelem in self._traverse(type=Data)]
+
+    def list_leaf_datas(self):
+        """
+        List all leaf Data elements (i.e. actually modified settings) found under this configuration (or subconfigurations). 
+        @return: A list of Data references. 
+        """
+        return [dataelem.fqr for dataelem in self._find_leaves(type=Data)]
+    
+    def get_leaf_datas(self):
+        """
+        Get all leaf Data elements (i.e. actually modified settings) found under this configuration (or subconfigurations). 
+        @return: A list of Data objects. 
+        """
+        return [dataelem for dataelem in self._find_leaves(type=Data)]
+
+    def get_view(self, ref):
+        """
+        Get a view object by its reference.
+        @param ref: The reference to the view object.
+        @return: A View object
+        """
+        # Populate the view object before returning it
+        view = self._get(ref)
+        view.populate()
+        return view
+
+    def add_view(self, viewname):
+        """
+        Add a view object to the configuration.
+        @param viewname: The name of the view to add. 
+        @return: None
+        """
+        return self._add(View(viewname))
+
+    def remove_view(self, ref):
+        """
+        Remove a view object from the configuration.
+        @param ref: The reference to the View. 
+        @return: None
+        @raise NotFound: when view is not found.
+        """
+        return self._remove(ref)
+
+    def list_views(self):
+        """
+        List all views found under the this configuration.
+        @return: a list of view references. 
+        """
+        return [view._path(self) for view in self._traverse(type=View)]
+
+    def save(self):
+        """
+        Save the object to the permanent Storage object. Calls the save operation of 
+        all the children.
+        """
+        for child in self._objects():
+            if isinstance(child, (Configuration,ConfigurationProxy)):
+                child.save()
+        self.get_project().unload(self.get_full_path(), self)
+
+    def close(self):
+        """
+        Close the configuration
+        """
+        for child in self._objects():
+            if isinstance(child, (Configuration, ConfigurationProxy)):
+                child.close()
+#        if self.get_full_path() != "":
+#            self.get_project().unload(self.get_full_path(), self)
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, Feature):
+            self.add_feature(child)
+        elif isinstance(child, View):
+            self._add(child)
+        elif isinstance(child, (Data)):
+            self.add_data(child)
+        else:
+            super(Configuration, self).add(child)
+
+    def get_default_view(self):
+        """
+        Get the default view from this configuration hierarchy.
+        This returns always the view from the Root configuration point of view.
+        """
+        try:
+            parent = self._find_parent_or_default() 
+            if parent and isinstance(parent, Configuration):
+                return parent.get_default_view()
+            else:
+                if not hasattr(self, '_default_view'):
+                    self._create_default_view()
+                return self._default_view
+        except exceptions.NotFound, e:
+            raise e
+        # raise exceptions.NotFound("Default View is not found! No root configuration?")
+    
+    def recreate_default_view(self):
+        try:
+            parent = self._find_parent_or_default() 
+            if parent and isinstance(parent, Configuration):
+                parent.recreate_default_view()
+            else:
+                self._create_default_view()
+        except exceptions.NotFound, e:
+            raise e
+        # raise exceptions.NotFound("Default View is not found! No root configuration?")
+    
+    def _create_default_view(self):
+        # Rebuild the default view for this Configuration
+        self._default_view = View("_default_view", data=True)
+        self._default_view._parent= self
+        # First add all features of the configuration to the view. 
+        # Then add all data elements under the features
+        for child in self._traverse(type=Feature):
+            self._default_view.add_feature(child, child.namespace)
+        for child in self._traverse(type=Data):
+            #parent_config = child._find_parent_or_default(type=Configuration)
+            #print "Adding data %s: fqr: %s from file %s." % (child.get_value(), child.fqr, parent_config.get_path())
+            try:
+                fea = self._default_view.get_feature(child.fqr)
+                fea.add_data(child)
+            except exceptions.NotFound, e:
+                data_parent_config = child._find_parent_or_default(type=Configuration)
+                logging.getLogger('cone').info("Warning: Feature '%s' for data in %s not found." % (child.fqr, data_parent_config.get_path()))
+
+class ConfigurationProxy(container.LoadProxy):
+    """
+    Configuration loading proxy. Loads the configuration from the given reference, when needed.
+    """
+    def __init__(self, path, **kwargs):
+        """
+        The ConfigurationProxy that represents a configuration that is included in another configuration.
+        @param ref: the reference to the storage resource 
+        The ConfigurationProxy trust to get the store_interface from the parent object with get_storage() function.
+        
+        """
+        container.LoadProxy.__init__(self, path)
+        self.set('_name', utils.resourceref.to_objref(path))
+
+    def _clone(self, **kwargs):
+        """
+        A ConfigurationProxy specific implementation for cloning.
+        Copies all (public) members in dictionary.
+        To clone call the actual object that is proxied as well if the reqursion is on.
+        @param recursion: Boolean to define recursion on or off
+        @param recursion_depth: positive integer to define recursion depth. default is -1 which will 
+        perform recursion to all objects.
+        """
+        dict = self._dict()
+        obj = self.__class__(**dict)
+        # handle the recursion argument
+        recursion = kwargs.get('recursion', False)
+        if recursion:
+            recursion_depth = kwargs.get('recursion_depth', -1)
+            if recursion_depth < 0 or recursion_depth > 0:
+                # decrease the recursion
+                kwargs['recursion_depth'] = recursion_depth - 1
+                newobj = self._get_obj()._clone(**kwargs) 
+                obj._set_obj(newobj)
+        return obj
+
+    def _dict(self):
+        """
+        Return the public variables in a dictionary
+        """
+        dict = {}
+        for key in self.__dict__.keys():
+            if key.startswith('_'):
+                continue
+            else:
+                dict[key] = self.__dict__[key]
+        return dict
+
+    def _get_mapper(self,modelname):
+        """
+        Return a instance of appropriate mapper for given model.
+        """
+        return mapping.BaseMapper()
+
+class Group(Base):
+    """
+    A Group class. Group is used in View to group up other Group/Feature objects.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(Group, self).__init__(ref, **kwargs)
+        self.name = ref
+        self.support_data = kwargs.get("data", False)
+
+    def _supported_type(self, obj):
+        if isinstance(obj, (Group, \
+                           Base, \
+                           _FeatureProxy, \
+                           FeatureLink)): 
+            return True
+        else:
+            return False
+
+    def _default_object(self, name):
+        return Group(name)
+
+    def get_name(self):
+        """
+        Return the name of the configuration
+        """
+        return self.name
+
+    def set_name(self, name):
+        """
+        Set the name
+        """
+        self.name
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, (Group, \
+                              Base, \
+                              _FeatureProxy, \
+                              FeatureLink)):
+            self._add(child)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+    def get_name(self):
+        """
+        Return the name of the configuration
+        """
+        return self.name
+
+    def set_name(self, name):
+        """
+        Set the name
+        """
+        self.name = name
+
+    def add_feature(self, feature, path=""):
+        """
+        Add feature to this Group.
+        """
+        if not isinstance(feature, Feature):
+            raise exceptions.IncorrectClassError("add_feature requires instance of Feature!! Given %s" % feature)
+        if not self.support_data:
+            self._add_to_path(path, _FeatureProxy(feature._name, feature))
+        else:
+            self._add_to_path(path, _FeatureDataProxy(feature._name, feature))
+
+    def remove_feature(self, ref):
+        """
+        remove a given feature from this view by reference. 
+        @param ref: 
+        """
+        self._remove(ref)
+
+    def get_feature(self, ref):
+        """
+        @param path: The path (ref) to the given feature 
+        """
+        try:
+            return self._get(ref)
+        except exceptions.NotFound:
+            raise exceptions.NotFound("Feature '%s' not found." % ref)
+
+    def get_features(self, ref, **kwargs):
+        """
+        Get a list of features that match the ref. 
+        Example1: get_features('foo.bar') would be the same as get_feature('foo.bar'), but this returns 
+        always a list [<Feature>].
+        Example2: get_features('foo.*') would try to retrieve a list of all foo children.
+        Example3: get_features('foo.*', type='') would try to retrieve a list of all foo children, 
+        that have a defined type.
+        @param path: The path (ref) to the given feature or xpath like expression 
+        @return: A list of features.
+        """
+        (startref, last) = utils.dottedref.psplit_ref(ref)
+        startelem = self._get(startref)
+        if last == '**':
+            return [fea for fea in startelem._traverse(**kwargs)]
+        elif last == '*':
+            return [fea for fea in startelem._objects(**kwargs)] 
+        else:
+            return [self._get(ref)]
+
+    def list_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return [fea.get_ref() for fea in self._objects(type=(_FeatureProxy))]
+
+    def list_all_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return [fea.fqr for fea in self._traverse(type=(_FeatureProxy))]
+
+    def add_group(self, groupname):
+        """
+        """
+        self._add(Group(groupname))
+
+    def remove_group(self, ref):
+        """
+        remove a given feature from this view by reference. 
+        @param ref: 
+        """
+        self._remove(ref)
+
+    def get_group(self, ref):
+        """
+        @param path: The path (ref) to the given feature 
+        """
+        return self._get(ref)
+
+    def list_groups(self):
+        """
+        """
+        return [group.get_name() for group in self._objects(type=Group)]
+
+    def populate(self):
+        """
+        Populate or fetch the link to the actual feature for this featureproxy.
+        This method fetches the feature to the _obj member variable and populates also 
+        subfeatures. 
+        """
+        for child in self._traverse(type=FeatureLink):
+            child.populate()
+        
+
+
+class View(Group):
+    """
+    A View class. View is intended to create new or different hierarchies of existing features. A View can contain Group and/or Feature objects.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(View, self).__init__(self.to_ref(ref), **kwargs)
+        self.name = ref
+        self.container = True
+
+    @classmethod
+    def to_ref(cls, ref):
+        """ 
+        return a view reference converted from name 
+        """
+        return ref.replace('.', '').replace('/', '')
+
+
+class Feature(Base):
+    """
+    A Feature class. Feature is the base for all Configurable items in a Configuration.
+    """
+    PROPERTIES = ['value']
+    def __init__(self, ref="", **kwargs):
+        super(Feature, self).__init__(ref, **kwargs)
+        self.name = kwargs.get('name', ref)
+        self.type = kwargs.get('type', None)
+        self._dataproxy = None
+
+    def __copy__(self):
+        dict = {}
+        for key in self.__dict__.keys():
+            if key.startswith('_') or key == 'ref':
+                continue
+            else:
+                dict[key] = self.__dict__[key]
+        fea = self.__class__(self.ref, **dict)
+        return fea
+
+
+    def _supported_type(self, obj):
+        # For now support added for desc element via support for Base
+        if isinstance(obj, (Feature, Option, Base)):
+            return True
+        else:
+            return False
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, Feature):
+            self.add_feature(child)
+        elif isinstance(child, Option):
+            self._add(child, policy)
+        elif isinstance(child, Base):
+            self._add(child, policy)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+    def get_name(self):
+        """
+        Return the name of the configuration
+        """
+        return self.name
+
+    def set_name(self, name):
+        """
+        Set the name
+        """
+        self.name = name
+
+    def get_type(self):
+        return self.type
+
+    def set_type(self, type):
+        self.type = type
+
+    def add_feature(self, feature, path=""):
+        """
+        @param feature: The Feature object to add 
+        """
+        configuration = self.find_parent(type=Configuration)
+        if configuration:
+            feapath = utils.dottedref.join_refs([self._path(configuration), path])
+            configuration.add_feature(feature, feapath)
+        else:
+            self._add_to_path(path, feature)
+
+    def get_feature(self, path):
+        """
+        @param path: The path (ref) to the given feature 
+        """
+        return self._get(path)
+
+    def remove_feature(self, ref):
+        """
+        remove a given feature from this view by reference. 
+        @param ref: 
+        """
+        configuration = self.find_parent(type=Configuration)
+        if configuration:
+            fullfqr = utils.dottedref.join_refs([self._path(configuration), ref])
+            configuration.remove_feature(fullfqr)
+        else:
+            self._remove(ref)
+
+    def list_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return [fea.get_ref() for fea in self._objects(type=Feature)]
+
+    def list_all_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return [fea._path(self) for fea in self._traverse(type=Feature)]
+
+    def add_option(self, option):
+        """
+        @param option: option object
+        """
+        if not isinstance(option, Option):
+            raise TypeError("%r is not an instance of Option!" % option)
+        self._add(option)
+    
+    def create_option(self, name, value):
+        """
+        @param name: option name
+        @param value: option value
+        """
+        self._add(Option(name, value))
+
+    def get_option(self, ref):
+        """
+        @param name: The option reference of the option (as returned by list_options()) 
+        """
+        real_ref = 'opt_' + ref
+        obj = self._get(real_ref)
+        if not isinstance(obj, Option):
+            raise TypeError('Object %r is not an instance of Option (%r instead)' % (real_ref, type(obj)))
+        return obj
+
+    def remove_option(self, ref):
+        """
+        remove a given option from this feature by option reference. 
+        """
+        real_ref = 'opt_' + ref
+        obj = self._get(real_ref)
+        if not isinstance(obj, Option):
+            raise TypeError('Trying to remove option with ref %r, but object with ref %r is not an instance of Option (%s instead)' % (ref, real_ref, type(obj)))
+        self._remove(real_ref)
+
+    def list_options(self):
+        """
+        Return a array of all Option children references under this object.
+        """
+        # Return option refs without the leading 'opt_'
+        return [opt.ref[4:] for opt in self._objects(type=Option)]
+
+    def get_value(self, attr=None):
+        """
+        Get the current value of the feature
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        # Do not allow getting of setting of sequence values directly with Feature object
+        if not self.is_sequence():
+            return self.get_value_cast(self.dataproxy._get_value(attr), attr)
+        else:
+            """ get the feature specific data from sequence => a column of data table """
+            coldata =  []
+            feasequence = self.get_sequence_parent()
+            feapath = self._path(feasequence)
+            for row in feasequence.data:
+                feadata = row.get_feature(feapath)
+                coldata.append(feadata.value)
+            return coldata
+
+    def set_value(self, value, attr=None):
+        """
+        Set the current value for this feature. Set the value on the topmost layer.
+        @param value: the value to set
+        """
+        # Do not allow setting of setting of sequence values directly with Feature object
+        if not self.is_sequence():
+            value = self.set_value_cast(value, attr)
+            self.dataproxy._set_value(value, attr)
+
+    def del_value(self, attr=None):
+        """
+        Delete the topmost value for this feature.
+        """
+        if not self.is_sequence():
+            self.dataproxy._del_value(attr)
+
+    def get_value_cast(self, value, attr=None):
+        """
+        A function to perform the value type casting in get operation  
+        @param value: the value to cast 
+        @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+        """
+        return value 
+    
+    def set_value_cast(self, value, attr=None):
+        """
+        A function to perform the value type casting in the set operation  
+        @param value: the value to cast 
+        @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+        """
+        return value 
+
+    def get_original_value(self, attr=None):
+        """
+        Get the current value of the feature
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        # Do not allow getting of setting of sequence values directly with Feature object
+        if not self.is_sequence():
+            return self.dataproxy._get_value(attr)
+        else:
+            """ get the feature specific data from sequence => a column of data table """
+            coldata =  []
+            feasequence = self.get_sequence_parent()
+            feapath = self._path(feasequence.data)
+            for row in feasequence.data:
+                feadata = row.get_feature(feapath)
+                coldata.append(feadata.value)
+            return coldata
+
+    def add_data(self, data):
+        """
+        Add a data value.
+        @param data: A Data object  
+        """
+        try:
+            return self.dataproxy._add_data(data)
+        except AttributeError:
+            self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr()) 
+            return self.dataproxy._add_data(data)
+
+    def get_data(self, attr=None):
+        """
+        Helper function to get the topmost data value from the default view.
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        try:
+            return self.dataproxy._get_data(attr)
+        except AttributeError:
+            self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr()) 
+            return self.dataproxy._get_data(attr)
+
+    def get_datas(self):
+        """
+        Helper function to get the data values from the default view.
+        """
+        try:
+            return self.dataproxy._get_datas()
+        except AttributeError:
+            self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr()) 
+            return self.dataproxy._get_datas()
+
+    def get_valueset(self):
+        """
+        Get the ValueSet object for this feature, that has the list of available values.
+        """
+        if self.get_type() == 'boolean':
+            return ValueSet([True, False])
+        elif self.get_type() == 'int':
+            return ValueRange(0, sys.maxint)
+        elif self.get_type() == 'string':
+            return ValueRe('.*')
+        elif self.get_type() in ('selection', 'multiSelection'):
+            values = []
+            for opt in self._objects(type=Option):
+                v = opt.get_value()
+                if v is not None: values.append(v)
+            return ValueSet(values)
+
+    def is_sequence(self):
+        """ Return true if the feature is a sequence or part of a sequence """
+        try:
+            return self._parent.is_sequence()
+        except AttributeError:
+            return False
+
+    def get_sequence_parent(self):
+        """ Try to get a FeatureSequence object for this Feature if it is found """
+        try:
+            return self._parent.get_sequence_parent()
+        except AttributeError:
+            return None
+
+    def getdataproxy(self): 
+        if self._dataproxy == None:
+            self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+        return self._dataproxy
+    def setdataproxy(self, value): self._dataproxy = value
+    def deldataproxy(self): self._dataproxy = None
+    dataproxy = property(getdataproxy, setdataproxy, deldataproxy)
+    value = property(get_value, set_value, del_value)
+
+class FeatureSequence(Feature):
+    POLICY_REPLACE = 0
+    POLICY_APPEND = 1
+    POLICY_PREPEND = 2
+    """
+    A Feature class. Feature is the base for all Configurable items in a Configuration.
+    """
+    dataelem_name = '?datarows'
+    template_name = '?template'
+    def __init__(self, ref="", **kwargs):
+        super(FeatureSequence, self).__init__(ref)
+        self.name = kwargs.get('name', ref)
+        self.type = 'sequence'
+        self.mapKey   = kwargs.get('mapKey')
+        self.mapValue = kwargs.get('mapValue')
+        self._templatedata = None
+
+    def _get_policy(self, data):
+        """
+        parse the policy from a policy string and return a constant
+        @return: POLICY_* constant
+        """
+        try:
+            containerdata = utils.get_list(data._get_parent()._get(data.get_ref()))
+            firstdata = containerdata[0]
+        except AttributeError:
+            firstdata = data
+        
+        if firstdata.policy == 'append':
+            return self.POLICY_APPEND
+        elif firstdata.policy == 'prefix':
+            return self.POLICY_PREPEND
+        elif firstdata == data:
+             # otherwise the policy is either replace or undefined
+             # (firstdata.policy == 'replace' or firstdata.policy == ''):
+            return self.POLICY_REPLACE
+        else:
+            return self.POLICY_APPEND
+        
+    def _set_template_data(self, data=None):
+        """
+        Set the template of the feature sequence  
+        """
+        # If template data is not existing, create it
+        if data != None:
+            self._templatedata = data
+            for feaname in self.list_features():
+                if self._templatedata._has(feaname):
+                    self.get_feature(feaname)._templatedata = self._templatedata._get(feaname)
+                else:
+                    subdata = Data(ref=feaname)
+                    self.get_feature(feaname)._templatedata = subdata
+                    self._templatedata._add(subdata) 
+
+    def _add_datarow(self, dataobj=None, policy=POLICY_APPEND):
+        """
+        Add a feature data row for a new data in this sequence 
+        """
+        if dataobj == None:
+            dataobj = Data(fqr=self.fqr)
+        elif dataobj.attr != 'data':
+            # Add data rows only for data objects (not e.g. RFS)
+            return
+        fea = FeatureSequenceSub(self.dataelem_name)
+        rowproxy = _FeatureDataProxy(fea._name, fea)
+        """ the imaginary features share the parent relation of the proxy objects """
+        self.dataproxy._add(rowproxy, policy)
+        fea._parent = rowproxy._parent
+        rowproxy._add_data(dataobj)
+        """ update the FeatureSequenceSub index from the index number of dataproxy """
+        fea._index = utils.get_list(self.dataproxy._get(self.dataelem_name)).index(rowproxy)
+        # Create a the subfeatures / columns for the parent feature and 
+        # add a data element under each feature.
+        for feaname in self.list_all_features():
+            (pathto_fea, fearef) = utils.dottedref.psplit_ref(feaname)
+            rowproxy.add_feature(FeatureSequenceSub(fearef), pathto_fea)
+            subproxy = rowproxy.get_feature(feaname)
+            subproxy._obj._parent = subproxy._parent 
+            if not dataobj._has(feaname):
+                dataobj._add_to_path(pathto_fea, Data(ref=fearef))
+            subproxy._add_data(dataobj._get(feaname))
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, Feature):
+            self.add_feature(child)
+        elif isinstance(child, Option):
+            self._add(child)
+        elif isinstance(child, Base):
+            self._add(child)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+    def add_sequence(self, data=None, policy=POLICY_APPEND):
+        """
+        Add a feature data row for a new data in this sequence 
+        """
+        self._add_datarow(None, policy)
+        # set the initial data if it is given
+        rowproxy = utils.get_list(self.dataproxy._get(self.dataelem_name))[-1]
+        if data != None:
+            for index in range(len(data)):
+                rowproxy[index].set_value(data[index])
+        # add the new data sequence/row to the last configuration layer
+        dataobj = rowproxy._get_data()
+        last_config = self.get_root_configuration().get_last_configuration()
+        last_config.add_data(dataobj, container.APPEND)
+        return dataobj
+
+    def set_template(self, data=None):
+        """
+        Set the template of the feature sequence  
+        """
+        # If template data is not existing, create it
+        if self._templatedata == None:
+            self._set_template_data(Data(ref=self.ref, template=True))
+            # Add the template data to parent config
+            pconfig = self.find_parent(type=Configuration)
+            pconfig.add_data(self._templatedata)
+
+        if data != None:
+            templdatas = self._templatedata._objects()
+            for index in range(len(data)):
+                templdatas[index].set_value(data[index])
+
+    def get_template(self):
+        """
+        Add a feature data row for a new data in this sequence 
+        """
+        #self._set_template(None)
+        # set the initial data if it is given
+        if self._templatedata:
+            return [data.get_value() for data in self._templatedata._objects()]
+        else:
+            return None
+
+    def get_data(self):
+        """
+        Helper function to get the topmost data value from the default view.
+        """
+        if self.dataproxy._has(self.dataelem_name):
+            return utils.get_list(self.dataproxy._get(self.dataelem_name))
+        else:
+            return []
+
+    def add_data(self, data):
+        """
+        Add a data value.
+        @param data: A Data object  
+        """
+        # Skip template data adding
+        if data.template:
+            self._set_template_data(data)
+        else:
+            # Get the data index
+            self._add_datarow(data, self._get_policy(data))
+        return
+    
+    def get_map_key(self):
+        """
+        Returns the setting that corresponds to mapKey attribute of this sequence feature.
+        """
+        if self.mapKey != None:
+            mapkey = self.get_feature(self.mapKey)
+            return mapkey
+        else:
+            return None
+
+    def get_map_key_value(self,key):
+        """
+        Returns the setting that corresponds to mapKey attribute of this sequence feature.
+        """
+        value = None
+        if self.mapKey != None and self.mapValue != None:
+            data = self.get_data()
+            for item in data:
+                kv = item.get_feature(self.mapKey).get_value()
+                if kv == key:
+                    value = item.get_feature(self.mapValue).get_value()
+        return value
+
+    def get_map_value(self):
+        """
+        Returns the setting that corresponds to mapValue attribute of this sequence feature.
+        """
+        if self.mapValue != None:
+            mapvalue = self.get_feature(self.mapValue)
+            return mapvalue
+        else:
+            return None
+        
+    def get_value(self, attr=None):
+        """
+        Helper function to get the topmost data value from the default view.
+        """
+        datatable =  self.get_data()
+        rettable = [] 
+        for row in datatable:
+            rowvalues = row.value
+            rettable.append(rowvalues)
+        return rettable
+
+    def set_value(self, value, attr=None):
+        """
+        Set the current value for this feature. Set the value on the topmost layer.
+        @param value: the value to set. The value must be a two dimensional array (e.g. matrix)
+        """
+        # sets the first data element to replace policy
+        try:
+            self.add_sequence(value.pop(0), self.POLICY_REPLACE)
+        # ignore the index error of an empty list
+        except IndexError:
+            pass
+        for row in value:
+            self.add_sequence(row)
+
+    def is_sequence(self):
+        """ Return always true from a sequence object """
+        return True
+
+    def get_sequence_parent(self):
+        """ Return this object as a sequence parent """
+        return self
+
+    value = property(get_value, set_value)
+    data = property(get_data)
+
+class FeatureSequenceCell(Feature):
+    """
+    A Feature class. Feature is the base for all Configurable items in a Configuration.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(Feature, self).__init__(ref)
+        self.name = kwargs.get('name', ref)
+        self.type = 'seqcell'
+ 
+    def get_value(self, attr=None):
+        """
+        Get the current value of the feature
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        return self.dataproxy._get_value(attr)
+
+    def set_value(self, value):
+        """
+        Set the current value for this feature. Set the value on the topmost layer.
+        @param value: the value to set
+        """
+        # The sequence cell only updates the latest value in the proxy  
+        self.dataproxy.get_data().set_value(value)
+
+    value = property(get_value, set_value)
+
+class FeatureSequenceSub(Feature):
+    """
+    A Feature class. Feature is the base for all Configurable items in a Configuration.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(Feature, self).__init__(ref)
+        self.name = kwargs.get('name', ref)
+        self.type = 'subseq'
+        self._index = 0
+
+    def get_index(self):
+        """
+        @return : the index of the data element for sequential data defined inside the same configuration.
+        0 for normal data.
+        """
+        return self._index
+
+    def set_value(self, value, attr=None):
+        """
+        Set the current value for this sequence row.
+        @param value: the value row to set
+        """
+        if utils.is_list(value):
+            for subindex in range(0, len(value)):  
+                self.dataproxy[subindex].get_data().set_value(value[subindex])
+        else: 
+            self.dataproxy.get_data().set_value(value)
+
+    def get_value(self, attr=None):
+        """
+        Set the current value for this feature. Set the value on the topmost layer.
+        @param value: the value to set
+        """
+        # dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+        # The sequence cell only updates the latest value in the proxy
+        childdatas = self.dataproxy._objects()
+        if len(childdatas) > 0:
+            return [subdata.value for subdata in childdatas]
+        else: 
+            return self.dataproxy._get_value(attr=attr)
+
+    value = property(get_value, set_value)
+
+
+class FeatureLink(Base):
+    """
+    A _FeatureProxy class. _FeatureProxy is the object that is added to View as a 
+    link to the actual Feature object. 
+    """
+    def __init__(self, link="", **kwargs):
+        # Store the fully qualified reference to this object
+        self.link = link
+        ref = link.replace('.', '_')
+        super(FeatureLink, self).__init__(ref)
+        self._obj = None
+        self._populated = False
+
+    @property
+    def fqr(self):
+        return self.link
+
+    def populate(self):
+        """
+        Populate or fetch the link to the actual feature for this featureproxy.
+        This method fetches the feature to the _obj member variable and populates also 
+        subfeatures. 
+        """
+        try:
+            if not self._populated:
+                feas = self.get_default_view().get_features(self.link)
+                # add the found features to the parent
+                for fea in feas:
+                    self._get_parent().add_feature(fea._obj)
+        except exceptions.NotFound, e:
+                parent_view = self._find_parent_or_default(type=View)
+                view_name = parent_view.get_name()
+                logging.getLogger('cone').info("Warning: Feature '%s' in view '%s' not found." % (self.link, view_name))
+
+
+class _FeatureProxy(container.ObjectProxyContainer, Base):
+    """
+    A _FeatureProxy class. _FeatureProxy is the object that is added to View as a 
+    link to the actual Feature object. 
+    """
+    def __init__(self, ref="", obj=None, **kwargs):
+        super(_FeatureProxy, self).__init__(obj, ref)
+        Base.__init__(self, ref)
+        self.support_data = False
+
+    def __getattr__(self, name):
+        """
+        First check if the requested attr is a children then 
+        direct all not found attribute calls to the sub object getattr
+        """
+        try:
+            return self.__dict__['_children'][name] 
+        except KeyError:
+            return getattr(self._obj, name)
+
+    def __getitem__(self, index):
+        return self._objects()[index]
+
+    def __setitem__(self, index, value):
+        raise exceptions.NotSupported()
+
+    def __delitem__(self, index):
+        item = self.__getitem__(index)
+        return self._remove(item.get_ref())
+
+    def __len__(self):
+        return len(self._order)
+
+    def _supported_type(self, obj):
+        if isinstance(obj, _FeatureProxy):
+            return True
+        else:
+            return False
+
+    def _default_object(self, name):
+        return Group(name)
+
+    def _set_parent(self, newparent):
+        """
+        @param newparent:  The new parent object
+        @return: None
+        """
+        self._parent = newparent
+
+    def add_feature(self, feature, path=""):
+        """
+        """
+        if not isinstance(feature, Feature):
+            raise exceptions.IncorrectClassError("add_feature requires instance of Feature!! Given %s" % feature)
+        if not self.support_data:
+            self._add_to_path(path, _FeatureProxy(feature._name, feature))
+        else:
+            self._add_to_path(path, _FeatureDataProxy(feature._name, feature))
+
+    def remove_feature(self, ref):
+        """
+        remove a given feature from this view by reference. 
+        @param ref: 
+        """
+        self._remove(ref)
+
+    def get_feature(self, path):
+        """
+        @param path: The path (ref) to the given feature 
+        """
+        return self._get(path)
+
+    def list_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return self._list()
+
+    def list_all_features(self):
+        """
+        Return a array of all Feature children references under this object.
+        """
+        return [fea._path(self) for fea in self._traverse(type=_FeatureProxy)]
+
+    def populate(self):
+        """
+        Dummy implementation of populate
+        """
+        pass
+
+
+class _FeatureDataProxy(_FeatureProxy):
+    """
+    A Feature class. Feature is the base for all Configurable items in a Configuration.
+    """
+    DEFAULT_KEY = 'data'
+    def __init__(self, ref="", obj=None, **kwargs):
+        # Initialize _obj to None, because __getattr__(), __setattr__()
+        # and __delattr__() access it.
+        # Note that we cannot use self._obj = None here, since that would
+        # invoke __setattr__(), causing a kind of a chicken-and-egg problem
+        object.__setattr__(self, '_obj', None)
+        
+        super(_FeatureDataProxy, self).__init__(ref, obj)
+        self.support_data = True
+        """ Create the data container of all types of data. Add the key for the default key. """
+        
+        self.defaultkey = _FeatureDataProxy.DEFAULT_KEY
+        self.datas = {self.defaultkey : []}
+
+    def __getattr__(self, name):
+        """
+        """
+        if object.__getattribute__(self, '_obj') is not None:
+            self._obj.dataproxy = self
+        
+        if name in Feature.PROPERTIES:
+            return getattr(self._obj, name)
+        else:
+            return super(_FeatureDataProxy, self).__getattr__(name)
+    
+    def __setattr__(self, name, value):
+        """
+        """
+        if object.__getattribute__(self, '_obj') is not None:
+            self._obj.dataproxy = self
+            
+        if name in Feature.PROPERTIES:
+            return setattr(self._obj, name, value)
+        else:
+            super(_FeatureDataProxy, self).__setattr__(name, value)
+
+    def __delattr__(self, name):
+        """
+        """
+        if name in Feature.PROPERTIES:
+            return delattr(self._obj, name)
+        else:
+            return super(_FeatureDataProxy, self).__delattr__(name)
+
+    def _add_data(self, data):
+        """
+        Add a data value.
+        @param data: A Data object  
+        """
+        try:
+            self.datas[data.attr].append(data)
+        except KeyError:
+            """ Create a list object for missing attribute """ 
+            self.datas[data.attr] = []
+            self.datas[data.attr].append(data)
+
+    def _get_data(self, attr=None):
+        """
+        Get the data value. in sequence setting cases returns an array of data.
+        """
+        dataattr = attr or self.defaultkey
+        try:
+            if len(self.datas[dataattr]) > 0:
+                return self.datas[dataattr][-1]
+            else:
+                return None
+        except KeyError:
+            """ return None for missing attribute """ 
+            return None
+
+    def _get_datas(self, attr=None):
+        """
+        Get the entire data array.
+        """
+        dataattr = attr or self.defaultkey
+        return self.datas[dataattr]
+
+    def _get_value(self, attr=None):
+        """
+        Get the topmost data value.
+        """
+        if self._get_data(attr):
+            return self._get_data(attr).get_value()
+        else:
+            return None
+
+    def _set_value(self, datavalue, attr=None):
+        """
+        Set the value for the feature the last configuration in the current hierarchy
+        @param value: The value for the feature.
+        @return: The created Data object.  
+        """
+        # Make sure that data value exists only once the the last configuration layer
+        # So if last_data exists on last layer, update the value of that data element.
+        # otherwise create a new data elem to the topmost layer
+        dataobj = self._get_data(attr)
+        last_config = self.get_root_configuration().get_last_configuration()
+        if dataobj and dataobj.find_parent(type=Configuration) == last_config:
+            dataobj.set_value(datavalue)
+        else:
+            dataobj = Data(fqr=self.fqr, value=datavalue, attr=attr)
+            last_config.add_data(dataobj)
+            self._add_data(dataobj)
+        return dataobj
+
+    def _del_value(self, attr=None):
+        """
+        Remove the 
+        """
+        data = self._get_data(attr)
+        if data:
+            dataattr = attr or self.defaultkey
+            parentconfig = data.find_parent(type=Configuration)
+            if parentconfig:
+                parentconfig.remove_data(data.get_fullfqr())
+            del self.datas[dataattr][-1]
+
+    def _get_values(self, attr=None):
+        """
+        Get the topmost data value.
+        """
+        dataattr = attr or self.defaultkey
+        return [dataelem.get_value() for dataelem in self.datas[dataattr]]
+
+
+class DataBase(Base):
+    def __init__(self, ref="", **kwargs):
+        super(DataBase, self).__init__(ref, **kwargs)
+
+    def _supported_type(self, obj):
+        if isinstance(obj, (DataContainer, DataBase)):
+            return True
+        else:
+            return False
+
+    def _default_object(self, name):
+        return Data(ref=name)
+
+    def count(self):
+        return len(self._objects())
+
+    def add(self, child, policy=container.REPLACE):
+        """
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, (Data)):
+                self._add(child, container.APPEND)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s object to %s" % (child, self))
+
+
+class DataContainer(DataBase):
+    def __init__(self, ref="", **kwargs):
+        super(DataContainer, self).__init__(ref, **kwargs)
+
+
+class Data(DataBase):
+    """
+    The data element can contain any data setting for a feature. The data element can be 
+    a value definition for any type of data. It basically just links some data to a feature. 
+    The default Data attribute is 'data', but it can be any string. For example current use case 
+    is 'rfs'.
+    """
+    def __init__(self, **kwargs):
+        """
+        @param ref: the reference to the feature. E.g. foo
+        @param fqr: the full reference to the feature. E.g. 'foo.bar' 
+        @param value: the value of the data
+        @param attr: the attribute which the Data object defines. e.g. default is 'data'. But could be 
+        for example 'rfs'
+        """
+        name = kwargs.get('ref', '')
+        self.fearef = kwargs.get('fqr', None)
+        if self.fearef:
+            (namespace, name) = utils.dottedref.psplit_ref(self.fearef)
+        super(Data, self).__init__(name)
+        self.value  = kwargs.get('value', None)
+        self.attr   = kwargs.get('attr') or 'data'
+        self.policy = kwargs.get('policy', '')
+        self.template = kwargs.get('template', False)
+        self.map    = kwargs.get('map')
+
+    def get_fearef(self):
+        if self.fearef:
+            return self.fearef
+        else:
+            return self.fqr
+
+    def get_value(self):
+        if self.map != None:
+            ref = utils.resourceref.to_dref(self.get_map_ref())
+            key = self.get_map_key_value()
+            dview = self.get_root_configuration().get_default_view()
+            fea = dview.get_feature(ref)
+            return fea.get_map_key_value(key)
+        else:
+            return self.value
+
+    def get_map(self):
+        return self.map
+
+    def set_map(self, map):
+        self.map = map
+        if self.value:
+            #Either value or mapping can be defined. Not both.
+            self.value = None
+
+    def get_map_ref(self):
+        if self.map != None:
+            return utils.DataMapRef.get_feature_ref(self.map)
+        else:
+            return None
+
+    def get_map_key_value(self):
+        if self.map != None:
+            return utils.DataMapRef.get_key_value(self.map)
+        else:
+            return None
+
+    def set_value(self, value):
+        self.value = value
+        if self.map:
+            #Either value or mapping can be defined. Not both.
+            self.map = None
+
+    def get_policy(self): return self._policy
+    def set_policy(self, value): self._policy = value
+    def del_policy(self):  self._policy = None
+    policy = property(get_policy, set_policy, del_policy)
+
+
+class ValueSet(sets.Set):
+    """
+    A value set object to indicate a set of possible values for a feature. 
+    e.g. A boolean feature ValueSet([True, False])
+    """
+    def __init__(self, initial_set=None):
+        super(ValueSet, self).__init__(initial_set or [])
+
+
+class ValueRange(object):
+    """
+    """
+    def __init__(self, fromvalue, tovalue, step=1):
+        self.fromvalue = fromvalue
+        self.tovalue = tovalue
+        self.step = step
+
+    def __contains__(self, value):
+        return self.fromvalue <= value and value <= self.tovalue and (value-self.fromvalue) % self.step == 0
+
+
+class ValueRe(object):
+    """
+    """
+    def __init__(self, regexp):
+        self.regexp = re.compile(regexp)
+
+    def __contains__(self, value):
+        if isinstance(value, str):
+            return self.regexp.match(value)
+        else:
+            return False
+    
+
+class Option(Base):
+    """
+    Confml option class.
+    """
+    def __init__(self, name, value, **kwargs):
+        super(Option, self).__init__(Option.to_optref(value, kwargs.get('map', None)))
+        self.name = name
+        self.value = value
+        self.map = kwargs.get('map', None)
+        self.relevant = kwargs.get('relevant', None)
+
+    @classmethod
+    def to_optref(cls, value, map):
+        """ 
+        @return: An option reference converted from value or map, depending
+            on which one is not None.
+        """
+        if value is not None:
+            return "opt_value_%s" % value.replace('.', '').replace('/', '').replace(' ', '')
+        elif map is not None:
+            return "opt_map_%s" % map.replace('.', '').replace('/', '').replace(' ', '')
+        else:
+            raise ValueError("Both value and map are None!")
+
+    def get_name(self):
+        return self.name
+
+    def get_value(self):
+        return self.value
+
+    def __cmp__(self, other):
+        try:
+            ref = getattr(other, 'ref')
+        except AttributeError:
+            ref = other
+        if self.ref < ref:
+            return -1
+        elif self.ref == ref:
+            return 0
+        else:
+            return 1
+
+
+class Storage(object):
+    """
+    A general base class for all storage type classes
+    """
+    """ File open modes """ 
+    MODE_UNKNOWN= -1
+    MODE_READ   = 1
+    MODE_WRITE  = 2
+    MODE_APPEND = 3
+    MODE_DELETE = 4
+
+    def __init__(self, path):
+        """
+        @param path: the reference to the root of the storage.
+        """
+        self.rootpath = path
+        self.curpath = ""
+        self.container = True
+        self.__opened_res__ = {}
+
+    def __opened__(self, res):
+        """
+        Internal function to add a newly opened Resource object to the list of open resources.
+        @param res: The resource object 
+        """
+        if self.__opened_res__.has_key(res.path):
+            self.__opened_res__[res.path].append(res)
+        else:
+            self.__opened_res__[res.path] = [res]
+
+    def __closed__(self, res):
+        """
+        Internal function to remove a Resource object from the list of open resources.
+        @param res: The resource object to remove
+        @raise StorageException if the given resource object is not found: 
+        """
+        try:
+            self.__opened_res__[res.path].remove(res)
+            if len(self.__opened_res__[res.path]) == 0:
+                del self.__opened_res__[res.path]
+        except KeyError, e:
+            raise exceptions.StorageException("No such %s open resource! %s" % (res, e))
+
+    def __has_open__(self, ref):
+        """
+        Internal function to find out if any Resource objects are open from given ref.
+        @param ref: The resource ref
+        @return: True if resources found. Otherwise False.   
+        """
+        return self.__opened_res__.has_key(ref)
+
+    def __get_open__(self, path):
+        """
+        Internal function to get all resource opened on a certain ref .
+        @param ref: The resource ref
+        @return: A list of open resources. Empty list if nothing is found   
+        """
+        if self.__has_open__(path):
+            # return a copy of currently open resources
+            return self.__opened_res__[path][:]
+        else:
+            return []
+
+    def __has_resource__(self, res):
+        """
+        Internal function to find out if the given Resource objects is open in this storage.
+        @param ref: The resource object
+        @return: True if resources found. Otherwise False.   
+        """
+        try:
+            res = self.__opened_res__[res.path].index(res)
+            return True
+        except KeyError, e:
+            return False
+
+    @classmethod
+    def open(cls,path, mode="r", **kwargs):
+        """
+        Class method for opening an instance of Storage
+        @param path: path to storage, which will determine what type of storage is initiated. 
+        """
+        # import all storage instances
+        from cone.storage import storages
+        for storagename in storages:
+            storagemodule = 'cone.storage.'+storagename
+            module = __import__(storagemodule)
+        for storage_class in utils.all_subclasses(Storage):
+            if storage_class.supported_storage(path):
+                if hasattr(storage_class, '__open__'):
+                    return storage_class.__open__(path, mode, **kwargs)
+                else:
+                    return storage_class(path, mode, **kwargs)
+        
+        obj = Storage(path)
+        return obj
+
+    @classmethod
+    def supported_storage(cls, path):
+        """
+        Class method for determing if the given clas supports a storage by given path. 
+        E.g. foo.zip, foo.cpd, foo/bar, http://foo.com/
+        @param path:
+        @return: Boolean value. True if the storage of the path is supported. False if not.  
+        """
+        return False
+
+    def set_path(self, path):
+        """
+        """
+        self.rootpath = path
+
+    def get_path(self):
+        """
+        """
+        return self.rootpath
+
+    def set_current_path(self, path):
+        """
+        @param path: the current path under the Storage. 
+        """
+        self.curpath = utils.resourceref.remove_end_slash(utils.resourceref.remove_begin_slash(path))
+
+    def get_current_path(self):
+        """
+        get the current path under the Storage. 
+        """
+        return self.curpath
+
+    def close(self):
+        """
+        Close the repository, which will save and close all open resources.  
+        """
+        for openref in self.__opened_res__.keys():
+            for res in self.__get_open__(openref):
+                self.close_resource(res)
+
+    def save(self):
+        """
+        Flush changes from all resources to the repository.  
+        """        
+        for openref in self.__opened_res__.keys():
+            for res in self.__get_open__(openref):
+                self.save_resource(res)
+
+    def open_resource(self, path, mode="r"):
+        """
+        Open the given resource and return a File object.
+        @param path : reference to the resource 
+        @param mode : the mode in which to open. Can be one of r = read, w = write, a = append.
+        raises a NotResource exception if the ref item is not a resource.
+        """  
+        raise exceptions.NotSupportedException()
+
+    def delete_resource(self, path):
+        """
+        Delete the given resource from storage
+        @param path: reference to the resource 
+        raises a NotSupportedException exception if delete operation is not supported by the storage
+        """  
+        raise exceptions.NotSupportedException()
+
+    def close_resource(self, path):
+        """
+        Close a given resource instance. Normally this is called by the Resource object 
+        in its own close.
+        @param path the reference to the resource to close. 
+        """
+        raise exceptions.NotSupportedException()
+
+    def is_resource(self, path):
+        """
+        Return true if the ref is a resource
+        @param ref : reference to path where resources are searched
+        """
+        raise exceptions.NotSupportedException()
+
+    def list_resources(self, path, recurse=False):
+        """
+        find the resources under certain ref/path 
+        @param ref : reference to path where resources are searched
+        @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders. 
+        Default value is False. Set to True to enable recursion.
+        """  
+        return []
+
+    def import_resources(self, paths, storage):
+        """
+        import resources from a list of resources to this storage
+        @param paths : a list of Resourse objects.
+        @param storage : the external storage from which files are imported.
+        """  
+        raise exceptions.NotSupportedException()
+
+    def export_resources(self, paths, storage):
+        """
+        export resources from this storage based on a list of reference to this storage
+        @param path : a list of resource paths in this storage (references).
+        @param storage : the external storage where to export.
+        """  
+        raise exceptions.NotSupportedException()
+
+    def close_resource(self, path):
+        """
+        Close a given resource instance. Normally this is called by the Resource object 
+        in its own close.
+        @param ref the reference to the resource to close. 
+        """
+        raise exceptions.NotSupportedException()
+
+    def save_resource(self, path):
+        """
+        Flush the changes of a given resource instance. Normally this is called by the Resource object 
+        in its own save.
+        @param ref the reference to the resource to close. 
+        """
+        raise exceptions.NotSupportedException()
+
+    def create_folder(self, path):
+        """
+        Create a folder entry to a path
+        @param path : path to the folder
+        """  
+        raise exceptions.NotSupportedException()
+
+    def delete_folder(self, path):
+        """
+        Delete a folder entry from a path. The path must be empty.
+        @param path : path to the folder
+        """  
+        raise exceptions.NotSupportedException()
+
+    def is_folder(self, path):
+        """
+        Check if the given path is an existing folder in the storage
+        @param path : path to the folder
+        """
+        raise exceptions.NotSupportedException()
+
+    def get_mode(self, mode_str):
+        if mode_str.find("w") != -1: 
+            return self.MODE_WRITE
+        elif mode_str.find("r") != -1:
+            return self.MODE_READ
+        elif mode_str.find("a") != -1:
+            return self.MODE_APPEND
+        elif mode_str.find("d") != -1:
+            return self.MODE_DELETE
+        else:
+            return self.MODE_UNKNOWN
+
+    def unload(self, path, object):
+        """
+        Dump a given object to the storage 
+        @param object: The object to dump to the storage, which is expected to be an instance 
+        of Base class.
+        @param path: The reference where to store the object 
+        @param object: The object instance to dump 
+        @raise StorageException: if the given object cannot be dumped to this storage 
+        """
+        raise exceptions.NotSupportedException()
+
+    def load(self, path):
+        """
+        Load an object from a reference.
+        @param path: The reference where to load the object 
+        @raise StorageException: if the given object cannot be loaded as an object from this storage 
+        """
+        raise exceptions.NotSupportedException()
+
+    path = property(get_path, set_path)
+
+class Resource(object):
+    STATE_OPEN = 0
+    STATE_CLOSE = 1
+    def __init__(self, storage, path, mode=Storage.MODE_READ):
+        self.storage = storage
+        self.path = path
+        self.mode = mode
+        self.state = Resource.STATE_OPEN
+        self.content_info = None
+
+    def get_path(self):
+        return self.path
+
+    def close(self):
+        """
+        Close the resource. 
+        Note1: the resource object cannot be accessed anymore after it has been closed.
+        Note2: the changes are not automatically saved. The save operation must be explicitly called, 
+        to save data. 
+        """
+        self.storage.close_resource(self.path)
+        self.state = Resource.STATE_OPEN
+
+    def read(self, bytes=0):
+        """
+        Read data.
+        """
+        raise exceptions.NotSupportedException()
+
+    def write(self, string):
+        """
+        Write data.
+        """
+        raise exceptions.NotSupportedException()
+
+    def truncate(self, size=0):
+        """
+        Trunkate this resource data to the given size.
+        @param size: The size to trunkate. Default value is zero, which make the resource empty. 
+        """
+        raise NotSupportedException()
+
+    def save(self, size=0):
+        """
+        Save all changes to data to storage.
+        """
+        raise NotSupportedException()
+
+    def get_mode(self):
+        return self.storage.get_mode(self.mode)
+    
+    def get_size(self):
+        """
+        Return the size of this resource in bytes.
+        
+        Note that this does not work in write mode.
+        @return: The resource size in bytes:
+        @raise exceptions.StorageException: The resource was opened in write mode.
+        """
+        raise exceptions.NotSupportedException()
+    
+    def get_content_info(self):
+        """
+        Return the ContentInfo class that contains content information about
+        resource.
+        """
+        raise exceptions.NotSupportedException()
+        
+class ContentInfo(object):
+    """
+    A ContentInfo object is used to describe content of Resource. 
+    """
+    logger = logging.getLogger('cone.contentinfo')
+
+    
+    def __init__(self, mimetype, mimesubtype):
+        #: MIME Media type (http://www.iana.org/assignments/media-types/)
+        #: as a string. E.g. 'image' or 'application'
+        self.mimetype = mimetype
+        #: MIME Media subtype as a string. E.g. 'svg+xml' or 'bmp'.
+        self.mimesubtype = mimesubtype
+    
+    @property
+    def content_type(self):
+        """
+        Returns MIME Media type (http://www.iana.org/assignments/media-types/) 
+        and subtype as a string. E.g. 'image/bmp'. 
+        """
+        return self.mimetype + '/' + self.mimesubtype
+
+class ImageContentInfo(ContentInfo):
+    
+    """
+    A ImageContentInfo object is used to describe content of image Resources.
+    """
+    def __init__(self):
+        ContentInfo.__init__(self, 'image', '')
+
+class BmpImageContentInfo(ImageContentInfo):
+    """
+    A BmpImageContentInfo object is used to describe content of bmp image 
+    Resources.
+    """
+    
+    _BMP_BITS_PER_PIXEL_OFFSET_ = int('0x1C', 16)
+    
+    def __init__(self, resource, data):
+        ContentInfo.__init__(self, 'image', 'bmp')
+        
+        #: Color depth as bits per pixel.
+        self.color_depth = None
+        if (resource != None):
+            try:
+                self.color_depth = ord(data[self._BMP_BITS_PER_PIXEL_OFFSET_])
+            except Exception, e:
+                self.logger.warning("Invalid BMP-file: %s" % resource.get_path())
+        
+class Folder(object):
+    """
+    A Folder object is a subfolder of a Storage, offering access to part of the Storages resources.
+    """
+    def __init__(self, storage, path):
+        """
+        Create a layer folder to the storage if it does not exist.
+        """
+        #if not storage.is_folder(path):
+        #    storage.create_folder(path)
+        self.storage = copy.copy(storage)
+        self.storage.set_current_path(path)
+
+    def __getattr__(self, name):
+        return getattr(self.storage, name)
+
+class CompositeLayer(object):
+    """
+    A base class for composite Configuration objects.  
+    """
+    def __init__(self, path="", **kwargs):
+        self.layers = kwargs.get('layers', [])
+        self.path = path
+
+    def add_layer(self, layer):
+        self.layers.append(layer)
+
+    def remove_layer(self, path):
+        if self.get_layer(path):
+            self.layers.remove(self.get_layer(path))
+        else:
+            raise exceptions.NotFound('Layer with given path %s not found!' % path)
+
+    def get_layer(self, path):
+        for layer in self.layers:
+            if layer.get_current_path() == path:
+                return layer
+        return None
+
+    def list_layers(self):
+        return [layer.get_current_path() for layer in self.layers]
+
+    def list_confml(self):
+        """
+        @return: array of confml file references.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            for respath in self.get_layer(layerpath).list_confml():
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+        return lres
+
+    def list_implml(self):
+        """
+        @return: array of implml file references.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            for respath in self.get_layer(layerpath).list_implml():
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+        return lres
+
+    def list_content(self):
+        """
+        @return: array of content file references.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            for respath in self.get_layer(layerpath).list_content():
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+        return lres
+
+    def list_doc(self):
+        """
+        @return: array of document file references.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            for respath in self.get_layer(layerpath).list_doc():
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+        return lres
+
+    def list_all_resources(self, empty_folders=False):
+        """
+        Returns a list of all layer related resource paths with full path in the storage.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            sublayer = self.get_layer(layerpath)
+            for respath in sublayer.list_all_resources(empty_folders):
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+                
+        return lres
+
+class Layer(CompositeLayer):
+    """
+    A Layer object is a subfolder of a Storage, offering access to part of the Storages resources.
+    """
+    def __init__(self, storage, path, **kwargs):
+        """
+        Create a layer folder to the storage if it does not exist.
+        @param storage: a reference to the Storage object
+        @param path: path for the layer 
+        @param confml_path: optional parameter for confml files path (give in confml_path="something") 
+        @param imlpml_path: optional parameter for implml files path (give in implml_path="something")
+        @param content_path: optional parameter for content files path (give in content_path="something")
+        @param doc_path: optional parameter for doc files path (give in doc_path="something")
+        """
+        super(Layer, self).__init__(path, **kwargs)
+        #if not storage.is_folder(path):
+        #    storage.create_folder(path)
+        self.storage = copy.copy(storage)
+        self.storage.set_current_path(path)
+        self.predefined = {'confml_path' : 'confml', 
+                           'implml_path' : 'implml', 
+                           'content_path' : 'content', 
+                           'doc_path' : 'doc'}
+        # list through all "hardcoded" paths and check whether the 
+        # hardcoded or given path exists under this Layer. 
+        # if it does then create a folder instance to that path 
+        for (pretag, prevalue) in self.predefined.items():
+            self.predefined[pretag] = kwargs.get(pretag, prevalue)
+
+    def __getattr__(self, name):
+        return getattr(self.storage, name)
+
+    def list_confml(self):
+        """
+        @return: array of confml file references.
+        """
+        res = self.storage.list_resources(self.predefined['confml_path'], True)
+        res += super(Layer, self).list_confml()
+        return res 
+
+    def list_implml(self):
+        """
+        @return: array of implml file references.
+        """
+        res = self.storage.list_resources(self.predefined['implml_path'], True)
+        res += super(Layer, self).list_implml()
+        return res 
+
+    def list_content(self):
+        """
+        @return: array of content file references.
+        """
+        res = self.storage.list_resources(self.predefined['content_path'], True)
+        res += super(Layer, self).list_content()
+        return res
+
+    def list_doc(self):
+        """
+        @return: array of document file references.
+        """
+        res = self.storage.list_resources(self.predefined['doc_path'], True)
+        res += super(Layer, self).list_doc()
+        return res
+
+    def confml_folder(self):
+        cpath = self.storage.get_current_path()
+        spath = self.predefined['confml_path']
+        return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
+
+    def implml_folder(self):
+        cpath = self.storage.get_current_path()
+        spath = self.predefined['implml_path']
+        return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
+
+    def content_folder(self):
+        cpath = self.storage.get_current_path()
+        spath = self.predefined['content_path']
+        return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
+
+    def doc_folder(self):
+        cpath = self.storage.get_current_path()
+        spath = self.predefined['doc_path']
+        return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
+
+    def list_all_resources(self, empty_folders=False):
+        """
+        Returns a list of all layer related resource paths with full path in the storage.
+        """
+        lres = []
+        mypath = self.get_current_path()
+        
+        for folderpath in sorted(self.predefined.values()):
+            lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
+                 
+        lres += super(Layer, self).list_all_resources(empty_folders)
+        
+        return lres
+
+    def list_all_related(self, empty_folders=False):
+        """
+        Returns a list of all (non confml) layer related resource paths with full path in the storage.
+        """
+        lres = []
+        predef = self.predefined.copy()
+        del predef['confml_path']
+        mypath = self.get_current_path()
+        for folderpath in sorted(predef.values()):
+            lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
+        lres += super(Layer, self).list_all_resources(empty_folders=empty_folders)
+       
+        return lres
+
+
+class Rule(object):
+    """
+    Base class for Rules in the system.
+    """
+    def __init__(self):
+        raise exceptions.NotSupportedException()
+            
+
+class FactoryBase(object):
+    pass
+
+class Factory(object):
+    def __getattr__(self, name):
+        """
+        The Factory getattr find all subclasses for the Factory and searches for given attr 
+        in those.
+        """
+        for sub_factory in utils.all_subclasses(FactoryBase):
+            try:
+                return getattr(sub_factory(), name)
+            except AttributeError:
+                continue 
+        raise AttributeError("type object %s has no attribute '%s'" % (self.__class__, name))
+
+def get_mapper(modelname):
+    """
+    Return a instance of appropriate mapper for given model.
+    """
+    mapmodule = __import__('cone.public.mapping')
+    return mapmodule.public.mapping.BaseMapper()
+
+
+##################################################################
+class NullHandler(logging.Handler):
+    """
+    Default handler that does not do anything.
+    """
+    def emit(self, record):
+        pass
+
+#Initialization of default logger that contains NullHandler.
+logger = logging.getLogger('cone')
+logger.addHandler(NullHandler())