diff --git a/dumux/common/parameters.hh b/dumux/common/parameters.hh
index 29908e98018ca9739db7957d794e7192374dacb0..6d7778d48125caa47a8de6f437acacc5a11a4395 100644
--- a/dumux/common/parameters.hh
+++ b/dumux/common/parameters.hh
@@ -33,6 +33,7 @@
 
 #include <sstream>
 #include <list>
+#include <unordered_map>
 
 /*!
  * \brief Retrieve a runtime parameter which _does_ have a default value taken from
@@ -52,14 +53,35 @@
  * // is taken from the property NewtonWriteConvergence
  * GET_PARAM(TypeTag, bool, Newton, WriteConvergence);
  */
-#define GET_PARAM(TypeTag, ParamType, ParamNameOrGroupName, ...) \
-    Dumux::Parameters::Param<TypeTag, PTAG(ParamNameOrGroupName ## __VA_ARGS__), ParamType> \
-    :: get(#ParamNameOrGroupName, Dumux::Parameters::getString_(#__VA_ARGS__))
+#define GET_PARAM(TypeTag, ParamType, ParamNameOrGroupName, ...)         \
+    Dumux::Parameters::Param<TypeTag>                                    \
+    ::template get<ParamType, PTAG(ParamNameOrGroupName ## __VA_ARGS__)> \
+    (#ParamType,                                                         \
+     #ParamNameOrGroupName,                                              \
+     Dumux::Parameters::getString_(#__VA_ARGS__))
 
-// retrieve a parameter which does _not_ have a default value taken
-// from the dumux property system
-//#define GET_RUNTIME_PARAM(TypeTag, ParamType, ParamName) 
-//    Dumux::Parameters::RunTimeParam<TypeTag, ParamType>::get(#ParamName)
+/*!
+ * \brief Retrieve a runtime parameter which _does not_ have a default value taken from
+ *        the Dumux property system.
+ *
+ * If the macro is called with four argument the third argument is
+ * group name
+ *
+ * Examples:
+ *
+ * // -> retrieves global integer value NumberOfCellsX
+ * GET_RUNTIME_PARAM(TypeTag, int, NumberOfCellsX);
+ *
+ * // -> retrieves global integer value NumberOfCellsX which is
+ * // located int the parameter group "Geometry"
+ * GET_RUNTIME_PARAM(TypeTag, int, Geometry, NumberOfCellsX);
+ */
+#define GET_RUNTIME_PARAM(TypeTag, ParamType, ParamNameOrGroupName, ...) \
+    Dumux::Parameters::Param<TypeTag>                                   \
+    ::template getRuntime<ParamType>                                    \
+    (#ParamType,                                                        \
+     #ParamNameOrGroupName,                                             \
+     Dumux::Parameters::getString_(#__VA_ARGS__))
 
 namespace Dumux
 {
@@ -139,43 +161,127 @@ void print(std::ostream &os = std::cout)
 const char *getString_(const char *foo = 0)
 { return foo; }
 
-template <class TypeTag, 
-          class PropTag,
-          class ParamType> 
+template <class TypeTag> 
 class Param
 {
     typedef typename GET_PROP(TypeTag, PTAG(ParameterTree)) Params;
 public:
-    static const ParamType &get(const char *groupOrParamName, const char *paramNameOrNil = 0)
+    template <class ParamType, class PropTag>
+    static const ParamType &get(const char *paramTypeName,
+                                const char *groupOrParamName, 
+                                const char *paramNameOrNil = 0)
     {
 #ifndef NDEBUG
+        // make sure that the parameter is used consistently. since
+        // this is potentially quite expensive, it is only done if
+        // debugging code is not explicitly turned off.
         const char *paramName, *groupName;
-        if (paramNameOrNil) {
+        std::string propertyName;
+        if (paramNameOrNil && strlen(paramNameOrNil) > 0) {
             groupName = groupOrParamName;
             paramName = paramNameOrNil;
+            propertyName  = groupName;
+            propertyName += paramName;
         }
         else {
             groupName = "";
             paramName = groupOrParamName;
+            propertyName = paramName;
         }
-        // make sure that a property is only the default for a single
-        // parameter, i.e. that a property is not used for multiple
-        // parameters
-        static std::string fixedGroupName = groupName;
-        if (fixedGroupName != groupName)
-        {
-            DUNE_THROW(Dune::InvalidStateException,
-                       "Conflicting prefixes for parameter '" << paramName
-                       << "': '" << fixedGroupName
-                       << "' and '" << groupName << "'.");
+
+        check_(propertyName, paramTypeName, groupName, paramName);
+#endif
+
+        static const ParamType &value = retrieve_<ParamType, PropTag>(groupOrParamName, paramNameOrNil);
+        return value;
+    }
+
+    template <class ParamType>
+    static const ParamType &getRuntime(const char *paramTypeName,
+                                       const char *groupOrParamName, 
+                                       const char *paramNameOrNil = 0)
+    {
+#ifndef NDEBUG
+        // make sure that the parameter is used consistently. since
+        // this is potentially quite expensive, it is only done if
+        // debugging code is not explicitly turned off.
+        const char *paramName, *groupName;
+        static const std::string propertyName("");
+        if (paramNameOrNil && strlen(paramNameOrNil) > 0) {
+            groupName = groupOrParamName;
+            paramName = paramNameOrNil;
         }
+        else {
+            groupName = "";
+            paramName = groupOrParamName;
+        }
+
+        check_(propertyName, paramTypeName, groupName, paramName);
 #endif
 
-        static const ParamType &value = retrieve_(groupOrParamName, paramNameOrNil);
+        static const ParamType &value = retrieveRuntime_<ParamType>(groupOrParamName, paramNameOrNil);
         return value;
     }
 
 private:
+    static void check_(const std::string &propertyName, 
+                       const char *paramTypeName, 
+                       const char *groupName, 
+                       const char *paramName)
+    {
+        struct Blubb {
+            std::string propertyName;
+            std::string paramTypeName;
+            std::string groupName;
+            
+            Blubb &operator=(const Blubb &b)
+            { 
+                propertyName = b.propertyName;
+                paramTypeName = b.paramTypeName;
+                groupName = b.groupName;
+                return *this;
+            };
+        };
+        typedef std::unordered_map<std::string, Blubb> StaticData;
+        static StaticData staticData;
+
+        typename StaticData::iterator it = staticData.find(paramName);
+        Blubb *b;
+        if (it == staticData.end())
+        {
+            Blubb a;
+            a.propertyName = propertyName;
+            a.paramTypeName = paramTypeName;
+            a.groupName = groupName;
+            staticData[paramName] = a;
+            b = &staticData[paramName];
+        }
+        else
+            b = &(it->second);
+        
+        if (b->groupName != groupName) {
+            DUNE_THROW(Dune::InvalidStateException,
+                       "GET_*_PARAM for parameter '" << paramName
+                       << "' called for at least two different groups ('" 
+                       << b->groupName << "' and '" << groupName << "')");
+        }
+
+        if (b->propertyName != propertyName) {
+            DUNE_THROW(Dune::InvalidStateException,
+                       "GET_*_PARAM for parameter '" << paramName
+                       << "' called for at least two different properties ('" 
+                       << b->propertyName << "' and '" << propertyName << "')");
+        }
+
+        if (b->paramTypeName != paramTypeName) {
+            DUNE_THROW(Dune::InvalidStateException,
+                       "GET_*_PARAM for parameter '" << paramName << "' in group '"
+                       << groupName << "' called with at least two different types (" 
+                       << b->paramTypeName << " and " << paramTypeName << ")");
+        }
+    }
+    
+    template <class ParamType, class PropTag>
     static const ParamType &retrieve_(const char *groupOrParamName, const char *paramNameOrNil = 0)
     {   
         const char *paramName, *groupName;
@@ -234,31 +340,62 @@ private:
         }
         return value;
     }
-};
 
-template <class TypeTag, 
-          class ParamType> 
-class RunTimeParam
-{
-    typedef typename GET_PROP(TypeTag, PTAG(ParameterTree)) Params;
+    template <class ParamType>
+    static const ParamType &retrieveRuntime_(const char *groupOrParamName, const char *paramNameOrNil = 0)
+    {   
+        const char *paramName, *groupName;
+        if (paramNameOrNil && strlen(paramNameOrNil) > 0) {
+            groupName = groupOrParamName;
+            paramName = paramNameOrNil;
+        }
+        else {
+            groupName = 0;
+            paramName = groupOrParamName;
+        }
 
-public:
-    static const ParamType &get(const char *name)
-    {
-        static const ParamType &value = retrieve_(name);
-        return value;
-    }
+        // prefix the parameter name by 'GroupName.'. E.g. 'Newton'
+        // and 'WriteConvergence' becomes 'Newton.WriteConvergence'
+        // with the default value specified by the
+        // 'NewtonWriteConvergence' property. in an INI file this
+        // would look like:
+        //
+        // [Newton]
+        // WriteConvergence = true
+        std::string finalName(paramName);
+        if (groupName && strlen(groupName) > 0) {
+            finalName.insert(0, ".");
+            finalName.insert(0, groupName);
+        }
 
-private:
-    static const ParamType &retrieve_(const char *name)
-    {   
-        static ParamType value = Params::tree().template get<ParamType>(name);
+        std::string modelParamGroup(GET_PROP(TypeTag, PTAG(ModelParameterGroup))::value());
+        // prefix the parameter with the parameter group of the
+        // model. this allows things like sub-model specific parameters like
+        //
+        // [Stokes.Newton]
+        // WriteConvergence = false
+        // [Darcy.Newton]
+        // WriteConvergence = true
+        if (modelParamGroup.size()) {
+            finalName.insert(0, ".");
+            finalName.insert(0, modelParamGroup);
+        }
 
-        Dune::ParameterTree &rt = Params::tree().sub("RunTimeParams");
-        if (Params::tree().hasKey(name)) {
-            rt[name] = Params::tree()[name];
+        // retrieve actual parameter from the parameter tree
+        if (Params::tree().hasKey(finalName)) {
+            DUNE_THROW(Dune::InvalidStateException,
+                       "Mandatory parameter '" << finalName
+                       << "' was not specified.");
         }
 
+        ParamType defaultValue;
+        static ParamType value = Params::tree().template get<ParamType>(finalName, defaultValue);
+
+        // remember whether the parameter was taken from the parameter
+        // tree or the default from the property system was taken.
+        Dune::ParameterTree &rt = Params::runTimeParams();
+        rt[finalName] = Params::tree()[finalName];
+
         return value;
     }
 };