diff --git a/dumux/common/basicproperties.hh b/dumux/common/basicproperties.hh
index cd1c98b46ab25781beea3d15a64260b516954dda..201e251302ada770791ad3a303c9b17317e9d9f3 100644
--- a/dumux/common/basicproperties.hh
+++ b/dumux/common/basicproperties.hh
@@ -67,6 +67,9 @@ NEW_PROP_TAG(Scalar);
 //! Property which provides a Dune::ParameterTree.
 NEW_PROP_TAG(ParameterTree);
 
+//! Property which defines the group that is queried for parameters by default
+NEW_PROP_TAG(ModelParameterGroup);
+
 ///////////////////////////////////
 // Default values for properties:
 //
@@ -113,6 +116,10 @@ bool Property<TypeTag,
               TTAG(NumericModel), 
               PTAG(ParameterTree)>::initFinished_ = false;
 
+// use the global group as default for the model's parameter group 
+SET_PROP(NumericModel, ModelParameterGroup) 
+{ static const char *value() { return ""; }; };
+
 } // namespace Properties
 } // namespace Dumux
 
diff --git a/dumux/common/parameters.hh b/dumux/common/parameters.hh
index fda6a80cc3c1957c3682a50f832cb09252f138ff..9799c167e635fff41fb1d001e2b0b01cb25c6436 100644
--- a/dumux/common/parameters.hh
+++ b/dumux/common/parameters.hh
@@ -33,18 +33,32 @@
 
 #include "propertysystem.hh"
 
