Add showMapping command to the PFW

BZ: 99822

Developers often need to get the mapping corresponding to a specific
parameter. However, the PFW doesn't provide a command to achieve this
goal.

This patch aims to add the showMapping command to the PFW.

Change-Id: I05af64a408abe4ceb7f5d177a0ff5fa0461034d0
Signed-off-by: Frédéric Boisnard <fredericx.boisnard@intel.com>
Reviewed-on: http://android.intel.com:8080/105145
Reviewed-by: Benavoli, Patrick <patrick.benavoli@intel.com>
Reviewed-by: Denneulin, Guillaume <guillaume.denneulin@intel.com>
Reviewed-by: Gonzalve, Sebastien <sebastien.gonzalve@intel.com>
Tested-by: Barthes, FabienX <fabienx.barthes@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/parameter/Android.mk b/parameter/Android.mk
index edfd71c..c356c4d 100644
--- a/parameter/Android.mk
+++ b/parameter/Android.mk
@@ -83,6 +83,7 @@
         SimulatedBackSynchronizer.cpp \
         MappingContext.cpp \
         SubsystemObject.cpp \
+        FormattedSubsystemObject.cpp \
         SubsystemObjectCreator.cpp \
         BaseParameter.cpp \
         AutoLock.cpp \
diff --git a/parameter/ConfigurableElement.cpp b/parameter/ConfigurableElement.cpp
index 2962295..b87811f 100644
--- a/parameter/ConfigurableElement.cpp
+++ b/parameter/ConfigurableElement.cpp
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -151,6 +151,20 @@
     return pChild->accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
 }
 
+void CConfigurableElement::getListOfElementsWithMapping(
+        list<const CConfigurableElement*>& configurableElementPath) const
+{
+    // Check parent
+    const CElement* pParent = getParent();
+    if (isOfConfigurableElementType(pParent)) {
+
+        const CConfigurableElement* pConfigurableElement =
+                static_cast<const CConfigurableElement*>(pParent);
+
+        pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
+    }
+}
+
 // Used for simulation and virtual subsystems
 void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
 {
diff --git a/parameter/ConfigurableElement.h b/parameter/ConfigurableElement.h
index 69816f6..796715a 100644
--- a/parameter/ConfigurableElement.h
+++ b/parameter/ConfigurableElement.h
@@ -91,6 +91,23 @@
 
     // Parameter access
     virtual bool accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const;
+
+    /**
+     * Get the list of all the ancestors that have a mapping.
+     *
+     * The mapping is represented as a string of all the mapping data (key:value) defined in the
+     * context of the element.
+     * In this class, the method is generic and calls its parent getListOfElementsWithMappings(...)
+     * method.
+     *
+     * @param[in:out] configurableElementPath List of all the ConfigurableElements found
+     * that have a mapping. Elements are added at the end of the list, so the root Element will be
+     * the last one.
+     *
+     */
+    virtual void getListOfElementsWithMapping(list<const CConfigurableElement*>&
+                                               configurableElementPath) const;
+
     // Used for simulation and virtual subsystems
     virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const;
 
@@ -106,6 +123,7 @@
     virtual void fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const;
     // Configuration Domain local search
     bool containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const;
+
 private:
     // Configurable domain association
     void addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain);
