Implement reset counters
diff --git a/src/glc.erl b/src/glc.erl
index ff0a6e6..95e3ebf 100644
--- a/src/glc.erl
+++ b/src/glc.erl
@@ -64,7 +64,9 @@
 -export([
     compile/2,
     handle/2,
-    delete/1
+    delete/1,
+    reset_counters/1,
+    reset_counters/2
 ]).
 
 -export([
@@ -184,7 +186,7 @@
 %%
 %% This releases all resources allocated by a compiled query. The query name
 %% is expected to be associated with an existing query module. Calling this
-%% function will result in a runtime error.
+%% function will shutdown all relevant processes and purge/delete the module.
 -spec delete(atom()) -> ok.
 delete(Module) ->
     Params = params_name(Module),
@@ -204,6 +206,19 @@
     code:delete(Module),
     ok.
 
+%% @doc Reset all counters
+%%
+%% This resets all the counters associated with a module
+-spec reset_counters(atom()) -> ok.
+reset_counters(Module) ->
+    Module:reset_counters(all).
+
+%% @doc Reset a specific counter
+%%
+%% This resets a specific counter associated with a module
+-spec reset_counters(atom(), atom()) -> ok.
+reset_counters(Module, Counter) ->
+    Module:reset_counters(Counter).
 
 %% @private Map a query to a module data term.
 -spec module_data(atom(), term()) -> {ok, #module{}}.
@@ -453,6 +468,34 @@
                     ?assertEqual(undefined, whereis(manage_params_name(Mod))),
                     ?assertEqual(undefined, whereis(manage_counts_name(Mod)))
                 end
+            },
+            {"reset counters test",
+                fun() ->
+                    {compiled, Mod} = setup_query(testmod14,
+                        glc:any([glc:eq(a, 1), glc:eq(b, 2)])),
+                    glc:handle(Mod, gre:make([{'a', 2}], [list])),
+                    glc:handle(Mod, gre:make([{'b', 1}], [list])),
+                    ?assertEqual(2, Mod:info(input)),
+                    ?assertEqual(2, Mod:info(filter)),
+                    glc:handle(Mod, gre:make([{'a', 1}], [list])),
+                    glc:handle(Mod, gre:make([{'b', 2}], [list])),
+                    ?assertEqual(4, Mod:info(input)),
+                    ?assertEqual(2, Mod:info(filter)),
+                    ?assertEqual(2, Mod:info(output)),
+
+                    glc:reset_counters(Mod, input),
+                    ?assertEqual(0, Mod:info(input)),
+                    ?assertEqual(2, Mod:info(filter)),
+                    ?assertEqual(2, Mod:info(output)),
+                    glc:reset_counters(Mod, filter),
+                    ?assertEqual(0, Mod:info(input)),
+                    ?assertEqual(0, Mod:info(filter)),
+                    ?assertEqual(2, Mod:info(output)),
+                    glc:reset_counters(Mod),
+                    ?assertEqual(0, Mod:info(input)),
+                    ?assertEqual(0, Mod:info(filter)),
+                    ?assertEqual(0, Mod:info(output))
+                end
             }
         ]
     }.
diff --git a/src/glc_code.erl b/src/glc_code.erl
index c966e59..e3d69fa 100644
--- a/src/glc_code.erl
+++ b/src/glc_code.erl
@@ -60,6 +60,10 @@
         ?erl:arity_qualifier(
             ?erl:atom(info),
             ?erl:integer(1)),
+        %% reset_counters/1
+        ?erl:arity_qualifier(
+            ?erl:atom(reset_counters),
+            ?erl:integer(1)),
         %% table/1
         ?erl:arity_qualifier(
             ?erl:atom(table),
@@ -76,7 +80,14 @@
         [?erl:clause(
             [?erl:underscore()], none,
                 [abstract_apply(erlang, error, [?erl:atom(badarg)])])]),
-     %% table(Name) -> ets:tid().
+     %% reset_counters(Name) -> boolean().
+     ?erl:function(
+        ?erl:atom(reset_counters),
+        abstract_reset() ++
+        [?erl:clause(
+            [?erl:underscore()], none,
+                [abstract_apply(erlang, error, [?erl:atom(badarg)])])]),
+     %% table(Name) -> atom().
      ?erl:function(
         ?erl:atom(table),
         abstract_tables(Tables) ++
@@ -120,6 +131,17 @@
         {output, abstract_getcount(output)}
     ]].
 
+
+abstract_reset() ->
+    [?erl:clause([?erl:abstract(K)], none, V)
+        || {K, V} <- [
+        {all, abstract_resetcount([input, filter, output])},
+        {input, abstract_resetcount(input)},
+        {filter, abstract_resetcount(filter)},
+        {output, abstract_resetcount(output)}
+    ]].
+
+
 %% @private Return the original query as an expression.
 abstract_query({with, _, _}) ->
     [?erl:abstract([])];
@@ -330,6 +352,14 @@
         [abstract_apply(table, [?erl:atom(counters)]),
          ?erl:abstract(Counter)])].
 
+%% @private Return an expression to reset a counter.
+-spec abstract_resetcount(atom()) -> [syntaxTree()].
+abstract_resetcount(Counter) ->
+    [abstract_apply(gr_counter, reset_counters,
+        [abstract_apply(table, [?erl:atom(counters)]),
+         ?erl:abstract(Counter)])].
+
+
 
 %% abstract code util functions
 
diff --git a/src/goldrush.app.src b/src/goldrush.app.src
index 4f482b4..06ac27f 100644
--- a/src/goldrush.app.src
+++ b/src/goldrush.app.src
@@ -1,6 +1,6 @@
 {application, goldrush, [
     {description, "Erlang event stream processor"},
-    {vsn, "0.1.3"},
+    {vsn, "0.1.4"},
     {registered, []},
     {applications, [kernel, stdlib, syntax_tools, compiler]},
     {mod, {gr_app, []}},
diff --git a/src/gr_counter.erl b/src/gr_counter.erl
index d2276f1..82d99e8 100644
--- a/src/gr_counter.erl
+++ b/src/gr_counter.erl
@@ -19,7 +19,7 @@
 %% API
 -export([start_link/1, 
          list/1, lookup_element/2,
-         update/3]).
+         update/3, reset_counters/2]).
 
 %% gen_server callbacks
 -export([init/1,
@@ -43,6 +43,9 @@
 update(Server, Counter, Value) ->
     gen_server:cast(Server, {update, Counter, Value}).
 
+reset_counters(Server, Counter) ->
+    gen_server:call(Server, {reset_counters, Counter}).
+
 %%--------------------------------------------------------------------
 %% @doc
 %% Starts the server
@@ -91,6 +94,15 @@
 handle_call({lookup_element, Counter}, _From, State) ->
     TableId = State#state.table_id,
     {reply, ets:lookup_element(TableId, Counter, 2), State};
+handle_call({reset_counters, Counter}, _From, State) ->
+    TableId = State#state.table_id,
+    Reset = case Counter of
+        _ when is_list(Counter) -> 
+            [{Item, 0} || Item <- Counter];
+        _ when is_atom(Counter) -> 
+            [{Counter, 0}]
+    end,
+    {reply, ets:insert(TableId, Reset), State};
 handle_call(_Request, _From, State) ->
     Reply = {error, unhandled_message},
     {reply, Reply, State}.