      (getPattern [_]
        pattern))))
 
+(defmulti add-hook-definition (fn [t & _] t))
+
+(defmethod add-hook-definition :before [_ tag-expression hook-fun]
+  (let [te (TagExpression. (list* (seq tag-expression)))]
+    (.addBeforeHook
+     @world
+     (reify
+       HookDefinition
+       (execute [hd scenario-result]
+         (hook-fun))
+       (matches [hd tags]
+         (.eval te tags))
+       (getOrder [hd] 0)))))
+
+(defmethod add-hook-definition :after [_ tag-expression hook-fun]
+  (let [te (TagExpression. (list* (seq tag-expression)))
+        max-parameter-count (->> hook-fun class .getDeclaredMethods
+                                 (filter #(= "invoke" (.getName %)))
+                                 (map #(count (.getParameterTypes %)))
+                                 (apply max))]
+    (.addBeforeHook
+     @world
+     (reify
+       HookDefinition
+       (execute [hd scenario-result]
+         (if (zero? max-parameter-count)
+           (hook-fun)
+           (hook-fun scenario-result)))
+       (matches [hd tags]
+         (.eval te tags))
+       (getOrder [hd] 0)))))
+
 ;; TODO: before and after hooks
 
 (defmacro step-macros [& names]

(ns cucumber.runtime.clj
  (:import (cucumber.runtime CucumberException
                             JdkPatternArgumentMatcher
                             StepDefinition)
           (clojure.lang RT))
  (:gen-class :name cucumber.runtime.clj.Backend
              :implements [cucumber.runtime.Backend]

                                      :line (:line (meta ~'&form))})))))
(step-macros
 Given When Then And But)

(defmacro Before [fun]
  `(add-hook-definition :before [] ~fun))

(defmacro After [fun]
  `(add-hook-definition :after [] ~fun))