diff --git a/parameter/FormattedSubsystemObject.cpp b/parameter/FormattedSubsystemObject.cpp
new file mode 100644
index 0000000..7e527e3
--- /dev/null
+++ b/parameter/FormattedSubsystemObject.cpp
@@ -0,0 +1,123 @@
+/*
+ * INTEL CONFIDENTIAL
+ * Copyright © 2013 Intel
+ * Corporation All Rights Reserved.
+ *
+ * The source code contained or described herein and all documents related to
+ * the source code ("Material") are owned by Intel Corporation or its suppliers
+ * or licensors. Title to the Material remains with Intel Corporation or its
+ * suppliers and licensors. The Material contains trade secrets and proprietary
+ * and confidential information of Intel or its suppliers and licensors. The
+ * Material is protected by worldwide copyright and trade secret laws and
+ * treaty provisions. No part of the Material may be used, copied, reproduced,
+ * modified, published, uploaded, posted, transmitted, distributed, or
+ * disclosed in any way without Intel’s prior express written permission.
+ *
+ * No license under any patent, copyright, trade secret or other intellectual
+ * property right is granted to or conferred upon you by disclosure or delivery
+ * of the Materials, either expressly, by implication, inducement, estoppel or
+ * otherwise. Any license under such intellectual property rights must be
+ * express and approved by Intel in writing.
+ *
+ */
+
+#include "FormattedSubsystemObject.h"
+#include "InstanceConfigurableElement.h"
+#include "MappingContext.h"
+#include <assert.h>
+
+#define base CSubsystemObject
+
+CFormattedSubsystemObject::CFormattedSubsystemObject(
+        CInstanceConfigurableElement* pInstanceConfigurableElement)
+    : base(pInstanceConfigurableElement)
+{
+}
+
+CFormattedSubsystemObject::CFormattedSubsystemObject(
+        CInstanceConfigurableElement* pInstanceConfigurableElement,
+        const string& strMappingValue)
+    : base(pInstanceConfigurableElement), _strFormattedMappingValue(strMappingValue)
+{
+
+}
+
+
+CFormattedSubsystemObject::CFormattedSubsystemObject(
+        CInstanceConfigurableElement* pInstanceConfigurableElement,
+        const string& strMappingValue,
+        uint32_t uiFirstAmendKey,
+        uint32_t uiNbAmendKeys,
+        const CMappingContext& context)
+    : base(pInstanceConfigurableElement), _strFormattedMappingValue(strMappingValue)
+{
+    // Cope with quotes in the name
+    if (strMappingValue[0] == '\'' && strMappingValue.length() >= 2) {
+
+        _strFormattedMappingValue = strMappingValue.substr(1, strMappingValue.length() - 2);
+    }
+    _strFormattedMappingValue = formatMappingValue(_strFormattedMappingValue, uiFirstAmendKey,
+                                                   uiNbAmendKeys, context);
+}
+
+CFormattedSubsystemObject::~CFormattedSubsystemObject()
+{
+}
+
+string CFormattedSubsystemObject::getFormattedMappingValue() const
+{
+    return _strFormattedMappingValue;
+}
+
+bool CFormattedSubsystemObject::isAmendKeyValid(uint32_t uiAmendKey)
+{
+
+    return (uiAmendKey > 0) && (uiAmendKey <= 9);
+}
+
+string CFormattedSubsystemObject::formatMappingValue(const string& strMappingValue,
+                                                     uint32_t uiFirstAmendKey,
+                                                     uint32_t uiNbAmendKeys,
+                                                     const CMappingContext& context)
+{
+    string strFormattedValue = strMappingValue;
+
+    // Search for amendment (only one supported for now)
+    size_t uiPercentPos = strFormattedValue.find('%', 0);
+
+    // Amendment limited to one digit (values from 1 to 9)
+    assert(isAmendKeyValid(uiNbAmendKeys));
+
+    // Check we found one and that there's room for value
+    if (uiPercentPos != string::npos && uiPercentPos < strFormattedValue.size() - 1) {
+
+        // Get Amend number
+        uint32_t uiAmendNumber = strFormattedValue[uiPercentPos + 1] - '0';
+
+        // Check if current Amend number is Valid
+        if ((uiAmendNumber > 0) && (uiAmendNumber <= uiNbAmendKeys)) {
+
+            uint32_t uiAmendType = uiFirstAmendKey + uiAmendNumber - 1;
+
+            // Check if current Amend type is Set in the context
+            if (context.iSet(uiAmendType)) {
+
+                // Make the amendment on the part of the string after the current Amend
+                string strEndOfLine = strFormattedValue.substr(uiPercentPos + 2,
+                                                               strFormattedValue.size()
+                                                               - uiPercentPos - 2);
+                string strEndOfLineAmended = formatMappingValue(strEndOfLine, uiFirstAmendKey,
+                                                                uiNbAmendKeys, context);
+
+                // Get current Amend value
+                string strAmendValue = context.getItem(uiAmendType);
+
+                // Make the amendment
+                strFormattedValue = strFormattedValue.substr(0, uiPercentPos) + strAmendValue
+                        + strEndOfLineAmended;
+
+            }
+        }
+    }
+    return strFormattedValue;
+}
diff --git a/parameter/FormattedSubsystemObject.h b/parameter/FormattedSubsystemObject.h
new file mode 100644
index 0000000..dd90822
--- /dev/null
+++ b/parameter/FormattedSubsystemObject.h
@@ -0,0 +1,105 @@
+/*
+ * INTEL CONFIDENTIAL
+ * Copyright © 2013 Intel
+ * Corporation All Rights Reserved.
+ *
+ * The source code contained or described herein and all documents related to
+ * the source code ("Material") are owned by Intel Corporation or its suppliers
+ * or licensors. Title to the Material remains with Intel Corporation or its
+ * suppliers and licensors. The Material contains trade secrets and proprietary
+ * and confidential information of Intel or its suppliers and licensors. The
+ * Material is protected by worldwide copyright and trade secret laws and
+ * treaty provisions. No part of the Material may be used, copied, reproduced,
+ * modified, published, uploaded, posted, transmitted, distributed, or
+ * disclosed in any way without Intel’s prior express written permission.
+ *
+ * No license under any patent, copyright, trade secret or other intellectual
+ * property right is granted to or conferred upon you by disclosure or delivery
+ * of the Materials, either expressly, by implication, inducement, estoppel or
+ * otherwise. Any license under such intellectual property rights must be
+ * express and approved by Intel in writing.
+ *
+ */
+#pragma once
+
+#include "SubsystemObject.h"
+
+class CFormattedSubsystemObject : public CSubsystemObject
+{
+public:
+    /**
+     * Builds a new CFormattedSubsystemObject instance, without any mapping information.
+     *
+     * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject.
+     */
+    CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement);
+
+    /**
+     * Builds a new CFormattedSubsystemObject instance, using a simple mapping value without Amends.
+     *
+     * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject.
+     * @param[in] strFormattedMapping A string corresponding to the mapping of the element. The
+     * string does not contain any Amend (%) and does not need to be formatted.
+     */
+    CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement,
+                              const string& strFormattedMapping);
+
+    /**
+     * Builds a new CFormattedSubsystemObject instance, using a mapping value containing Amends.
+     *
+     * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject.
+     * @param[in] strMappingValue A string corresponding to the mapping of the element. The
+     * string contains Amend (%) and needs to be formatted with information from the context.
+     * @param[in] uiFirstAmendKey Index of the first Amend key
+     * @param[in] uiNbAmendKeys Number of Amends
+     * @param[in] context Contains values associated to Amend keys
+     */
+    CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement,
+                              const string& strMappingValue,
+                              uint32_t uiFirstAmendKey,
+                              uint32_t uiNbAmendKeys,
+                              const CMappingContext& context);
+    virtual ~CFormattedSubsystemObject();
+
+    /**
+     * Returns the formatted mapping value associated to the element.
+     *
+     * @return A string containing the mapping
+     */
+    virtual string getFormattedMappingValue() const;
+
+private:
+
+    /**
+     * Check if the index of Amend key is valid.
+     *
+     * @param uiAmendKey Index of the Amend key
+     *
+     * @return true if the index of the Amend key is > 0 and <= 9.
+     */
+    static bool isAmendKeyValid(uint32_t uiAmendKey);
+
+    /**
+     * Generic mapping formatting
+     *
+     * Format a string from mapping data and its context, replacing amendments by their value
+     *
+     * @param[in] strMappingValue The input mapping string containing amendments
+     * @param[in] context uiFirstAmendKey The index of the first Amend key in the key list of the
+     * context
+     * @param[in] uiNbAmendKeys Number of Amend keys in the context
+     * @param[in] context The context containing Amend values
+     *
+     * @return The formatted string, corresponding to the input strMappingValue where %n have been
+     * replaced by their value
+     */
+    static string formatMappingValue(const string& strMappingValue,
+                                     uint32_t uiFirstAmendKey,
+                                     uint32_t uiNbAmendKeys,
+                                     const CMappingContext& context);
+
+    /**
+     * string containing the formatted mapping value
+     */
+    string _strFormattedMappingValue;
+};
diff --git a/parameter/InstanceConfigurableElement.cpp b/parameter/InstanceConfigurableElement.cpp
index cc84a3e..d3cd740 100644
--- a/parameter/InstanceConfigurableElement.cpp
+++ b/parameter/InstanceConfigurableElement.cpp
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -100,6 +100,19 @@
     return true;
 }
 
