diff --git a/dumux/common/properties/newpropertysystem.hh b/dumux/common/properties/newpropertysystem.hh
new file mode 100644
index 0000000000000000000000000000000000000000..cfed97a9bbfb0ce5b291c2d4fc88a319b3610a4e
--- /dev/null
+++ b/dumux/common/properties/newpropertysystem.hh
@@ -0,0 +1,130 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup Common
+ * \ingroup TypeTraits
+ * \author Timo Koch
+ * \brief The Dumux property system, traits with inheritance
+ */
+#ifndef DUMUX_NEW_PROPERTY_SYSTEM_HH
+#define DUMUX_NEW_PROPERTY_SYSTEM_HH
+
+#include <tuple>
+#include <type_traits>
+
+namespace Dumux {
+namespace Properties {
+
+//! a tag to mark properties as undefined
+struct UndefinedProperty {};
+
+//! implementation details for template meta programming
+namespace Detail {
+
+//! check if a property P is defined
+template<class P>
+constexpr auto isDefinedProperty(int)
+-> decltype(std::integral_constant<bool, !std::is_same<typename P::type, UndefinedProperty>::value>{})
+{ return {}; }
+
+//! fall back if a Property is defined
+template<class P>
+constexpr std::true_type isDefinedProperty(...) { return {}; }
+
+//! check if a TypeTag inherits from other TypeTags
+template<class T>
+constexpr auto hasParentTypeTag(int)
+-> decltype(std::declval<typename T::InheritsFrom>(), std::true_type{})
+{ return {}; }
+
+//! fall back if a TypeTag doesn't inherit
+template<class T>
+constexpr std::false_type hasParentTypeTag(...) { return {}; }
+
+//! helper alias to concatenate multiple tuples
+template<class ...Tuples>
+using ConCatTuples = decltype(std::tuple_cat(std::declval<Tuples>()...));
+
+//! helper struct to get the first property that is defined in the TypeTag hierarchy
+template<class TypeTag, template<class,class> class Property, class TTagList>
+struct GetDefined;
+
+//! helper struct to iteratre over the TypeTag hierarchy
+template<class TypeTag, template<class,class> class Property, class TTagList, class Enable>
+struct GetNextTypeTag;
+
+template<class TypeTag, template<class,class> class Property, class LastTypeTag>
+struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
+{ using type = typename GetDefined<TypeTag, Property, typename LastTypeTag::InheritsFrom>::type; };
+
+template<class TypeTag, template<class,class> class Property, class LastTypeTag>
+struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
+{ using type = UndefinedProperty; };
+
+template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
+struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
+{ using type = typename GetDefined<TypeTag, Property, ConCatTuples<typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::type; };
+
+template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
+struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
+{ using type = typename GetDefined<TypeTag, Property, std::tuple<Args...>>::type; };
+
+template<class TypeTag, template<class,class> class Property, class LastTypeTag>
+struct GetDefined<TypeTag, Property, std::tuple<LastTypeTag>>
+{
+     using LastType = Property<TypeTag, LastTypeTag>;
+     using type = std::conditional_t<isDefinedProperty<LastType>(int{}), LastType,
+                                     typename GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, void>::type>;
+};
+
+template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
+struct GetDefined<TypeTag, Property, std::tuple<FirstTypeTag, Args...>>
+{
+     using FirstType = Property<TypeTag, FirstTypeTag>;
+     using type = std::conditional_t<isDefinedProperty<FirstType>(int{}), FirstType,
+                                     typename GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, void>::type>;
+};
+
+//! helper struct to extract get the Property specilization given a TypeTag, asserts that the property is defined
+template<class TypeTag, template<class,class> class Property>
+struct GetPropImpl
+{
+    using type = typename Detail::GetDefined<TypeTag, Property, std::tuple<TypeTag>>::type;
+    static_assert(!std::is_same<type, UndefinedProperty>::value, "Property is undefined!");
+};
+
+} // end namespace Detail
+
+//! get the type of a property (equivalent to old macro GET_PROP(...))
+template<class TypeTag, template<class,class> class Property>
+using GetProp = typename Detail::GetPropImpl<TypeTag, Property>::type;
+
+//! get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
+template<class TypeTag, template<class,class> class Property>
+using GetPropType = typename Detail::GetPropImpl<TypeTag, Property>::type::type;
+
+//! get the value data member of a property (C++17 only, equivalent to old macro GET_PROP_VALUE(...))
+// template<class TypeTag, template<class,class> class Property>
+// constexpr auto getPropValue = Detail::GetPropImpl<TypeTag, Property>::type::value;
+
+} // end namespace Property
+} // end namespace Dumux
+
+#endif
diff --git a/test/common/propertysystem/CMakeLists.txt b/test/common/propertysystem/CMakeLists.txt
index a5eeb1c9721bc4ab386292027deb184a2fac0bc8..65a70edc5753cfe8ae0b4ceee08b344e77c245a6 100644
--- a/test/common/propertysystem/CMakeLists.txt
+++ b/test/common/propertysystem/CMakeLists.txt
@@ -1,5 +1,7 @@
 # build the test for the property system
 dune_add_test(SOURCES test_propertysystem.cc)
