diff --git a/dune/perftool/vectorization/CMakeLists.txt b/dune/perftool/vectorization/CMakeLists.txt
index fb3e48fb066252a0dbbcb4d9986ede9e701493e8..a3d7d417c0818ed0963f12c8759b6b47f30909d3 100644
--- a/dune/perftool/vectorization/CMakeLists.txt
+++ b/dune/perftool/vectorization/CMakeLists.txt
@@ -23,4 +23,4 @@ install(FILES complexvec.h
               vectormath_hyp.h
               vectormath_lib.h
               vectormath_trig.h
-        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/vectorization)
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/perftool/vectorization)
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index a76e429d5740e9ce26c3efd0f271332dbcd75b16..12966e6bd2103f150aba3a7583c83aea3af087c9 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -15,7 +15,6 @@ dune_install_python_package(PATH cgen MAJOR_VERSION 2)
 dune_install_python_package(PATH loopy MAJOR_VERSION 2)
 dune_install_python_package(PATH ufl MAJOR_VERSION 2)
 
-
 # Install out python package
 dune_install_python_package(PATH . MAJOR_VERSION 2)
 
diff --git a/python/dune/perftool/compile.py b/python/dune/perftool/compile.py
index ba636abf0d6d7886ee487936372592bfaef4a42a..33ee3d077b63b691574f251220f44eac71fa1fa9 100644
--- a/python/dune/perftool/compile.py
+++ b/python/dune/perftool/compile.py
@@ -61,24 +61,13 @@ def generate_driver(form, filename):
     vtkoutput()
 
     from dune.perftool.generation import retrieve_cache_items
+    from cgen import FunctionDeclaration, FunctionBody, Block, Value
+    driver_signature = FunctionDeclaration(Value('void', 'driver'), [Value('int', 'argc'), Value('char**', 'argv')])
+    driver_body = Block(contents=[i for i in retrieve_cache_items(("driver", "preamble"), union=False, make_generable=True)])
+    driver = FunctionBody(driver_signature, driver_body)
 
-    # Get all preambles for the driver and sort them.
-    driver_content = [i[1] for i in sorted(retrieve_cache_items("preamble"), key=lambda x : x[0])]
-
-    # And flatten out those, that contained nested lists
-    def flatjoin(l):
-        if isinstance(l, str):
-            return "\n" + l
-        return "".join(flatjoin(i) for i in l)
-
-    from cgen import LiteralBlock
-    driver = LiteralBlock(flatjoin(driver_content))
-
-    # Write the file.
-    f = open(filename, 'w')
-    f.write("\n".join(retrieve_cache_items("include")))
-    f.write("\n\nvoid driver(int argc, char** argv)\n")
-    f.write("\n".join(driver.generate()))
+    from dune.perftool.file import generate_file
+    generate_file(filename, "driver", [driver])
 
     # Reset the caching data structure
     from dune.perftool.generation import delete_cache
diff --git a/python/dune/perftool/file.py b/python/dune/perftool/file.py
index 590c610262afc15062c8a05cde736afcf188a50c..d0e751d0bab72d2afade66e0adee25f63a88380e 100644
--- a/python/dune/perftool/file.py
+++ b/python/dune/perftool/file.py
@@ -1,22 +1,38 @@
 """ Manages the generation of C++ header files """
 