+void CInstanceConfigurableElement::getListOfElementsWithMapping(
+        list<const CConfigurableElement*>& configurableElementPath) const
+{
+    const CTypeElement* pTypeElement = getTypeElement();
+
+    if (pTypeElement && pTypeElement->hasMappingData()) {
+
+        configurableElementPath.push_back(this);
+    }
+
+    base::getListOfElementsWithMapping(configurableElementPath);
+}
+
 // Element properties
 void CInstanceConfigurableElement::showProperties(string& strResult) const
 {
diff --git a/parameter/InstanceConfigurableElement.h b/parameter/InstanceConfigurableElement.h
index b1ffdf8..7cded0d 100644
--- a/parameter/InstanceConfigurableElement.h
+++ b/parameter/InstanceConfigurableElement.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -79,6 +79,21 @@
 
     // Array Length
     uint32_t getArrayLength() const;
+
+    /**
+     * Get the list of all the ancestors that have a mapping.
+     *
+     * The mapping is represented as a string of all the mapping data (key:value) defined in the
+     * context of the element.
+     * In this class, the method is generic and calls its parent getListOfElementsWithMappings(...)
+     * method.
+     *
+     * @param[in:out] configurableElementPath List of all the ConfigurableElements found
+     * that have a mapping. Elements are added at the end of the list, so the root Element will be
+     * the last one.
+     */
+    virtual void getListOfElementsWithMapping(list<const CConfigurableElement*>&
+                                               configurableElementPath) const;
 protected:
     // Syncer
     virtual ISyncer* getSyncer() const;
diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp
index 6293129..fdca8da 100644
--- a/parameter/ParameterMgr.cpp
+++ b/parameter/ParameterMgr.cpp
@@ -1,4 +1,4 @@
- /*
+     /*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -71,6 +71,7 @@
 #include "ParameterHandle.h"
 #include "LinearParameterAdaptation.h"
 #include "EnumValuePair.h"
+#include "Subsystem.h"
 #include "XmlFileDocSink.h"
 #include "XmlFileDocSource.h"
 #include "XmlStringDocSink.h"
@@ -221,6 +222,8 @@
     { "setConfigurationParameter", &CParameterMgr::setConfigurationParameterCommmandProcess, 4,
             "<domain> <configuration> <param path> <value>",
             "Set value for parameter at given path to configuration" },
+    { "showMapping", &CParameterMgr::showMappingCommmandProcess, 1,
+            "<elem path>", "Show mapping for an element at given path" },
 
     /// Browse
     { "listAssociatedElements", &CParameterMgr::listAssociatedElementsCommmandProcess, 0,
@@ -671,8 +674,9 @@
     }
 }
 
-// Dynamic parameter handling
-CParameterHandle* CParameterMgr::createParameterHandle(const string& strPath, string& strError)
+// Get the configurableElement corresponding to the given path
+const CConfigurableElement* CParameterMgr::getConfigurableElement(const string& strPath,
+                                                                  string& strError) const
 {
     CPathNavigator pathNavigator(strPath);
 
@@ -695,6 +699,21 @@
     // Check found element is a parameter
     const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pElement);
 
+    return pConfigurableElement;
+}
+
+// Dynamic parameter handling
+CParameterHandle* CParameterMgr::createParameterHandle(const string& strPath, string& strError)
+{
+    const CConfigurableElement* pConfigurableElement = getConfigurableElement(strPath, strError);
+
+    if (!pConfigurableElement) {
+
+        // Element not found
+        strError = "Element not found";
+        return NULL;
+    }
+
     if (!pConfigurableElement->isParameter()) {
 
         // Element is not parameter
@@ -704,7 +723,7 @@
     }
 
     // Convert as parameter and return new handle
-    return new CParameterHandle(static_cast<const CBaseParameter*>(pElement), this);
+    return new CParameterHandle(static_cast<const CBaseParameter*>(pConfigurableElement), this);
 }
 
 /////////////////// Remote command parsers
@@ -1372,6 +1391,18 @@
     return bSuccess ? CCommandHandler::EDone : CCommandHandler::EFailed;
 }
 
+CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showMappingCommmandProcess(
+        const IRemoteCommand& remoteCommand,
+        string& strResult)
+{
+    if (!getParameterMapping(remoteCommand.getArgument(0), strResult)) {
+
+        return CCommandHandler::EFailed;
+    }
+
+    return CCommandHandler::ESucceeded;
+}
+
 /// Settings Import/Export
 CParameterMgr::CCommandHandler::CommandStatus
         CParameterMgr::exportConfigurableDomainsToXMLCommmandProcess(
@@ -1465,6 +1496,42 @@
     return accessValue(parameterAccessContext, strPath, strValue, bSet, strError);
 }
 
+// User get parameter mapping
+bool CParameterMgr::getParameterMapping(const string& strPath, string& strResult) const
+{
+    CPathNavigator pathNavigator(strPath);
+
+    // Nagivate through system class
+    if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strResult)) {
+
+        return false;
+    }
+
+    // Get the ConfigurableElement corresponding to strPath
+    const CConfigurableElement* pConfigurableElement = getConfigurableElement(strPath, strResult);
+    if (!pConfigurableElement) {
+
+        return false;
+    }
+
+    // Find the list of the ancestors of the current ConfigurableElement that have a mapping
+    list<const CConfigurableElement*> configurableElementPath;
+    pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
+
+    // Get the Subsystem containing the ConfigurableElement
+    const CSubsystem* pSubsystem = pConfigurableElement->getBelongingSubsystem();
+    if (!pSubsystem) {
+
+        strResult = "Unable to find the Subsystem containing the parameter";
+        return false;
+    }
+
+    // Fetch the mapping corresponding to the ConfigurableElement
+    strResult = pSubsystem->getMapping(configurableElementPath);
+
+    return true;
+}
+
 // User set/get parameters in specific Configuration BlackBoard
 bool CParameterMgr::accessConfigurationValue(const string& strDomain, const string& strConfiguration, const string& strPath, string& strValue, bool bSet, string& strError)
 {
@@ -1535,6 +1602,8 @@
     // Nagivate through system class
     if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strError)) {
 
+        parameterAccessContext.setError(strError);
+
         return false;
     }
 
diff --git a/parameter/ParameterMgr.h b/parameter/ParameterMgr.h
index e7cb2bd..9677303 100644
--- a/parameter/ParameterMgr.h
+++ b/parameter/ParameterMgr.h
@@ -50,6 +50,7 @@
 class CParameterHandle;
 class CSubsystemPlugins;
 class CParameterAccessContext;
+class CConfigurableElement;
 
 class CParameterMgr : private CElement
 {
@@ -116,6 +117,17 @@
     // Configuration application
     void applyConfigurations();
 
+    /**
+     * Returns the CConfigurableElement corresponding to the path given in argument.
+     *
+     * @param[in] strPath A string representing a path to an element.
+     * @param[out] strError Error message
+     *
+     * @return A const pointer to the corresponding CConfigurableElement.
+     * On error, NULL is returned and the error is explained in strError.
+     */
+    const CConfigurableElement* getConfigurableElement(const string& strPath,
+                                                       string& strError) const;
     // Dynamic parameter handling
     CParameterHandle* createParameterHandle(const string& strPath, string& strError);
 
@@ -140,6 +152,15 @@
     // User set/get parameters
     bool accessValue(CParameterAccessContext& parameterAccessContext, const string& strPath, string& strValue, bool bSet, string& strError);
     bool accessParameterValue(const string& strPath, string& strValue, bool bSet, string& strError);
+    /**
+     * Returns the element mapping corresponding to the path given in parameter.
+     *
+     * @param[in] strPath Path of an element
+     * @param[out] strValue A sting containing the mapping
+     *
+     * @return true if a mapping was found for this element
+     */
+    bool getParameterMapping(const string& strPath, string& strValue) const;
     bool accessConfigurationValue(const string &strDomain, const string &stConfiguration, const string& strPath, string& strValue, bool bSet, string& strError);
 
     ////////// Configuration/Domains handling //////////////
@@ -280,6 +301,8 @@
     CCommandHandler::CommandStatus setConfigurationParameterCommmandProcess(const IRemoteCommand& remoteCommand, string& strResult);
     CCommandHandler::CommandStatus listBelongingDomainsCommmandProcess(const IRemoteCommand& remoteCommand, string& strResult);
     CCommandHandler::CommandStatus listAssociatedDomainsCommmandProcess(const IRemoteCommand& remoteCommand, string& strResult);
+    CCommandHandler::CommandStatus showMappingCommmandProcess(const IRemoteCommand& remoteCommand,
+                                                              string& strResult);
     /// Browse
     CCommandHandler::CommandStatus listAssociatedElementsCommmandProcess(const IRemoteCommand& remoteCommand, string& strResult);
     CCommandHandler::CommandStatus listConflictingElementsCommmandProcess(const IRemoteCommand& remoteCommand, string& strResult);
diff --git a/parameter/Subsystem.cpp b/parameter/Subsystem.cpp
index feac79d..5ae04d2 100644
--- a/parameter/Subsystem.cpp
+++ b/parameter/Subsystem.cpp
@@ -29,7 +29,9 @@
 #include "ParameterAccessContext.h"
 #include "ConfigurationAccessContext.h"
 #include "SubsystemObjectCreator.h"
+#include "MappingData.h"
 #include <assert.h>
+#include <sstream>
 
 #define base CConfigurableElement
 
@@ -172,6 +174,115 @@
     return base::accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
 }
 
