diff --git a/elements/local/annotationvalidator.cc b/elements/local/annotationvalidator.cc
new file mode 100644
index 0000000..1324afa
--- /dev/null
+++ b/elements/local/annotationvalidator.cc
@@ -0,0 +1,90 @@
+#include <click/config.h>
+#include <click/error.hh>
+#include <click/confparse.hh>
+#include <click/handlercall.hh>
+
+#include "AnnotationValidator.hh"
+
+CLICK_DECLS
+
+AnnotationValidator::AnnotationValidator() : _error(false), _debug(false) {
+}
+
+AnnotationValidator::~AnnotationValidator() {
+
+}
+
+int AnnotationValidator::configure(Vector<String> &conf, ErrorHandler *errh) {
+    String count_call, byte_count_call;
+    if (cp_va_kparse(conf, this, errh,
+            "ELEMENT", cpkP + cpkM, cpElement, &_currentElement,
+            cpEnd) < 0)
+        return -1;
+
+    return 0;
+}
+
+int AnnotationValidator::initialize(ErrorHandler *errh) {
+    check(_currentElement, errh);
+    if (_error){
+        errh->fatal("Houston we have a problem");
+    }
+    return 0;
+}
+
+void AnnotationValidator::check(Element* element, ErrorHandler *errh) {
+    if (element) {
+        // first part
+        if (_debug){
+            click_chatter("AnnoVal: %s %s ", element->name().c_str(), element->class_name());
+        }
+
+        // check annotation
+        String req = element->require_anno().c_str();
+        if (req != "") {
+            Vector<String> reqVector;
+            cp_argvec(req, reqVector);
+            for (int k = 0; k < reqVector.size(); k++) {
+                if (_debug){
+                    click_chatter("\t requires %s", reqVector[k].c_str());
+                }
+                bool found = false;
+                for (int i = 0; i < _stack.size(); i++) {
+                    for (int j = 0; j < _stack[i].size(); j++) {
+                        if (_stack[i][j] == reqVector[k]) {
+                            found = true;
+                        }
+                    }
+                }
+
+                if (!found) {
+                    errh->error("Element %s of type %s requires %s annotation",
+                            element->name().c_str(), element->class_name(), reqVector[k].c_str());
+                    _error = true;
+                }
+            }
+        }
+
+        // push annotation
+        String prov = element->provide_anno().c_str();
+        Vector<String> provVector;
+        if (prov != "") {
+            if (_debug){
+                click_chatter("\t provides %s", prov.c_str());
+            }
+            cp_argvec(prov, provVector);
+            provVector.push_back(element->provide_anno());
+        }
+        _stack.push_back(provVector);
+
+        // second part, go deeper
+        for (int i = 0; i < element->noutputs(); i++) {
+            Element* element2 = element->output(i).element();
+            check(element2, errh);
+        }
+        //_stack.pop();
+    }
+}
+
+CLICK_ENDDECLS
+EXPORT_ELEMENT(AnnotationValidator)
diff --git a/elements/local/annotationvalidator.hh b/elements/local/annotationvalidator.hh
new file mode 100644
index 0000000..5c936b7
--- /dev/null
+++ b/elements/local/annotationvalidator.hh
@@ -0,0 +1,31 @@
+#ifndef ANNOTATION_VALIDATOR_HH
+#define ANNOTATION_VALIDATOR_HH
+#include <click/element.hh>
+CLICK_DECLS
+
+class AnnotationValidator : public Element { public:
+
+    AnnotationValidator();
+    ~AnnotationValidator();
+
+    const char *class_name() const		{ return "AnnotationValidator"; }
+    const char *port_count() const		{ return PORTS_0_0; }
+    const char *processing() const		{ return AGNOSTIC; }
+    // configure phase last -> initialise last -> we can check config
+    int configure_phase() const                 { return CONFIGURE_PHASE_LAST;}
+    
+    int configure(Vector<String> &, ErrorHandler *);
+    int initialize(ErrorHandler *);
+
+    void check(Element* element,ErrorHandler *errh);
+
+
+  private:
+      Element*  _currentElement;
+      Vector<Vector<String> > _stack;
+      bool _error;
+      bool _debug;
+};
+
+CLICK_ENDDECLS
+#endif
diff --git a/elements/standard/checkpaint.hh b/elements/standard/checkpaint.hh
index b142c35..b275710 100644
--- a/elements/standard/checkpaint.hh
+++ b/elements/standard/checkpaint.hh
@@ -31,6 +31,7 @@ class CheckPaint : public Element { public:
     const char *class_name() const	{ return "CheckPaint"; }
     const char *port_count() const	{ return PORTS_1_1X2; }
     const char *processing() const	{ return PROCESSING_A_AH; }
+    String require_anno() const         { return "PAINT"; }
 
     int configure(Vector<String> &, ErrorHandler *);
     void add_handlers();
diff --git a/elements/standard/paint.hh b/elements/standard/paint.hh
index 3d71046..40916d8 100644
--- a/elements/standard/paint.hh
+++ b/elements/standard/paint.hh
@@ -33,7 +33,8 @@ class Paint : public Element { public:
     const char *class_name() const		{ return "Paint"; }
     const char *port_count() const		{ return PORTS_1_1; }
     const char *processing() const		{ return AGNOSTIC; }
-
+    String provide_anno() const                 { return "PAINT"; }
+    
     int configure(Vector<String> &, ErrorHandler *);
     bool can_live_reconfigure() const		{ return true; }
     void add_handlers();
diff --git a/include/click/element.hh b/include/click/element.hh
index b0e10f1..0ba9b6b 100644
--- a/include/click/element.hh
+++ b/include/click/element.hh
@@ -26,6 +26,9 @@ class EtherAddress;
 
 class Element { public:
 
+    virtual String require_anno() const;
+    virtual String provide_anno() const;
+
     Element();
     virtual ~Element();
     static int nelements_allocated;
diff --git a/lib/element.cc b/lib/element.cc
index cc2cc6e..da428e2 100644
--- a/lib/element.cc
+++ b/lib/element.cc
@@ -2824,4 +2824,8 @@ Element::run_timer()
     assert(0 /* run_timer not overridden */);
 }
 
+String Element::require_anno() const { return ""; }
+
+String Element::provide_anno() const { return ""; }
+
 CLICK_ENDDECLS