-class FileGenerator(object):
-    def __init__(self, filename, headerguard=True):
-        self.filename = filename
-        self.content = []
-        self.includes = {}
-        
-    def generate(self):
-        with open(self.filename) as f:
-            if self.headerguard:
-                macro = self.filename.upper().replace("/", "_").replace(".", "_")
-                f.write("#ifndef {}\n#define {}\n\n".format(macro))
-
-            for inc in self.includes:
-                f.write("#include {}\n".format(inc))
-#                 
-#             for c in self.content:
-#                 generate_code(c)
-#             
-            if self.headerguard:
-                f.write("\n\n#endif")
\ No newline at end of file
+from dune.perftool.generation import retrieve_cache_items
+
+def generate_file(filename, tag, content, headerguard=True):
+    """
+    Write a file from the generation cache:
+
+    Arguments:
+    ----------
+
+    Keyword Arguments:
+    ------------------
+    """
+    with open(filename, 'w') as f:
+        # Add a double inclusion protection header
+        if headerguard:
+            macro = filename.upper().replace("/", "_").replace(".", "_")
+            f.write("#ifndef {0}\n#define {0}\n\n".format(macro))
+
+        # Add the includes from the cache
+        for inc in retrieve_cache_items((tag, 'include'), union=False):
+            from cgen import Include
+            assert isinstance(inc, Include)
+            for line in inc.generate():
+                f.write(line)
+            f.write('\n')
+
+        f.write('\n\n')
+
+        for c in content:
+            from cgen import Generable
+            assert isinstance(c, Generable)
+            for line in c.generate():
+                f.write(line)
+
+        if headerguard:
+            f.write("\n\n#endif //{}".format(macro))
diff --git a/python/dune/perftool/generation.py b/python/dune/perftool/generation.py
index 25d2425e3e1d886d70b6aa6c360fcf18c58a7941..03b791e31f6eef5d53bea9e408d5b73283f576f1 100644
--- a/python/dune/perftool/generation.py
+++ b/python/dune/perftool/generation.py
@@ -67,14 +67,15 @@ class _CacheItemMeta(type):
         def _init(s, x):
             s.content = on_store(x)
             s.tags = item_tags
+            s.counted = counted
 
         setattr(rettype, '__init__', _init)
 
         return rettype
 
 
-from pytools import memoize as _memo
-@_memo(use_kwargs=True)
+from pytools import memoize
+@memoize(use_kwargs=True)
 def _construct_cache_item_type(name, **kwargs):
     """ Wrap the generation of cache item types from the meta class.
     At the same time, memoization assures that types are the same for
@@ -161,17 +162,22 @@ def generator_factory(**factory_kwargs):
         return _dec
 
 
-def retrieve_cache_items(tags, union=True):
+def retrieve_cache_items(tags, union=True, make_generable=False):
     """ Retrieve items from the cache.
 
     If union is True, all items that match one of the given tags are
     returned. If unions is False, only items that match all tags are
     returned. The items do remain in the cache.
+
+    If make_generable is True, any strings are wrapped as cgen.Line
     """
     if isinstance(tags, str):
         tags = (tags,)
 
+    choice = []
+
     for item in _cache.values():
+        # Determine whether this item is a match with the given tags and the union parameter
         match = False
         if union:
             for t in item.tags:
@@ -182,8 +188,34 @@ def retrieve_cache_items(tags, union=True):
             for t in item.tags:
                 if t not in tags:
                     match = False
+
+        # Append the item to the list
         if match:
-            yield item.content
+            choice.append(item)
+
+    def as_generable(content):
+        if make_generable:
+            from cgen import Generable, Line
+            if isinstance(content, Generable):
+                return content
+            if isinstance(content, str):
+                return Line(text=content + '\n')
+            assert False
+        else:
+            return content
+
+    # First yield all those items that are not sorted
+    for item in choice:
+        if not item.counted:
+            yield as_generable(item.content)
+
+    for item in sorted([i for i in choice if i.counted], key = lambda i: i.content[0]):
+        from collections import Iterable
+        if isinstance(item.content[1], Iterable) and not isinstance(item.content[1], str):
+            for l in item.content[1]:
+                yield as_generable(l)
+        else:
+            yield as_generable(item.content[1])
 
 
 def delete_cache_items(tags, union=True):
@@ -198,6 +230,7 @@ def delete_cache_items(tags, union=True):
     global _cache
     _cache = {k: v for k,v in _cache.items() if v not in removing}
 
+
 def delete_cache(tags=[], union=True):
     # TODO this implementation is horribly inefficient, but does the job
     keeping = retrieve_cache_items(tags, union)
diff --git a/python/dune/perftool/pdelab/argument.py b/python/dune/perftool/pdelab/argument.py
index 71d989cb85c18e9d870da1a25a8393c0d59f37b1..7b2ba8f4190facb910ff89783a27e3dfbc3cdeb7 100644
--- a/python/dune/perftool/pdelab/argument.py
+++ b/python/dune/perftool/pdelab/argument.py
@@ -6,7 +6,7 @@ from dune.perftool.ufl.modified_terminals import ModifiedArgumentDescriptor
 @dune_symbol
 def name_testfunction(modarg):
     ma = ModifiedArgumentDescriptor(modarg)
-    if len(ma.expr.ufl_element().sub_elements()) > 0:
+    if len(ma.expr.element().sub_elements()) > 0:
         pass
     return "{}a{}".format("grad_" if ma.grad else "", ma.expr.number())
 
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index 4dd55ca8d95e68f4aef951ed7e52a164f1d07a25..7ac76ee0dcb75060bbc6f2eee817c6befd5c0d56 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -6,8 +6,13 @@ Currently, these are hardcoded as strings. It would be possible
 to switch these to cgen expression. OTOH, there is not much to be
 gained there.
 """