+// Formats the mapping of the ConfigurableElements
+string CSubsystem::formatMappingDataList(
+        const list<const CConfigurableElement*>& configurableElementPath) const
+{
+    // The list is parsed in reverse order because it has been filled from the leaf to the trunk
+    // of the tree. When formatting the mapping, we want to start from the subsystem level
+    ostringstream ossStream;
+    list<const CConfigurableElement*>::const_reverse_iterator it;
+    for (it = configurableElementPath.rbegin(); it != configurableElementPath.rend(); ++it) {
+
+        const CInstanceConfigurableElement* pInstanceConfigurableElement =
+                static_cast<const CInstanceConfigurableElement*>(*it);
+
+        ossStream << pInstanceConfigurableElement->getFormattedMapping() << ", ";
+    }
+    return ossStream.str();
+}
+
+// Find the CSubystemObject containing a specific CInstanceConfigurableElement
+const CSubsystemObject* CSubsystem::findSubsystemObjectFromConfigurableElement(
+        const CInstanceConfigurableElement* pInstanceConfigurableElement) const {
+
+    const CSubsystemObject* pSubsystemObject = NULL;
+
+    list<CSubsystemObject*>::const_iterator it;
+    for (it = _subsystemObjectList.begin(); it != _subsystemObjectList.end(); ++it) {
+
+        // Check if one of the SubsystemObjects is associated with a ConfigurableElement
+        // corresponding to the expected one
+        pSubsystemObject = *it;
+        if (pSubsystemObject->getConfigurableElement() == pInstanceConfigurableElement) {
+
+            break;
+        }
+    }
+
+    return pSubsystemObject;
+}
+
+void CSubsystem::findSusbystemLevelMappingKeyValue(
+        const CInstanceConfigurableElement* pInstanceConfigurableElement,
+        string& strMappingKey,
+        string& strMappingValue) const
+{
+    // Find creator to get key name
+    vector<CSubsystemObjectCreator*>::const_iterator it;
+    for (it = _subsystemObjectCreatorArray.begin();
+         it != _subsystemObjectCreatorArray.end(); ++it) {
+
+        const CSubsystemObjectCreator* pSubsystemObjectCreator = *it;
+
+        strMappingKey = pSubsystemObjectCreator->getMappingKey();
+
+        // Check if the ObjectCreator MappingKey corresponds to the element mapping data
+        const string* pStrValue;
+        if (pInstanceConfigurableElement->getMappingData(strMappingKey, pStrValue)) {
+
+            strMappingValue = *pStrValue;
+            return;
+        }
+    }
+    assert(0);
+}
+
+// Formats the mapping data as a comma separated list of key value pairs
+string CSubsystem::getFormattedSubsystemMappingData(
+        const CInstanceConfigurableElement* pInstanceConfigurableElement) const
+{
+    // Find the SubsystemObject related to pInstanceConfigurableElement
+    const CSubsystemObject* pSubsystemObject = findSubsystemObjectFromConfigurableElement(
+                pInstanceConfigurableElement);
+
+    // Exit if node does not correspond to a SubsystemObject
+    if (pSubsystemObject == NULL) {
+
+        return "";
+    }
+
+    // Find SubsystemCreator mapping key
+    string strMappingKey;
+    string strMappingValue; // mapping value where amends are not replaced by their value
+    findSusbystemLevelMappingKeyValue(pInstanceConfigurableElement, strMappingKey, strMappingValue);
+
+    // Find SubSystemObject mapping value (with amends replaced by their value)
+    return strMappingKey + ":" + pSubsystemObject->getFormattedMappingValue();
+}
+
+string CSubsystem::getMapping(list<const CConfigurableElement*>& configurableElementPath) const
+{
+    if (configurableElementPath.empty()) {
+
+        return "";
+    }
+
+    // Get the first element, which is the element containing the amended mapping
+    const CInstanceConfigurableElement* pInstanceConfigurableElement =
+            static_cast<const CInstanceConfigurableElement*>(configurableElementPath.front());
+    configurableElementPath.pop_front();
+    // Now the list only contains elements whose mapping are related to the context
+
+    // Format context mapping data
+    string strValue = formatMappingDataList(configurableElementPath);
+
+    // Print the mapping of the first node, which corresponds to a SubsystemObject
+    strValue += getFormattedSubsystemMappingData(pInstanceConfigurableElement);
+
+    return strValue;
+}
+
 void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const
 {
     CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext);