-#define GET_PARAM(TypeTag, ParamType, ParamName)                         \
-    Dumux::Parameters::Param<TypeTag, PTAG(ParamName), ParamType>::get(#ParamName)
+// retrieve a parameter which _does_ have a default value taken from
+// the dumux property system. the optional last argument is the group
+// name which must be the prefix to the property name which provides
+// the default value for the parameter.
+#define GET_PARAM(TypeTag, ParamType, ParamName, ...)      \
+    Dumux::Parameters::Param<TypeTag, PTAG(__VA_ARGS__ ## ParamName), ParamType> \
+    :: get(#ParamName, Dumux::Parameters::getGroupName_(#__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)
 
 namespace Dumux
 {
 namespace Properties
 {
 NEW_PROP_TAG(ParameterTree);
+NEW_PROP_TAG(ModelParameterGroup);
 } // namespace Properties
 
 namespace Parameters {
 
+const char *getGroupName_(const char *group = "")
+{ return group; }
+
 template <class TypeTag, 
           class PropTag,
           class ParamType> 
@@ -52,34 +66,104 @@ class Param
 {
     typedef typename GET_PROP(TypeTag, PTAG(ParameterTree)) Params;
 public:
-    static const ParamType &get(const char *name)
+    static const ParamType &get(const char *paramName, const char *groupName = "")
     {
-        static const ParamType &value = retrieve_(name);
+#ifndef NDEBUG
+        // 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 << "'.");
+        }
+#endif
+
+        static const ParamType &value = retrieve_(paramName, groupName);
         return value;
     }
 
 private:
-    static const ParamType &retrieve_(const char *name)
+    static const ParamType &retrieve_(const char *paramName, const char *groupName)
     {   
+        // 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);
+        int groupNameLen = strlen(groupName);
+        if (groupNameLen) {
+            finalName.insert(0, ".");
+            finalName.insert(0, groupName);
+        }
+        
+        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);
+        }
+        
+        // retrieve actual parameter from the parameter tree
         ParamType defaultValue = GET_PROP_VALUE(TypeTag, PropTag);
-        static ParamType value = Params::tree().template get<ParamType>(name, 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::tree().sub("RunTimeParams");
         Dune::ParameterTree &ct = Params::tree().sub("DefaultParams");
-        if (Params::tree().hasKey(name)) {
-            rt[name] = Params::tree()[name];
+        if (Params::tree().hasKey(finalName)) {
+            rt[finalName] = Params::tree()[finalName];
         }
         else {
             std::string s;
             std::ostringstream oss(s);
             oss << defaultValue;
-            ct[name] = oss.str();
+            ct[finalName] = oss.str();
         }
         return value;
     }
 };
 
+template <class TypeTag, 
+          class ParamType> 
+class RunTimeParam
+{
+    typedef typename GET_PROP(TypeTag, PTAG(ParameterTree)) Params;
 
+public:
+    static const ParamType &get(const char *name)
+    {
+        static const ParamType &value = retrieve_(name);
+        return value;
+    }
+
+private:
+    static const ParamType &retrieve_(const char *name)
+    {   
+        static ParamType value = Params::tree().template get<ParamType>(name);
+
+        Dune::ParameterTree &rt = Params::tree().sub("RunTimeParams");
+        if (Params::tree().hasKey(name)) {
+            rt[name] = Params::tree()[name];
+        }
+
+        return value;
+    }
+};
 
 } // namespace Parameters
 
diff --git a/dumux/nonlinear/newtoncontroller.hh b/dumux/nonlinear/newtoncontroller.hh
index 78472ad68fcb2e92a01eb50d434355534ce474c8..3b128237de5c85363c1154bad6a5047ceb535cb6 100644
--- a/dumux/nonlinear/newtoncontroller.hh
+++ b/dumux/nonlinear/newtoncontroller.hh
@@ -168,20 +168,20 @@ public:
         enablePartialReassemble_ = GET_PARAM(TypeTag, bool, EnablePartialReassemble);
         enableJacobianRecycling_ = GET_PARAM(TypeTag, bool, EnableJacobianRecycling);
 
-        useLineSearch_ = GET_PARAM(TypeTag, bool, NewtonUseLineSearch);
-        enableRelativeCriterion_ = GET_PARAM(TypeTag, bool, NewtonEnableRelativeCriterion);
-        enableAbsoluteCriterion_ = GET_PARAM(TypeTag, bool, NewtonEnableAbsoluteCriterion);
-        satisfyAbsAndRel_ = GET_PARAM(TypeTag, bool, NewtonSatisfyAbsAndRel);
+        useLineSearch_ = GET_PARAM(TypeTag, bool, UseLineSearch, Newton);
+        enableRelativeCriterion_ = GET_PARAM(TypeTag, bool, EnableRelativeCriterion, Newton);
+        enableAbsoluteCriterion_ = GET_PARAM(TypeTag, bool, EnableAbsoluteCriterion, Newton);
+        satisfyAbsAndRel_ = GET_PARAM(TypeTag, bool, SatisfyAbsAndRel, Newton);
         if (!enableRelativeCriterion_ && !enableAbsoluteCriterion_)
         {
             DUNE_THROW(Dune::NotImplemented, "at least one of NewtonEnableRelativeCriterion or "
                     << "NewtonEnableAbsoluteCriterion has to be set to true");
         }
 
-        setRelTolerance(GET_PARAM(TypeTag, Scalar, NewtonRelTolerance));
-        setAbsTolerance(GET_PARAM(TypeTag, Scalar, NewtonAbsTolerance));
-        setTargetSteps(GET_PARAM(TypeTag, int, NewtonTargetSteps));
-        setMaxSteps(GET_PARAM(TypeTag, int, NewtonMaxSteps));
+        setRelTolerance(GET_PARAM(TypeTag, Scalar, RelTolerance, Newton));
+        setAbsTolerance(GET_PARAM(TypeTag, Scalar, AbsTolerance, Newton));
+        setTargetSteps(GET_PARAM(TypeTag, int, TargetSteps, Newton));
+        setMaxSteps(GET_PARAM(TypeTag, int, MaxSteps, Newton));
         
         verbose_ = true;
         numSteps_ = 0;
@@ -302,7 +302,7 @@ public:
         method_ = &method;
         numSteps_ = 0;
 
-        if (GET_PARAM(TypeTag, bool, NewtonWriteConvergence))
+        if (GET_PARAM(TypeTag, bool, WriteConvergence, Newton))
             convergenceWriter_.beginTimestep();
     }
 
@@ -496,7 +496,7 @@ public:
      */
     void newtonEnd()
     {
-        if (GET_PARAM(TypeTag, bool, NewtonWriteConvergence))
+        if (GET_PARAM(TypeTag, bool, WriteConvergence, Newton))
             convergenceWriter_.endTimestep();
     }
 
@@ -639,7 +639,7 @@ protected:
     void writeConvergence_(const SolutionVector &uLastIter,
                            const SolutionVector &deltaU)
     {
-        if (GET_PARAM(TypeTag, bool, NewtonWriteConvergence)) {
+        if (GET_PARAM(TypeTag, bool, WriteConvergence, Newton)) {
             convergenceWriter_.beginIteration(this->gridView_());
             convergenceWriter_.writeFields(uLastIter, deltaU);
             convergenceWriter_.endIteration();