+from dune.perftool.generation import generator_factory
+from dune.perftool.pdelab import dune_symbol
 
-from dune.perftool.pdelab import dune_symbol, dune_preamble, dune_include
+from cgen import Include
+
+driver_include = generator_factory(on_store=lambda i: Include(i), item_tags=("driver", "include"), no_deco=True)
+driver_preamble = generator_factory(item_tags=("driver", "preamble"), counted=True)
 
 # Have a global variable with the entire form data. This allows functions that depend
 # deterministically on the entire data set to directly access it instead of passing it
@@ -58,10 +63,10 @@ def name_inifile():
     # TODO pass some other option here.
     return "argv[1]"
 
-@dune_preamble
+@driver_preamble
 def parse_initree(varname):
-    dune_include("dune/common/parametertree.hh")
-    dune_include("dune/common/parametertreeparser.hh")
+    driver_include("dune/common/parametertree.hh")
+    driver_include("dune/common/parametertreeparser.hh")
     filename = name_inifile()
     return ["Dune::ParameterTree initree;", "Dune::ParameterTreeParser::readINITree({}, {});".format(filename, varname)]
 
@@ -71,25 +76,25 @@ def name_initree():
     #TODO we can get some other ini file here.
     return "initree"
 
-@dune_preamble
+@driver_preamble
 def define_dimension(name):
-    return "static const int {} = {};".format(name, __form.geometric_dimension)
+    return "static const int {} = {};".format(name, _form.cell().geometric_dimension())
 
 @dune_symbol
 def name_dimension():
     define_dimension("dim")
     return "dim"
 
-@dune_preamble
+@driver_preamble
 def typedef_grid(name):
     dim = name_dimension()
-    if any(_form.unique_elements[0].cell().cellname() in x for x in ["vertex", "interval", "quadrilateral", "hexalateral"]):
+    if any(_form.cell().cellname() in x for x in ["vertex", "interval", "quadrilateral", "hexalateral"]):
         gridt = "Dune::YaspGrid<{}>".format(dim)
-        dune_include("dune/grid/yaspgrid.hh")
+        driver_include("dune/grid/yaspgrid.hh")
     else:
-        if any(_form.unique_elements[0].cell().cellname() in x for x in ["triangle", "tetrahedron"]):
+        if any(_form.cell().cellname() in x for x in ["triangle", "tetrahedron"]):
             gridt = "Dune::UGGrid<{}>".format(dim)
-            dune_include("dune/grid/uggrid.hh")
+            driver_include("dune/grid/uggrid.hh")
         else:
             raise ValueError("Cant match your geometry with a DUNE grid. Please report bug.")
     return "typedef {} {};".format(gridt, name)
@@ -99,9 +104,9 @@ def type_grid():
     typedef_grid("Grid")
     return "Grid"
 
-@dune_preamble
+@driver_preamble
 def define_grid(name):