@@ -209,22 +320,38 @@
     _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator);
 }
 
+// Generic error handling from derived subsystem classes
+string CSubsystem::getMappingError(const string& strKey,
+                                   const string& strMessage,
+                                   const CInstanceConfigurableElement* pInstanceConfigurableElement)
+const
+{
+    return getName() + " " + getKind() + " " +
+            "mapping:\n" + strKey + " " +
+            "error: \"" + strMessage + "\" " +
+            "for element " + pInstanceConfigurableElement->getPath();
+}
+
 // Mapping generic context handling
-bool CSubsystem::handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError)
+bool CSubsystem::handleMappingContext(
+        const CInstanceConfigurableElement* pInstanceConfigurableElement,
+        const vector<string>& contextMappingKeyArray,
+        CMappingContext& context,
+        string& strError) const
 {
     // Feed context with found mapping data
     uint32_t uiItem;
 
-    for (uiItem = 0; uiItem < _contextMappingKeyArray.size(); uiItem++) {
+    for (uiItem = 0; uiItem < contextMappingKeyArray.size(); uiItem++) {
 
-        string strKey = _contextMappingKeyArray[uiItem];
+        string strKey = contextMappingKeyArray[uiItem];
         const string* pStrValue;
 
         if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) {
             // Assign item to context
             if (!context.setItem(uiItem, pStrValue)) {
 
-                getMappingError(strError, strKey, "Already set", pInstanceConfigurableElement);
+                strError = getMappingError(strKey, "Already set", pInstanceConfigurableElement);
 
                 return false;
             }
@@ -267,8 +394,8 @@
                 // Check ancestor was provided
                 if (!context.iSet(uiAncestorKey)) {
 
-                    getMappingError(strError, strKey, _contextMappingKeyArray[uiAncestorKey] +
-                                    " not set", pInstanceConfigurableElement);
+                    strError = getMappingError(strKey, _contextMappingKeyArray[uiAncestorKey] +
+                                               " not set", pInstanceConfigurableElement);
 
                     return false;
                 }
@@ -281,7 +408,7 @@
                 string strSizeError = "Size should not exceed " +
                                       pSubsystemObjectCreator->getMaxConfigurableElementSize();
 
-                getMappingError(strError, strKey, strSizeError, pInstanceConfigurableElement);
+                strError = getMappingError(strKey, strSizeError, pInstanceConfigurableElement);
 
                 return false;
             }
@@ -302,16 +429,6 @@
     return true;
 }
 
-// Generic error handling from derived subsystem classes
-void CSubsystem::getMappingError(string& strError, const string& strKey, const string& strMessage,
-                                 const CInstanceConfigurableElement* pInstanceConfigurableElement)
-{
-    strError = getName() + " " + getKind() + " "
-               "mapping:\n" + strKey + " "
-               "error: \"" + strMessage + "\" "
-               "for element " + pInstanceConfigurableElement->getPath();
-}
-
 // From IMapper
 // Handle a configurable element mapping
 bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement,
@@ -321,7 +438,8 @@
     CMappingContext context = _contextStack.top();
 
     // Add mapping in context
-    if (!handleMappingContext(pInstanceConfigurableElement, context, strError)) {
+    if (!handleMappingContext(pInstanceConfigurableElement, _contextMappingKeyArray, context,
+                              strError)) {
 
         return false;
     }
@@ -358,9 +476,9 @@
             // Check for creation error
             if (bShouldCreateSubsystemObject && !bHasCreatedSubsystemObject) {
 
-                getMappingError(strError, "Not found",
-                                "Subsystem object mapping key is missing",
-                                pInstanceConfigurableElement);
+                strError = getMappingError("Not found",
+                                           "Subsystem object mapping key is missing",
+                                           pInstanceConfigurableElement);
                 return false;
             }
             // Not created and no error, keep diving
diff --git a/parameter/Subsystem.h b/parameter/Subsystem.h
index 996b546..277ff25 100644
--- a/parameter/Subsystem.h
+++ b/parameter/Subsystem.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -34,6 +34,7 @@
 class CComponentLibrary;
 class CSubsystemObject;
 class CSubsystemObjectCreator;
+class CInstanceConfigurableElement;
 
 class CSubsystem : public CConfigurableElement, private IMapper
 {
@@ -60,6 +61,23 @@
 
     // from CElement
     virtual string getKind() const;
+
+    /**
+     * Fetch mapping data of an element.
+     *
+     * The mapping is represented as a string of all the mapping data (key:value) defined in the
+     * context of the element.
+     * This method gathers the mapping data found in each Element of the configurableElementPath
+     * list to format the resulting string.
+     *
+     * @param[in] configurableElementPath List of all the ConfigurableElements found
+     * that have a mapping. Elements are added at the end of the list, so the root Element will be
+     * the last one.
+     *
+     * @return Formatted string of the mapping data
+     */
+    virtual string getMapping(list<const CConfigurableElement*>& configurableElementPath) const;
+
 protected:
     // Parameter access
     virtual bool accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const;
@@ -83,19 +101,6 @@
     bool mapSubsystemElements(string& strError);
 
     /**
-     * Generic subsystem mapping error handling
-     *
-     * Format an human readable error string from a key and a message in case of mapping error
-     *
-     * @param[out] strError The formated error string
-     * @param[in] strKey The key on which the error refers
-     * @param[in] strMessage The error message
-     * @param[in] pInstanceConfigurableElement The element on wich the error refers
-     */
-    void getMappingError(string& strError, const string& strKey, const string& strMessage,
-                         const CInstanceConfigurableElement* pInstanceConfigurableElement);
-
-    /**
      * Handle a configurable element mapping.
      *
      * Add context mappings to the context and instantiate a subsystem object if needed.
@@ -112,8 +117,87 @@
     virtual bool mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, string& strError);
     virtual void mapEnd();
 
-    // Mapping generic context handling
-    bool handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError);
+    // Mapping access
+    /**
+     * Generic mapping error handling
+     *
+     * Format an human readable error string from a key and a message in case of mapping error
+     *
+     * @param[in] strKey The key on which the error refers
+     * @param[in] strMessage The error message
+     * @param[in] pInstanceConfigurableElement The element on wich the error refers
+     *
+     * returns The formated error string
+     */
+    string getMappingError(const string& strKey,
+                           const string& strMessage,
+                           const CInstanceConfigurableElement* pInstanceConfigurableElement) const;
+
+    /**
+     * Format the mapping data of the ConfigurableElements that have been gathered through recursive
+     * calls to the getMapping() method.
+     * These elements shall be evaluated from the root level to the leaves level, so the list must
+     * be parsed in reverse order.
+     *
+     * @param[in] configurableElementPath List of ConfigurableElements containing mapping data
+     *
+     * @return String containing the formatted mapping
+     */
+    string formatMappingDataList(
+            const list<const CConfigurableElement*>& configurableElementPath) const;
+
+    /**
+     * Find the SubystemObject which contains a specific CInstanceConfigurableElement.
+     *
+     * @param[in] pInstanceConfigurableElement The CInstanceConfigurableElement that is related to
+     * the wanted SubsystemObject. Each SubsystemObject of the Subystem internal list is checked in
+     * order to find a match.
+     *
+     * @return A pointer to the SubsystemObject related to pInstanceConfigurableElement
+     */
+    const CSubsystemObject* findSubsystemObjectFromConfigurableElement(
+            const CInstanceConfigurableElement* pInstanceConfigurableElement) const;
+
+    /**
+     * Find the mapping data defined for the CInstanceConfigurableElement given in parameter, that
+     * corresponds to Susbystem level mapping (Susbystem level mapping keys are defined in
+     * CSubsystemObjectCreator classes).
+     * The CInstanceConfigurableElement might as well contain local mapping data.
+     *
+     * @param[in] pInstanceConfigurableElement The element which mapping data will be parsed for
+     * a match
+     * @param[out] strMappingKey Mapping key defined at the Subsystem level
+     * @param[out] strMappingValue Mapping value contained in pInstanceConfigurableElement
+     */
+    void findSusbystemLevelMappingKeyValue(
+            const CInstanceConfigurableElement* pInstanceConfigurableElement,
+            string& strMappingKey,
+            string& strMappingValue) const;
+
+    /**
+     * Formats the mapping of a SubsystemObject
+     *
+     * @param[in] pInstanceConfigurableElement Element corresponding to a SubsystemObject
+     *
+     * @return String containing the formatted mapping
+     */
+    string getFormattedSubsystemMappingData(
+            const CInstanceConfigurableElement* pInstanceConfigurableElement) const;
+    /**
+     * Generic context handling
+     *
+     * Feed context with mapping data of the current element
+     *
+     * @param[in] pInstanceConfigurableElement The element containing mapping data
+     * @param[in] contextMappingKeyArray The list of keys of the context mapping
+     * @param[out] context The context mapping to update with the current element mapping values
+     * @param[out] strError The formated error string
+     * @return true on success
+     */
+    bool handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement,
+                              const vector<string>& contextMappingKeyArray,
+                              CMappingContext& context,
+                              string& strError) const;
 
     /**
      * Looks if a subsystem object needs to be instantiated for the given configurable
@@ -130,7 +214,8 @@
      * @return true on success, false on failure
      */
     bool handleSubsystemObjectCreation(CInstanceConfigurableElement* pInstanceConfigurableElement,
-                                       CMappingContext& context, bool& bHasCreatedSubsystemObject, string& strError);
+                                       CMappingContext& context, bool& bHasCreatedSubsystemObject,
+                                       string& strError);
 
     // Subsystem context mapping keys
     vector<string> _contextMappingKeyArray;
diff --git a/parameter/SubsystemObject.cpp b/parameter/SubsystemObject.cpp
index c778baf..8c4e187 100644
--- a/parameter/SubsystemObject.cpp
+++ b/parameter/SubsystemObject.cpp
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -49,6 +49,12 @@
     _pInstanceConfigurableElement->unsetSyncer();
 }
 
