diff --git a/dumux/material/components/air.hh b/dumux/material/components/air.hh
index 6b49313dc1c50b9b9235b401bd143b9cc787b646..ae0264b97b573549bfa3b2e97c39a76aecfb1092 100644
--- a/dumux/material/components/air.hh
+++ b/dumux/material/components/air.hh
@@ -40,7 +40,8 @@ namespace Components {
  * \tparam Scalar The type used for scalar values
  */
 template <class Scalar>
-class Air : public Component<Scalar, Air<Scalar> >
+class Air : public Components::Base<Scalar, Air<Scalar> >,
+            public Components::Gas<Scalar, Air<Scalar> >
 {
     using IdealGas = Dumux::IdealGas<Scalar>;
 
diff --git a/dumux/material/components/base.hh b/dumux/material/components/base.hh
index 8605839dab351c5a19b36e80e60a8bd1f560bb63..48213dd5b5b9f7faf58cb3098da6532129c4009c 100644
--- a/dumux/material/components/base.hh
+++ b/dumux/material/components/base.hh
@@ -39,11 +39,16 @@
 namespace Dumux {
 namespace Components {
 
-template <class Scalar, class Implementation>
+template <class ScalarType, class Component>
 class Base
 {
 public:
-    static const bool isTabulated = false;
+
+    //! export the scalar type used by the component
+    using Scalar = ScalarType;
+
+    //! if the component relies on tabulated values
+    static constexpr bool isTabulated = false;
 
     /*!
      * \brief A default routine for initialization, not needed for components and must not be called.
@@ -65,7 +70,7 @@ public:
      * \brief A human readable name for the component.
      * \note Mandatory for all components
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static std::string name()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: name()");
@@ -75,7 +80,7 @@ public:
     /*!
      * \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of the component.
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static constexpr Scalar molarMass()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: molarMass()");
@@ -85,7 +90,7 @@ public:
     /*!
      * \brief Returns the critical temperature in \f$\mathrm{[K]}\f$ of the component.
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static constexpr Scalar criticalTemperature()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: criticalTemperature()");
@@ -95,7 +100,7 @@ public:
     /*!
      * \brief Returns the critical pressure in \f$\mathrm{[Pa]}\f$ of the component.
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static constexpr Scalar criticalPressure()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: criticalPressure()");
@@ -105,7 +110,7 @@ public:
     /*!
      * \brief Returns the temperature in \f$\mathrm{[K]}\f$ at the component's triple point.
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static constexpr Scalar tripleTemperature()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: tripleTemperature()");
@@ -115,7 +120,7 @@ public:
     /*!
      * \brief Returns the pressure in \f$\mathrm{[Pa]}\f$ at the component's triple point.
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static constexpr Scalar triplePressure()
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: triplePressure()");
@@ -128,7 +133,7 @@ public:
      *
      * \param T temperature of the component in \f$\mathrm{[K]}\f$
      */
-    template<class C = Implementation>
+    template<class C = Component>
     static Scalar vaporPressure(Scalar t)
     {
         static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: vaporPressure(t)");
diff --git a/dumux/material/components/componenttraits.hh b/dumux/material/components/componenttraits.hh
new file mode 100644
index 0000000000000000000000000000000000000000..27cfa721b5dca13ecb5fb0b73fa6ac1a5291b6d8
--- /dev/null
+++ b/dumux/material/components/componenttraits.hh
@@ -0,0 +1,53 @@
+// -*- 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 Components
+ * \brief Component traits, i.e. information extracted from components
+ */
+#ifndef DUMUX_COMPONENT_TRAITS_HH
+#define DUMUX_COMPONENT_TRAITS_HH
+
+#include <type_traits>
+
+#include <dumux/material/components/solid.hh>
+#include <dumux/material/components/liquid.hh>
+#include <dumux/material/components/gas.hh>
+
+namespace Dumux {
+
+template<class Component>
+struct ComponentTraits
+{
+    using Scalar = typename Component::Scalar;
+
+    //! if the component implements a solid state
+    static constexpr bool hasSolidState = std::is_base_of<Components::Solid<Scalar, Component>, Component>::value;
+
+    //! if the component implements a liquid state
+    static constexpr bool hasLiquidState = std::is_base_of<Components::Liquid<Scalar, Component>, Component>::value;
+
+    //! if the component implements a gaseous state
+    static constexpr bool hasGasState = std::is_base_of<Components::Gas<Scalar, Component>, Component>::value;
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/material/components/gas.hh b/dumux/material/components/gas.hh
index 821f4173b8bb7278aa71d75e7cd470386de833b6..0dea8837a51be446067dbd08899d07328fdafed8 100644
--- a/dumux/material/components/gas.hh
+++ b/dumux/material/components/gas.hh
@@ -36,12 +36,6 @@ template<class Scalar, class Component>
 class Gas
 {
 public:
-    /*!
-     * \brief the component has a gas state if it derives from Gas
-     */
-    static constexpr bool hasGasState()
-    { return true; }
-
     /*!
      * \brief Returns true if the gas phase is assumed to be compressible
      */
diff --git a/dumux/material/components/liquid.hh b/dumux/material/components/liquid.hh
index 6738635c8a514f8bf24f06fb2a992f27f6fe254f..171cae6a692880405d8e0e8b1d86921cedca7783 100644
--- a/dumux/material/components/liquid.hh
+++ b/dumux/material/components/liquid.hh
@@ -36,12 +36,6 @@ template<class Scalar, class Component>
 class Liquid
 {
 public:
-    /*!
-     * \brief the component has a liquid state if it derives from Liquid
-     */
-    static constexpr bool hasLiquidState()
-    { return true; }
-
     /*!
      * \brief Returns true if the liquid phase is assumed to be compressible
      */
diff --git a/dumux/material/components/solid.hh b/dumux/material/components/solid.hh
index 84b9a3b314f7bb2aeafd343909a736f8fd4466a1..62bb74099bdfee762f7800870bcbfa1c1aaf279b 100644
--- a/dumux/material/components/solid.hh
+++ b/dumux/material/components/solid.hh
@@ -36,12 +36,6 @@ template<class Scalar, class Component>
 class Solid
 {
 public:
-    /*!
-     * \brief the component has a solid state if it derives from Solid
-     */
-    static constexpr bool hasSolidState()
-    { return true; }
-
     /*!
      * \brief Returns true if the solid phase is assumed to be compressible
      */
diff --git a/test/material/components/CMakeLists.txt b/test/material/components/CMakeLists.txt
index ee9e5e00d3462825e572d72878a767f75681e1fa..3ca8fcc7aad34a43c05124d5b0bf989be870b06c 100644
--- a/test/material/components/CMakeLists.txt
+++ b/test/material/components/CMakeLists.txt
@@ -1,3 +1,6 @@
+dune_add_test(SOURCES test_componenttraits.cc
+              COMPILE_ONLY)
+
 add_executable(plot_component plotproperties.cc)
 
 dune_add_test(NAME plot_air
diff --git a/test/material/components/plotproperties.cc b/test/material/components/plotproperties.cc
index 51908570a6299a91d1859f2b6d33c9eba8d9e3f9..09b9cf2d490cace4722878b8cdac34377764fbac 100644
--- a/test/material/components/plotproperties.cc
+++ b/test/material/components/plotproperties.cc
@@ -46,6 +46,7 @@
 #include <dumux/material/components/simpleh2o.hh>
 #include <dumux/material/components/trichloroethene.hh>
 #include <dumux/material/components/xylene.hh>
+#include <dumux/material/components/componenttraits.hh>
 
 using namespace std;
 using namespace Dumux;
@@ -108,7 +109,7 @@ void plot(Functor&& f,
 //! Plot properties if overloads compile
 template<class C, class hasNoDensityOverload = checkLiqDen>
 auto plotLiquidDensity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value && ComponentTraits<C>::hasLiquidState, void>
 {
     auto f = [] (auto T, auto p) { return C::liquidDensity(T, p); };
     plot(f, T, p, C::name(), "liquid", "density", "[kg/^3]", openPlot);
@@ -116,7 +117,7 @@ auto plotLiquidDensity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoEnthalpyOverload = checkLiqEnth>
 auto plotLiquidEnthalpy(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value && ComponentTraits<C>::hasLiquidState, void>
 {
     auto f = [] (auto T, auto p) { return C::liquidEnthalpy(T, p); };
     plot(f, T, p, C::name(), "liquid", "enthalpy", "[J/(kg)]", openPlot);
@@ -124,7 +125,7 @@ auto plotLiquidEnthalpy(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoHeatCapOverload = checkLiqHeatCap>
 auto plotLiquidHeatCapacity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value && ComponentTraits<C>::hasLiquidState, void>
 {
     auto f = [] (auto T, auto p) { return C::liquidHeatCapacity(T, p); };
     plot(f, T, p, C::name(), "liquid", "heat capacity", "[J/(kg*K)]", openPlot);
@@ -132,7 +133,7 @@ auto plotLiquidHeatCapacity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoViscOverload = checkLiqVisc>
 auto plotLiquidViscosity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoViscOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoViscOverload{})(declval<C>()))::value && ComponentTraits<C>::hasLiquidState, void>
 {
     auto f = [] (auto T, auto p) { return C::liquidViscosity(T, p); };
     plot(f, T, p, C::name(), "liquid", "viscosity", "[Pa*s]", openPlot);
@@ -140,7 +141,7 @@ auto plotLiquidViscosity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoThermCondOverload = checkLiqThermCond>
 auto plotLiquidThermalConductivity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value && ComponentTraits<C>::hasLiquidState, void>
 {
     auto f = [] (auto T, auto p) { return C::liquidThermalConductivity(T, p); };
     plot(f, T, p, C::name(), "liquid", "thermal conductivity", "[J/(kg*K)]", openPlot);
@@ -148,7 +149,7 @@ auto plotLiquidThermalConductivity(const vector<double>& T, double p, bool openP
 
 template<class C, class hasNoDensityOverload = checkGasDen>
 auto plotGasDensity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value && ComponentTraits<C>::hasGasState, void>
 {
     auto f = [] (auto T, auto p) { return C::gasDensity(T, p); };
     plot(f, T, p, C::name(), "gas", "density", "[kg/^3]", openPlot);
@@ -156,7 +157,7 @@ auto plotGasDensity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoEnthalpyOverload = checkGasEnth>
 auto plotGasEnthalpy(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value && ComponentTraits<C>::hasGasState, void>
 {
     auto f = [] (auto T, auto p) { return C::gasEnthalpy(T, p); };
     plot(f, T, p, C::name(), "gas", "enthalpy", "[J/(kg)]", openPlot);
@@ -164,7 +165,7 @@ auto plotGasEnthalpy(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoHeatCapOverload = checkGasHeatCap>
 auto plotGasHeatCapacity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value && ComponentTraits<C>::hasGasState, void>
 {
     auto f = [] (auto T, auto p) { return C::gasHeatCapacity(T, p); };
     plot(f, T, p, C::name(), "gas", "heat capacity", "[J/(kg*K)]", openPlot);
@@ -172,7 +173,7 @@ auto plotGasHeatCapacity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoViscOverload = checkGasVisc>
 auto plotGasViscosity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoViscOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoViscOverload{})(declval<C>()))::value && ComponentTraits<C>::hasGasState, void>
 {
     auto f = [] (auto T, auto p) { return C::gasViscosity(T, p); };
     plot(f, T, p, C::name(), "gas", "viscosity", "[Pa*s]", openPlot);
@@ -180,7 +181,7 @@ auto plotGasViscosity(const vector<double>& T, double p, bool openPlot)
 
 template<class C, class hasNoThermCondOverload = checkGasThermCond>
 auto plotGasThermalConductivity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<!decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value, void>
+-> typename std::enable_if_t<!decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value && ComponentTraits<C>::hasGasState, void>
 {
     auto f = [] (auto T, auto p) { return C::gasThermalConductivity(T, p); };
     plot(f, T, p, C::name(), "gas", "thermal conductivity", "[J/(kg*K)]", openPlot);
@@ -189,43 +190,43 @@ auto plotGasThermalConductivity(const vector<double>& T, double p, bool openPlot
 //! Do not plot properties if overloads don't compile
 template<class C, class hasNoDensityOverload = checkLiqDen>
 auto plotLiquidDensity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasLiquidState, void> {}
 
 template<class C, class hasNoEnthalpyOverload = checkLiqEnth>
 auto plotLiquidEnthalpy(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasLiquidState, void> {}
 
 template<class C, class hasNoHeatCapOverload = checkLiqHeatCap>
 auto plotLiquidHeatCapacity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasLiquidState, void> {}
 
 template<class C, class hasNoViscOverload = checkLiqVisc>
 auto plotLiquidViscosity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoViscOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoViscOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasLiquidState, void> {}
 
 template<class C, class hasNoThermCondOverload = checkLiqThermCond>
 auto plotLiquidThermalConductivity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasLiquidState, void> {}
 
 template<class C, class hasNoDensityOverload = checkGasDen>
 auto plotGasDensity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasGasState, void> {}
 
 template<class C, class hasNoEnthalpyOverload = checkGasEnth>
 auto plotGasEnthalpy(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasGasState, void> {}
 
 template<class C, class hasNoHeatCapOverload = checkGasHeatCap>
 auto plotGasHeatCapacity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasGasState, void> {}
 
 template<class C, class hasNoViscOverload = checkGasVisc>
 auto plotGasViscosity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoViscOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoViscOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasGasState, void> {}
 
 template<class C, class hasNoThermCondOverload = checkGasThermCond>
 auto plotGasThermalConductivity(const vector<double>& T, double p, bool openPlot)
--> typename std::enable_if_t<decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value, void> {}
+-> typename std::enable_if_t<decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value || !ComponentTraits<C>::hasGasState, void> {}
 
 //! a number of properties of a component
 template<class Component>
diff --git a/test/material/components/test_componenttraits.cc b/test/material/components/test_componenttraits.cc
new file mode 100644
index 0000000000000000000000000000000000000000..976370946ab7416229b73a7f8e724258de2a97c9
--- /dev/null
+++ b/test/material/components/test_componenttraits.cc
@@ -0,0 +1,41 @@
+// -*- 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
+ *
+ * \brief Test the compoent traits
+ */
+
+#include "config.h"
+
+#include <type_traits>
+
+#include <dumux/material/components/air.hh>
+#include <dumux/material/components/componenttraits.hh>
+
+int main(int argc, char *argv[])
+{
+    using namespace Dumux;
+
+    using Traits = ComponentTraits<Components::Air<double>>;
+    static_assert(Traits::hasGasState, "Air component is reported to have no gas state?!");
+    static_assert(!Traits::hasSolidState, "Air component is reported to implement a solid state?!");
+    static_assert(!Traits::hasLiquidState, "Air component is reported to implement a liquid state?!");
+    static_assert(std::is_same<double, Traits::Scalar>::value, "Scalar type not correctly reported!");
+}