-    dune_include("dune/testtools/gridconstruction.hh")
+    driver_include("dune/testtools/gridconstruction.hh")
     ini = name_initree()
     _type = type_grid()
     return ["IniGridFactory<{}> factory({});".format(_type, ini),
@@ -112,7 +117,7 @@ def name_grid():
     define_grid("grid")
     return "grid"
 
-@dune_preamble
+@driver_preamble
 def typedef_leafview(name):
     grid = type_grid()
     return "typedef {}::LeafGridView {};".format(grid, name)
@@ -122,7 +127,7 @@ def type_leafview():
     typedef_leafview("GV")
     return "GV"
 
-@dune_preamble
+@driver_preamble
 def define_leafview(name):
     _type = type_leafview()
     grid = name_grid()
@@ -133,9 +138,9 @@ def name_leafview():
     define_leafview("gv")
     return "gv"
 
-@dune_preamble
+@driver_preamble
 def typedef_vtkwriter(name):
-    dune_include("dune/grid/io/file/vtk/subsamplingvtkwriter.hh")
+    driver_include("dune/grid/io/file/vtk/subsamplingvtkwriter.hh")
     gv = type_leafview()
     return "typedef Dune::SubsamplingVTKWriter<{}> {}".format(gv, name)
 
@@ -144,7 +149,7 @@ def type_vtkwriter():
     typedef_vtkwriter("VTKWriter")
     return "VTKWriter"
 
-@dune_preamble
+@driver_preamble
 def define_subsamplinglevel(name):
     ini = name_initree()
     return "int {} = {}.get<int>(\"vtk.subsamplinglevel\", 0);".format(name, ini)
@@ -154,7 +159,7 @@ def name_subsamplinglevel():
     define_subsamplinglevel("sublevel")
     return "sublevel"
 
-@dune_preamble
+@driver_preamble
 def define_vtkwriter(name):
     _type = type_vtkwriter()
     gv = name_leafview()
@@ -166,7 +171,7 @@ def name_vtkwriter():
     define_vtkwriter("vtkwriter")
     return "vtkwriter"
 
-@dune_preamble
+@driver_preamble
 def typedef_domainfield(name):
     gridt = type_grid()
     return "typedef {}::ctype {};".format(gridt, name)
@@ -176,7 +181,7 @@ def type_domainfield():
     typedef_domainfield("DF")
     return "DF"
 
-@dune_preamble
+@driver_preamble
 def typedef_range(name):
     return "typedef double {};".format(name)
 
@@ -185,16 +190,16 @@ def type_range():
     typedef_range("R")
     return "R"
 
-@dune_preamble
+@driver_preamble
 def typedef_fem(expr, name):
     gv = type_leafview()
     df = type_domainfield()
     r = type_range()
     if isPk(expr):
-        dune_include("dune/pdelab/finiteelementmap/pkfem.hh")
+        driver_include("dune/pdelab/finiteelementmap/pkfem.hh")
         return "typedef Dune::PDELab::PkLocalFiniteElementMap<{}, {}, {}, {}> {};".format(gv, df, r, expr._degree, name)
     if isQk(generator._kwargs['expr']):
-        dune_include("dune/pdelab/finiteelementmap/qkfem.hh")
+        driver_include("dune/pdelab/finiteelementmap/qkfem.hh")
         return "typedef Dune::PDELab::QkLocalFiniteElementMap<{}, {}, {}, {}> {};".format(gv, df, r, expr._degree, name)
     raise NotImplementedError("FEM not implemented in dune-perftool")
 
@@ -204,7 +209,7 @@ def type_fem(expr):
     typedef_fem(expr, name)
     return "{}_fem".format(name)
 
-@dune_preamble
+@driver_preamble
 def define_fem(expr, name):
     femtype = type_fem(expr)
     gv = name_leafview()
@@ -216,10 +221,10 @@ def name_fem(expr):
     define_fem(expr, name)
     return "{}_fem".format(name)
 
-@dune_preamble
+@driver_preamble
 def typedef_vectorbackend(name):
-    dune_include("dune/pdelab/backend/istlvectorbackend.hh")
-    return "typedef Dune::PDELab::ISTLVectorBacken<Dune::PDELab::ISTLParameters::no_blocking, 1> {}".format(name)
+    driver_include("dune/pdelab/backend/istlvectorbackend.hh")
+    return "typedef Dune::PDELab::ISTLVectorBacken<Dune::PDELab::ISTLParameters::no_blocking, 1> {};".format(name)
 
 @dune_symbol
 def type_vectorbackend():
@@ -230,9 +235,9 @@ def type_vectorbackend():
 def type_orderingtag():
     return "Dune::PDELab::LexicographicOrderingTag"
 
-@dune_preamble
+@driver_preamble
 def typedef_constraintsassembler(name):
-    dune_include("dune/pdelab/constraints/conforming.hh")
+    driver_include("dune/pdelab/constraints/conforming.hh")
     return "typedef Dune::PDELab::ConformingDirichletConstraints {}".format(name)
 
 @dune_symbol
@@ -240,7 +245,7 @@ def type_constraintsassembler():
     typedef_constraintsassembler("ConstraintsAssembler")
     return "ConstraintsAssembler"
 
-@dune_preamble
+@driver_preamble
 def typedef_constraintscontainer(expr, name):
     gfs = type_gfs(expr)
     r = type_range()
@@ -252,7 +257,7 @@ def type_constraintscontainer(expr):
     typedef_constraintscontainer(expr, name)
     return name
 
-@dune_preamble
+@driver_preamble
 def define_constraintscontainer(expr, name):
     cctype = type_constraintscontainer(expr)
     return ["{} {};".format(cctype, name), "{}.clear();".format(name)]
@@ -263,7 +268,7 @@ def name_constraintscontainer(expr):
     define_constraintscontainer(expr, name)
     return name
 
-@dune_preamble
+@driver_preamble
 def typedef_gfs(expr, name):
     vb = type_vectorbackend()
     from ufl import FiniteElement, MixedElement, VectorElement, EnrichedElement, RestrictedElement
@@ -277,7 +282,7 @@ def typedef_gfs(expr, name):
         args = ", ".join(type_gfs(e) for e in expr._sub_elements)
         return "typedef Dune::PDELab::CompositeGridFunctionSpace<{}, {}, {}> {}".format(vb, ot, args, name)
     if isinstance(expr, VectorElement):
-        dune_include("dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh")
+        driver_include("dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh")
         gv = type_leafview()
         fem = type_fem(expr._sub_elements[0])
         dim = name_dimension()
@@ -294,7 +299,7 @@ def type_gfs(expr):
     typedef_gfs(expr, name)
     return "{}_GFS".format(name)
 
-@dune_preamble
+@driver_preamble
 def define_gfs(expr, name):
     gfstype = type_gfs(expr)
     from ufl import FiniteElement, MixedElement, VectorElement, EnrichedElement, RestrictedElement
@@ -320,14 +325,14 @@ def name_gfs(expr):
     define_gfs(expr, name)
     return name
 
-@dune_preamble
+@driver_preamble
 def define_dofestimate(name):
     # Provide a worstcase estimate for the number of entries per row based on the given gridfunction space and cell geometry
-    if isQuadrilateral(_form.coefficient_elements[0]):
+    if isQuadrilateral(_form.coefficients()[0].element()):
         geo_factor = "4"
     else:
         geo_factor = "6"
-    gfs = name_gfs(_form.coefficient_elements[0])
+    gfs = name_gfs(_form.coefficients()[0].element())
     ini = name_initree()
     return ["int generic_dof_estimate =  {} * {}.maxLocalSize();".format(geo_factor, gfs),
             "int dof_estimate = {}.get<int>(\"istl.number_of_nnz\", generic_dof_estimate);".format(ini)]
@@ -337,9 +342,9 @@ def name_dofestimate():
     define_dofestimate("dofestimate")
     return "dofestimate"
 
-@dune_preamble
+@driver_preamble
 def typedef_matrixbackend(name):
-    dune_include("dune/pdelab/backend/istl/bcrsmatrixbackend.hh")
+    driver_include("dune/pdelab/backend/istl/bcrsmatrixbackend.hh")
     return "typedef Dune::PDELab::istl::BCRSMatrixBackend<> {};".format(name)
 
 @dune_symbol
@@ -347,7 +352,7 @@ def type_matrixbackend():
     typedef_matrixbackend("MatrixBackend")
     return "MatrixBackend"
 
-@dune_preamble
+@driver_preamble
 def define_matrixbackend(name):
     mbtype = type_matrixbackend()
     dof = name_dofestimate()
@@ -358,7 +363,7 @@ def name_matrixbackend():
     define_matrixbackend("mb")
     return "mb"
 
-@dune_preamble
+@driver_preamble
 def typedef_parameters(name):
     return "typedef LocalOperatorParameters {}".format(name)
 
@@ -367,7 +372,7 @@ def type_parameters():
     typedef_parameters("Params")
     return "Params"
 
-@dune_preamble
+@driver_preamble
 def define_parameters(name):
     partype = type_parameters()
     return "{} {}();".format(partype, name)
@@ -377,7 +382,7 @@ def name_parameters():
     define_parameters("params")
     return "params"
 
-@dune_preamble
+@driver_preamble
 def typedef_localoperator(name):
     params = type_parameters()
     return "typedef LocalOperator<{}> {}".format(params, name)
@@ -387,7 +392,7 @@ def type_localoperator():
     typedef_localoperator("LocalOperator")
     return "LocalOperator"
 
-@dune_preamble
+@driver_preamble
 def define_localoperator(name):
     loptype = type_localoperator()
     ini = name_initree()
@@ -399,17 +404,17 @@ def name_localoperator():
     define_localoperator("lop")
     return "lop"
 
-@dune_preamble
+@driver_preamble
 def typedef_gridoperator(name):
-    ugfs = type_gfs(_form.coefficient_elements[0])
-    vgfs = type_gfs(_form.argument_elements[0])
+    ugfs = type_gfs(_form.coefficients()[0].element())
+    vgfs = type_gfs(_form.arguments()[0].element())
     lop = type_localoperator()
-    ucc = type_constraintscontainer(_form.coefficient_elements[0])
-    vcc = type_constraintscontainer(_form.argument_elements[0])
+    ucc = type_constraintscontainer(_form.coefficients()[0].element())
+    vcc = type_constraintscontainer(_form.arguments()[0].element())
     mb = type_matrixbackend()
     df = type_domainfield()
     r = type_range()
-    dune_include("dune/pdelab/gridoperator/gridoperator.hh")
+    driver_include("dune/pdelab/gridoperator/gridoperator.hh")
     return "typedef Dune::PDELab::GridOperator<{}, {}, {}, {}, {}, {}, {}, {}, {}> {}".format(ugfs, vgfs, lop, mb, df, r, r, ucc, vcc, name)
 
 @dune_symbol
@@ -417,13 +422,13 @@ def type_gridoperator():
     typedef_gridoperator("GO")
     return "GO"
 
-@dune_preamble
+@driver_preamble
 def define_gridoperator(name):
     gotype = type_gridoperator()
-    ugfs = name_gfs(_form.coefficient_elements[0])
-    ucc = name_constraintscontainer(_form.coefficient_elements[0])
-    vgfs = name_gfs(_form.argument_elements[0])
-    vcc = name_constraintscontainer(_form.argument_elements[0])
+    ugfs = name_gfs(_form.coefficients()[0].element())
+    ucc = name_constraintscontainer(_form.coefficients()[0].element())
+    vgfs = name_gfs(_form.arguments()[0].element())
+    vcc = name_constraintscontainer(_form.arguments()[0].element())
     lop = name_localoperator()
     mb = name_matrixbackend()
     return "{} {}({}, {}, {}, {}, {}, {});".format(gotype, name, ugfs, ucc, vgfs, vcc, lop, mb)
@@ -433,7 +438,7 @@ def name_gridoperator():
     define_gridoperator("go")
     return "go"
 
-@dune_preamble
+@driver_preamble
 def typedef_vector(name):
     gotype = type_gridoperator()
     return "typedef {}::Traits::Domain {}".format(gotype, name)
@@ -443,10 +448,10 @@ def type_vector():
     typedef_vector("V")
     return "V"
 
-@dune_preamble
+@driver_preamble
 def define_vector(name):
     vtype = type_vector()
-    gfs = name_gfs(_form.coefficient_elements[0])
+    gfs = name_gfs(_form.coefficients()[0].element())
     return ["{} {}({});".format(vtype, name, gfs), "{} = 0.0;".format(name)]
 
 @dune_symbol
@@ -454,9 +459,9 @@ def name_vector():
     define_vector("x")
     return "x"
 
-@dune_preamble
+@driver_preamble
 def typedef_linearsolver(name):
-    dune_include("dune/pdelab/backend/istlsolverbackend.hh")
+    driver_include("dune/pdelab/backend/istlsolverbackend.hh")
     return "typedef Dune::PDELab::ISTLBackend_SEQ_UMFPack {};".format(name)
 
 @dune_symbol
@@ -464,7 +469,7 @@ def type_linearsolver():
     typedef_linearsolver("LinearSolver")
     return "LinearSolver"
 
-@dune_preamble
+@driver_preamble
 def define_linearsolver(name):
     lstype = type_linearsolver()
     return "{} {}(false);".format(lstype, name)
@@ -474,7 +479,7 @@ def name_linearsolver():
     define_linearsolver("ls")
     return "ls"
 
-@dune_preamble
+@driver_preamble
 def define_reduction(name):
     ini = name_initree()
     return "double {} = {}.get<double>(\"reduction\", 1e-12);".format(name, ini)
@@ -486,7 +491,7 @@ def name_reduction():
 
 @dune_symbol
 def typedef_stationarylinearproblemsolver(name):
-    dune_include("dune/pdelab/stationary/linearproblem.hh")
+    driver_include("dune/pdelab/stationary/linearproblem.hh")
     gotype = type_gridoperator()
     lstype = type_linearsolver()
     xtype = type_vector()
@@ -497,7 +502,7 @@ def type_stationarylinearproblemsolver():
     typedef_stationarylinearproblemsolver("SLP")
     return "SLP"
 
-@dune_preamble
+@driver_preamble
 def define_stationarylinearproblemsolver(name):
     slptype = type_stationarylinearproblemsolver()
     go = name_gridoperator()
@@ -511,19 +516,21 @@ def name_stationarylinearproblemsolver():
     define_stationarylinearproblemsolver("slp")
     return "slp"
 
-@dune_preamble
+@driver_preamble
 def dune_solve():
     from ufl.algorithms.predicates import is_multilinear
-    if is_multilinear(_form.preprocessed_form):
+    # This is crap as it does check for linearity of the rank 1 form,
+    # which is by definition True.
+    if is_multilinear(_form):
         slp = name_stationarylinearproblemsolver()
         return "{}.apply();".format(slp)
     else:
-        pass
+        raise NotImplementedError
 
-@dune_preamble
+@driver_preamble
 def define_vtkfile(name):
     ini = name_initree()
-    dune_include("string")
+    driver_include("string")
     return "std::string {} = {}.get<std::string>(\"vtk.filename\", \"output\");".format(name, ini)
 
 @dune_symbol
@@ -531,11 +538,11 @@ def name_vtkfile():
     define_vtkfile("vtkfile")
     return "vtkfile"
 
-@dune_preamble
+@driver_preamble
 def vtkoutput():
-    dune_include("dune/pdelab/gridfunctionspace/vtk.hh")
+    driver_include("dune/pdelab/gridfunctionspace/vtk.hh")
     vtkwriter = name_vtkwriter()
-    gfs = name_gfs(_form.coefficient_elements[0])
+    gfs = name_gfs(_form.coefficients()[0].element())
     vec = name_vector()
     vtkfile = name_vtkfile()
     dune_solve()
diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index fc3e3844803950147adab0843646f1ef809de5de..ad52006aa85c8dccd300198c08aa3955e5dd8e3b 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -1,13 +1,18 @@
 from __future__ import absolute_import
-from pytools import memoize
+
 from dune.perftool.options import get_option
 from dune.perftool.generation import generator_factory
 from dune.perftool.pdelab import dune_symbol
 
+from cgen import Include
+
+from pytools import memoize
+
 # Define the generators used in-here
-operator_include = generator_factory(item_tags=("pdelab", "include", "operator"), on_store=lambda i: "#include<{}>".format(i), no_deco=True)
+operator_include = generator_factory(item_tags=("pdelab", "include", "operator"), on_store=lambda i: Include(i), no_deco=True)
 base_class = generator_factory(item_tags=("pdelab", "baseclass", "operator"), counted=True, no_deco=True)
 initializer_list = generator_factory(item_tags=("pdelab", "initializer", "operator"), counted=True, no_deco=True)
+
 # TODO definition
 #private_member = generator_factory(item_tags=("pdelab", "member", "privatemember"))
 
@@ -79,10 +84,6 @@ def generate_term(integrand=None, measure=None):
     # Get the measure specifics
     specifics = measure_specific_details(measure)
 
-#     from dune.perftool.ufl.rank import ufl_rank
-#     if ufl_rank(integrand) == 2:
-#         from IPython import embed; embed()
-
     # Now split the given integrand into accumulation expressions
     from dune.perftool.ufl.transformations.extract_accumulation_terms import split_into_accumulation_terms
     accterms = split_into_accumulation_terms(integrand)
@@ -91,10 +92,6 @@ def generate_term(integrand=None, measure=None):
     for term in accterms:
         from dune.perftool.loopy.transformer import transform_accumulation_term
         transform_accumulation_term(term)
-#
-#     # Transform the expression. All relevant results are then in the cache
-#     from dune.perftool.loopy.transformer import transform_expression
-#     transform_expression(integrand)
 
     # Extract the information, which is needed to create a loopy kernel.
     # First extracting it, might be useful to alter it before kernel generation.
@@ -148,7 +145,6 @@ def generate_localoperator(form, operatorfile):
             signature = measure_specific_details(integral.integral_type())["jacobian_signature"]
             operator_methods.append((signature, body))
 
-
     # TODO: JacobianApply for matrix-free computations.
 
     # Manage includes and base classes that we always need
diff --git a/python/dune/perftool/ufl/transformations/__init__.py b/python/dune/perftool/ufl/transformations/__init__.py
index f9ff45ae0af58f3587cdfff1c4aced3b559becf5..d67f112bc8a1b8a34d7a6887d76cd548e4801449 100644
--- a/python/dune/perftool/ufl/transformations/__init__.py
+++ b/python/dune/perftool/ufl/transformations/__init__.py
@@ -1,3 +1,5 @@
+""" Define the general infrastructure for debuggable UFL transformations"""
+
 class TransformationWrapper(object):
     def __init__(self, func, **kwargs):
         # Store the decorated function
@@ -37,7 +39,6 @@ class TransformationWrapper(object):
         assert isinstance(expr, Expr)
 
         # Maybe output the input expression!
-        from dune.perftool.options import get_option
         self.write_trafo([expr], True)
 
         # Call the original function
diff --git a/python/dune/perftool/ufl/transformations/argument_elimination.py b/python/dune/perftool/ufl/transformations/argument_elimination.py
index b2e0afa91d56588c6f016274caebd2b457f26e23..70cc660c692cb6508f4343d9a62786e08407f47d 100644
--- a/python/dune/perftool/ufl/transformations/argument_elimination.py
+++ b/python/dune/perftool/ufl/transformations/argument_elimination.py
@@ -8,7 +8,6 @@ class EliminateArguments(MultiFunction):
 
     def __call__(self, o):
         from dune.perftool.ufl.modified_terminals import ModifiedArgumentExtractor
-        from dune.perftool.ufl.rank import ufl_rank
 
         self.arguments = ModifiedArgumentExtractor()(o)
         e = self.call(o)
diff --git a/python/setup.py b/python/setup.py
index 8ed37cb08f90e6297e97577d870376c99391f384..2ef4dc99c468ab2b4b686e80d12f005a46013d5d 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -30,7 +30,7 @@ setup(name='dune.perftool',
       author='Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>',
       url='http://conan2.iwr.uni-heidelberg.de/git/dominic/dune-perftool',
       packages=['dune.perftool'],
-      install_requires=[],
+      install_requires=['sympy'],
       tests_require=['pytest'],
       cmdclass={'test': PyTest},
       entry_points = {