+string CSubsystemObject::getFormattedMappingValue() const
+{
+    // Default formatted mapping value is empty
+    return "";
+}
+
 // Blackboard data location
 uint8_t* CSubsystemObject::getBlackboardLocation() const
 {
@@ -134,13 +140,15 @@
 // Sync to/from HW
 bool CSubsystemObject::sendToHW(string& strError)
 {
-    strError = "Send to HW interface not implemented at subsystsem level!";
+    strError = "Send to HW interface not implemented at subsystem level";
 
     return false;
 }
 
-bool CSubsystemObject::receiveFromHW(string& )
+bool CSubsystemObject::receiveFromHW(string& strError)
 {
+    (void)strError;
+
     // Back synchronization is not supported at subsystem level.
     // Rely on blackboard content
 
@@ -208,53 +216,11 @@
     _pInstanceConfigurableElement->log_warning(acBuffer);
 }
 
-// Amendment
-string CSubsystemObject::formatMappingValue(const string& strMappingValue, uint32_t uiFirstAmendKey, uint32_t uiNbAmendKeys, const CMappingContext& context)
-{
-    string strFormattedValue = strMappingValue;
-
-    // Search for amendment (only one supported for now)
-    size_t uiPercentPos = strFormattedValue.find('%', 0);
-
-    // Amendment limited to one digit (values from 1 to 9)
-    assert((uiNbAmendKeys > 0) && (uiNbAmendKeys <= 9));
-
-    // Check we found one and that there's room for value
-    if (uiPercentPos != string::npos && uiPercentPos < strFormattedValue.size() - 1) {
-
-        // Get Amend number
-        uint32_t uiAmendNumber = strFormattedValue[uiPercentPos + 1] - '0';
-
-        // Valid?
-        if (uiAmendNumber && uiAmendNumber <= uiNbAmendKeys) {
-
-            uint32_t uiAmendType = uiFirstAmendKey + uiAmendNumber - 1;
-
-            // Set?
-            if (context.iSet(uiAmendType)) {
-
-                // Make the amendment on the part of the string after the current Amend
-                string strEndOfLine = strFormattedValue.substr(uiPercentPos + 2, strFormattedValue.size() - uiPercentPos - 2);
-                string strEndOfLineAmended = formatMappingValue(strEndOfLine, uiFirstAmendKey, uiNbAmendKeys, context);
-
-                // Get current Amend value
-                string strAmendValue = context.getItem(uiAmendType);
-
-                // Make the amendment
-                strFormattedValue = strFormattedValue.substr(0, uiPercentPos) + strAmendValue + strEndOfLineAmended;
-
-            }
-        }
-    }
-    return strFormattedValue;
-}
-
 // Configurable element retrieval
 const CInstanceConfigurableElement* CSubsystemObject::getConfigurableElement() const
 {
     return _pInstanceConfigurableElement;
 }
-
 // Belonging Subsystem retrieval
 const CSubsystem* CSubsystemObject::getSubsystem() const
 {
diff --git a/parameter/SubsystemObject.h b/parameter/SubsystemObject.h
index 8fab017..ca52df8 100644
--- a/parameter/SubsystemObject.h
+++ b/parameter/SubsystemObject.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.
@@ -37,6 +37,16 @@
     CSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement);
     virtual ~CSubsystemObject();
 
+    /**
+     * Return the mapping value of the SubystemObject.
+     *
+     * @return A string containing the mapping value
+     */
+    virtual string getFormattedMappingValue() const;
+
+    // Configurable element retrieval
+    const CInstanceConfigurableElement* getConfigurableElement() const;
+
 protected:
     // Blackboard data location
     uint8_t* getBlackboardLocation() const;
@@ -57,10 +67,6 @@
     // Logging
     void log_info(const string& strMessage, ...) const;
     void log_warning(const string& strMessage, ...) const;
-    // Mapping formatting
-    static string formatMappingValue(const string& strMappingValue, uint32_t uiFirstAmendKey, uint32_t uiNbAmendKeys, const CMappingContext& context);
-    // Configurable element retrieval
-    const CInstanceConfigurableElement* getConfigurableElement() const;
     // Belonging Subsystem retrieval
     const CSubsystem* getSubsystem() const;
 
diff --git a/parameter/TypeElement.h b/parameter/TypeElement.h
index db40412..353b0a5 100644
--- a/parameter/TypeElement.h
+++ b/parameter/TypeElement.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * INTEL CONFIDENTIAL
  * Copyright © 2011 Intel 
  * Corporation All Rights Reserved.