+# build the test for the new property system
+dune_add_test(SOURCES test_newpropertysystem.cc)
 
 #install sources
 install(FILES
diff --git a/test/common/propertysystem/test_newpropertysystem.cc b/test/common/propertysystem/test_newpropertysystem.cc
new file mode 100644
index 0000000000000000000000000000000000000000..56515ea3551cbfd9701f87533e33b8685cba0740
--- /dev/null
+++ b/test/common/propertysystem/test_newpropertysystem.cc
@@ -0,0 +1,124 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup Common
+ * \ingroup Tests
+ * \brief Testing the Dumux property system
+ */
+
+#include <iostream>
+#include <type_traits>
+
+#include <dune/common/classname.hh>
+#include <dune/common/exceptions.hh>
+
+#include <dumux/common/properties/newpropertysystem.hh>
+
+namespace Dumux {
+namespace Properties {
+
+// create some Properties (equivalent to old macro NEW_PROP_TAG(...))
+// the first type tag is the actual TypeTag for which the property will be obtained
+// (can be used to make properties depend on other properties),
+// the second type tag is for parital specialization (equivalent to old macro SET_PROP(...), see below)
+// the default property should be always undefined to produce a good error message
+// if the user attempt to get an unset property
+template<class TypeTag, class MyTypeTag>
+struct Scalar { using type = UndefinedProperty;  };
+
+template<class TypeTag, class MyTypeTag>
+struct CoordinateType { using type = UndefinedProperty; };
+
+namespace TTag {
+// create some TypeTags (equivalent to old macro NEW_TYPE_TAG(..., INHERITS_FROM(...)))
+// the tuple is sorted by precedence, the first one overwriting the following
+struct Base { };
+struct Grid { };
+struct CCTpfaDisc { using InheritsFrom = std::tuple<Grid, Base>; };
+struct BoxDisc { using InheritsFrom = std::tuple<Grid, Base>; };
+struct OnePModel { using InheritsFrom = std::tuple<Base>; };
+struct OnePTestTypeTag { using InheritsFrom = std::tuple<OnePModel, BoxDisc>; };
+
+} // end namespace TTag
+
+// set and overwrite some properties (equivalent to old macro SET_PROP(...){};)
+template<class TypeTag>
+struct Scalar<TypeTag, TTag::Base> { using type = float; };
+
+template<class TypeTag>
+struct Scalar<TypeTag, TTag::OnePModel> { using type = double; };
+
+template<class TypeTag>
+struct Scalar<TypeTag, TTag::OnePTestTypeTag> { using type = int; };
+
+template<class TypeTag>
+struct CoordinateType<TypeTag, TTag::Grid> { using type = GetPropType<TypeTag, Scalar>; };
+
+} // end namespace Properties
+} // end namespace Dumux
+
+//! the main function
+int main(int argc, char* argv[]) try
+{
+    using namespace Dumux;
+    using namespace Properties;
+
+    {
+        using Scalar = GetPropType<TTag::Base, Scalar>;
+        if (!std::is_same<Scalar, float>::value)
+            DUNE_THROW(Dune::InvalidStateException, "Property Scalar in TTag::Base should be float but is " << Dune::className<Scalar>());
+    }
+    {
+        using Scalar = GetPropType<TTag::OnePTestTypeTag, Scalar>;
+        if (!std::is_same<Scalar, int>::value)
+            DUNE_THROW(Dune::InvalidStateException, "Property Scalar in TTag::OnePTestTypeTag should be int but is " << Dune::className<Scalar>());
+    }
+    {
+        using Scalar = GetPropType<TTag::OnePModel, Scalar>;
+        if (!std::is_same<Scalar, double>::value)
+        DUNE_THROW(Dune::InvalidStateException, "Property Scalar in TTag::OnePModel should be double but is " << Dune::className<Scalar>());
+    }
+    {
+        using CoordinateType = GetPropType<TTag::OnePTestTypeTag, CoordinateType>;
+        if (!std::is_same<CoordinateType, int>::value)
+            DUNE_THROW(Dune::InvalidStateException, "Property CoordinateType in TTag::OnePTestTypeTag should be int but is " << Dune::className<CoordinateType>());
+    }
+    {
+        using CoordinateType = GetPropType<TTag::CCTpfaDisc, CoordinateType>;
+        if (!std::is_same<CoordinateType, float>::value)
+            DUNE_THROW(Dune::InvalidStateException, "Property CoordinateType in TTag::CCTpfaDisc should be float but is " << Dune::className<CoordinateType>());
+    }
+
+    std::cout << "All tests passed!" << std::endl;
+    return 0;
+}
+
+// error handler
+catch (const Dune::Exception& e)
+{
+    std::cerr << "Dune exception thrown: " << e << " --> Abort!" << std::endl;
+    return 1;
+}
+
+catch (...)
+{
+    std::cerr << "Unknown exception thrown --> Abort!" << std::endl;
+    return 2;
+}