diff --git a/dune/common/Makefile.am b/dune/common/Makefile.am
index ed5d9d73738ccf38508d0ea329456819867e751b..84503f2192512fbd91a7d2fbe02fb1f75224013f 100644
--- a/dune/common/Makefile.am
+++ b/dune/common/Makefile.am
@@ -9,6 +9,7 @@ libcommon_la_SOURCES =				\
 	configparser.cc				\
 	ios_state.cc				\
 	parametertree.cc                        \
+	parametertreeparser.cc			\
 	path.cc					\
 	exceptions.cc				\
 	stdstreams.cc
@@ -62,6 +63,7 @@ commoninclude_HEADERS = 			\
 	mpitraits.hh				\
 	nullptr.hh				\
 	parametertree.hh                        \
+	parametertreeparser.hh			\
 	path.hh					\
 	poolallocator.hh			\
 	precision.hh				\
diff --git a/dune/common/parametertreeparser.cc b/dune/common/parametertreeparser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..35a90b2f126b4af82d55ecf06d1494d42c938ec0
--- /dev/null
+++ b/dune/common/parametertreeparser.cc
@@ -0,0 +1,155 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#include "parametertreeparser.hh"
+
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <set>
+
+#include <dune/common/exceptions.hh>
+
+std::string Dune::ParameterTreeParser::ltrim(const std::string& s)
+{
+  std::size_t firstNonWS = s.find_first_not_of(" \t\n\r");
+
+  if (firstNonWS!=std::string::npos)
+    return s.substr(firstNonWS);
+  return std::string();
+}
+
+std::string Dune::ParameterTreeParser::rtrim(const std::string& s)
+{
+  std::size_t lastNonWS = s.find_last_not_of(" \t\n\r");
+
+  if (lastNonWS!=std::string::npos)
+    return s.substr(0, lastNonWS+1);
+  return std::string();
+}
+
+
+
+void Dune::ParameterTreeParser::readINITree(std::string file,
+                                            ParameterTree& pt,
+                                            bool overwrite)
+{
+  std::ifstream in(file.c_str());
+
+  if (!in)
+    DUNE_THROW(Dune::IOError, "Could not open configuration file " << file);
+
+  readINITree(in, pt, "file '" + file + "'", overwrite);
+}
+
+
+void Dune::ParameterTreeParser::readINITree(std::istream& in,
+                                            ParameterTree& pt,
+                                            bool overwrite)
+{
+  readINITree(in, pt, "stream", overwrite);
+}
+
+
+void Dune::ParameterTreeParser::readINITree(std::istream& in,
+                                            ParameterTree& pt,
+                                            const std::string srcname,
+                                            bool overwrite)
+{
+  std::string prefix;
+  std::set<std::string> keysInFile;
+  while(!in.eof())
+  {
+    std::string line;
+    getline(in, line);
+    line = ltrim(line);
+    switch (line[0]) {
+    case '#' :
+      break;
+    case '[' :
+      line = rtrim(line);
+      if (line[line.length()-1] == ']')
+      {
+        prefix = rtrim(ltrim(line.substr(1, line.length()-2)));
+        if (prefix != "")
+          prefix += ".";
+      }
+      break;
+    default :
+      std::string::size_type comment = line.find("#");
+      line = line.substr(0,comment);
+      std::string::size_type mid = line.find("=");
+      if (mid != std::string::npos)
+      {
+        std::string key = prefix+rtrim(ltrim(line.substr(0, mid)));
+        std::string value = ltrim(line.substr(mid+1));
+
+        if (value.length()>0)
+        {
+          // handle quoted strings
+          if ((value[0]=='\'')or (value[0]=='"'))
+          {
+            char quote = value[0];
+            value=value.substr(1);
+            while (*(rtrim(value).rbegin())!=quote)
+            {
+              if (not in.eof())
+              {
+                std::string l;
+                getline(in, l);
+                value = value+"\n"+l;
+              }
+              else
+                value = value+quote;
+            }
+            value = rtrim(value);
+            value = value.substr(0,value.length()-1);
+          }
+          else
+            value = rtrim(value);
+        }
+
+        if (keysInFile.count(key) != 0)
+          DUNE_THROW(Exception, "Key '" << key <<
+                     "' appears twice in " << srcname << " !");
+        else
+        {
+          if(overwrite || ! pt.hasKey(key))
+            pt[key] = value;
+          keysInFile.insert(key);
+        }
+      }
+      break;
+    }
+  }
+
+}
+
+
+void Dune::ParameterTreeParser::readOptions(int argc, char* argv [],
+                                            ParameterTree& pt)
+{
+  std::string v = "";
+  std::string k = "";
+
+  for(int i=1; i<argc; i++)
+  {
+    std::string s(argv[i]);
+
+    if ((argv[i][0]=='-') && (argv[i][1]!='\000'))
+    {
+      k = argv[i]+1;
+      continue;
+    }
+    else
+    {
+      if (k.size())
+        pt[k] = argv[i];
+      k.clear();
+    }
+
+  }
+
+}
diff --git a/dune/common/parametertreeparser.hh b/dune/common/parametertreeparser.hh
new file mode 100644
index 0000000000000000000000000000000000000000..f848dbd82e1d0d63564e201e7103a4f057a6ddd9
--- /dev/null
+++ b/dune/common/parametertreeparser.hh
@@ -0,0 +1,125 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_PARAMETER_PARSER_HH
+#define DUNE_PARAMETER_PARSER_HH
+
+#include <istream>
+#include <string>
+
+#include <dune/common/parametertree.hh>
+
+namespace Dune {
+
+  /** \brief Parser for hierarchical configuration files
+   * \ingroup Common
+   *
+   * This class parses config files into a hierarchical structure.
+   * Config files should look like this
+   *
+     \verbatim
+   # this file configures fruit colors in fruitsalad
+
+
+   ##these are no fruit but could also appear in fruit salad
+     honeydewmelon = yellow
+     watermelon = green
+
+     fruit.tropicalfruit.orange = orange
+
+     [fruit]
+     strawberry = red
+     pomegranate = red
+
+     [fruit.pipfruit]
+     apple = green/red/yellow
+     pear = green
+
+     [fruit.stonefruit]
+     cherry = red
+     plum = purple
+
+     \endverbatim
+   *
+   *
+   * If a '[prefix]' statement appears all following entries use this prefix
+   * until the next '[prefix]' statement. Fruitsalads for example contain:
+     \verbatim
+     honeydewmelon = yellow
+     fruit.tropicalfruit.orange = orange
+     fruit.pipfruit.apple = green/red/yellow
+     fruit.stonefruit.cherry = red
+     \endverbatim
+   *
+   * All keys with a common 'prefix.' belong to the same substructure called
+   * 'prefix'.  Leading and trailing spaces and tabs are removed from the
+   * values unless you use single or double quotes around them.  Using single
+   * or double quotes you can also have multiline values.
+   *
+   */
+  class ParameterTreeParser
+  {
+
+    static std::string ltrim(const std::string& s);
+    static std::string rtrim(const std::string& s);
+
+
+  public:
+    /** \brief parse C++ stream
+     *
+     * Parses C++ stream and build hierarchical config structure.
+     *
+     * \param in        The stream to parse
+     * \param overwrite Whether to overwrite already existing values.
+     *                  If false, values in the stream will be ignored
+     *                  if the key is already present.
+     *
+     * \note This method is identical to parseStream(std::istream&,
+     *       const std::string&, bool) with the exception that that
+     *       method allows to give a custom name for the stream.
+     */
+    static void readINITree(std::istream& in, ParameterTree& pt,
+                            bool overwrite);
+
+
+    /** \brief parse C++ stream
+     *
+     * Parses C++ stream and build hierarchical config structure.
+     *
+     * \param in      The stream to parse
+     * \param srcname Name of the configuration source for error
+     *                messages, "stdin" or a filename.
+     * \param overwrite Whether to overwrite already existing values.
+     *                  If false, values in the stream will be ignored
+     *                  if the key is already present.
+     */
+    static void readINITree(std::istream& in, ParameterTree& pt,
+                            const std::string srcname = "stream",
+                            bool overwrite = true);
+
+
+    /** \brief parse file
+     *
+     * Parses file with given name and build hierarchical config structure.
+     *
+     * \param file filename
+     * \param overwrite Whether to overwrite already existing values.
+     *                  If false, values in the stream will be ignored
+     *                  if the key is already present.
+     */
+    static void readINITree(std::string file, ParameterTree& pt, bool overwrite = true);
+
+
+    /** \brief parse command line
+     *
+     * Parses command line options and build hierarchical ParameterTree structure.
+     *
+     * \param argc arg count
+     * \param argv arg values
+     */
+    static void readOptions(int argc, char* argv [], ParameterTree& pt);
+
+  };
+
+} // end namespace Dune
+
+#endif // DUNE_PARAMETER_PARSER_HH