diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
index 63e33cdb9ef352382d9daf3cb97737565d2c28c9..6b6757ce3a2f70e509ac9fc04809778e68259995 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -17,7 +17,9 @@
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
 
-#include <std/set.hpp>
+#include <set>
+#include <deque>
+#include <algorithm>
 
 namespace grammar {
 
@@ -64,6 +66,75 @@ template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterm
 template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar );
 template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar );
 
+std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals(const grammar::Grammar& grammar) {
+	std::set<alphabet::Symbol> out;
+	grammar.getData().Accept((void*) &out, ProductiveNonterminals::PRODUCTIVE_NONTERMINALS);
+	return out;
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::LeftLG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::LeftRG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::RightLG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::RightRG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::LG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::CFG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::CNF& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void* data, const grammar::GNF& grammar) const {
+	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
+	out = std::move(this->getProductiveNonterminals(grammar));
+}
+
+void ProductiveNonterminals::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ProductiveNonterminals::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ProductiveNonterminals::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ProductiveNonterminals::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const ProductiveNonterminals ProductiveNonterminals::PRODUCTIVE_NONTERMINALS;
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
index 6139ad94085beb92027ab12dc8d84c4c4c1cca0a..317b51cd280cdb92cc57d79013c63c128aba2db1 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
@@ -8,12 +8,7 @@
 #ifndef PRODUCTIVE_NONTERMINALS_H_
 #define PRODUCTIVE_NONTERMINALS_H_
 
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <exception/AlibException.h>
-
+#include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
 namespace grammar {
@@ -23,14 +18,32 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class ProductiveNonterminals {
+class ProductiveNonterminals : public grammar::VisitableGrammarBase::const_visitor_type {
 public:
+	static std::set<alphabet::Symbol> getProductiveNonterminals( const grammar::Grammar & grammar );
+
 	/**
 	 * Implements steps 1 through 3 in Melichar 3.6
 	 */
 	template<class T>
 	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
 
+private:
+	void Visit(void*, const grammar::LeftLG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LG& grammar) const;
+	void Visit(void*, const grammar::CFG& grammar) const;
+	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
+	void Visit(void*, const grammar::CNF& grammar) const;
+	void Visit(void*, const grammar::GNF& grammar) const;
+	void Visit(void*, const grammar::CSG& grammar) const;
+	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
+	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
+	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
+
+	static const ProductiveNonterminals PRODUCTIVE_NONTERMINALS;
 };
 
 } /* namespace properties */