File rebar-2.6.1-git.patch of Package rebar

diff --git a/.travis.yml b/.travis.yml
index 9494ca9..e4a3149 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,7 @@ otp_release:
   - R14B04
   - R14B03
   - 17.0
+  - 18.0
 before_script:
   - hostname -f
   - cc -v
diff --git a/README.md b/README.md
index ec65693..54e6ad1 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+**rebar is deprecated and will receive only bug fixes. We encourage you to move to [rebar3](https://github.com/erlang/rebar3).**
+
+----
+
 rebar
 =====
 
@@ -5,6 +9,7 @@ rebar is an Erlang build tool that makes it easy to compile and test Erlang
 applications, port drivers and releases.
 
 [![Build Status](https://secure.travis-ci.org/rebar/rebar.png?branch=master)](http://travis-ci.org/rebar/rebar)
+[![Build status](https://ci.appveyor.com/api/projects/status/4c48dw0cbu265cvt?svg=true)](https://ci.appveyor.com/project/rebar-win-ci/rebar-t0g71)
 
 rebar is a self-contained Erlang script, so it's easy to distribute or even
 embed directly in a project. Where possible, rebar uses standard Erlang/OTP
diff --git a/THANKS b/THANKS
index 582a153..ab7935c 100644
--- a/THANKS
+++ b/THANKS
@@ -145,3 +145,8 @@ James Fish
 Tony Rogvall
 Andrey Teplyashin
 Duncan McGreggor
+Sebastien Serre
+John Daily
+Yury Gargay
+Frank Hunleth
+Matwey Kornilov
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..59b9570
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,24 @@
+version: 2.6.1.{build}
+clone_depth: 1
+build_script:
+- cmd: >-
+    bootstrap.bat
+
+    set REBAR_EXTRA_DEPS=1
+
+    .\rebar get-deps
+
+    copy rebar deps\retest
+
+    copy rebar.cmd deps\retest
+
+    cd deps\retest & .\rebar compile escriptize
+test_script:
+- cmd: >-
+    rebar eunit
+
+    "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
+
+    cd deps\retest & retest -l debug -t 120000 ..\..\inttest
+artifacts:
+- path: rebar
diff --git a/inttest/app_src/app_src_rt.erl b/inttest/app_src/app_src_rt.erl
index d71f03e..2b5a87e 100644
--- a/inttest/app_src/app_src_rt.erl
+++ b/inttest/app_src/app_src_rt.erl
@@ -30,9 +30,14 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {create, "src/app_src.app.src", app(app_src)}].
+    [
+     {create, "src/app_src.app.src", app(app_src)}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/app_src_script/app_src_script_rt.erl b/inttest/app_src_script/app_src_script_rt.erl
index 4c00ec8..c0de128 100644
--- a/inttest/app_src_script/app_src_script_rt.erl
+++ b/inttest/app_src_script/app_src_script_rt.erl
@@ -30,9 +30,14 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {create, "src/app_src_script.app.src.script", app_script(app_src_script)}].
+    [
+     {create, "src/app_src_script.app.src.script", app_script(app_src_script)}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/app_src_script_2/app_src_script_2_rt.erl b/inttest/app_src_script_2/app_src_script_2_rt.erl
index 1bf59d1..613e3f9 100644
--- a/inttest/app_src_script_2/app_src_script_2_rt.erl
+++ b/inttest/app_src_script_2/app_src_script_2_rt.erl
@@ -30,10 +30,15 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
+    [
      {create, "src/app_src_script_2.app.src.script", app_script(app_src_script_2)},
-     {create, "src/app_src_script_2.app.src", app(app_src_script_2)}].
+     {create, "src/app_src_script_2.app.src", app(app_src_script_2)}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/appup_src/appup_src_rt.erl b/inttest/appup_src/appup_src_rt.erl
index 2ca6788..7530aa4 100644
--- a/inttest/appup_src/appup_src_rt.erl
+++ b/inttest/appup_src/appup_src_rt.erl
@@ -30,9 +30,14 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {copy, "src", "src"}].
+    [
+     {copy, "src", "src"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/appup_src_2/appup_src_2_rt.erl b/inttest/appup_src_2/appup_src_2_rt.erl
index 09d2503..99e6248 100644
--- a/inttest/appup_src_2/appup_src_2_rt.erl
+++ b/inttest/appup_src_2/appup_src_2_rt.erl
@@ -30,9 +30,14 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {copy, "src", "src"}].
+    [
+     {copy, "src", "src"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/appup_src_2/appup_src_rt_2.erl b/inttest/appup_src_2/appup_src_rt_2.erl
index d662183..fff6f62 100644
--- a/inttest/appup_src_2/appup_src_rt_2.erl
+++ b/inttest/appup_src_2/appup_src_rt_2.erl
@@ -30,9 +30,13 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {copy, "src", "src"}].
+    [{copy, "src", "src"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/appup_src_script/appup_src_script_rt.erl b/inttest/appup_src_script/appup_src_script_rt.erl
index c98e54e..1aeb680 100644
--- a/inttest/appup_src_script/appup_src_script_rt.erl
+++ b/inttest/appup_src_script/appup_src_script_rt.erl
@@ -30,9 +30,14 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
-     {copy, "src", "src"}].
+    [
+     {copy, "src", "src"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/bug_5_rt.erl b/inttest/bug_5_rt.erl
index 8894cb5..f198d40 100644
--- a/inttest/bug_5_rt.erl
+++ b/inttest/bug_5_rt.erl
@@ -4,20 +4,21 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
 
 files() ->
     [{create, "ebin/a1.app", app(a1)},
      {create, "deps/d1/src/d1.app.src", app(d1)},
      {create, "rebar.config",
-      <<"{deps, [{d1, \"1\", {hg, \"http://example.com\", \"tip\"}}]}.\n">>},
-     {copy, "../rebar", "rebar"}].
+      <<"{deps, [{d1, \"1\", {hg, \"http://example.com\", \"tip\"}}]}.\n">>}
+    ] ++ inttest_utils:rebar_setup("..").
 
 run(_Dir) ->
     {ok, _} = retest:sh("./rebar compile"),
     ok.
 
-
-
 %%
 %% Generate the contents of a simple .app file
 %%
diff --git a/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl b/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl
index 74d035e..a2ca980 100644
--- a/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl
+++ b/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl
@@ -28,14 +28,17 @@
 -export([files/0,
          run/1]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "src", "src"},
      {copy, "test", "test"},
      {copy, "deps", "deps"}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     retest:log(info, "Compile project~n"),
diff --git a/inttest/cover/cover_rt.erl b/inttest/cover/cover_rt.erl
index a9f3f08..3f5e485 100644
--- a/inttest/cover/cover_rt.erl
+++ b/inttest/cover/cover_rt.erl
@@ -30,13 +30,18 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{create, "ebin/foo.app", app(foo)},
-     {copy, "../../rebar","rebar"},
+    [
+     {create, "ebin/foo.app", app(foo)},
      {copy, "src", "src"},
      {copy,
       "rebar-cover_export_json.config",
-      "rebar-cover_export_json.config"}].
+      "rebar-cover_export_json.config"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ifdef_test(),
diff --git a/inttest/cross1/c_src/test1.c b/inttest/cross1/c_src/test1.c
new file mode 100644
index 0000000..4073ed6
--- /dev/null
+++ b/inttest/cross1/c_src/test1.c
@@ -0,0 +1 @@
+#include "test1.h"
diff --git a/inttest/cross1/c_src/test1.h b/inttest/cross1/c_src/test1.h
new file mode 100644
index 0000000..e69de29
diff --git a/inttest/cross1/cross1_rt.erl b/inttest/cross1/cross1_rt.erl
new file mode 100644
index 0000000..297f353
--- /dev/null
+++ b/inttest/cross1/cross1_rt.erl
@@ -0,0 +1,66 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% rebar: Erlang Build Tools
+%%
+%% Copyright (c) 2016 Luis Rascao
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% -------------------------------------------------------------------
+
+-module(cross1_rt).
+-export([files/0,
+         run/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
+files() ->
+    [
+     {copy, "c_src", "c_src"},
+     {create, "ebin/foo.app", app(foo, [])}
+    ] ++ inttest_utils:rebar_setup().
+
+run(_Dir) ->
+    %% we will now determine where gcc is located
+    %% create a symlink to it in the cwd and change the
+    %% rebar arch so that rebar is fooled into believing
+    %% it's doing cross compilation.
+    {ok, [_, GccLocation]} = retest_sh:run("which gcc", []),
+    {ok, _} = retest_sh:run(io_lib:format("ln -s ~s unknown-unknown-linux-gnu-gcc", [GccLocation]),
+                            []),
+    ?assertMatch({ok, _}, retest_sh:run("./rebar compile -vvv",
+                                        [{env, [{"PATH", "./:" ++ os:getenv("PATH")},
+                                                {"REBAR_TARGET_ARCH", "unknown-unknown-linux-gnu"}]}])).
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name, Modules) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, Modules},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/ct1/ct1_rt.erl b/inttest/ct1/ct1_rt.erl
index dc83095..03b4ed8 100644
--- a/inttest/ct1/ct1_rt.erl
+++ b/inttest/ct1/ct1_rt.erl
@@ -4,21 +4,23 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
 
 files() ->
-    [{create, "ebin/a1.app", app(a1)},
-     {copy, "../../rebar", "rebar"},
+    [
+     {create, "ebin/a1.app", app(a1)},
      {copy, "rebar.config", "rebar.config"},
      {copy, "app.config", "app.config"},
-     {copy, "test_SUITE.erl", "itest/test_SUITE.erl"}].
+     {copy, "test_SUITE.erl", "itest/test_SUITE.erl"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     {ok, _} = retest:sh("./rebar compile ct"),
     {ok, _} = retest:sh("./rebar compile ct -v"),
     ok.
 
-
-
 %%
 %% Generate the contents of a simple .app file
 %%
diff --git a/inttest/ct2/ct2_rt.erl b/inttest/ct2/ct2_rt.erl
index f9d2b19..b3138d4 100644
--- a/inttest/ct2/ct2_rt.erl
+++ b/inttest/ct2/ct2_rt.erl
@@ -4,13 +4,17 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
 
 files() ->
-    [{create, "ebin/foo.app", app(foo)},
-     {copy, "../../rebar", "rebar"},
+    [
+     {create, "ebin/foo.app", app(foo)},
      {copy, "foo.test.spec", "foo.test.spec"},
      {copy, "deps/bar.test.spec", "deps/bar.test.spec"},
-     {copy, "foo_SUITE.erl", "test/foo_SUITE.erl"}].
+     {copy, "foo_SUITE.erl", "test/foo_SUITE.erl"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     Ref = retest:sh("./rebar compile ct -vvv", [async]),
diff --git a/inttest/ct3/ct3_rt.erl b/inttest/ct3/ct3_rt.erl
index a87cf21..b5739db 100644
--- a/inttest/ct3/ct3_rt.erl
+++ b/inttest/ct3/ct3_rt.erl
@@ -28,19 +28,23 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
 
 files() ->
-    [{create, "ebin/a1.app", app(a1)},
-     {copy, "../../rebar", "rebar"},
+    [
+     {create, "ebin/a1.app", app(a1)},
      {copy, "rebar.config", "rebar.config"},
      {copy, "app.config", "itest/app.config"},
      {copy, "test_SUITE.erl", "itest/test_SUITE.erl"},
      {copy, "converted"},
-     {copy, "unconverted"}].
+     {copy, "unconverted"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     {ok, _} = retest:sh("./rebar compile ct -v",
-                        [{env, [{"ERL_FLAGS", "-name ct_rt3"}]}]),
+                        [{env, [{"ERL_FLAGS", "-name ct_rt3@localhost"}]}]),
     ok.
 
 %%
diff --git a/inttest/ct4/ct4_rt.erl b/inttest/ct4/ct4_rt.erl
new file mode 100644
index 0000000..bc010e8
--- /dev/null
+++ b/inttest/ct4/ct4_rt.erl
@@ -0,0 +1,44 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(ct4_rt).
+
+-compile(export_all).
+
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
+files() ->
+    [
+     {create, "ebin/foo.app", app(foo)},
+     {copy, "rebar.config", "rebar.config"},
+     {copy, "foo.test.spec", "test/foo.test.spec"},
+     {copy, "deps/bar.test.spec", "deps/bar.test.spec"},
+     {copy, "deps/bar.test.spec", "baz.test.spec"},
+     {copy, "foo_SUITE.erl", "test/foo_SUITE.erl"}
+    ] ++ inttest_utils:rebar_setup().
+
+run(_Dir) ->
+    Ref = retest:sh("./rebar compile ct -vvv", [async]),
+    {ok, [[CTRunCmd]]} = retest:sh_expect(Ref, "^\"ct_run.*",
+                                  [global, {capture, first, binary}]),
+    {match, _} = re:run(CTRunCmd, "foo.test.spec", [global]),
+    %% deps/bar.test.spec should be ignored by rebar_ct:collect_glob/3
+    nomatch = re:run(CTRunCmd, "bar.test.spec", [global]),
+    %% baz.test.spec should be also ignored by rebar_ct:collect_glob/3
+    %% since we specified in rebar.config that we want to search for
+    %% ct specs from the test dir
+    nomatch = re:run(CTRunCmd, "baz.test.spec", [global]),
+    ok.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, []},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/ct4/deps/bar.test.spec b/inttest/ct4/deps/bar.test.spec
new file mode 100644
index 0000000..a16610c
--- /dev/null
+++ b/inttest/ct4/deps/bar.test.spec
@@ -0,0 +1 @@
+%% this test spec should be ignored
diff --git a/inttest/ct4/foo.test.spec b/inttest/ct4/foo.test.spec
new file mode 100644
index 0000000..1850410
--- /dev/null
+++ b/inttest/ct4/foo.test.spec
@@ -0,0 +1 @@
+{suites, "../", [foo_SUITE]}.
diff --git a/inttest/ct4/foo_SUITE.erl b/inttest/ct4/foo_SUITE.erl
new file mode 100644
index 0000000..fb4f56a
--- /dev/null
+++ b/inttest/ct4/foo_SUITE.erl
@@ -0,0 +1,11 @@
+-module(foo_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+all() -> [simple].
+
+simple(Config) ->
+    io:format("Test: ~p\n", [Config]),
+    ok.
diff --git a/inttest/ct4/rebar.config b/inttest/ct4/rebar.config
new file mode 100644
index 0000000..387f8c3
--- /dev/null
+++ b/inttest/ct4/rebar.config
@@ -0,0 +1,2 @@
+{ct_dir, "test"}.
+{ct_search_specs_from_test_dir, true}.
diff --git a/inttest/ct_cover/ct_cover_rt.erl b/inttest/ct_cover/ct_cover_rt.erl
index c7f8776..361d85b 100644
--- a/inttest/ct_cover/ct_cover_rt.erl
+++ b/inttest/ct_cover/ct_cover_rt.erl
@@ -4,14 +4,19 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{create, "ebin/a1.app", app(a1)},
-     {copy, "../../rebar", "rebar"},
+    [
+     {create, "ebin/a1.app", app(a1)},
      {copy, "rebar.config", "rebar.config"},
      {copy, "app.config", "app.config"},
      {copy, "cover.spec", "cover.spec"},
      {copy, "test_SUITE.erl", "itest/test_SUITE.erl"},
-     {copy, "mock", "deps"}].
+     {copy, "mock", "deps"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     {ok, _} = retest:sh("./rebar compile ct"),
diff --git a/inttest/ct_make_fails/app.config b/inttest/ct_make_fails/app.config
new file mode 100644
index 0000000..bb718b2
--- /dev/null
+++ b/inttest/ct_make_fails/app.config
@@ -0,0 +1,2 @@
+%% This file is an application config file, not a CT test config file
+[{a1, [{foo, bar}]}].
diff --git a/inttest/ct_make_fails/ct_make_fails_rt.erl b/inttest/ct_make_fails/ct_make_fails_rt.erl
new file mode 100644
index 0000000..a7959a7
--- /dev/null
+++ b/inttest/ct_make_fails/ct_make_fails_rt.erl
@@ -0,0 +1,31 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(ct_make_fails_rt).
+
+-compile(export_all).
+
+
+files() ->
+    [{create, "ebin/a1.app", app(a1)},
+     {copy, "../../rebar", "rebar"},
+     {copy, "rebar.config", "rebar.config"},
+     {copy, "app.config", "app.config"},
+     {copy, "test_SUITE.erl", "itest/test_SUITE.erl"}].
+
+run(_Dir) ->
+    ok = case catch retest:sh("./rebar compile ct -v") of
+                {error, {stopped, _}} -> ok;
+                _ -> expected_to_fail
+              end.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, []},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/ct_make_fails/rebar.config b/inttest/ct_make_fails/rebar.config
new file mode 100644
index 0000000..58047ba
--- /dev/null
+++ b/inttest/ct_make_fails/rebar.config
@@ -0,0 +1,2 @@
+{ct_dir, "itest"}.
+{ct_extra_params, "-repeat 2 -erl_args -config app"}.
diff --git a/inttest/ct_make_fails/test_SUITE.erl b/inttest/ct_make_fails/test_SUITE.erl
new file mode 100644
index 0000000..343aa5a
--- /dev/null
+++ b/inttest/ct_make_fails/test_SUITE.erl
@@ -0,0 +1,17 @@
+-module(test_SUITE).
+
+-compile(export_all).
+
+-include_lib("ct.hrl").
+
+all() ->
+    [simple_test,
+     app_config_file_test].
+
+simple_test(Config) ->
+    io:format("Test: ~p\n" [Config]).
+
+app_config_file_test(_Config) ->
+    application:start(a1),
+    {ok, bar} = application:get_env(a1, foo),
+    application:stop(a1).
diff --git a/inttest/ct_test_fails/app.config b/inttest/ct_test_fails/app.config
new file mode 100644
index 0000000..bb718b2
--- /dev/null
+++ b/inttest/ct_test_fails/app.config
@@ -0,0 +1,2 @@
+%% This file is an application config file, not a CT test config file
+[{a1, [{foo, bar}]}].
diff --git a/inttest/ct_test_fails/ct_test_fails.test.spec b/inttest/ct_test_fails/ct_test_fails.test.spec
new file mode 100644
index 0000000..7bba687
--- /dev/null
+++ b/inttest/ct_test_fails/ct_test_fails.test.spec
@@ -0,0 +1 @@
+{suites,"../itest",[test_SUITE, test2_SUITE]}.
diff --git a/inttest/ct_test_fails/ct_test_fails_rt.erl b/inttest/ct_test_fails/ct_test_fails_rt.erl
new file mode 100644
index 0000000..a556891
--- /dev/null
+++ b/inttest/ct_test_fails/ct_test_fails_rt.erl
@@ -0,0 +1,33 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(ct_test_fails_rt).
+
+-compile(export_all).
+
+
+files() ->
+    [{create, "ebin/a1.app", app(a1)},
+     {copy, "../../rebar", "rebar"},
+     {copy, "rebar.config", "rebar.config"},
+     {copy, "app.config", "app.config"},
+     {copy, "ct_test_fails.test.spec", "itest/ct_test_fails.test.spec"},
+     {copy, "test_SUITE.erl", "itest/test_SUITE.erl"},
+     {copy, "test2_SUITE.erl", "itest/test2_SUITE.erl"}].
+
+run(Dir) ->
+    ok = case catch retest:sh("./rebar compile ct -v 3") of
+                {error, {stopped, _}} -> ok;
+                _ -> expected_to_fail
+              end.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, []},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/ct_test_fails/rebar.config b/inttest/ct_test_fails/rebar.config
new file mode 100644
index 0000000..84c23ef
--- /dev/null
+++ b/inttest/ct_test_fails/rebar.config
@@ -0,0 +1,13 @@
+{ct_dir, ["itest"]}.
+{ct_extra_params, "-erl_args -config app"}.
+
+%% http://erlang.org/doc/apps/common_test/run_test_chapter.html#id77160
+%%      Any relative paths specified in the test specification, will be relative to the
+%%      directory which contains the  test specification file, if ct_run -spec TestSpecFile ...
+%%      or ct:run:test([{spec,TestSpecFile},...]) executes the  test. The path will be
+%%      relative to the top level log directory, if ct:run:testspec(TestSpec) executes the test.
+%% however for versions older than R16  what counts is the project root path and not the path
+%% of the location of the test spec. This will cause the test to fail since R15/14 can't find the
+%% test.spec file. Since we can't change the file we have no choice but to bypass the test
+%% completely
+{require_min_otp_vsn, "R16B"}.
diff --git a/inttest/ct_test_fails/test2_SUITE.erl b/inttest/ct_test_fails/test2_SUITE.erl
new file mode 100644
index 0000000..4b9299f
--- /dev/null
+++ b/inttest/ct_test_fails/test2_SUITE.erl
@@ -0,0 +1,9 @@
+-module(test2_SUITE).
+
+-compile(export_all).
+
+all() ->
+    [simple_test].
+
+simple_test(Config) ->
+    io:format("Test: ~p\n", [Config]).
diff --git a/inttest/ct_test_fails/test_SUITE.erl b/inttest/ct_test_fails/test_SUITE.erl
new file mode 100644
index 0000000..124fbe8
--- /dev/null
+++ b/inttest/ct_test_fails/test_SUITE.erl
@@ -0,0 +1,10 @@
+-module(test_SUITE).
+
+-compile(export_all).
+
+all() ->
+    [simple_test].
+
+simple_test(Config) ->
+    io:format("Test: ~p\n", [Config]),
+    ok = not_ok.
diff --git a/inttest/depplugins/depplugins_rt.erl b/inttest/depplugins/depplugins_rt.erl
index 7bcfe86..fc72dec 100644
--- a/inttest/depplugins/depplugins_rt.erl
+++ b/inttest/depplugins/depplugins_rt.erl
@@ -21,9 +21,12 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "base_dir_cwd_plugin.erl", "base_dir_cwd_plugin.erl"},
      {create, "ebin/fish.app", app(fish, [])},
@@ -38,7 +41,7 @@ files() ->
       "deps/testplugin/plugins/testplugin_mod.erl"},
      {copy, "dep_cwd_plugin.erl", "deps/testplugin/dep_cwd_plugin.erl"},
      {create, "deps/testplugin/ebin/testplugin.app", app(testplugin, [])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
diff --git a/inttest/erlc/erlc_rt.erl b/inttest/erlc/erlc_rt.erl
index 0c1f25d..3ac5956 100644
--- a/inttest/erlc/erlc_rt.erl
+++ b/inttest/erlc/erlc_rt.erl
@@ -54,9 +54,12 @@
          "foo_worker.beam",
          "SIMPLE-ASN.beam"]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "rebar-no_debug_info.config", "rebar-no_debug_info.config"},
      {copy, "include", "include"},
@@ -73,7 +76,7 @@ files() ->
      %% deps
      {create, "deps/foobar/ebin/foobar.app", app(foobar, [foobar])},
      {copy, "foobar.erl", "deps/foobar/src/foobar.erl"}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
diff --git a/inttest/erlc_dep_graph/erlc_dep_graph_rt.erl b/inttest/erlc_dep_graph/erlc_dep_graph_rt.erl
index 384ce87..72c6928 100644
--- a/inttest/erlc_dep_graph/erlc_dep_graph_rt.erl
+++ b/inttest/erlc_dep_graph/erlc_dep_graph_rt.erl
@@ -30,39 +30,57 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
+    [
      {copy, "rebar.config", "rebar.config"},
      {copy, "src", "src"},
      {copy, "include", "include"},
-     {copy, "extra_include", "extra_include"}].
+     {copy, "extra_include", "extra_include"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
+    retest_log:log(debug, "compiling all...\n\n", []),
     compile_all(ok, ""),
+    retest_log:log(debug, "checking beams integrity...\n\n", []),
     check_beams_ok(),
     check_beams_untouched(filelib:wildcard("ebin/*.beam")),
+    retest_log:log(debug, "modifying lisp.erl and recompiling...\n\n", []),
     modify_and_recompile_ok("src/lisp.erl", "ebin/lisp.beam"),
 
+    retest_log:log(debug, "cleaning all...\n\n", []),
     clean_all_ok(),
+    retest_log:log(debug, "compiling all (expect fail)...\n\n", []),
     compile_all(error, "-C rebar.config.non-existing"),
+    retest_log:log(debug, "compiling all...\n\n", []),
     compile_all(ok, ""),
+    retest_log:log(debug, "modifying extra_include/extra.hrl and recompiling...\n\n", []),
     modify_and_recompile_ok("extra_include/extra.hrl", "ebin/java.beam"),
 
+    retest_log:log(debug, "rewriting src/java.erl...\n\n", []),
     Java = "src/java.erl",
     {ok, OrigContent} = file:read_file(Java),
     %% Remove header file inclusion
     {ok, _} = file:copy("src/java.erl.no_extra", Java),
     %% Ensure recompilation
     touch([Java]),
+    retest_log:log(debug, "compiling all...\n\n", []),
     compile_all(ok, ""),
     %% Modify that header file
+    retest_log:log(debug, "again modifying extra_include/extra.hrl and recompiling...\n\n", []),
     touch(["extra_include/extra.hrl"]),
     %% Ensure we don't have to recompile anything
+    retest_log:log(debug, "ensure ebin/java.beam was untouched...\n\n", []),
     check_beams_untouched(["ebin/java.beam"]),
     %% Clean up
+    retest_log:log(debug, "modifying src/java.erl...\n\n", []),
     ok = file:write_file(Java, OrigContent),
 
     %% Check that changes propagate deeply through the dependency tree
+    retest_log:log(debug, "modifying include/lambda.hrl...\n\n", []),
     modify_and_recompile_ok("include/lambda.hrl", "ebin/perl.beam"),
 
     ok.
@@ -82,7 +100,9 @@ compile_all_and_assert_mtimes(Beams, Cmp) ->
     BeamsModifiedBefore = mtime_ns(Beams),
     compile_all(ok, ""),
     BeamsModifiedAfter = mtime_ns(Beams),
-    lists:zipwith(fun(Before, After) -> ?assert(Cmp(Before, After)) end,
+    lists:zipwith(fun(Before, After) ->
+                    ?assert(Cmp(Before, After))
+                  end,
                   BeamsModifiedBefore, BeamsModifiedAfter).
 
 with_erl_beams(F) ->
@@ -95,13 +115,13 @@ with_erl_beams(F) ->
         filelib:wildcard("src/*.erl")).
 
 mtime_ns(Files) ->
-    [os:cmd("stat -c%y " ++ File) || File <- Files].
+    [calendar:datetime_to_gregorian_seconds(filelib:last_modified(File)) || File <- Files].
 
 touch(Files) ->
     %% Sleep one second so that filelib:last_modified/1 is guaranteed to notice
     %% that files have changed.
     ok = timer:sleep(1000),
-    [os:cmd("touch " ++ File) || File <- Files].
+    [file:change_time(File, calendar:local_time()) || File <- Files].
 
 compile_all(Result, Opts) ->
     ?assertMatch({Result, _},
diff --git a/inttest/eunit/eunit_rt.erl b/inttest/eunit/eunit_rt.erl
index 1d71404..bc24b26 100644
--- a/inttest/eunit/eunit_rt.erl
+++ b/inttest/eunit/eunit_rt.erl
@@ -5,14 +5,19 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{create, "ebin/foo.app", app(foo)},
-     {copy, "../../rebar", "rebar"},
+    [
+     {create, "ebin/foo.app", app(foo)},
      {copy, "src", "src"},
      {copy, "eunit_src", "eunit_src"},
      {copy,
       "rebar-eunit_compile_opts.config",
-      "rebar-eunit_compile_opts.config"}].
+      "rebar-eunit_compile_opts.config"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ifdef_test(),
diff --git a/inttest/eunit_surefire/eunit_src/bar.erl b/inttest/eunit_surefire/eunit_src/bar.erl
new file mode 100644
index 0000000..6a80dac
--- /dev/null
+++ b/inttest/eunit_surefire/eunit_src/bar.erl
@@ -0,0 +1,6 @@
+-module(bar).
+
+-include_lib("eunit/include/eunit.hrl").
+
+bar_test() ->
+    ?assert(true).
diff --git a/inttest/eunit_surefire/eunit_surefire_rt.erl b/inttest/eunit_surefire/eunit_surefire_rt.erl
new file mode 100644
index 0000000..fd26d4b
--- /dev/null
+++ b/inttest/eunit_surefire/eunit_surefire_rt.erl
@@ -0,0 +1,40 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(eunit_surefire_rt).
+-export([files/0, run/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
+files() ->
+    [
+     {create, "ebin/foo.app", app(foo)},
+     {copy, "src", "src"},
+     {copy, "eunit_src", "eunit_src"},
+     {copy, "rebar.config"}
+    ] ++ inttest_utils:rebar_setup().
+
+run(_Dir) ->
+    {ok, Output} = retest:sh("./rebar -v eunit tests=bar"),
+    ?assert(check_output(Output, "bar_test")),
+    ok.
+
+check_output(Output, Target) ->
+    lists:any(fun(Line) ->
+                      string:str(Line, Target) > 0
+              end, Output).
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, []},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/eunit_surefire/rebar.config b/inttest/eunit_surefire/rebar.config
new file mode 100644
index 0000000..0172560
--- /dev/null
+++ b/inttest/eunit_surefire/rebar.config
@@ -0,0 +1,7 @@
+{eunit_compile_opts, [
+    {src_dirs, ["eunit_src"]}
+]}.
+
+{eunit_opts, [
+    {report, {eunit_surefire, [{dir, "."}]}}
+]}.
diff --git a/inttest/eunit_surefire/src/foo.erl b/inttest/eunit_surefire/src/foo.erl
new file mode 100644
index 0000000..a4c91ba
--- /dev/null
+++ b/inttest/eunit_surefire/src/foo.erl
@@ -0,0 +1,10 @@
+-module(foo).
+
+-ifdef(TEST).
+
+-include_lib("eunit/include/eunit.hrl").
+
+foo_test() ->
+    ?assert(true).
+
+-endif.
diff --git a/inttest/inttest_utils.erl b/inttest/inttest_utils.erl
new file mode 100644
index 0000000..d896f4d
--- /dev/null
+++ b/inttest/inttest_utils.erl
@@ -0,0 +1,16 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(inttest_utils).
+
+-compile(export_all).
+
+rebar_setup({win32, nt}, Dir) ->
+    [{copy, filename:join(Dir, "rebar.cmd"), "rebar.cmd"}];
+rebar_setup({_, _}, _) -> [].
+
+rebar_setup(Dir) ->
+    [{copy,
+      filename:join(Dir, "rebar"), "rebar"}] ++ rebar_setup(os:type(), Dir).
+
+rebar_setup() ->
+    rebar_setup("../..").
diff --git a/inttest/logging/logging_rt.erl b/inttest/logging/logging_rt.erl
index 2709a84..f774376 100644
--- a/inttest/logging/logging_rt.erl
+++ b/inttest/logging/logging_rt.erl
@@ -30,11 +30,14 @@
 
 -define(APP_FILE, "ebin/logging.app").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {create, ?APP_FILE, app(invalid_name, [])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     SharedExpected = "==> logging_rt \\(compile\\)",
diff --git a/inttest/neotoma1/mock/neotoma/priv/peg_includes.hrl b/inttest/neotoma1/mock/neotoma/priv/peg_includes.hrl
new file mode 100644
index 0000000..183b98c
--- /dev/null
+++ b/inttest/neotoma1/mock/neotoma/priv/peg_includes.hrl
@@ -0,0 +1,253 @@
+-file("peg_includes.hrl", 1).
+-type index() :: {{line, pos_integer()}, {column, pos_integer()}}.
+-type input() :: binary().
+-type parse_failure() :: {fail, term()}.
+-type parse_success() :: {term(), input(), index()}.
+-type parse_result() :: parse_failure() | parse_success().
+-type parse_fun() :: fun((input(), index()) -> parse_result()).
+-type xform_fun() :: fun((input(), index()) -> term()).
+
+-spec p(input(), index(), atom(), parse_fun(), xform_fun()) -> parse_result().
+p(Inp, StartIndex, Name, ParseFun, TransformFun) ->
+  case get_memo(StartIndex, Name) of      % See if the current reduction is memoized
+    {ok, Memo} -> %Memo;                     % If it is, return the stored result
+      Memo;
+    _ ->                                        % If not, attempt to parse
+      Result = case ParseFun(Inp, StartIndex) of
+        {fail,_} = Failure ->                       % If it fails, memoize the failure
+          Failure;
+        {Match, InpRem, NewIndex} ->               % If it passes, transform and memoize the result.
+          Transformed = TransformFun(Match, StartIndex),
+          {Transformed, InpRem, NewIndex}
+      end,
+      memoize(StartIndex, Name, Result),
+      Result
+  end.
+
+-spec setup_memo() -> ets:tid().
+setup_memo() ->
+  put({parse_memo_table, ?MODULE}, ets:new(?MODULE, [set])).
+
+-spec release_memo() -> true.
+release_memo() ->
+  ets:delete(memo_table_name()).
+
+-spec memoize(index(), atom(), parse_result()) -> true.
+memoize(Index, Name, Result) ->
+  Memo = case ets:lookup(memo_table_name(), Index) of
+              [] -> [];
+              [{Index, Plist}] -> Plist
+         end,
+  ets:insert(memo_table_name(), {Index, [{Name, Result}|Memo]}).
+
+-spec get_memo(index(), atom()) -> {ok, term()} | {error, not_found}.
+get_memo(Index, Name) ->
+  case ets:lookup(memo_table_name(), Index) of
+    [] -> {error, not_found};
+    [{Index, Plist}] ->
+      case proplists:lookup(Name, Plist) of
+        {Name, Result}  -> {ok, Result};
+        _  -> {error, not_found}
+      end
+    end.
+
+-spec memo_table_name() -> ets:tid().
+memo_table_name() ->
+    get({parse_memo_table, ?MODULE}).
+
+-ifdef(p_eof).
+-spec p_eof() -> parse_fun().
+p_eof() ->
+  fun(<<>>, Index) -> {eof, [], Index};
+     (_, Index) -> {fail, {expected, eof, Index}} end.
+-endif.
+
+-ifdef(p_optional).
+-spec p_optional(parse_fun()) -> parse_fun().
+p_optional(P) ->
+  fun(Input, Index) ->
+      case P(Input, Index) of
+        {fail,_} -> {[], Input, Index};
+        {_, _, _} = Success -> Success
+      end
+  end.
+-endif.
+
+-ifdef(p_not).
+-spec p_not(parse_fun()) -> parse_fun().
+p_not(P) ->
+  fun(Input, Index)->
+      case P(Input,Index) of
+        {fail,_} ->
+          {[], Input, Index};
+        {Result, _, _} -> {fail, {expected, {no_match, Result},Index}}
+      end
+  end.
+-endif.
+
+-ifdef(p_assert).
+-spec p_assert(parse_fun()) -> parse_fun().
+p_assert(P) ->
+  fun(Input,Index) ->
+      case P(Input,Index) of
+        {fail,_} = Failure-> Failure;
+        _ -> {[], Input, Index}
+      end
+  end.
+-endif.
+
+-ifdef(p_seq).
+-spec p_seq([parse_fun()]) -> parse_fun().
+p_seq(P) ->
+  fun(Input, Index) ->
+      p_all(P, Input, Index, [])
+  end.
+
+-spec p_all([parse_fun()], input(), index(), [term()]) -> parse_result().
+p_all([], Inp, Index, Accum ) -> {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) ->
+  case P(Inp, Index) of
+    {fail, _} = Failure -> Failure;
+    {Result, InpRem, NewIndex} -> p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+  end.
+-endif.
+
+-ifdef(p_choose).
+-spec p_choose([parse_fun()]) -> parse_fun().
+p_choose(Parsers) ->
+  fun(Input, Index) ->
+      p_attempt(Parsers, Input, Index, none)
+  end.
+
+-spec p_attempt([parse_fun()], input(), index(), none | parse_failure()) -> parse_result().
+p_attempt([], _Input, _Index, Failure) -> Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)->
+  case P(Input, Index) of
+    {fail, _} = Failure ->
+      case FirstFailure of
+        none -> p_attempt(Parsers, Input, Index, Failure);
+        _ -> p_attempt(Parsers, Input, Index, FirstFailure)
+      end;
+    Result -> Result
+  end.
+-endif.
+
+-ifdef(p_zero_or_more).
+-spec p_zero_or_more(parse_fun()) -> parse_fun().
+p_zero_or_more(P) ->
+  fun(Input, Index) ->
+      p_scan(P, Input, Index, [])
+  end.
+-endif.
+
+-ifdef(p_one_or_more).
+-spec p_one_or_more(parse_fun()) -> parse_fun().
+p_one_or_more(P) ->
+  fun(Input, Index)->
+      Result = p_scan(P, Input, Index, []),
+      case Result of
+        {[_|_], _, _} ->
+          Result;
+        _ ->
+          {fail, {expected, Failure, _}} = P(Input,Index),
+          {fail, {expected, {at_least_one, Failure}, Index}}
+      end
+  end.
+-endif.
+
+-ifdef(p_label).
+-spec p_label(atom(), parse_fun()) -> parse_fun().
+p_label(Tag, P) ->
+  fun(Input, Index) ->
+      case P(Input, Index) of
+        {fail,_} = Failure ->
+           Failure;
+        {Result, InpRem, NewIndex} ->
+          {{Tag, Result}, InpRem, NewIndex}
+      end
+  end.
+-endif.
+
+-ifdef(p_scan).
+-spec p_scan(parse_fun(), input(), index(), [term()]) -> {[term()], input(), index()}.
+p_scan(_, <<>>, Index, Accum) -> {lists:reverse(Accum), <<>>, Index};
+p_scan(P, Inp, Index, Accum) ->
+  case P(Inp, Index) of
+    {fail,_} -> {lists:reverse(Accum), Inp, Index};
+    {Result, InpRem, NewIndex} -> p_scan(P, InpRem, NewIndex, [Result | Accum])
+  end.
+-endif.
+
+-ifdef(p_string).
+-spec p_string(binary()) -> parse_fun().
+p_string(S) ->
+    Length = erlang:byte_size(S),
+    fun(Input, Index) ->
+      try
+          <<S:Length/binary, Rest/binary>> = Input,
+          {S, Rest, p_advance_index(S, Index)}
+      catch
+          error:{badmatch,_} -> {fail, {expected, {string, S}, Index}}
+      end
+    end.
+-endif.
+
+-ifdef(p_anything).
+-spec p_anything() -> parse_fun().
+p_anything() ->
+  fun(<<>>, Index) -> {fail, {expected, any_character, Index}};
+     (Input, Index) when is_binary(Input) ->
+          <<C/utf8, Rest/binary>> = Input,
+          {<<C/utf8>>, Rest, p_advance_index(<<C/utf8>>, Index)}
+  end.
+-endif.
+
+-ifdef(p_charclass).
+-spec p_charclass(string() | binary()) -> parse_fun().
+p_charclass(Class) ->
+    {ok, RE} = re:compile(Class, [unicode, dotall]),
+    fun(Inp, Index) ->
+            case re:run(Inp, RE, [anchored]) of
+                {match, [{0, Length}|_]} ->
+                    {Head, Tail} = erlang:split_binary(Inp, Length),
+                    {Head, Tail, p_advance_index(Head, Index)};
+                _ -> {fail, {expected, {character_class, binary_to_list(Class)}, Index}}
+            end
+    end.
+-endif.
+
+-ifdef(p_regexp).
+-spec p_regexp(binary()) -> parse_fun().
+p_regexp(Regexp) ->
+    {ok, RE} = re:compile(Regexp, [unicode, dotall, anchored]),
+    fun(Inp, Index) ->
+        case re:run(Inp, RE) of
+            {match, [{0, Length}|_]} ->
+                {Head, Tail} = erlang:split_binary(Inp, Length),
+                {Head, Tail, p_advance_index(Head, Index)};
+            _ -> {fail, {expected, {regexp, binary_to_list(Regexp)}, Index}}
+        end
+    end.
+-endif.
+
+-ifdef(line).
+-spec line(index() | term()) -> pos_integer() | undefined.
+line({{line,L},_}) -> L;
+line(_) -> undefined.
+-endif.
+
+-ifdef(column).
+-spec column(index() | term()) -> pos_integer() | undefined.
+column({_,{column,C}}) -> C;
+column(_) -> undefined.
+-endif.
+
+-spec p_advance_index(input() | unicode:charlist() | pos_integer(), index()) -> index().
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) orelse is_binary(MatchedInput)-> % strings
+  lists:foldl(fun p_advance_index/2, Index, unicode:characters_to_list(MatchedInput));
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -> % single characters
+  {{line, Line}, {column, Col}} = Index,
+  case MatchedInput of
+    $\n -> {{line, Line+1}, {column, 1}};
+    _ -> {{line, Line}, {column, Col+1}}
+  end.
diff --git a/inttest/neotoma1/mock/neotoma/src/neotoma.app.src b/inttest/neotoma1/mock/neotoma/src/neotoma.app.src
new file mode 100644
index 0000000..dff6cef
--- /dev/null
+++ b/inttest/neotoma1/mock/neotoma/src/neotoma.app.src
@@ -0,0 +1,10 @@
+{application, neotoma,
+ [
+  {description, "PEG/Packrat toolkit and parser-generator."},
+  {vsn, "1.7.3"},
+  {applications, [kernel, stdlib]},
+  {contributors, ["Sean Cribbs"]},
+  {licenses, ["MIT"]},
+  {links, [{"Github", "https://github.com/seancribbs/neotoma"}]}
+ ]
+}.
diff --git a/inttest/neotoma1/mock/neotoma/src/neotoma.erl b/inttest/neotoma1/mock/neotoma/src/neotoma.erl
new file mode 100644
index 0000000..f4102f6
--- /dev/null
+++ b/inttest/neotoma1/mock/neotoma/src/neotoma.erl
@@ -0,0 +1,145 @@
+-module(neotoma).
+-author("Sean Cribbs <seancribbs@gmail.com>").
+-export([file/1, file/2, bootstrap/0]).
+-export([main/1]).
+
+-define(ALL_COMBINATORS, [p_eof, p_optional, p_not, p_assert, p_seq,
+        p_choose, p_zero_or_more, p_one_or_more, p_label, p_scan,
+        p_string, p_anything, p_charclass, p_regexp, line, column]).
+
+-type option() :: {module, atom()} | {output, file:filename()} |  {transform_module, atom()} |
+                  {neotoma_priv_dir, file:filename()}.
+
+%% @doc Handler function for escript.
+-spec main(list()) -> ok | no_return().
+main([]) ->
+    io:format("Usage: neotoma filename [-module output_module] [-output output_dir] [-transform_module transform_module]\n");
+main([Filename | Args]) ->
+    %% code:priv_dir is unreliable when called in escript context, but
+    %% escript:script_name does what we want.
+    PrivDir = filename:join([filename:dirname(escript:script_name()), "priv"]),
+    file(Filename, [{neotoma_priv_dir, PrivDir} | parse_options(Args)]).
+
+%% @doc Generates a parser from the specified file.
+%% @equiv file(Filename, [])
+-spec file(file:filename()) -> ok | {error, atom()}.
+file(InputGrammar) ->
+    file(InputGrammar, []).
+
+%% @doc Generates a parser from the specified file with the given options.
+-spec file(file:filename(), [option()]) -> ok | {error, atom()}.
+file(InputGrammar, Options) ->
+    Basename = filename:basename(InputGrammar, ".peg"),
+    InputDir = filename:dirname(InputGrammar),
+    ModuleName = proplists:get_value(module, Options, list_to_atom(Basename)),
+    OutputDir = proplists:get_value(output, Options, InputDir),
+    OutputFilename = filename:join(OutputDir, atom_to_list(ModuleName) ++ ".erl"),
+    TransformModule = proplists:get_value(transform_module, Options, false),
+    validate_params(filename:absname(InputGrammar),
+                    ModuleName,
+                    TransformModule,
+                    filename:absname(OutputFilename)),
+    Parsed = parse_grammar(InputGrammar),
+    Rules = proplists:get_value(rules, Parsed),
+    Root = proplists:get_value(root, Parsed),
+    Code = proplists:get_value(code, Parsed),
+    GenTransform = proplists:get_value(transform, Parsed),
+    Combinators = proplists:get_value(combinators, Parsed, ?ALL_COMBINATORS),
+    ModuleAttrs = generate_module_attrs(ModuleName, Combinators),
+    EntryFuns = generate_entry_functions(Root),
+    TransformFun = create_transform(TransformModule, OutputDir, GenTransform),
+    PrivDir = proplists:get_value(neotoma_priv_dir, Options, code:priv_dir(neotoma)),
+    {ok, PegIncludes} = file:read_file(filename:join([PrivDir, "peg_includes.hrl"])),
+    file:write_file(OutputFilename, [ModuleAttrs, "\n", Code, "\n", EntryFuns, "\n", Rules, "\n", TransformFun, "\n", PegIncludes]).
+
+-spec validate_params(file:filename(),atom(),atom(),file:filename()) -> 'ok'.
+validate_params(InputGrammar, _, _, OutputFile) when InputGrammar =:= OutputFile ->
+    throw({badarg, "Input and output file are the same!"});
+validate_params(_,_, false, _) -> ok;
+validate_params(_,_, TransformModule, _) when not is_atom(TransformModule) ->
+    throw({badarg, "transform_module option must be an atom"});
+validate_params(_,Basename, TransformModule, _) when Basename =:= TransformModule ->
+    throw({badarg, "Transform module named same as parser module!"});
+validate_params(_,_, TransformModule, OutputFile) ->
+    OutMod = list_to_atom(filename:basename(OutputFile, ".erl")),
+    case OutMod of
+        TransformModule -> throw({badarg, "Transform module file same as parser output file!"});
+        _ -> ok
+    end.
+
+-spec generate_module_attrs(atom(), [atom()]) -> iolist().
+generate_module_attrs(ModName, Combinators) ->
+    ["-module(", atom_to_list(ModName) ,").\n",
+     "-export([parse/1,file/1]).\n",
+     [ generate_combinator_macro(C) || Combinators /= undefined, C <- Combinators ],
+     "\n"
+     ].
+
+generate_combinator_macro(C) ->
+    ["-define(", atom_to_list(C), ",true).\n"].
+
+-spec generate_entry_functions({iodata(),_}) -> iolist().
+generate_entry_functions(Root) ->
+    {RootRule,_} = Root,
+     ["-spec file(file:name()) -> any().\n",
+     "file(Filename) -> case file:read_file(Filename) of {ok,Bin} -> parse(Bin); Err -> Err end.\n\n",
+     "-spec parse(binary() | list()) -> any().\n",
+     "parse(List) when is_list(List) -> parse(unicode:characters_to_binary(List));\n",
+     "parse(Input) when is_binary(Input) ->\n",
+     "  _ = setup_memo(),\n",
+     "  Result = case '",RootRule,"'(Input,{{line,1},{column,1}}) of\n",
+     "             {AST, <<>>, _Index} -> AST;\n",
+     "             Any -> Any\n"
+     "           end,\n",
+     "  release_memo(), Result.\n"].
+
+-spec parse_grammar(file:filename()) -> any().
+parse_grammar(InputFile) ->
+    case neotoma_parse:file(InputFile) of
+        {fail, Index} ->
+            throw({grammar_error, {fail, Index}});
+        {Parsed, Remainder, Index} ->
+            io:format("WARNING: Grammar parse ended unexpectedly at ~p, generated parser may be incorrect.~nRemainder:~n~p",
+                      [Index, Remainder]),
+            Parsed;
+        L when is_list(L) -> L;
+        _ -> throw({error, {unknown, grammar, InputFile}})
+    end.
+
+-spec create_transform(atom() | boolean(),file:filename(),_) -> iolist().
+create_transform(_,_,[]) -> [];
+create_transform(false,_,_) ->
+    "transform(_,Node,_Index) -> Node.";
+create_transform(ModName,Dir,_) when is_atom(ModName) ->
+    XfFile = filename:join(Dir, atom_to_list(ModName) ++ ".erl"),
+    case filelib:is_regular(XfFile) of
+        true -> io:format("'~s' already exists, skipping generation.~n", [XfFile]);
+        false -> generate_transform_stub(XfFile, ModName)
+    end,
+    ["transform(Symbol,Node,Index) -> ",atom_to_list(ModName),":transform(Symbol, Node, Index)."].
+
+-spec generate_transform_stub(file:filename(), atom()) -> 'ok' | {'error',atom()}.
+generate_transform_stub(XfFile,ModName) ->
+    Data = ["-module(",atom_to_list(ModName),").\n",
+            "-export([transform/3]).\n\n",
+            "%% Add clauses to this function to transform syntax nodes\n",
+            "%% from the parser into semantic output.\n",
+            "transform(Symbol, Node, _Index) when is_atom(Symbol) ->\n  Node."],
+    file:write_file(XfFile, Data).
+
+%% @doc Bootstraps the neotoma metagrammar.  Intended only for internal development!
+%% @equiv file("src/neotoma_parse.peg")
+-spec bootstrap() -> 'ok'.
+bootstrap() ->
+    file("priv/neotoma_parse.peg", [{output, "src/"}, {neotoma_priv_dir, "priv"}]).
+
+%% @doc Parses arguments passed to escript
+-spec parse_options(list()) -> list().
+parse_options(["-module", ModName | Rest]) ->
+    [{module, list_to_atom(ModName)} | parse_options(Rest)];
+parse_options(["-output", Dir | Rest]) ->
+    [{output, Dir} | parse_options(Rest)];
+parse_options(["-transform_module", ModName | Rest]) ->
+    [{transform_module, list_to_atom(ModName)} | parse_options(Rest)];
+parse_options([]) ->
+    [].
diff --git a/inttest/neotoma1/mock/neotoma/src/neotoma_parse.erl b/inttest/neotoma1/mock/neotoma/src/neotoma_parse.erl
new file mode 100644
index 0000000..1bffaf8
--- /dev/null
+++ b/inttest/neotoma1/mock/neotoma/src/neotoma_parse.erl
@@ -0,0 +1,625 @@
+-module(neotoma_parse).
+-export([parse/1,file/1]).
+-define(p_anything,true).
+-define(p_charclass,true).
+-define(p_choose,true).
+-define(p_label,true).
+-define(p_not,true).
+-define(p_one_or_more,true).
+-define(p_optional,true).
+-define(p_scan,true).
+-define(p_seq,true).
+-define(p_string,true).
+-define(p_zero_or_more,true).
+
+
+
+% insert escapes into a string
+-spec escape_string(string()) -> string().
+escape_string(String) -> escape_string(String, []).
+
+-spec escape_string(string(), string()) -> string().
+escape_string([], Output) ->
+  lists:reverse(Output);
+escape_string([H|T], Output) ->
+  escape_string(T,
+    case H of
+        $/  -> [$/,$\\|Output];
+        $\" -> [$\",$\\|Output];     % " comment inserted to help some editors with highlighting the generated parser
+        $\' -> [$\',$\\|Output];     % ' comment inserted to help some editors with highlighting the generated parser
+        $\b -> [$b,$\\|Output];
+        $\d -> [$d,$\\|Output];
+        $\e -> [$e,$\\|Output];
+        $\f -> [$f,$\\|Output];
+        $\n -> [$n,$\\|Output];
+        $\r -> [$r,$\\|Output];
+        $\s -> [$s,$\\|Output];
+        $\t -> [$t,$\\|Output];
+        $\v -> [$v,$\\|Output];
+        _   -> [H|Output]
+    end).
+
+-spec add_lhs(binary(), index()) -> true.
+add_lhs(Symbol, Index) ->
+  case ets:lookup(memo_table_name(), lhs) of
+    [] ->
+      ets:insert(memo_table_name(), {lhs, [{Symbol,Index}]});
+    [{lhs, L}] when is_list(L) ->
+      ets:insert(memo_table_name(), {lhs, [{Symbol,Index}|L]})
+  end.
+
+-spec add_nt(binary(), index()) -> true | ok.
+add_nt(Symbol, Index) ->
+  case ets:lookup(memo_table_name(), nts) of
+    [] ->
+      ets:insert(memo_table_name(), {nts, [{Symbol,Index}]});
+    [{nts, L}] when is_list(L) ->
+      case proplists:is_defined(Symbol, L) of
+        true ->
+          ok;
+        _ ->
+          ets:insert(memo_table_name(), {nts, [{Symbol,Index}|L]})
+      end
+  end.
+
+-spec verify_rules() -> ok | no_return().
+verify_rules() ->
+  [{lhs, LHS}] = ets:lookup(memo_table_name(), lhs),
+  [{nts, NTs}] = ets:lookup(memo_table_name(), nts),
+  [Root|NonRoots] = lists:reverse(LHS),
+  lists:foreach(fun({Sym,Idx}) ->
+                    case proplists:is_defined(Sym, NTs) of
+                      true ->
+                        ok;
+                      _ ->
+                        io:format("neotoma warning: rule '~s' is unused. ~p~n", [Sym,Idx])
+                    end
+                end, NonRoots),
+  lists:foreach(fun({S,I}) ->
+                    case proplists:is_defined(S, LHS) of
+                      true ->
+                        ok;
+                      _ ->
+                        io:format("neotoma error: nonterminal '~s' has no reduction. (found at ~p) No parser will be generated!~n", [S,I]),
+                        exit({neotoma, {no_reduction, list_to_atom(binary_to_list(S))}})
+                    end
+                end, NTs),
+    Root.
+
+-spec used_combinator(atom()) -> true.
+used_combinator(C) ->
+    case ets:lookup(memo_table_name(), combinators) of
+        [] ->
+            ets:insert(memo_table_name(), {combinators, ordsets:from_list([C])});
+        [{combinators, Cs}] ->
+            ets:insert(memo_table_name(), {combinators, ordsets:add_element(C, Cs)})
+    end.
+
+-spec used_transform_variables(binary()) -> [ 'Node' | 'Idx' ].
+used_transform_variables(Transform) ->
+  Code = unicode:characters_to_list(Transform),
+  {ok, Tokens, _} = erl_scan:string(Code),
+  used_transform_variables(Tokens, []).
+
+used_transform_variables([{var, _, Name}|Tokens], Acc) ->
+  used_transform_variables(Tokens, case Name of
+                                    'Node' -> [Name | Acc];
+                                    'Idx'  -> [Name | Acc];
+                                    _      -> Acc
+                                  end);
+used_transform_variables([_|Tokens], Acc) ->
+  used_transform_variables(Tokens, Acc);
+used_transform_variables([], Acc) ->
+  lists:usort(Acc).
+
+-spec file(file:name()) -> any().
+file(Filename) -> case file:read_file(Filename) of {ok,Bin} -> parse(Bin); Err -> Err end.
+
+-spec parse(binary() | list()) -> any().
+parse(List) when is_list(List) -> parse(unicode:characters_to_binary(List));
+parse(Input) when is_binary(Input) ->
+  _ = setup_memo(),
+  Result = case 'rules'(Input,{{line,1},{column,1}}) of
+             {AST, <<>>, _Index} -> AST;
+             Any -> Any
+           end,
+  release_memo(), Result.
+
+-spec 'rules'(input(), index()) -> parse_result().
+'rules'(Input, Index) ->
+  p(Input, Index, 'rules', fun(I,D) -> (p_seq([p_optional(fun 'space'/2), fun 'declaration_sequence'/2, p_optional(fun 'space'/2), p_optional(fun 'code_block'/2), p_optional(fun 'space'/2)]))(I,D) end, fun(Node, _Idx) ->
+  RootRule = verify_rules(),
+  Rules = unicode:characters_to_binary(lists:map(fun(R) -> [R, "\n\n"] end, lists:nth(2, Node))),
+  Code = case lists:nth(4, Node) of
+             {code, Block} -> Block;
+             _ -> []
+         end,
+  [{rules, Rules},
+   {code, Code},
+   {root, RootRule},
+   {transform, ets:lookup(memo_table_name(),gen_transform)},
+   {combinators, ets:lookup_element(memo_table_name(), combinators, 2)}]
+
+ end).
+
+-spec 'declaration_sequence'(input(), index()) -> parse_result().
+'declaration_sequence'(Input, Index) ->
+  p(Input, Index, 'declaration_sequence', fun(I,D) -> (p_seq([p_label('head', fun 'declaration'/2), p_label('tail', p_zero_or_more(p_seq([fun 'space'/2, fun 'declaration'/2])))]))(I,D) end, fun(Node, _Idx) ->
+  FirstRule = proplists:get_value(head, Node),
+  OtherRules =  [I || [_,I] <- proplists:get_value(tail, Node, [])],
+  [FirstRule|OtherRules]
+ end).
+
+-spec 'declaration'(input(), index()) -> parse_result().
+'declaration'(Input, Index) ->
+  p(Input, Index, 'declaration', fun(I,D) -> (p_seq([fun 'nonterminal'/2, p_zero_or_more(fun 'space'/2), p_string(<<"<-">>), p_zero_or_more(fun 'space'/2), fun 'parsing_expression'/2, p_optional(fun 'space'/2), p_optional(fun 'code_block'/2), p_optional(fun 'space'/2), p_string(<<";">>)]))(I,D) end, fun(Node, _Idx) ->
+  [{nonterminal,Symbol}|Tail] = Node,
+  add_lhs(Symbol, Index),
+  Transform = case lists:nth(6,Tail) of
+                  {code, CodeBlock} -> CodeBlock;
+                  _ ->
+                      ets:insert_new(memo_table_name(),{gen_transform, true}),
+                      ["transform('",Symbol,"', Node, Idx)"]
+                  end,
+  TransformArgs = case used_transform_variables(Transform) of
+    []              -> "_Node, _Idx";
+    ['Idx']         -> "_Node, Idx";
+    ['Node']        -> "Node, _Idx";
+    ['Idx', 'Node'] -> "Node, Idx"
+  end,
+  ["-spec '", Symbol, "'(input(), index()) -> parse_result().\n",
+   "'",Symbol,"'","(Input, Index) ->\n  ",
+        "p(Input, Index, '",Symbol,"', fun(I,D) -> (",
+        lists:nth(4, Tail),
+        ")(I,D) end, fun(", TransformArgs, ") ->",Transform," end)."]
+ end).
+
+-spec 'parsing_expression'(input(), index()) -> parse_result().
+'parsing_expression'(Input, Index) ->
+  p(Input, Index, 'parsing_expression', fun(I,D) -> (p_choose([fun 'choice'/2, fun 'sequence'/2, fun 'primary'/2]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'choice'(input(), index()) -> parse_result().
+'choice'(Input, Index) ->
+  p(Input, Index, 'choice', fun(I,D) -> (p_seq([p_label('head', fun 'alternative'/2), p_label('tail', p_one_or_more(p_seq([fun 'space'/2, p_string(<<"\/">>), fun 'space'/2, fun 'alternative'/2])))]))(I,D) end, fun(Node, _Idx) ->
+  Tail = [lists:last(S) || S <- proplists:get_value(tail, Node)],
+  Head = proplists:get_value(head, Node),
+  Statements = [[", ", TS] ||  TS <- Tail],
+  used_combinator(p_choose),
+  ["p_choose([", Head, Statements, "])"]
+ end).
+
+-spec 'alternative'(input(), index()) -> parse_result().
+'alternative'(Input, Index) ->
+  p(Input, Index, 'alternative', fun(I,D) -> (p_choose([fun 'sequence'/2, fun 'labeled_primary'/2]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'primary'(input(), index()) -> parse_result().
+'primary'(Input, Index) ->
+  p(Input, Index, 'primary', fun(I,D) -> (p_choose([p_seq([fun 'prefix'/2, fun 'atomic'/2]), p_seq([fun 'atomic'/2, fun 'suffix'/2]), fun 'atomic'/2]))(I,D) end, fun(Node, _Idx) ->
+case Node of
+  [Atomic, one_or_more] ->
+        used_combinator(p_one_or_more),
+        used_combinator(p_scan),
+        ["p_one_or_more(", Atomic, ")"];
+  [Atomic, zero_or_more] ->
+        used_combinator(p_zero_or_more),
+        used_combinator(p_scan),
+        ["p_zero_or_more(", Atomic, ")"];
+  [Atomic, optional] ->
+        used_combinator(p_optional),
+        ["p_optional(", Atomic, ")"];
+  [assert, Atomic] ->
+        used_combinator(p_assert),
+        ["p_assert(", Atomic, ")"];
+  [not_, Atomic] ->
+        used_combinator(p_not),
+        ["p_not(", Atomic, ")"];
+  _ -> Node
+end
+ end).
+
+-spec 'sequence'(input(), index()) -> parse_result().
+'sequence'(Input, Index) ->
+  p(Input, Index, 'sequence', fun(I,D) -> (p_seq([p_label('head', fun 'labeled_primary'/2), p_label('tail', p_one_or_more(p_seq([fun 'space'/2, fun 'labeled_primary'/2])))]))(I,D) end, fun(Node, _Idx) ->
+  Tail = [lists:nth(2, S) || S <- proplists:get_value(tail, Node)],
+  Head = proplists:get_value(head, Node),
+  Statements = [[", ", TS] || TS <- Tail],
+  used_combinator(p_seq),
+  ["p_seq([", Head, Statements, "])"]
+ end).
+
+-spec 'labeled_primary'(input(), index()) -> parse_result().
+'labeled_primary'(Input, Index) ->
+  p(Input, Index, 'labeled_primary', fun(I,D) -> (p_seq([p_optional(fun 'label'/2), fun 'primary'/2]))(I,D) end, fun(Node, _Idx) ->
+  case hd(Node) of
+    [] -> lists:nth(2, Node);
+    Label ->
+          used_combinator(p_label),
+          ["p_label('",  Label, "', ", lists:nth(2, Node), ")"]
+  end
+ end).
+
+-spec 'label'(input(), index()) -> parse_result().
+'label'(Input, Index) ->
+  p(Input, Index, 'label', fun(I,D) -> (p_seq([fun 'alpha_char'/2, p_zero_or_more(fun 'alphanumeric_char'/2), p_string(<<":">>)]))(I,D) end, fun(Node, _Idx) ->
+  lists:sublist(Node, length(Node)-1)
+ end).
+
+-spec 'suffix'(input(), index()) -> parse_result().
+'suffix'(Input, Index) ->
+  p(Input, Index, 'suffix', fun(I,D) -> (p_choose([fun 'repetition_suffix'/2, fun 'optional_suffix'/2]))(I,D) end, fun(Node, _Idx) ->
+  case Node of
+    <<"*">> -> zero_or_more;
+    <<"+">> -> one_or_more;
+    <<"?">> -> optional
+  end
+ end).
+
+-spec 'optional_suffix'(input(), index()) -> parse_result().
+'optional_suffix'(Input, Index) ->
+  p(Input, Index, 'optional_suffix', fun(I,D) -> (p_string(<<"?">>))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'repetition_suffix'(input(), index()) -> parse_result().
+'repetition_suffix'(Input, Index) ->
+  p(Input, Index, 'repetition_suffix', fun(I,D) -> (p_choose([p_string(<<"+">>), p_string(<<"*">>)]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'prefix'(input(), index()) -> parse_result().
+'prefix'(Input, Index) ->
+  p(Input, Index, 'prefix', fun(I,D) -> (p_choose([p_string(<<"&">>), p_string(<<"!">>)]))(I,D) end, fun(Node, _Idx) ->
+  case Node of
+    <<"&">> -> assert;
+    <<"!">> -> not_
+  end
+ end).
+
+-spec 'atomic'(input(), index()) -> parse_result().
+'atomic'(Input, Index) ->
+  p(Input, Index, 'atomic', fun(I,D) -> (p_choose([fun 'terminal'/2, fun 'nonterminal'/2, fun 'parenthesized_expression'/2]))(I,D) end, fun(Node, _Idx) ->
+case Node of
+  {nonterminal, Symbol} ->
+                [<<"fun '">>, Symbol, <<"'/2">>];
+  _ -> Node
+end
+ end).
+
+-spec 'parenthesized_expression'(input(), index()) -> parse_result().
+'parenthesized_expression'(Input, Index) ->
+  p(Input, Index, 'parenthesized_expression', fun(I,D) -> (p_seq([p_string(<<"(">>), p_optional(fun 'space'/2), fun 'parsing_expression'/2, p_optional(fun 'space'/2), p_string(<<")">>)]))(I,D) end, fun(Node, _Idx) ->lists:nth(3, Node) end).
+
+-spec 'nonterminal'(input(), index()) -> parse_result().
+'nonterminal'(Input, Index) ->
+  p(Input, Index, 'nonterminal', fun(I,D) -> (p_seq([fun 'alpha_char'/2, p_zero_or_more(fun 'alphanumeric_char'/2)]))(I,D) end, fun(Node, Idx) ->
+  Symbol = unicode:characters_to_binary(Node),
+  add_nt(Symbol, Idx),
+  {nonterminal, Symbol}
+ end).
+
+-spec 'terminal'(input(), index()) -> parse_result().
+'terminal'(Input, Index) ->
+  p(Input, Index, 'terminal', fun(I,D) -> (p_choose([fun 'regexp_string'/2, fun 'quoted_string'/2, fun 'character_class'/2, fun 'anything_symbol'/2]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'regexp_string'(input(), index()) -> parse_result().
+'regexp_string'(Input, Index) ->
+  p(Input, Index, 'regexp_string', fun(I,D) -> (p_seq([p_string(<<"#">>), p_label('string', p_one_or_more(p_seq([p_not(p_string(<<"#">>)), p_choose([p_string(<<"\\#">>), p_anything()])]))), p_string(<<"#">>)]))(I,D) end, fun(Node, _Idx) ->
+  used_combinator(p_regexp),
+  ["p_regexp(<<\"",
+	% Escape \ and " as they are used in erlang string. Other sumbol stay as is.
+	%  \ -> \\
+	%  " -> \"
+   re:replace(proplists:get_value(string, Node), "\"|\\\\", "\\\\&", [{return, binary}, global]),
+   "\">>)"]
+ end).
+
+-spec 'quoted_string'(input(), index()) -> parse_result().
+'quoted_string'(Input, Index) ->
+  p(Input, Index, 'quoted_string', fun(I,D) -> (p_choose([fun 'single_quoted_string'/2, fun 'double_quoted_string'/2]))(I,D) end, fun(Node, _Idx) ->
+  used_combinator(p_string),
+  lists:flatten(["p_string(<<\"",
+   escape_string(unicode:characters_to_list(proplists:get_value(string, Node))),
+   "\">>)"])
+ end).
+
+-spec 'double_quoted_string'(input(), index()) -> parse_result().
+'double_quoted_string'(Input, Index) ->
+  p(Input, Index, 'double_quoted_string', fun(I,D) -> (p_seq([p_string(<<"\"">>), p_label('string', p_zero_or_more(p_seq([p_not(p_string(<<"\"">>)), p_choose([p_string(<<"\\\\">>), p_string(<<"\\\"">>), p_anything()])]))), p_string(<<"\"">>)]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'single_quoted_string'(input(), index()) -> parse_result().
+'single_quoted_string'(Input, Index) ->
+  p(Input, Index, 'single_quoted_string', fun(I,D) -> (p_seq([p_string(<<"\'">>), p_label('string', p_zero_or_more(p_seq([p_not(p_string(<<"\'">>)), p_choose([p_string(<<"\\\\">>), p_string(<<"\\\'">>), p_anything()])]))), p_string(<<"\'">>)]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'character_class'(input(), index()) -> parse_result().
+'character_class'(Input, Index) ->
+  p(Input, Index, 'character_class', fun(I,D) -> (p_seq([p_string(<<"[">>), p_label('characters', p_one_or_more(p_seq([p_not(p_string(<<"]">>)), p_choose([p_seq([p_string(<<"\\\\">>), p_anything()]), p_seq([p_not(p_string(<<"\\\\">>)), p_anything()])])]))), p_string(<<"]">>)]))(I,D) end, fun(Node, _Idx) ->
+  used_combinator(p_charclass),
+  ["p_charclass(<<\"[",
+   escape_string(unicode:characters_to_list(proplists:get_value(characters, Node))),
+   "]\">>)"]
+ end).
+
+-spec 'anything_symbol'(input(), index()) -> parse_result().
+'anything_symbol'(Input, Index) ->
+  p(Input, Index, 'anything_symbol', fun(I,D) -> (p_string(<<".">>))(I,D) end, fun(_Node, _Idx) -> used_combinator(p_anything), <<"p_anything()">>  end).
+
+-spec 'alpha_char'(input(), index()) -> parse_result().
+'alpha_char'(Input, Index) ->
+  p(Input, Index, 'alpha_char', fun(I,D) -> (p_charclass(<<"[A-Za-z_]">>))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'alphanumeric_char'(input(), index()) -> parse_result().
+'alphanumeric_char'(Input, Index) ->
+  p(Input, Index, 'alphanumeric_char', fun(I,D) -> (p_choose([fun 'alpha_char'/2, p_charclass(<<"[0-9]">>)]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'space'(input(), index()) -> parse_result().
+'space'(Input, Index) ->
+  p(Input, Index, 'space', fun(I,D) -> (p_one_or_more(p_choose([fun 'white'/2, fun 'comment_to_eol'/2])))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'comment_to_eol'(input(), index()) -> parse_result().
+'comment_to_eol'(Input, Index) ->
+  p(Input, Index, 'comment_to_eol', fun(I,D) -> (p_seq([p_not(p_string(<<"%{">>)), p_string(<<"%">>), p_zero_or_more(p_seq([p_not(p_string(<<"\n">>)), p_anything()]))]))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'white'(input(), index()) -> parse_result().
+'white'(Input, Index) ->
+  p(Input, Index, 'white', fun(I,D) -> (p_charclass(<<"[\s\t\n\r]">>))(I,D) end, fun(Node, _Idx) ->Node end).
+
+-spec 'code_block'(input(), index()) -> parse_result().
+'code_block'(Input, Index) ->
+  p(Input, Index, 'code_block', fun(I,D) -> (p_choose([p_seq([p_string(<<"%{">>), p_label('code', p_one_or_more(p_choose([p_string(<<"\\%">>), p_string(<<"$%">>), p_seq([p_not(p_string(<<"%}">>)), p_anything()])]))), p_string(<<"%}">>)]), p_seq([p_string(<<"`">>), p_label('code', p_one_or_more(p_choose([p_string(<<"\\`">>), p_string(<<"$`">>), p_seq([p_not(p_string(<<"`">>)), p_anything()])]))), p_string(<<"`">>)]), p_string(<<"~">>)]))(I,D) end, fun(Node, _Idx) ->
+   case Node of
+       <<"~">> -> {code, <<"Node">>};
+       _   -> {code, proplists:get_value('code', Node)}
+   end
+ end).
+
+
+
+-file("peg_includes.hrl", 1).
+-type index() :: {{line, pos_integer()}, {column, pos_integer()}}.
+-type input() :: binary().
+-type parse_failure() :: {fail, term()}.
+-type parse_success() :: {term(), input(), index()}.
+-type parse_result() :: parse_failure() | parse_success().
+-type parse_fun() :: fun((input(), index()) -> parse_result()).
+-type xform_fun() :: fun((input(), index()) -> term()).
+
+-spec p(input(), index(), atom(), parse_fun(), xform_fun()) -> parse_result().
+p(Inp, StartIndex, Name, ParseFun, TransformFun) ->
+  case get_memo(StartIndex, Name) of      % See if the current reduction is memoized
+    {ok, Memo} -> %Memo;                     % If it is, return the stored result
+      Memo;
+    _ ->                                        % If not, attempt to parse
+      Result = case ParseFun(Inp, StartIndex) of
+        {fail,_} = Failure ->                       % If it fails, memoize the failure
+          Failure;
+        {Match, InpRem, NewIndex} ->               % If it passes, transform and memoize the result.
+          Transformed = TransformFun(Match, StartIndex),
+          {Transformed, InpRem, NewIndex}
+      end,
+      memoize(StartIndex, Name, Result),
+      Result
+  end.
+
+-spec setup_memo() -> ets:tid().
+setup_memo() ->
+  put({parse_memo_table, ?MODULE}, ets:new(?MODULE, [set])).
+
+-spec release_memo() -> true.
+release_memo() ->
+  ets:delete(memo_table_name()).
+
+-spec memoize(index(), atom(), parse_result()) -> true.
+memoize(Index, Name, Result) ->
+  Memo = case ets:lookup(memo_table_name(), Index) of
+              [] -> [];
+              [{Index, Plist}] -> Plist
+         end,
+  ets:insert(memo_table_name(), {Index, [{Name, Result}|Memo]}).
+
+-spec get_memo(index(), atom()) -> {ok, term()} | {error, not_found}.
+get_memo(Index, Name) ->
+  case ets:lookup(memo_table_name(), Index) of
+    [] -> {error, not_found};
+    [{Index, Plist}] ->
+      case proplists:lookup(Name, Plist) of
+        {Name, Result}  -> {ok, Result};
+        _  -> {error, not_found}
+      end
+    end.
+
+-spec memo_table_name() -> ets:tid().
+memo_table_name() ->
+    get({parse_memo_table, ?MODULE}).
+
+-ifdef(p_eof).
+-spec p_eof() -> parse_fun().
+p_eof() ->
+  fun(<<>>, Index) -> {eof, [], Index};
+     (_, Index) -> {fail, {expected, eof, Index}} end.
+-endif.
+
+-ifdef(p_optional).
+-spec p_optional(parse_fun()) -> parse_fun().
+p_optional(P) ->
+  fun(Input, Index) ->
+      case P(Input, Index) of
+        {fail,_} -> {[], Input, Index};
+        {_, _, _} = Success -> Success
+      end
+  end.
+-endif.
+
+-ifdef(p_not).
+-spec p_not(parse_fun()) -> parse_fun().
+p_not(P) ->
+  fun(Input, Index)->
+      case P(Input,Index) of
+        {fail,_} ->
+          {[], Input, Index};
+        {Result, _, _} -> {fail, {expected, {no_match, Result},Index}}
+      end
+  end.
+-endif.
+
+-ifdef(p_assert).
+-spec p_assert(parse_fun()) -> parse_fun().
+p_assert(P) ->
+  fun(Input,Index) ->
+      case P(Input,Index) of
+        {fail,_} = Failure-> Failure;
+        _ -> {[], Input, Index}
+      end
+  end.
+-endif.
+
+-ifdef(p_seq).
+-spec p_seq([parse_fun()]) -> parse_fun().
+p_seq(P) ->
+  fun(Input, Index) ->
+      p_all(P, Input, Index, [])
+  end.
+
+-spec p_all([parse_fun()], input(), index(), [term()]) -> parse_result().
+p_all([], Inp, Index, Accum ) -> {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) ->
+  case P(Inp, Index) of
+    {fail, _} = Failure -> Failure;
+    {Result, InpRem, NewIndex} -> p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+  end.
+-endif.
+
+-ifdef(p_choose).
+-spec p_choose([parse_fun()]) -> parse_fun().
+p_choose(Parsers) ->
+  fun(Input, Index) ->
+      p_attempt(Parsers, Input, Index, none)
+  end.
+
+-spec p_attempt([parse_fun()], input(), index(), none | parse_failure()) -> parse_result().
+p_attempt([], _Input, _Index, Failure) -> Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)->
+  case P(Input, Index) of
+    {fail, _} = Failure ->
+      case FirstFailure of
+        none -> p_attempt(Parsers, Input, Index, Failure);
+        _ -> p_attempt(Parsers, Input, Index, FirstFailure)
+      end;
+    Result -> Result
+  end.
+-endif.
+
+-ifdef(p_zero_or_more).
+-spec p_zero_or_more(parse_fun()) -> parse_fun().
+p_zero_or_more(P) ->
+  fun(Input, Index) ->
+      p_scan(P, Input, Index, [])
+  end.
+-endif.
+
+-ifdef(p_one_or_more).
+-spec p_one_or_more(parse_fun()) -> parse_fun().
+p_one_or_more(P) ->
+  fun(Input, Index)->
+      Result = p_scan(P, Input, Index, []),
+      case Result of
+        {[_|_], _, _} ->
+          Result;
+        _ ->
+          {fail, {expected, Failure, _}} = P(Input,Index),
+          {fail, {expected, {at_least_one, Failure}, Index}}
+      end
+  end.
+-endif.
+
+-ifdef(p_label).
+-spec p_label(atom(), parse_fun()) -> parse_fun().
+p_label(Tag, P) ->
+  fun(Input, Index) ->
+      case P(Input, Index) of
+        {fail,_} = Failure ->
+           Failure;
+        {Result, InpRem, NewIndex} ->
+          {{Tag, Result}, InpRem, NewIndex}
+      end
+  end.
+-endif.
+
+-ifdef(p_scan).
+-spec p_scan(parse_fun(), input(), index(), [term()]) -> {[term()], input(), index()}.
+p_scan(_, <<>>, Index, Accum) -> {lists:reverse(Accum), <<>>, Index};
+p_scan(P, Inp, Index, Accum) ->
+  case P(Inp, Index) of
+    {fail,_} -> {lists:reverse(Accum), Inp, Index};
+    {Result, InpRem, NewIndex} -> p_scan(P, InpRem, NewIndex, [Result | Accum])
+  end.
+-endif.
+
+-ifdef(p_string).
+-spec p_string(binary()) -> parse_fun().
+p_string(S) ->
+    Length = erlang:byte_size(S),
+    fun(Input, Index) ->
+      try
+          <<S:Length/binary, Rest/binary>> = Input,
+          {S, Rest, p_advance_index(S, Index)}
+      catch
+          error:{badmatch,_} -> {fail, {expected, {string, S}, Index}}
+      end
+    end.
+-endif.
+
+-ifdef(p_anything).
+-spec p_anything() -> parse_fun().
+p_anything() ->
+  fun(<<>>, Index) -> {fail, {expected, any_character, Index}};
+     (Input, Index) when is_binary(Input) ->
+          <<C/utf8, Rest/binary>> = Input,
+          {<<C/utf8>>, Rest, p_advance_index(<<C/utf8>>, Index)}
+  end.
+-endif.
+
+-ifdef(p_charclass).
+-spec p_charclass(string() | binary()) -> parse_fun().
+p_charclass(Class) ->
+    {ok, RE} = re:compile(Class, [unicode, dotall]),
+    fun(Inp, Index) ->
+            case re:run(Inp, RE, [anchored]) of
+                {match, [{0, Length}|_]} ->
+                    {Head, Tail} = erlang:split_binary(Inp, Length),
+                    {Head, Tail, p_advance_index(Head, Index)};
+                _ -> {fail, {expected, {character_class, binary_to_list(Class)}, Index}}
+            end
+    end.
+-endif.
+
+-ifdef(p_regexp).
+-spec p_regexp(binary()) -> parse_fun().
+p_regexp(Regexp) ->
+    {ok, RE} = re:compile(Regexp, [unicode, dotall, anchored]),
+    fun(Inp, Index) ->
+        case re:run(Inp, RE) of
+            {match, [{0, Length}|_]} ->
+                {Head, Tail} = erlang:split_binary(Inp, Length),
+                {Head, Tail, p_advance_index(Head, Index)};
+            _ -> {fail, {expected, {regexp, binary_to_list(Regexp)}, Index}}
+        end
+    end.
+-endif.
+
+-ifdef(line).
+-spec line(index() | term()) -> pos_integer() | undefined.
+line({{line,L},_}) -> L;
+line(_) -> undefined.
+-endif.
+
+-ifdef(column).
+-spec column(index() | term()) -> pos_integer() | undefined.
+column({_,{column,C}}) -> C;
+column(_) -> undefined.
+-endif.
+
+-spec p_advance_index(input() | unicode:charlist() | pos_integer(), index()) -> index().
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) orelse is_binary(MatchedInput)-> % strings
+  lists:foldl(fun p_advance_index/2, Index, unicode:characters_to_list(MatchedInput));
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -> % single characters
+  {{line, Line}, {column, Col}} = Index,
+  case MatchedInput of
+    $\n -> {{line, Line+1}, {column, 1}};
+    _ -> {{line, Line}, {column, Col+1}}
+  end.
diff --git a/inttest/neotoma1/neotoma_src_rt.erl b/inttest/neotoma1/neotoma_src_rt.erl
new file mode 100644
index 0000000..6f7c6ff
--- /dev/null
+++ b/inttest/neotoma1/neotoma_src_rt.erl
@@ -0,0 +1,81 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% rebar: Erlang Build Tools
+%%
+%% Copyright (c) 2015 Luis Rascao (luis.rascao@gmail.com)
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% -------------------------------------------------------------------
+-module(neotoma_src_rt).
+
+-compile(export_all).
+
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("deps/retest/include/retest.hrl").
+
+-define(GENERATED_MODULES,
+        [csv_peg]).
+
+files() ->
+    [{copy, "../../rebar", "rebar"},
+     {copy, "rebar.config", "rebar.config"},
+     {copy, "mock", "deps"},
+     {copy, "src", "src"}].
+
+run(Dir) ->
+    retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
+    ?assertMatch({ok, _}, retest:sh("./rebar compile",
+                                    [{async, false}])),
+
+    ok = check_files_generated(),
+
+    retest_log:log(debug, "Verify cleanup~n", []),
+    ?assertMatch({ok, _}, retest_sh:run("./rebar clean",
+                                        [])),
+    ok = check_files_deleted(),
+    ok.
+
+check_files_generated() ->
+    check(fun filelib:is_regular/1,
+          generated_erl_files()).
+
+check_files_deleted() ->
+    check(fun file_does_not_exist/1,
+          generated_erl_files()).
+
+generated_erl_files() ->
+    add_dir("src", add_ext(?GENERATED_MODULES, ".erl")).
+
+add_ext(Modules, Ext) ->
+    [lists:concat([Module, Ext]) || Module <- Modules].
+
+add_dir(Dir, Files) ->
+    [filename:join(Dir, File) || File <- Files].
+
+file_does_not_exist(F) ->
+    not filelib:is_regular(F).
+
+check(Check, Files) ->
+    lists:foreach(
+      fun(F) ->
+              ?assertMatch({true, _}, {Check(F), F})
+      end,
+      Files).
diff --git a/inttest/neotoma1/rebar.config b/inttest/neotoma1/rebar.config
new file mode 100644
index 0000000..8757da8
--- /dev/null
+++ b/inttest/neotoma1/rebar.config
@@ -0,0 +1,15 @@
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 ft=erlang et
+
+{deps,
+ [
+  %% The dependency below to neotoma is needed for "rebar compile" to
+  %% work, thus for the inttest to work, but the neotoma that is actually
+  %% used in inttest is brought in from the inttest/neotoma1/mock
+  %% subdirectory.
+  {neotoma, ".*"}
+ ]}.
+
+{neotoma_opts, [
+    {module_ext, "_peg"}
+]}.
diff --git a/inttest/neotoma1/src/csv.peg b/inttest/neotoma1/src/csv.peg
new file mode 100644
index 0000000..000c00f
--- /dev/null
+++ b/inttest/neotoma1/src/csv.peg
@@ -0,0 +1,31 @@
+rows <- head:row tail:(crlf row)* / ''
+`
+case Node of
+  [] -> [];
+  [""] -> [];
+  _ ->
+    Head = proplists:get_value(head, Node),
+    Tail = [R || [_,R] <- proplists:get_value(tail, Node)],
+    [Head|Tail]
+end
+`;
+
+row <- head:field tail:(field_sep field)* / ''
+`
+case Node of
+  [] -> [];
+  [""] -> [];
+  _ ->
+    Head = proplists:get_value(head, Node),
+    Tail = [F || [_,F] <- proplists:get_value(tail, Node)],
+    [Head|Tail]
+end
+`;
+field <- quoted_field / (!field_sep !crlf .)* `iolist_to_binary(Node)`;
+quoted_field <- '"' string:('""' / (!'"' .))* '"'
+`
+  String = proplists:get_value(string, Node),
+  re:replace(String, "[\"]{2}", "\"",[global, {return, binary}])
+`;
+field_sep <- ',' ~;
+crlf <- [\r]? [\n] ~;
diff --git a/inttest/neotoma1/src/neotoma1.app.src b/inttest/neotoma1/src/neotoma1.app.src
new file mode 100644
index 0000000..96a50e5
--- /dev/null
+++ b/inttest/neotoma1/src/neotoma1.app.src
@@ -0,0 +1,6 @@
+{application, neotoma1,
+    [{vsn, "1"},
+     {modules, []},
+     {registered, []},
+     {applications, [kernel, stdlib]}]}.
+
diff --git a/inttest/port/port_rt.erl b/inttest/port/port_rt.erl
index 90ecbdc..c910e0e 100644
--- a/inttest/port/port_rt.erl
+++ b/inttest/port/port_rt.erl
@@ -31,13 +31,16 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "c_src", "c_src"},
      {create, "ebin/foo.app", app(foo, [])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     %% wait a bit for new files to have different timestamps
@@ -45,48 +48,76 @@ run(_Dir) ->
     %% test.so is created during first compile
     ?assertEqual(0, filelib:last_modified("priv/test.so")),
     ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
-    TestSo1 = filelib:last_modified("priv/test.so"),
+    TestSo1 = filelib:last_modified("priv/test" ++
+                                    shared_library_file_extension(os:type())),
     ?assert(TestSo1 > 0),
     wait(),
     %% nothing happens during second compile
     ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
-    TestSo2 = filelib:last_modified("priv/test.so"),
-    Test1o2 = filelib:last_modified("c_src/test1.o"),
-    Test2o2 = filelib:last_modified("c_src/test2.o"),
+    TestSo2 = filelib:last_modified("priv/test" ++
+                                    shared_library_file_extension(os:type())),
+    Test1o2 = filelib:last_modified("c_src/test1" ++
+                                    object_file_extension(os:type())),
+    Test2o2 = filelib:last_modified("c_src/test2" ++
+                                    object_file_extension(os:type())),
     ?assertEqual(TestSo1, TestSo2),
     ?assert(TestSo1 >= Test1o2),
     ?assert(TestSo1 >= Test2o2),
     wait(),
     %% when test2.c changes, at least test2.o and test.so are rebuilt
-    ?assertMatch({ok, _}, retest_sh:run("touch c_src/test2.c", [])),
+    ?assertMatch({ok, _}, retest:run({touch, "c_src/test2.c"}, [{dir, "."}])),
     ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
-    TestSo3 = filelib:last_modified("priv/test.so"),
-    Test2o3 = filelib:last_modified("c_src/test2.o"),
+    TestSo3 = filelib:last_modified("priv/test" ++
+                                    shared_library_file_extension(os:type())),
+    Test2o3 = filelib:last_modified("c_src/test2" ++
+                                    object_file_extension(os:type())),
     ?assert(TestSo3 > TestSo2),
     ?assert(Test2o3 > TestSo2),
-    wait(),
-    %% when test2.h changes, at least test2.o and test.so are rebuilt
-    ?assertMatch({ok, _}, retest_sh:run("touch c_src/test2.h", [])),
-    ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
-    TestSo4 = filelib:last_modified("priv/test.so"),
-    Test2o4 = filelib:last_modified("c_src/test2.o"),
-    ?assert(TestSo4 > TestSo3),
-    ?assert(Test2o4 > TestSo3),
-    wait(),
-    %% when test1.h changes, everything is rebuilt
-    ?assertMatch({ok, _}, retest_sh:run("touch c_src/test1.h", [])),
-    ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
-    TestSo5 = filelib:last_modified("priv/test.so"),
-    Test1o5 = filelib:last_modified("c_src/test1.o"),
-    Test2o5 = filelib:last_modified("c_src/test2.o"),
-    ?assert(TestSo5 > TestSo4),
-    ?assert(Test1o5 > TestSo4),
-    ?assert(Test2o5 > TestSo4),
-    ok.
+    %% detecting the a full recompile is needed when changing a .h file is a feature attained
+    %% by using the -MMD gcc flag which sadly is not available in Windows, so this part of the
+    %% test is only executed in Unix
+    case os:type() of
+        {win32, _} -> ok;
+        _ ->
+            wait(),
+            %% when test2.h changes, at least test2.o and test.so are rebuilt
+            ?assertMatch({ok, _},
+                retest:run({touch, "c_src/test2.h"}, [{dir, "."}])),
+            ?assertMatch({ok, _},
+                retest_sh:run("./rebar compile", [])),
+            TestSo4 = filelib:last_modified("priv/test" ++
+                                            shared_library_file_extension(os:type())),
+            Test2o4 = filelib:last_modified("c_src/test2" ++
+                                            object_file_extension(os:type())),
+            ?assert(TestSo4 > TestSo3),
+            ?assert(Test2o4 > TestSo3),
+            wait(),
+            %% when test1.h changes, everything is rebuilt
+            ?assertMatch({ok, _},
+                retest:run({touch, "c_src/test1.h"}, [{dir, "."}])),
+            ?assertMatch({ok, _},
+                retest_sh:run("./rebar compile", [])),
+            TestSo5 = filelib:last_modified("priv/test" ++
+                                            shared_library_file_extension(os:type())),
+            Test1o5 = filelib:last_modified("c_src/test1" ++
+                                            object_file_extension(os:type())),
+            Test2o5 = filelib:last_modified("c_src/test2" ++
+                                            object_file_extension(os:type())),
+            ?assert(TestSo5 > TestSo4),
+            ?assert(Test1o5 > TestSo4),
+            ?assert(Test2o5 > TestSo4),
+            ok
+    end.
 
 wait() ->
     timer:sleep(1000).
 
+object_file_extension({win32, nt}) -> ".o";
+object_file_extension(_) -> ".o".
+
+shared_library_file_extension({win32, nt}) -> ".dll";
+shared_library_file_extension(_) -> ".so".
+
 %%
 %% Generate the contents of a simple .app file
 %%
diff --git a/inttest/port/rebar.config b/inttest/port/rebar.config
index a941218..efab1af 100644
--- a/inttest/port/rebar.config
+++ b/inttest/port/rebar.config
@@ -1 +1,2 @@
-{port_specs, [{"priv/test.so", ["c_src/*.c"]}]}.
+{port_specs, [{"win32", "priv/test.dll", ["c_src/*.c"]},
+              {"priv/test.so", ["c_src/*.c"]}]}.
diff --git a/inttest/port2/c_src/test1.c b/inttest/port2/c_src/test1.c
new file mode 100644
index 0000000..f1c8ef8
--- /dev/null
+++ b/inttest/port2/c_src/test1.c
@@ -0,0 +1,13 @@
+#include "test1.h"
+
+#ifndef TEST1
+#error TEST1 is not defined!
+#endif
+
+#ifndef TEST2
+#error TEST2 is not defined!
+#endif
+
+#ifndef TEST3
+#error TEST3 is not defined!
+#endif
diff --git a/inttest/port2/c_src/test1.h b/inttest/port2/c_src/test1.h
new file mode 100644
index 0000000..e69de29
diff --git a/inttest/port2/port2_rt.erl b/inttest/port2/port2_rt.erl
new file mode 100644
index 0000000..ffe8f23
--- /dev/null
+++ b/inttest/port2/port2_rt.erl
@@ -0,0 +1,75 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% rebar: Erlang Build Tools
+%%
+%% Copyright (c) 2016 Luis Rascao
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% -------------------------------------------------------------------
+
+-module(port2_rt).
+-export([files/0,
+         run/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
+files() ->
+    [
+     {copy, "rebar.config", "rebar.config"},
+     {copy, "c_src", "c_src"},
+     {create, "ebin/foo.app", app(foo, [])}
+    ] ++ inttest_utils:rebar_setup().
+
+run(_Dir) ->
+    %% wait a bit for new files to have different timestamps
+    wait(),
+    %% test.so is created during first compile
+    ?assertEqual(0, filelib:last_modified("priv/test.so")),
+    ?assertMatch({ok, _}, retest_sh:run("./rebar compile",
+                                        [{env, [{"ERL_CFLAGS", "-DTEST3=test3"}]}])),
+    TestSo1 = filelib:last_modified("priv/test" ++
+                                    shared_library_file_extension(os:type())),
+    ?assert(TestSo1 > 0).
+
+wait() ->
+    timer:sleep(1000).
+
+object_file_extension({win32, nt}) -> ".o";
+object_file_extension(_) -> ".o".
+
+shared_library_file_extension({win32, nt}) -> ".dll";
+shared_library_file_extension(_) -> ".so".
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name, Modules) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, Modules},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/port2/rebar.config b/inttest/port2/rebar.config
new file mode 100644
index 0000000..3527ee5
--- /dev/null
+++ b/inttest/port2/rebar.config
@@ -0,0 +1,9 @@
+{port_specs, [
+    {"(darwin|linux|freebsd)", "priv/test.so",
+         ["c_src/*.c"], [
+            {env, [
+                {"CFLAGS", "$CFLAGS -DTEST1=test1"},
+                {"ERL_CFLAGS", "$ERL_CFLAGS -DTEST2=test2"}
+            ]}
+         ]}
+]}.
diff --git a/inttest/profile/profile_rt.erl b/inttest/profile/profile_rt.erl
index b128517..b8a9e09 100644
--- a/inttest/profile/profile_rt.erl
+++ b/inttest/profile/profile_rt.erl
@@ -30,10 +30,12 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [
-     {copy, "../../rebar", "rebar"}
-    ].
+    inttest_utils:rebar_setup().
 
 run(_Dir) ->
     Cmd = "./rebar list-deps",
diff --git a/inttest/proto_gpb/proto_gpb_rt.erl b/inttest/proto_gpb/proto_gpb_rt.erl
index 8a7cacf..307aca0 100644
--- a/inttest/proto_gpb/proto_gpb_rt.erl
+++ b/inttest/proto_gpb/proto_gpb_rt.erl
@@ -30,7 +30,6 @@
 
 -include_lib("eunit/include/eunit.hrl").
 -include_lib("kernel/include/file.hrl").
--include_lib("deps/retest/include/retest.hrl").
 
 -define(MODULES,
         [foo,
@@ -51,9 +50,12 @@
          "c/test4.proto",
          "c/d/test5.proto"]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "rebar2.config", "rebar2.config"},
      {copy, "rebar.bad.config", "rebar.bad.config"},
@@ -63,7 +65,7 @@ files() ->
      {copy, "proto.bad", "proto.bad"},
      {copy, "mock", "deps"},
      {create, "ebin/foo.app", app(foo, ?MODULES ++ ?GENERATED_MODULES)}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     % perform test obtaining the .proto files from src dir
@@ -99,7 +101,7 @@ run_from_dir(success_expected, ProtoDir, ConfigFile) ->
     %% the .hrl file was generated before foo was compiled.
     ok = check_beams_generated(),
 
-    ?DEBUG("Verifying recompilation~n", []),
+    retest_log:log(debug, "Verifying recompilation~n", []),
     TestErl = hd(generated_erl_files()),
     TestProto = hd(source_proto_files(ProtoDir)),
     make_proto_newer_than_erl(TestProto, TestErl),
@@ -111,7 +113,7 @@ run_from_dir(success_expected, ProtoDir, ConfigFile) ->
     TestMTime2 = read_mtime(TestErl),
     ?assert(TestMTime2 > TestMTime1),
 
-    ?DEBUG("Verifying recompilation with no changes~n", []),
+    retest_log:log(debug, "Verifying recompilation with no changes~n", []),
     TestMTime3 = read_mtime(TestErl),
     ?assertMatch({ok, _}, retest_sh:run("./rebar --config "
                                         ++ ConfigFile
@@ -120,7 +122,7 @@ run_from_dir(success_expected, ProtoDir, ConfigFile) ->
     TestMTime4 = read_mtime(TestErl),
     ?assert(TestMTime3 =:= TestMTime4),
 
-    ?DEBUG("Verify cleanup~n", []),
+    retest_log:log(debug, "Verify cleanup~n", []),
     ?assertMatch({ok, _}, retest_sh:run("./rebar --config "
                                         ++ ConfigFile
                                         ++ " clean",
diff --git a/inttest/proto_protobuffs/proto_protobuffs_rt.erl b/inttest/proto_protobuffs/proto_protobuffs_rt.erl
index 1bb7b5e..ee4c294 100644
--- a/inttest/proto_protobuffs/proto_protobuffs_rt.erl
+++ b/inttest/proto_protobuffs/proto_protobuffs_rt.erl
@@ -42,15 +42,18 @@
          "foo_sup.beam",
          "test_pb.beam"]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "include", "include"},
      {copy, "src", "src"},
      {copy, "mock", "deps"},
      {create, "ebin/foo.app", app(foo, ?MODULES)}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ?assertMatch({ok, _}, retest_sh:run("./rebar clean", [])),
diff --git a/inttest/rebar3_deps1/a.erl b/inttest/rebar3_deps1/a.erl
new file mode 100644
index 0000000..835522a
--- /dev/null
+++ b/inttest/rebar3_deps1/a.erl
@@ -0,0 +1,8 @@
+-module(a).
+
+-compile(export_all).
+
+-include_lib("b/include/b.hrl").
+
+hello() ->
+    io:format("~s\n", [?HELLO]).
diff --git a/inttest/rebar3_deps1/a.rebar.config b/inttest/rebar3_deps1/a.rebar.config
new file mode 100644
index 0000000..de3abe3
--- /dev/null
+++ b/inttest/rebar3_deps1/a.rebar.config
@@ -0,0 +1,4 @@
+{deps, [
+	{b, {git, "../repo/b"}},
+	{c, {git, "../repo/c"}, [raw]}
+]}.
diff --git a/inttest/rebar3_deps1/b.hrl b/inttest/rebar3_deps1/b.hrl
new file mode 100644
index 0000000..25dfeda
--- /dev/null
+++ b/inttest/rebar3_deps1/b.hrl
@@ -0,0 +1 @@
+-define(HELLO, "Hi From B").
diff --git a/inttest/rebar3_deps1/c.txt b/inttest/rebar3_deps1/c.txt
new file mode 100644
index 0000000..5adcd3d
--- /dev/null
+++ b/inttest/rebar3_deps1/c.txt
@@ -0,0 +1 @@
+This is a text file.
diff --git a/inttest/rebar3_deps1/rebar3_deps1_rt.erl b/inttest/rebar3_deps1/rebar3_deps1_rt.erl
new file mode 100644
index 0000000..e84b6ba
--- /dev/null
+++ b/inttest/rebar3_deps1/rebar3_deps1_rt.erl
@@ -0,0 +1,63 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(rebar3_deps1_rt).
+
+-compile(export_all).
+
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
+%% Test deps with rebar3-type dependencies (that is, dependencies without Regexes)
+%% Example: {git, {appname, "git://something/something", {branch, master}}}
+files() ->
+    [
+     %% A application
+     {create, "ebin/a.app", app(a, [a])},
+     {copy, "a.rebar.config", "rebar.config"},
+     {copy, "a.erl", "src/a.erl"},
+
+     %% B application
+     {create, "repo/b/ebin/b.app", app(b, [])},
+     {copy, "b.hrl", "repo/b/include/b.hrl"},
+
+     {copy, "c.txt", "repo/c/c.txt"}
+
+    ] ++ inttest_utils:rebar_setup().
+
+apply_cmds([], _Params) ->
+    ok;
+apply_cmds([Cmd | Rest], Params) ->
+    io:format("Running: ~s (~p)\n", [Cmd, Params]),
+    {ok, _} = retest_sh:run(Cmd, Params),
+    apply_cmds(Rest, Params).
+
+run(_Dir) ->
+    %% Initialize the dep app as git repos so that dependencies pull
+    %% properly
+    GitCmds = ["git init",
+               "git add -A",
+               "git config user.email 'tdeps@example.com'",
+               "git config user.name 'tdeps'",
+               "git commit -a -m \"Initial Commit\""],
+    apply_cmds(GitCmds, [{dir, "repo/b"}]),
+    apply_cmds(GitCmds, [{dir, "repo/c"}]),
+
+    {ok, _} = retest_sh:run("./rebar get-deps", []),
+    {ok, _} = retest_sh:run("./rebar compile", []),
+
+    true = filelib:is_regular("ebin/a.beam"),
+    true = filelib:is_regular("deps/c/c.txt"),
+    ok.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name, Modules) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, Modules},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/require_vsn/require_vsn_rt.erl b/inttest/require_vsn/require_vsn_rt.erl
index 0b947c5..8ff87f7 100644
--- a/inttest/require_vsn/require_vsn_rt.erl
+++ b/inttest/require_vsn/require_vsn_rt.erl
@@ -28,12 +28,15 @@
 -export([files/0,
          run/1]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {create, "ebin/require_vsn.app", app(require_vsn, [])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     SharedExpected = "==> require_vsn_rt \\(compile\\)",
diff --git a/inttest/rgen1/retest.config b/inttest/rgen1/retest.config
index b569f14..244096d 100644
--- a/inttest/rgen1/retest.config
+++ b/inttest/rgen1/retest.config
@@ -1 +1 @@
-{timeout, 120000}.
+{timeout, 240000}.
diff --git a/inttest/rgen1/rgen1_rt.erl b/inttest/rgen1/rgen1_rt.erl
index 1bf36c2..5847f4a 100644
--- a/inttest/rgen1/rgen1_rt.erl
+++ b/inttest/rgen1/rgen1_rt.erl
@@ -6,13 +6,16 @@
 
 %% Exercise release generation w/ templating
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
      {copy, "reltool.config"},
      {copy, "test.config"},
-     {copy, "vars.config"},
-     {copy, "../../rebar"}
-    ].
+     {copy, "vars.config"}
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     {ok, _} = retest_sh:run("./rebar -v generate", []),
diff --git a/inttest/t_custom_config/t_custom_config_rt.erl b/inttest/t_custom_config/t_custom_config_rt.erl
index a373b32..1f21927 100644
--- a/inttest/t_custom_config/t_custom_config_rt.erl
+++ b/inttest/t_custom_config/t_custom_config_rt.erl
@@ -6,10 +6,15 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
-    [{copy, "../../rebar", "rebar"},
+    [
      {copy, "custom.config", "custom.config"},
-     {create, "ebin/custom_config.app", app(custom_config, [custom_config])}].
+     {create, "ebin/custom_config.app", app(custom_config, [custom_config])}
+    ] ++ inttest_utils:rebar_setup().
 
 run(Dir) ->
     retest_log:log(debug, "Running in Dir: ~s~n", [Dir]),
diff --git a/inttest/tdeps1/tdeps1_rt.erl b/inttest/tdeps1/tdeps1_rt.erl
index 3591ec0..849403b 100644
--- a/inttest/tdeps1/tdeps1_rt.erl
+++ b/inttest/tdeps1/tdeps1_rt.erl
@@ -4,16 +4,18 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 %% Exercise transitive dependencies
 %% A -> B -> C, where A includes a .hrl from B which includes .hrl from C
-
 files() ->
     [
      %% A application
      {create, "ebin/a.app", app(a, [a])},
      {copy, "a.rebar.config", "rebar.config"},
      {copy, "a.erl", "src/a.erl"},
-     {copy, "../../rebar", "rebar"},
 
      %% B application
      {create, "repo/b/ebin/b.app", app(b, [])},
@@ -23,7 +25,7 @@ files() ->
      %% C application
      {create, "repo/c/ebin/c.app", app(c, [])},
      {copy, "c.hrl", "repo/c/include/c.hrl"}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 apply_cmds([], _Params) ->
     ok;
@@ -39,7 +41,7 @@ run(_Dir) ->
                "git add -A",
                "git config user.email 'tdeps@example.com'",
                "git config user.name 'tdeps'",
-               "git commit -a -m 'Initial Commit'"],
+               "git commit -a -m \"Initial Commit\""],
     apply_cmds(GitCmds, [{dir, "repo/b"}]),
     apply_cmds(GitCmds, [{dir, "repo/c"}]),
 
diff --git a/inttest/tdeps2/tdeps2_rt.erl b/inttest/tdeps2/tdeps2_rt.erl
index 97a24ce..a5665ad 100644
--- a/inttest/tdeps2/tdeps2_rt.erl
+++ b/inttest/tdeps2/tdeps2_rt.erl
@@ -4,10 +4,13 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 %% Exercise transitive dependencies where there are multiple files
 %% depending on the same set of deps
 %% [A1, A2] -> B -> C ; A1 and A2 includes B.hrl which includes C.hrl
-
 files() ->
     [
      %% A1 application
@@ -21,7 +24,6 @@ files() ->
      {template, "a.erl", "apps/a2/src/a2.erl", dict:from_list([{module, a2}])},
 
      {copy, "root.rebar.config", "rebar.config"},
-     {copy, "../../rebar", "rebar"},
 
      %% B application
      {create, "repo/b/ebin/b.app", app(b, [])},
@@ -31,7 +33,7 @@ files() ->
      %% C application
      {create, "repo/c/ebin/c.app", app(c, [])},
      {copy, "c.hrl", "repo/c/include/c.hrl"}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 apply_cmds([], _Params) ->
     ok;
@@ -47,7 +49,7 @@ run(_Dir) ->
                "git add -A",
                "git config user.email 'tdeps@example.com'",
                "git config user.name 'tdeps'",
-               "git commit -a -m 'Initial Commit'"],
+               "git commit -a -m \"Initial Commit\""],
     ok = apply_cmds(GitCmds, [{dir, "repo/b"}]),
     ok = apply_cmds(GitCmds, [{dir, "repo/c"}]),
 
diff --git a/inttest/tdeps3/tdeps3_rt.erl b/inttest/tdeps3/tdeps3_rt.erl
index f56b3ca..bc47772 100644
--- a/inttest/tdeps3/tdeps3_rt.erl
+++ b/inttest/tdeps3/tdeps3_rt.erl
@@ -4,12 +4,15 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 %% Exercise transitive dependencies where there are multiple files
 %% depending on the same set of deps as well as lib_dir directives
 %% A -> B -> C -> D -> E
 %%      |--> G(via lib_dir)
 %% |--> F -> D -> E
-
 files() ->
     [
      %% A1 application
@@ -17,7 +20,6 @@ files() ->
      {template, "a.erl", "src/a.erl", dict:from_list([{module, a}, {dep, b}])},
 
      {copy, "a.rebar.config", "rebar.config"},
-     {copy, "../../rebar", "rebar"},
 
      %% B application
      {create, "repo/b/ebin/b.app", app(b, [b])},
@@ -52,7 +54,7 @@ files() ->
      {create, "repo/b/apps/g/ebin/g.app", app(g, [])},
      {copy, "e.hrl", "repo/b/apps/g/include/g.hrl"}
 
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 apply_cmds([], _Params) ->
     ok;
@@ -68,7 +70,7 @@ run(_Dir) ->
                "git add -A",
                "git config user.email 'tdeps@example.com'",
                "git config user.name 'tdeps'",
-               "git commit -a -m 'Initial Commit'"],
+               "git commit -a -m \"Initial Commit\""],
     ok = apply_cmds(GitCmds, [{dir, "repo/b"}]),
     ok = apply_cmds(GitCmds, [{dir, "repo/c"}]),
     ok = apply_cmds(GitCmds, [{dir, "repo/d"}]),
diff --git a/inttest/tdeps_prefer/a.erl b/inttest/tdeps_prefer/a.erl
new file mode 100644
index 0000000..bf413a6
--- /dev/null
+++ b/inttest/tdeps_prefer/a.erl
@@ -0,0 +1,4 @@
+-module({{module}}).
+
+-include_lib("b/include/b.hrl").
+-include_lib("c/include/c.hrl").
diff --git a/inttest/tdeps_prefer/a.rebar.config b/inttest/tdeps_prefer/a.rebar.config
new file mode 100644
index 0000000..41fe9bc
--- /dev/null
+++ b/inttest/tdeps_prefer/a.rebar.config
@@ -0,0 +1,4 @@
+{deps, [
+	{c, "1", {git, "../repo/c"}},
+	{b, "1", {git, "../repo/b"}}
+]}.
diff --git a/inttest/tdeps_prefer/b.hrl b/inttest/tdeps_prefer/b.hrl
new file mode 100644
index 0000000..9f02fab
--- /dev/null
+++ b/inttest/tdeps_prefer/b.hrl
@@ -0,0 +1 @@
+-define(HELLO, hello).
diff --git a/inttest/tdeps_prefer/c.hrl b/inttest/tdeps_prefer/c.hrl
new file mode 100644
index 0000000..152a99f
--- /dev/null
+++ b/inttest/tdeps_prefer/c.hrl
@@ -0,0 +1 @@
+-define(WORLD, world).
diff --git a/inttest/tdeps_prefer/root.rebar.config b/inttest/tdeps_prefer/root.rebar.config
new file mode 100644
index 0000000..d1c3793
--- /dev/null
+++ b/inttest/tdeps_prefer/root.rebar.config
@@ -0,0 +1 @@
+{sub_dirs, ["apps/a"]}.
diff --git a/inttest/tdeps_prefer/tdeps_prefer_rt.erl b/inttest/tdeps_prefer/tdeps_prefer_rt.erl
new file mode 100644
index 0000000..94c9b8f
--- /dev/null
+++ b/inttest/tdeps_prefer/tdeps_prefer_rt.erl
@@ -0,0 +1,68 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(tdeps_prefer_rt).
+
+-compile(export_all).
+
+setup([Target]) ->
+    retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+    ok.
+
+%% Test REBAR_DEPS_FORCE_LIB
+%% A -> [B, C]
+%% where B should be found globally and C should be found locally
+files() ->
+    [
+    %% A application
+    {create, "apps/a/ebin/a.app", app(a, [a])},
+    {copy, "a.rebar.config", "apps/a/rebar.config"},
+    {template, "a.erl", "apps/a/src/a.erl", dict:from_list([{module, a}])},
+
+    %% B application
+    {create, "libs/b-1/ebin/b.app", app(b, [])},
+    {copy, "b.hrl", "libs/b-1/include/b.hrl"},
+
+    %% C application
+    {create, "repo/c/ebin/c.app", app(c, [])},
+    {copy, "c.hrl", "repo/c/include/c.hrl"},
+
+    {copy, "root.rebar.config", "rebar.config"}
+    ] ++ inttest_utils:rebar_setup().
+
+apply_cmds([], _Params) ->
+    ok;
+apply_cmds([Cmd | Rest], Params) ->
+    io:format("Running: ~s (~p)\n", [Cmd, Params]),
+    {ok, _} = retest_sh:run(Cmd, Params),
+    apply_cmds(Rest, Params).
+
+run(Dir) ->
+    %% Initialize the c apps as git repos so that dependencies pull
+    %% properly
+    GitCmds = ["git init",
+               "git add -A",
+               "git config user.email 'tdeps@example.com'",
+               "git config user.name 'tdeps'",
+               "git commit -a -m \"Initial Commit\""],
+    ErlLibs = filename:join(Dir, "libs"),
+    ok = apply_cmds(GitCmds, [{dir, "repo/c"}]),
+    Env = [
+        {"REBAR_DEPS_PREFER_LIBS", "1"},
+        {"ERL_LIBS", ErlLibs}
+    ],
+
+    {ok, _} = retest_sh:run("./rebar -v get-deps", [{env, Env}]),
+    {ok, _} = retest_sh:run("./rebar -v compile", [{env, Env}]),
+    ok.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name, Modules) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, "1"},
+            {modules, Modules},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
diff --git a/inttest/tdeps_update/tdeps_update_rt.erl b/inttest/tdeps_update/tdeps_update_rt.erl
index c53e253..b4919c5 100644
--- a/inttest/tdeps_update/tdeps_update_rt.erl
+++ b/inttest/tdeps_update/tdeps_update_rt.erl
@@ -4,6 +4,10 @@
 
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 %% Exercises update deps, with recursive dependency updates.
 %% Initially:
 %%     A(v0.5) -> B(v0.2.3) -> C(v1.0)
@@ -25,7 +29,6 @@ files() ->
      {template, "a.erl", "apps/a1/src/a1.erl", dict:from_list([{module, a1}])},
 
      {copy, "root.rebar.config", "rebar.config"},
-     {copy, "../../rebar", "rebar"},
 
      %% B application
      {create, "repo/b/ebin/b.app", app(b, [], "0.2.3")},
@@ -64,57 +67,62 @@ files() ->
      {copy, "c.rebar.config", "c.rebar.config"},
      {copy, "c2.rebar.config", "c2.rebar.config"},
      {copy, "c3.rebar.config", "c3.rebar.config"}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 apply_cmds([], _Params) ->
     ok;
 apply_cmds([Cmd | Rest], Params) ->
-    io:format("Running: ~s (~p)\n", [Cmd, Params]),
-    {ok, _} = retest_sh:run(Cmd, Params),
+    io:format("Running: ~p (~p)\n", [Cmd, Params]),
+    {ok, _} = retest:run(Cmd, Params),
     apply_cmds(Rest, Params).
 
-run(_Dir) ->
+run(Dir) ->
     %% Initialize the b/c/d apps as git repos so that dependencies pull
     %% properly
     GitCmds = ["git init",
                "git add -A",
-               "git config user.email 'tdeps@example.com'",
-               "git config user.name 'tdeps'",
-               "git commit -a -m 'Initial Commit'"],
+               "git config user.email \"tdeps@example.com\"",
+               "git config user.name \"tdeps\"",
+               "git commit -a -m \"Initial Commit\""],
     BCmds = ["git tag 0.2.3",
-             "cp ../../b2.rebar.config rebar.config",
-             "cp ../../b2.app ebin/b.app",
-             "git commit -a -m 'update to 0.2.4'",
+             {copy, "../../b2.rebar.config", "rebar.config"},
+             {copy, "../../b2.app", "ebin/b.app"},
+             {touch, "ebin/b.app"},
+             "git commit -a -m \"update to 0.2.4\"",
              "git tag 0.2.4",
-             "cp ../../b3.rebar.config rebar.config",
-             "cp ../../b3.app ebin/b.app",
-             "git commit -a -m 'update to 0.2.5'",
+             {copy, "../../b3.rebar.config", "rebar.config"},
+             {copy, "../../b3.app", "ebin/b.app"},
+             {touch, "ebin/b.app"},
+             "git commit -a -m \"update to 0.2.5\"",
              "git tag 0.2.5",
-             "cp ../../b4.rebar.config rebar.config",
-             "cp ../../b4.app ebin/b.app",
-             "git commit -a -m 'update to 0.2.6'",
+             {copy, "../../b4.rebar.config", "rebar.config"},
+             {copy, "../../b4.app", "ebin/b.app"},
+             {touch, "ebin/b.app"},
+             "git commit -a -m \"update to 0.2.6\"",
              "git tag 0.2.6"],
              %"git checkout 0.2.3"],
     CCmds = ["git tag 1.0",
-             "cp ../../c2.hrl include/c.hrl",
-             "cp ../../c2.app ebin/c.app",
-             "cp ../../c.rebar.config rebar.config",
+             {copy, "../../c2.hrl", "include/c.hrl"},
+             {copy, "../../c2.app", "ebin/c.app"},
+             {copy, "../../c.rebar.config", "rebar.config"},
              "git add rebar.config",
-             "git commit -a -m 'update to 1.1'",
+             "git commit -a -m \"update to 1.1\"",
              "git tag 1.1",
-             "cp ../../c3.app ebin/c.app",
-             "cp ../../c2.rebar.config rebar.config",
-             "git commit -a -m 'update to 1.2'",
+             {copy, "../../c3.app", "ebin/c.app"},
+             {copy, "../../c2.rebar.config", "rebar.config"},
+             "git commit -a -m \"update to 1.2\"",
              "git tag 1.2",
-             "cp ../../c4.app ebin/c.app",
-             "cp ../../c3.rebar.config rebar.config",
-             "git commit -a -m 'update to 1.3'",
+             {copy, "../../c4.app", "ebin/c.app"},
+             {copy, "../../c3.rebar.config", "rebar.config"},
+             {touch, "rebar.config"},
+             "git commit -a -m \"update to 1.3\"",
              "git tag 1.3"],
              %"git checkout 1.0"],
     DCmds = ["git tag 0.7"],
     ECmds = ["git tag 2.0",
-             "cp ../../e2.app ebin/e.app",
-             "git commit -a -m 'update to 2.1'",
+             {copy, "../../e2.app", "ebin/e.app"},
+             {touch, "ebin/e.app"},
+             "git commit -a -m \"update to 2.1\"",
              "git tag 2.1"],
     FCmds = ["git tag 0.1"],
 
@@ -126,13 +134,16 @@ run(_Dir) ->
 
     {ok, _} = retest_sh:run("./rebar -v get-deps", []),
     {ok, _} = retest_sh:run("./rebar -v compile", []),
-    os:cmd("cp a2.rebar.config apps/a1/rebar.config"),
+    retest:run({copy, "a2.rebar.config", "apps/a1/rebar.config"},
+               [{dir, Dir}]),
     {ok, _} = retest_sh:run("./rebar -v update-deps", []),
     {ok, _} = retest_sh:run("./rebar -v compile", []),
-    os:cmd("cp a3.rebar.config apps/a1/rebar.config"),
+    retest:run({copy, "a3.rebar.config", "apps/a1/rebar.config"},
+               [{dir, Dir}]),
     {ok, _} = retest_sh:run("./rebar -v update-deps", []),
     {ok, _} = retest_sh:run("./rebar -v compile", []),
-    os:cmd("cp a4.rebar.config apps/a1/rebar.config"),
+    retest:run({copy, "a4.rebar.config", "apps/a1/rebar.config"},
+               [{dir, Dir}]),
     {ok, _} = retest_sh:run("./rebar -v update-deps", []),
     {ok, _} = retest_sh:run("./rebar -v compile", []),
     ok.
diff --git a/inttest/thooks/thooks_rt.erl b/inttest/thooks/thooks_rt.erl
index 3cca6bb..f1e7fa4 100644
--- a/inttest/thooks/thooks_rt.erl
+++ b/inttest/thooks/thooks_rt.erl
@@ -5,14 +5,17 @@
 -include_lib("eunit/include/eunit.hrl").
 -compile(export_all).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
      %% dummy lfe files
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "fish.erl", "src/fish.erl"},
      {create, "ebin/fish.app", app(fish, [fish])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ?assertMatch({ok, _}, retest_sh:run("./rebar -v clean compile", [])),
@@ -27,7 +30,13 @@ ensure_command_ran_only_once(Command) ->
     ?assert(filelib:is_regular(File)),
     %% ensure that this command only ran once (not for each module)
     {ok, Content} = file:read_file(File),
-    ?assertEqual(Command ++ "\n", binary_to_list(Content)).
+    %% echo behaves differently in windows and unix
+    case os:type() of
+        {win32, nt} ->
+            ?assertEqual(Command ++ " \r\n", binary_to_list(Content));
+        _ ->
+            ?assertEqual(Command ++ "\n", binary_to_list(Content))
+    end.
 
 %%
 %% Generate the contents of a simple .app file
diff --git a/inttest/tplugins/tplugins_rt.erl b/inttest/tplugins/tplugins_rt.erl
index 01d296e..d36afdd 100644
--- a/inttest/tplugins/tplugins_rt.erl
+++ b/inttest/tplugins/tplugins_rt.erl
@@ -8,9 +8,12 @@
 -define(COMPILE_ERROR,
         "ERROR: Plugin bad_plugin contains compilation errors:").
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "bad.config", "bad.config"},
      {copy, "fish.erl", "src/fish.erl"},
@@ -18,7 +21,7 @@ files() ->
      {copy, "bad_plugin.erl", "bad_plugins/bad_plugin.erl"},
      {create, "fwibble.test", <<"fwibble">>},
      {create, "ebin/fish.app", app(fish, [fish])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     ?assertMatch({ok, _}, retest_sh:run("./rebar fwibble -v", [])),
diff --git a/inttest/vsn_cache/main.erl b/inttest/vsn_cache/main.erl
new file mode 100644
index 0000000..67b6465
--- /dev/null
+++ b/inttest/vsn_cache/main.erl
@@ -0,0 +1,13 @@
+-module(main).
+-behaviour(application).
+     
+-export([start/0,start/1,start/2,stop/1]).
+
+start() ->
+	start(permanent).
+start(_Restart) ->
+	ok.
+start(_Type,_Args) ->
+	ok.
+stop(_State) ->
+	ok.
diff --git a/inttest/vsn_cache/vsn_cache_rt.erl b/inttest/vsn_cache/vsn_cache_rt.erl
new file mode 100644
index 0000000..b482888
--- /dev/null
+++ b/inttest/vsn_cache/vsn_cache_rt.erl
@@ -0,0 +1,90 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(vsn_cache_rt).
+
+-compile(export_all).
+
+setup([Target]) ->
+    retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+    ok.
+
+files() ->
+    [
+    %% Cache save check
+    {create, "save/src/save.app.src", app(save, [main])},
+    {create, "save/vsn_cache_file", ""},
+    {copy, "main.erl", "save/src/main.erl"},
+
+    %% Cache load check
+    {create, "load/src/load.app.src", app(load, [main])},
+    {copy, "main.erl", "load/src/main.erl"}
+    ] ++ inttest_utils:rebar_setup().
+
+apply_cmds([], _Params) ->
+    ok;
+apply_cmds([Cmd | Rest], Params) ->
+    io:format("Running: ~s (~p)\n", [Cmd, Params]),
+    {ok, _} = retest_sh:run(Cmd, Params),
+    apply_cmds(Rest, Params).
+
+run_save(Dir) ->
+    GitCmds = ["git init",
+               "git add -A",
+               "git config user.email 'vsn_cache@example.com'",
+               "git config user.name 'vsn_cache'",
+               "git commit -a -m \"Initial Commit\""],
+    AppDir = filename:join(Dir, "save"),
+    EbinDir = filename:join(AppDir, "ebin"),
+    AppFile = filename:join(EbinDir, "save.app"),
+    VsnCacheFile = filename:join(AppDir, "vsn_cache_file"),
+    Env = [{"REBAR_VSN_CACHE_FILE", VsnCacheFile}],
+
+    %% Initialize test git repository 
+    ok = apply_cmds(GitCmds, [{dir, AppDir}]),
+    %% Compile test project with vsn cache enabled
+    {ok, _} = retest_sh:run("../rebar -v compile", [{env, Env}, {dir, AppDir}]),
+    %% Vsn cache file has an entry
+    {ok, [{{git, AppDir}, Hash}]} = file:consult(VsnCacheFile),
+    %% This vsn entry must coincide with entry from ebin/save.app
+    {ok, [{application, save, PropList}]} = file:consult(AppFile),
+    Hash = proplists:get_value(vsn, PropList),
+    ok.
+
+run_load(Dir) ->
+    AppDir = filename:join(Dir, "load"),
+    EbinDir = filename:join(AppDir, "ebin"),
+    AppFile = filename:join(EbinDir, "load.app"),
+    VsnCacheFile = filename:join(AppDir, "vsn_cache_file"),
+    Hash = "deadbeef",
+    CacheEntries = [{{git, AppDir}, Hash}],
+    Env = [{"REBAR_VSN_CACHE_FILE", VsnCacheFile}],
+
+    %% Initialize dummy vsn cache file
+    vsn_cache_file(VsnCacheFile, CacheEntries),
+    %% Compile test project with vsn cache enabled
+    {ok, _} = retest_sh:run("../rebar -v compile", [{env, Env}, {dir, AppDir}]),
+    %% This vsn entry in cache file must coincide with entry in ebin/load.app
+    {ok, [{application, load, PropList}]} = file:consult(AppFile),
+    Hash = proplists:get_value(vsn, PropList),
+    ok.
+
+run(Dir) ->
+    run_save(Dir),
+    run_load(Dir),
+    ok.
+
+%%
+%% Generate the contents of a simple .app file
+%%
+app(Name, Modules) ->
+    App = {application, Name,
+           [{description, atom_to_list(Name)},
+            {vsn, git},
+            {modules, Modules},
+            {registered, []},
+            {applications, [kernel, stdlib]}]},
+    io_lib:format("~p.\n", [App]).
+
+vsn_cache_file(Name, Entries) ->
+    file:write_file(Name,
+        [io_lib:format("~p.~n", [X]) || X <- Entries]).
diff --git a/inttest/xref_behavior/xref_behavior_rt.erl b/inttest/xref_behavior/xref_behavior_rt.erl
index 8536710..f6d5ff8 100644
--- a/inttest/xref_behavior/xref_behavior_rt.erl
+++ b/inttest/xref_behavior/xref_behavior_rt.erl
@@ -2,16 +2,19 @@
 
 -export([files/0, run/1]).
 
+setup([Target]) ->
+  retest_utils:load_module(filename:join(Target, "inttest_utils.erl")),
+  ok.
+
 files() ->
     [
-     {copy, "../../rebar", "rebar"},
      {copy, "rebar.config", "rebar.config"},
      {copy, "xref_behavior.erl", "src/xref_behavior.erl"},
      {copy, "gen_xref_behavior.erl", "src/gen_xref_behavior.erl"},
      {create, "ebin/xref_behavior.app", app(xref_behavior,
                                             [xref_behavior,
                                              gen_xref_behavior])}
-    ].
+    ] ++ inttest_utils:rebar_setup().
 
 run(_Dir) ->
     {ok, _} = retest_sh:run("./rebar compile", []),
diff --git a/priv/templates/simplenode.windows.runner.cmd b/priv/templates/simplenode.windows.runner.cmd
index d71a8c7..1e3a3f3 100644
--- a/priv/templates/simplenode.windows.runner.cmd
+++ b/priv/templates/simplenode.windows.runner.cmd
@@ -17,8 +17,18 @@
     @call :set_trim release_version %%J
 )
 
-@set vm_args=%releases_dir%\%release_version%\vm.args
-@set sys_config=%releases_dir%\%release_version%\sys.config
+@if exist "%releases_dir%\%release_version%\vm.args" (
+    @set vm_args="%releases_dir%\%release_version%\vm.args"
+) else (
+    @set vm_args="%node_root%\etc\vm.args"
+)
+
+@if exist "%releases_dir%\%release_version%\sys.config" (
+    @set sys_config="%releases_dir%\%release_version%\sys.config"
+) else (
+    @set sys_config="%node_root%\etc\app.config"
+)
+
 @set node_boot_script=%releases_dir%\%release_version%\%node_name%
 @set clean_boot_script=%releases_dir%\%release_version%\start_clean
 
diff --git a/rebar.config.sample b/rebar.config.sample
index 916e47c..224c85c 100644
--- a/rebar.config.sample
+++ b/rebar.config.sample
@@ -148,6 +148,10 @@
 %% Option to use short names (i.e., -sname test) when starting ct
 {ct_use_short_names, true}.
 
+%% Recursively search for .spec files from the test dir, default
+%% is false (ie. the search will be from the current working directory)
+{ct_search_specs_from_test_dir, true}.
+
 %% == QuickCheck ==
 
 %% If qc_mod is unspecified, rebar tries to detect Triq or EQC
diff --git a/rebar.config.script b/rebar.config.script
index 6735645..eacd510 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -1,7 +1,8 @@
 %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
 %% ex: ts=4 sw=4 ft=erlang et
 
-ExtraDeps = [{retest, ".*", {git, "git://github.com/dizzyd/retest.git"}}],
+ExtraDeps = [{retest, ".*", {git, "git://github.com/rebar/retest.git",
+                             {tag, "1.1.0"}}}],
 
 case os:getenv("REBAR_EXTRA_DEPS") of
     false ->
diff --git a/src/rebar.erl b/src/rebar.erl
index dcfb353..5a809d2 100644
--- a/src/rebar.erl
+++ b/src/rebar.erl
@@ -143,7 +143,7 @@ init_config({Options, _NonOptArgs}) ->
     %% Keep track of how many operations we do, so we can detect bad commands
     BaseConfig1 = rebar_config:set_xconf(BaseConfig, operations, 0),
     %% Initialize vsn cache
-    rebar_config:set_xconf(BaseConfig1, vsn_cache, dict:new()).
+    rebar_utils:init_vsn_cache(BaseConfig1).
 
 init_config1(BaseConfig) ->
     %% Determine the location of the rebar executable; important for pulling
@@ -284,7 +284,12 @@ help() ->
                       {"freebsd", compile, "c_src/freebsd_tweaks.sh"},
                       {eunit, "touch file2.out"},
                       {compile, "touch postcompile.out"}]}
-       ]).
+       ]),
+    ?CONSOLE(
+       "Environment variables:~n"
+       "  REBAR_DEPS_PREFER_LIBS to look for dependecies in system libs prior fetching.~n"
+       "  REBAR_VSN_CACHE_FILE to load vsn cache from and save to specified file.~n"
+       "~n", []).
 
 %%
 %% Parse command line arguments using getopt and also filtering out any
@@ -501,7 +506,9 @@ option_spec_list() ->
      {profile,  $p, "profile",  undefined,
       "Profile this run of rebar. Via profiler= you can optionally select "
       "either fprof (default) or eflame. The result can be found in "
-      "fprof.analysis or eflame.svg."},
+      "fprof.analysis or eflame.svg. Additionally, in fprof mode, if "
+      "erlgrind can be found in $PATH, a Cachegrind file (fprof.cgrind) "
+      "will be generated as well."},
      {keep_going, $k, "keep-going", undefined,
       "Keep running after a command fails"},
      {recursive, $r, "recursive", boolean,
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index 0650430..6cc8d38 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -106,7 +106,7 @@ process_commands([Command | Rest], ParentConfig) ->
                                                       ParentConfig2),
             %% Wipe out vsn cache to avoid invalid hits when
             %% dependencies are updated
-            rebar_config:set_xconf(ParentConfig3, vsn_cache, dict:new())
+            rebar_utils:init_vsn_cache(ParentConfig3)
         catch
             throw:rebar_abort ->
                 case rebar_config:get_xconf(ParentConfig1, keep_going, false) of
diff --git a/src/rebar_ct.erl b/src/rebar_ct.erl
index 022dfc4..b27f661 100644
--- a/src/rebar_ct.erl
+++ b/src/rebar_ct.erl
@@ -66,6 +66,7 @@ info(help, ct) ->
        "  ~p~n"
        "  ~p~n"
        "  ~p~n"
+       "  ~p~n"
        "Valid command line options:~n"
        "  suites=Suite1,Suite2,...,SuiteN~n"
        "      - run Suite1_SUITE, Suite2_SUITE, ..., SuiteN_SUITE~n"
@@ -81,7 +82,8 @@ info(help, ct) ->
         {ct_dir, "itest"},
         {ct_log_dir, "test/logs"},
         {ct_extra_params, "-boot start_sasl -s myapp"},
-        {ct_use_short_names, true}
+        {ct_use_short_names, true},
+        {ct_search_specs_from_test_dir, false}
        ]).
 
 run_test_if_present(TestDir, LogDir, Config, File) ->
@@ -113,7 +115,12 @@ run_test(TestDir, LogDir, Config, _File) ->
                  false ->
                      " >> " ++ RawLog ++ " 2>&1";
                  true ->
+                 case os:type() of
+                   {win32, nt} ->
+                     " >> " ++ RawLog ++ " 2>&1";
+                   _ ->
                      " 2>&1 | tee -a " ++ RawLog
+                 end
              end,
 
     ShOpts = [{env,[{"TESTDIR", TestDir}]}, return_on_error],
@@ -155,14 +162,27 @@ failure_logger(Command, {Rc, Output}) ->
 check_fail_log(Config, RawLog, Command, Result) ->
     check_log(Config, RawLog, failure_logger(Command, Result)).
 
-check_log(Config,RawLog,Fun) ->
-    {ok, Msg} =
-        rebar_utils:sh("grep -e \"TEST COMPLETE\" -e \"{error,make_failed}\" "
-                       ++ RawLog, [{use_stdout, false}]),
-    MakeFailed = string:str(Msg, "{error,make_failed}") =/= 0,
-    RunFailed = string:str(Msg, ", 0 failed") =:= 0,
+check_log(Config,RawLogFilename,Fun) ->
+    %% read the file and split into a list separated by newlines
+    {ok, RawLog} = file:read_file(RawLogFilename),
+    Msg = string:tokens(binary_to_list(RawLog), "\n"),
+    %% now filter out all the list entries that do not have test
+    %% completion strings
+    CompleteRuns = lists:filter(fun(M) ->
+                                  string:str(M, "TEST COMPLETE") =/= 0
+                                end, Msg),
+    MakeFailed = lists:filter(fun(M) ->
+                                  string:str(M, "{error,make_failed}") =/= 0
+                              end, Msg),
+    %% the run has failed if at least one of the tests failed
+    RunFailed = lists:foldl(fun(M, Acc) ->
+                              %% the "0 failed" string must be present for
+                              %% the test to be considered successful
+                              TestFailed = string:str(M, "0 failed") =:= 0,
+                              TestFailed orelse Acc
+                            end, false, CompleteRuns),
     if
-        MakeFailed ->
+        MakeFailed =/= [] ->
             show_log(Config, RawLog),
             ?ERROR("Building tests failed\n",[]),
             ?FAIL;
@@ -182,8 +202,7 @@ show_log(Config, RawLog) ->
     ?CONSOLE("Showing log\n", []),
     case rebar_log:is_verbose(Config) of
         false ->
-            {ok, Contents} = file:read_file(RawLog),
-            ?CONSOLE("~s", [Contents]);
+            ?CONSOLE("~s", [RawLog]);
         true ->
             ok
     end.
@@ -218,7 +237,7 @@ make_cmd(TestDir, RawLogDir, Config) ->
     CodeDirs = [io_lib:format("\"~s\"", [Dir]) ||
                    Dir <- [EbinDir|NonLibCodeDirs]],
     CodePathString = string:join(CodeDirs, " "),
-    Cmd = case get_ct_specs(Config, Cwd) of
+    Cmd = case get_ct_specs(Config, search_ct_specs_from(Cwd, TestDir, Config)) of
               undefined ->
                   ?FMT("~s"
                        " -pa ~s"
@@ -259,10 +278,20 @@ make_cmd(TestDir, RawLogDir, Config) ->
     RawLog = filename:join(LogDir, "raw.log"),
     {Cmd, RawLog}.
 
+search_ct_specs_from(Cwd, TestDir, Config) ->
+    case rebar_config:get_local(Config, ct_search_specs_from_test_dir, false) of
+        true -> filename:join(Cwd, TestDir);
+        false ->
+          Cwd
+    end.
+
 build_name(Config) ->
+    %% generate a unique name for our test node, we want
+    %% to make sure the odds of name clashing are low
+    Random = integer_to_list(crypto:rand_uniform(0, 10000)),
     case rebar_config:get_local(Config, ct_use_short_names, false) of
-        true -> "-sname test";
-        false -> " -name test@" ++ net_adm:localhost()
+        true -> "-sname test" ++ Random;
+        false -> " -name test" ++ Random ++ "@" ++ net_adm:localhost()
     end.
 
 get_extra_params(Config) ->
diff --git a/src/rebar_deps.erl b/src/rebar_deps.erl
index a6e5b27..251bdee 100644
--- a/src/rebar_deps.erl
+++ b/src/rebar_deps.erl
@@ -58,16 +58,19 @@ preprocess(Config, _) ->
     %% used globally since it will be set on the first time through here
     Config1 = set_shared_deps_dir(Config, get_shared_deps_dir(Config, [])),
 
+    %% Check whether user forced deps resolution via system wide libs
+    Config2 = set_deps_prefer_libs(Config1, get_deps_prefer_libs(Config1, undefined)),
+
     %% Get the list of deps for the current working directory and identify those
     %% deps that are available/present.
-    Deps = rebar_config:get_local(Config1, deps, []),
-    {Config2, {AvailableDeps, MissingDeps}} = find_deps(Config1, find, Deps),
+    Deps = rebar_config:get_local(Config2, deps, []),
+    {Config3, {AvailableDeps, MissingDeps}} = find_deps(Config2, find, Deps),
 
     ?DEBUG("Available deps: ~p\n", [AvailableDeps]),
     ?DEBUG("Missing deps  : ~p\n", [MissingDeps]),
 
     %% Add available deps to code path
-    Config3 = update_deps_code_path(Config2, AvailableDeps),
+    Config4 = update_deps_code_path(Config3, AvailableDeps),
 
     %% Filtering out 'raw' dependencies so that no commands other than
     %% deps-related can be executed on their directories.
@@ -83,8 +86,8 @@ preprocess(Config, _) ->
                           fun(D, Acc) ->
                                   rebar_config:set_skip_dir(Acc, D#dep.dir)
                           end,
-                          Config3,
-                          collect_deps(rebar_utils:get_cwd(), Config3)),
+                          Config4,
+                          collect_deps(rebar_utils:get_cwd(), Config4)),
             %% Return the empty list, as we don't want anything processed before
             %% us.
             {ok, NewConfig, []};
@@ -97,12 +100,12 @@ preprocess(Config, _) ->
             %% Also, if skip_deps=comma,separated,app,list, then only the given
             %% dependencies are skipped.
             NewConfig =
-                case rebar_config:get_global(Config3, skip_deps, false) of
+                case rebar_config:get_global(Config4, skip_deps, false) of
                     "true" ->
                         lists:foldl(
                           fun(#dep{dir = Dir}, C) ->
                                   rebar_config:set_skip_dir(C, Dir)
-                          end, Config3, AvailableDeps);
+                          end, Config4, AvailableDeps);
                     Apps when is_list(Apps) ->
                         SkipApps = [list_to_atom(App) ||
                                        App <- string:tokens(Apps, ",")],
@@ -112,9 +115,9 @@ preprocess(Config, _) ->
                                       true -> rebar_config:set_skip_dir(C, Dir);
                                       false -> C
                                   end
-                          end, Config3, AvailableDeps);
+                          end, Config4, AvailableDeps);
                     _ ->
-                        Config3
+                        Config4
                 end,
 
             %% Return all the available dep directories for process
@@ -254,7 +257,9 @@ info_help(Description) ->
        "  ~p~n"
        "  ~p~n"
        "Valid command line options:~n"
-       "  deps_dir=\"deps\" (override default or rebar.config deps_dir)~n",
+       "  deps_dir=\"deps\" (override default or rebar.config deps_dir)~n"
+       "Environment variables:~n"
+       "  REBAR_DEPS_PREFER_LIBS to look for dependecies in system libs prior fetching.~n",
        [
         Description,
         {deps_dir, "deps"},
@@ -263,15 +268,24 @@ info_help(Description) ->
           {rebar, "1.0.*"},
           {rebar, ".*",
            {git, "git://github.com/rebar/rebar.git"}},
+          {rebar,
+           {git, "git://github.com/rebar/rebar.git"}},
           {rebar, ".*",
            {git, "git://github.com/rebar/rebar.git", "Rev"}},
+          {rebar,
+           {git, "git://github.com/rebar/rebar.git", "Rev"}},
           {rebar, "1.0.*",
            {git, "git://github.com/rebar/rebar.git", {branch, "master"}}},
+          {rebar,
+           {git, "git://github.com/rebar/rebar.git", {branch, "master"}}},
           {rebar, "1.0.0",
            {git, "git://github.com/rebar/rebar.git", {tag, "1.0.0"}}},
           {rebar, "",
            {git, "git://github.com/rebar/rebar.git", {branch, "master"}},
            [raw]},
+          {rebar,
+           {git, "git://github.com/rebar/rebar.git", {branch, "master"}},
+           [raw]},
           {app_name, ".*", {hg, "https://www.example.org/url"}},
           {app_name, ".*", {rsync, "Url"}},
           {app_name, ".*", {svn, "https://www.example.org/url"}},
@@ -302,6 +316,18 @@ set_shared_deps_dir(Config, _DepsDir) ->
 get_shared_deps_dir(Config, Default) ->
     rebar_config:get_xconf(Config, deps_dir, Default).
 
+set_deps_prefer_libs(Config, undefined) ->
+    DepsPreferLibs = case os:getenv("REBAR_DEPS_PREFER_LIBS") of
+        false -> false;
+        _ -> true
+    end,
+    rebar_config:set_xconf(Config, deps_prefer_libs, DepsPreferLibs);
+set_deps_prefer_libs(Config, _DepsPreferLibs) ->
+    Config.
+
+get_deps_prefer_libs(Config, Default) ->
+    rebar_config:get_xconf(Config, deps_prefer_libs, Default).
+
 get_deps_dir(Config) ->
     get_deps_dir(Config, "").
 
@@ -354,8 +380,12 @@ find_deps(Config, read, [], Deps) ->
     {Config, lists:reverse(Deps)};
 find_deps(Config, Mode, [App | Rest], Acc) when is_atom(App) ->
     find_deps(Config, Mode, [{App, ".*", undefined} | Rest], Acc);
+find_deps(Config, Mode, [{App, Source} | Rest], Acc) when is_tuple(Source) ->
+    find_deps(Config, Mode, [{App, ".*", Source} | Rest], Acc);
 find_deps(Config, Mode, [{App, VsnRegex} | Rest], Acc) when is_atom(App) ->
     find_deps(Config, Mode, [{App, VsnRegex, undefined} | Rest], Acc);
+find_deps(Config, Mode, [{App, Source, Opts} | Rest], Acc) when is_tuple(Source) ->
+    find_deps(Config, Mode, [{App, ".*", Source, Opts} | Rest], Acc);
 find_deps(Config, Mode, [{App, VsnRegex, Source} | Rest], Acc) ->
     find_deps(Config, Mode, [{App, VsnRegex, Source, []} | Rest], Acc);
 find_deps(Config, Mode, [{App, VsnRegex, Source, Opts} | Rest], Acc)
@@ -378,9 +408,15 @@ find_dep(Config, Dep) ->
     %% e.g. {git, "https://github.com/mochi/mochiweb.git", "HEAD"}
     %% Deps with a source must be found (or fetched) locally.
     %% Those without a source may be satisfied from lib dir (get_lib_dir).
-    find_dep(Config, Dep, Dep#dep.source).
-
-find_dep(Config, Dep, undefined) ->
+    DepsPreferLibs = get_deps_prefer_libs(Config, false),
+    Mode = case {Dep#dep.source, DepsPreferLibs} of
+        {undefined, _DepsPreferLibs} -> maybe_in_lib;
+        {_DepSource, true} -> maybe_in_lib;
+        {_DepSource, false} -> local_only
+    end,
+    find_dep(Config, Dep, Mode).
+
+find_dep(Config, Dep, maybe_in_lib) ->
     %% 'source' is undefined.  If Dep is not satisfied locally,
     %% go ahead and find it amongst the lib_dir's.
     case find_dep_in_dir(Config, Dep, get_deps_dir(Config, Dep#dep.app)) of
@@ -389,7 +425,7 @@ find_dep(Config, Dep, undefined) ->
         {Config1, {missing, _}} ->
             find_dep_in_dir(Config1, Dep, get_lib_dir(Dep#dep.app))
     end;
-find_dep(Config, Dep, _Source) ->
+find_dep(Config, Dep, local_only) ->
     %% _Source is defined.  Regardless of what it is, we must find it
     %% locally satisfied or fetch it from the original source
     %% into the project's deps
diff --git a/src/rebar_dia_compiler.erl b/src/rebar_dia_compiler.erl
index 56d5189..a45cd55 100644
--- a/src/rebar_dia_compiler.erl
+++ b/src/rebar_dia_compiler.erl
@@ -88,6 +88,8 @@ info_help(Description) ->
 compile_dia(Source, Target, Config) ->
     ok = filelib:ensure_dir(Target),
     ok = filelib:ensure_dir(filename:join("include", "dummy.hrl")),
+    ok = filelib:ensure_dir(filename:join("ebin", "dummy.beam")),
+    true = code:add_path(filename:absname("ebin")),
     Opts = [{outdir, "src"}] ++ rebar_config:get(Config, dia_opts, []),
     case diameter_dict_util:parse({path, Source}, []) of
         {ok, Spec} ->
diff --git a/src/rebar_eunit.erl b/src/rebar_eunit.erl
index 913f2f9..6026740 100644
--- a/src/rebar_eunit.erl
+++ b/src/rebar_eunit.erl
@@ -128,6 +128,7 @@ info_help(Description) ->
        "               name starts with bar and, if no such test exists,~n"
        "               run the test whose name starts with bar in the~n"
        "               suite's _tests module)~n"
+       "  test[s]=\"foo:bar_test\" (Run bar_test located in module foo)~n"
        "  random_suite_order=true (Run tests in random order)~n"
        "  random_suite_order=Seed (Run tests in random order,~n"
        "                           with the PRNG seeded with Seed)~n"
@@ -460,7 +461,7 @@ make_test_primitives(RawTests) ->
                             %% Generator
                             MakePrimitive(generator, M, F2)
                     end,
-                [NewFunction|Acc]
+                [eunit_module_suite(M, NewFunction)|Acc]
         end,
     lists:foldl(F, [], RawTests).
 
@@ -472,6 +473,11 @@ pre15b02_eunit_primitive(test, M, F) ->
 pre15b02_eunit_primitive(generator, M, F) ->
     {generator, eunit_test:function_wrapper(M, F)}.
 
+% Add a test group for eunit_surefire to be able to deduce the testsuite.
+% Calling eunit:test({module, M}) does exactly this as well.
+eunit_module_suite(M, X) ->
+    {"module '" ++ atom_to_list(M) ++ "'", X}.
+
 %%
 %% == run tests ==
 %%
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl
index 0fc1403..a4d3be7 100644
--- a/src/rebar_file_utils.erl
+++ b/src/rebar_file_utils.erl
@@ -88,7 +88,7 @@ mv(Source, Dest) ->
                         ?FMT("move /y \"~s\" \"~s\" 1> nul",
                              [filename:nativename(Source),
                               filename:nativename(Dest)]),
-                        [{use_stdout, false}, return_on_error]),
+                        [{use_stdout, false}, abort_on_error]),
             case R of
                 [] ->
                     ok;
@@ -131,14 +131,14 @@ delete_each_dir_win32([]) -> ok;
 delete_each_dir_win32([Dir | Rest]) ->
     {ok, []} = rebar_utils:sh(?FMT("rd /q /s \"~s\"",
                                    [filename:nativename(Dir)]),
-                              [{use_stdout, false}, return_on_error]),
+                              [{use_stdout, false}, abort_on_error]),
     delete_each_dir_win32(Rest).
 
 xcopy_win32(Source,Dest)->
     {ok, R} = rebar_utils:sh(
                 ?FMT("xcopy \"~s\" \"~s\" /q /y /e 2> nul",
                      [filename:nativename(Source), filename:nativename(Dest)]),
-                [{use_stdout, false}, return_on_error]),
+                [{use_stdout, false}, abort_on_error]),
     case length(R) > 0 of
         %% when xcopy fails, stdout is empty and and error message is printed
         %% to stderr (which is redirected to nul)
@@ -162,8 +162,10 @@ cp_r_win32({false, Source} = S,{true, DestDir}) ->
     cp_r_win32(S, {false, filename:join(DestDir, filename:basename(Source))});
 cp_r_win32({false, Source},{false, Dest}) ->
     %% from file to file
-    {ok,_} = file:copy(Source, Dest),
-    ok;
+    case file:copy(Source, Dest) of
+        {ok,_} -> ok;
+        _ -> throw(rebar_abort)
+    end;
 cp_r_win32({true, SourceDir}, {false, DestDir}) ->
     case filelib:is_regular(DestDir) of
         true ->
diff --git a/src/rebar_neotoma_compiler.erl b/src/rebar_neotoma_compiler.erl
index 5549dc4..f93d492 100644
--- a/src/rebar_neotoma_compiler.erl
+++ b/src/rebar_neotoma_compiler.erl
@@ -40,7 +40,7 @@
 %% source_ext: extension of peg source files
 -module(rebar_neotoma_compiler).
 
--export([compile/2]).
+-export([compile/2, clean/2]).
 
 %% for internal use only
 -export([info/2]).
@@ -59,6 +59,20 @@ compile(Config, _AppFile) ->
                             option(module_ext, NeoOpts) ++ ".erl",
                             fun compile_neo/3, [{check_last_mod, true}]).
 
+-spec clean(rebar_config:config(), file:filename()) -> 'ok'.
+clean(Config, _AppFile) ->
+    NeoOpts = neotoma_opts(Config),
+    GeneratedFiles = neotoma_generated_files(
+                       option(out_dir, NeoOpts),
+                       option(module_ext, NeoOpts),
+                       neotoma_source_files(
+                         option(doc_root, NeoOpts),
+                         option(source_ext, NeoOpts)
+                        )
+                      ),
+    ok = rebar_file_utils:delete_each(GeneratedFiles),
+    ok.
+
 %% ============================================================================
 %% Internal functions
 %% ============================================================================
@@ -161,3 +175,20 @@ referenced_pegs1(Step, Config, Seen) ->
         _ -> referenced_pegs1(sets:to_list(New), Config,
                               sets:union(New, Seen))
     end.
+
+neotoma_source_files(SrcDir, Ext) ->
+    lists:map(
+      fun filename:basename/1,
+      filelib:wildcard(filename:join([SrcDir, "*" ++ Ext]))
+     ).
+
+
+neotoma_generated_files(OutDir, ModExt, SourceFiles) ->
+    lists:map(
+      fun(PegFile) ->
+              Base = filename:rootname(PegFile),
+              NewName = Base ++ ModExt ++ ".erl",
+              filename:join(OutDir, NewName)
+      end,
+      SourceFiles
+     ).
diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl
index 906bcb0..50093c9 100644
--- a/src/rebar_port_compiler.erl
+++ b/src/rebar_port_compiler.erl
@@ -624,12 +624,17 @@ default_env() ->
      %% OS X Leopard flags for 64-bit
      {"darwin9.*-64$", "CFLAGS", "-m64 $CFLAGS"},
      {"darwin9.*-64$", "CXXFLAGS", "-m64 $CXXFLAGS"},
-     {"darwin9.*-64$", "LDFLAGS", "-arch x86_64 $LDFLAGS"},
+     {"darwin9.*-64$", "LDFLAGS", "-arch x86_64 -flat_namespace -undefined suppress $LDFLAGS"},
+
+     %% OS X Lion onwards flags for 64-bit
+     {"darwin1[0-4].*-64$", "CFLAGS", "-m64 $CFLAGS"},
+     {"darwin1[0-4].*-64$", "CXXFLAGS", "-m64 $CXXFLAGS"},
+     {"darwin1[0-4].*-64$", "LDFLAGS", "-arch x86_64 -flat_namespace -undefined suppress $LDFLAGS"},
 
      %% OS X Snow Leopard, Lion, and Mountain Lion flags for 32-bit
      {"darwin1[0-2].*-32", "CFLAGS", "-m32 $CFLAGS"},
      {"darwin1[0-2].*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
-     {"darwin1[0-2].*-32", "LDFLAGS", "-arch i386 $LDFLAGS"},
+     {"darwin1[0-2].*-32", "LDFLAGS", "-arch i386 -flat_namespace -undefined suppress $LDFLAGS"},
 
      %% Windows specific flags
      %% add MS Visual C++ support to rebar on Windows
diff --git a/src/rebar_require_vsn.erl b/src/rebar_require_vsn.erl
index 5eecf74..684578a 100644
--- a/src/rebar_require_vsn.erl
+++ b/src/rebar_require_vsn.erl
@@ -31,7 +31,8 @@
 -include("rebar.hrl").
 
 -export([compile/2,
-         eunit/2]).
+         eunit/2,
+         version_tuple/1]).
 
 %% for internal use only
 -export([info/2,
@@ -103,12 +104,12 @@ check_versions(Config) ->
     case rebar_config:get(Config, require_min_otp_vsn, undefined) of
         undefined -> ?DEBUG("Min OTP version unconfigured~n", []);
         MinOtpVsn ->
-            {MinMaj, MinMin} = version_tuple(ShouldAbort, MinOtpVsn,
+            {MinMaj, MinMin, MinPatch} = version_tuple(ShouldAbort, MinOtpVsn,
                                              "configured"),
-            {OtpMaj, OtpMin} = version_tuple(ShouldAbort,
+            {OtpMaj, OtpMin, OtpPatch} = version_tuple(ShouldAbort,
                                              erlang:system_info(otp_release),
                                              "OTP Release"),
-            case {OtpMaj, OtpMin} >= {MinMaj, MinMin} of
+            case {OtpMaj, OtpMin, OtpPatch} >= {MinMaj, MinMin, MinPatch} of
                 true ->
                     ?DEBUG("~s satisfies the requirement for vsn ~s~n",
                            [erlang:system_info(otp_release),
@@ -122,12 +123,17 @@ check_versions(Config) ->
             end
     end.
 
+version_tuple(OtpRelease) ->
+    version_tuple(keep_going, OtpRelease, "").
+
 version_tuple(ShouldAbort, OtpRelease, Type) ->
-    case re:run(OtpRelease, "R?(\\d+)B?-?(\\d+)?", [{capture, all, list}]) of
+    case re:run(OtpRelease, "R?(\\d+)B?\.?(\\d+)?\.?-?(\\d+)?", [{capture, all, list}]) of
+        {match, [_Full, Maj, Min, Patch]} ->
+            {list_to_integer(Maj), list_to_integer(Min), list_to_integer(Patch)};
         {match, [_Full, Maj, Min]} ->
-            {list_to_integer(Maj), list_to_integer(Min)};
+            {list_to_integer(Maj), list_to_integer(Min), 0};
         {match, [_Full, Maj]} ->
-            {list_to_integer(Maj), 0};
+            {list_to_integer(Maj), 0, 0};
         nomatch ->
             maybe_abort(ShouldAbort,
                         "Cannot parse ~s version string: ~s~n",
diff --git a/src/rebar_upgrade.erl b/src/rebar_upgrade.erl
index 23da5a3..01edbd2 100644
--- a/src/rebar_upgrade.erl
+++ b/src/rebar_upgrade.erl
@@ -44,18 +44,24 @@
 'generate-upgrade'(Config0, ReltoolFile) ->
     %% Get the old release path
     {Config, ReltoolConfig} = rebar_rel_utils:load_config(Config0, ReltoolFile),
+    ?DEBUG("reltool.config: ~p~n", [ReltoolConfig]),
     TargetParentDir = rebar_rel_utils:get_target_parent_dir(Config,
                                                             ReltoolConfig),
     TargetDir = rebar_rel_utils:get_target_dir(Config, ReltoolConfig),
+    ?DEBUG("target dir: ~p~n", [TargetDir]),
 
     PrevRelPath = rebar_rel_utils:get_previous_release_path(Config),
     OldVerPath = filename:join([TargetParentDir, PrevRelPath]),
+    ?DEBUG("old version path: ~p~n", [OldVerPath]),
 
     %% Run checks to make sure that building a package is possible
     {NewVerPath, NewName, NewVer, OldVer} = run_checks(Config, OldVerPath,
                                                        ReltoolConfig),
+    ?DEBUG("old version: ~p~n", [OldVer]),
     NameVer = NewName ++ "_" ++ NewVer,
     OldRelName = get_old_rel_name(OldVerPath, OldVer, NewName),
+    ?DEBUG("new version path: ~p~n", [NewVerPath]),
+    ?DEBUG("old version: ~p~n", [NewVer]),
 
     %% Save the code path prior to doing anything
     OrigPath = code:get_path(),
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index 64595a2..c3ebfe5 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -67,7 +67,9 @@
          processing_base_dir/1,
          processing_base_dir/2,
          patch_env/2,
-         cleanup_code_path/1
+         cleanup_code_path/1,
+         init_vsn_cache/1,
+         save_vsn_cache/1
         ]).
 
 %% for internal use only
@@ -268,6 +270,23 @@ expand_env_variable(InStr, VarName, RawVarValue) ->
             re:replace(InStr, RegEx, [VarValue, "\\2"], ReOpts)
     end.
 
+init_vsn_cache(Config) ->
+    init_vsn_cache(Config, os:getenv("REBAR_VSN_CACHE_FILE")).
+init_vsn_cache(Config, false) ->
+    rebar_config:set_xconf(Config, vsn_cache, dict:new());
+init_vsn_cache(Config, CacheFile) ->
+    {ok, CacheList} = file:consult(CacheFile),
+    CacheDict = dict:from_list(CacheList),
+    rebar_config:set_xconf(Config, vsn_cache, CacheDict).
+
+save_vsn_cache(Config) ->
+    save_vsn_cache(Config, os:getenv("REBAR_VSN_CACHE_FILE")).
+save_vsn_cache(_Config, false) ->
+    ok;
+save_vsn_cache(Config, CacheFile) ->
+    file:write_file(CacheFile,
+        [io_lib:format("~p.~n", [X]) || X <- dict:to_list(rebar_config:get_xconf(Config, vsn_cache))]).
+
 vcs_vsn(Config, Vsn, Dir) ->
     Key = {Vsn, Dir},
     Cache = rebar_config:get_xconf(Config, vsn_cache),
@@ -276,6 +295,7 @@ vcs_vsn(Config, Vsn, Dir) ->
             VsnString = vcs_vsn_1(Vsn, Dir),
             Cache1 = dict:store(Key, VsnString, Cache),
             Config1 = rebar_config:set_xconf(Config, vsn_cache, Cache1),
+            save_vsn_cache(Config1),
             {Config1, VsnString};
         {ok, VsnString} ->
             {Config, VsnString}
@@ -760,7 +780,7 @@ cross_sizeof(Arch, Type) ->
                          >>),
     Cmd = Compiler ++ " -DTYPE=\""++Type++"\" " ++ TempFile,
     ShOpts = [{use_stdout, false}, return_on_error],
-    {ok, Res} = sh(Cmd, ShOpts),
+    {error, {_,Res}} = sh(Cmd, ShOpts),
     ok = file:delete(TempFile),
     case string:tokens(Res, ":") of
         [_, Ln | _] ->
diff --git a/src/rebar_xref.erl b/src/rebar_xref.erl
index fdce75e..ee3414d 100644
--- a/src/rebar_xref.erl
+++ b/src/rebar_xref.erl
@@ -60,9 +60,9 @@ xref(Config, _) ->
     true = code:add_path(rebar_utils:ebin_dir()),
 
     %% Add extra paths to code path to, for example, be used
-    %%   when behaviour modules are defined
-    [code:add_path(Path)
-     || Path <- rebar_config:get(Config, xref_extra_paths, [])],
+    %% when behaviour modules are defined.
+    lists:foreach(fun(P) -> true = code:add_path(P) end,
+                  rebar_config:get(Config, xref_extra_paths, [])),
 
     %% Get list of xref checks we want to run
     ConfXrefChecks = rebar_config:get(Config, xref_checks,
diff --git a/test/rebar_compiler_tests.erl b/test/rebar_compiler_tests.erl
index 3ed600b..104a7d8 100644
--- a/test/rebar_compiler_tests.erl
+++ b/test/rebar_compiler_tests.erl
@@ -84,11 +84,11 @@ not_keep_going_test_() ->
      setup,
      fun() ->
              setup_basic_project(),
-             setup_rebar_config(),
-             rebar("compile")
+             setup_rebar_config()
      end,
      fun teardown/1,
-     fun(RebarOut)->
+     fun()->
+             RebarOut = rebar("compile"),
              [
               {"Exit after error",
                ?_assert(string:str(RebarOut, "ERROR: compile failed") =/= 0)}
diff --git a/test/rebar_dia_tests.erl b/test/rebar_dia_tests.erl
new file mode 100644
index 0000000..556a552
--- /dev/null
+++ b/test/rebar_dia_tests.erl
@@ -0,0 +1,116 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+-module(rebar_dia_tests).
+
+-compile([export_all]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+-define(REBAR_SCRIPT, "../rebar").
+
+-define(TMP_DIR, "dia_project/").
+
+dia_test_() ->
+    case supported_otp_version() of
+        true -> 
+            {"Test the dia compiler",
+             setup, fun() -> setup_project(), rebar("compile") end,
+             fun teardown/1,
+             fun(RebarOut) ->
+                 [{"Check ebin is created",
+                   ?_assert(filelib:is_dir("ebin") =:= true)},
+
+                  {"Check include is created",
+                   ?_assert(filelib:is_dir("include") =:= true)},
+                  
+                  {"Check dia/a.dia is compiled",
+                   ?_assert(string:str(RebarOut, "Compiled dia/a.dia") /= 0)},
+
+                  {"Check dia/b.dia is compiled",
+                   ?_assert(string:str(RebarOut, "Compiled dia/b.dia") /= 0)}
+                 ]
+             end};
+        false -> {setup, fun() -> ok end, []}
+    end.
+
+
+%% ====================================================================
+%% Setup and Teardown
+%% ====================================================================
+
+-define(myapp_dia_a,
+        ["@id     0\n",
+         "@name   a\n",
+         "@vendor 1 ABC\n",
+         "@avp_types\n",
+         "   IMSI 1 UTF8String V"
+        ]).
+
+-define(myapp_dia_b,
+        ["@id     2\n",
+         "@name   b\n",
+         "@vendor 2 ABC\n",
+         "@inherits a\n",
+         "@avp_types\n",
+         "   IMEIV 900 OctetString MV"
+        ]).
+
+-define(myapp_rebarconfig,
+        ["{dia_first_files, [\"dia/a.dia\"]}.\n",
+         "{dia_opts, []}.\n"
+        ]).
+
+supported_otp_version() ->
+    Min = rebar_require_vsn:version_tuple(keep_going, "15", "configured"),
+    Otp = rebar_require_vsn:version_tuple(keep_going, 
+                                          erlang:system_info(otp_release),
+                                          "OTP Release"),
+    Otp >= Min.
+
+
+setup_environment() ->
+    ok = file:make_dir(?TMP_DIR),
+    prepare_rebar_script(),
+    ok = file:set_cwd(?TMP_DIR).
+
+prepare_project() ->
+    setup_environment(),
+    rebar("create-app appid=myapp").
+
+
+setup_project() ->
+    prepare_project(),
+    ok = file:make_dir("dia"),
+    ok = file:write_file("dia/a.dia", ?myapp_dia_a),
+    ok = file:write_file("dia/b.dia", ?myapp_dia_b),
+    ok = file:write_file("rebar.config", ?myapp_rebarconfig).
+
+
+teardown(_) ->
+    ok = file:set_cwd(".."),
+    ok = remove_tmp_dir().
+
+remove_tmp_dir() ->
+    ok = rebar_file_utils:rm_rf(?TMP_DIR).
+
+%% ====================================================================
+%% Helper Functions
+%% ====================================================================
+
+prepare_rebar_script() ->
+    Rebar = ?TMP_DIR ++ "rebar",
+    {ok, _} = file:copy(?REBAR_SCRIPT, Rebar),
+    case os:type() of
+        {unix, _} ->
+            [] = os:cmd("chmod u+x " ++ Rebar);
+        {win32, _} ->
+            {ok, _} = file:copy(?REBAR_SCRIPT ++ ".cmd",
+                                ?TMP_DIR ++ "rebar.cmd")
+    end.
+
+rebar() ->
+    rebar([]).
+
+rebar(Args) when is_list(Args) ->
+    Out = os:cmd(filename:nativename("./rebar") ++ " " ++ Args),
+    Out.
diff --git a/test/rebar_eunit_tests.erl b/test/rebar_eunit_tests.erl
index cb331a4..d481dae 100644
--- a/test/rebar_eunit_tests.erl
+++ b/test/rebar_eunit_tests.erl
@@ -56,7 +56,7 @@ eunit_test_() ->
                ?_assert(string:str(RebarOut, "myapp_mymod:") =/= 0)},
 
               {"Tests are only run once",
-               ?_assert(string:str(RebarOut, "All 2 tests passed") =/= 0)}]
+               ?_assert(string:str(RebarOut, "2 tests passed") =/= 0)}]
      end}.
 
 eunit_with_suites_and_tests_test_() ->
@@ -80,7 +80,7 @@ eunit_with_suites_and_tests_test_() ->
                 ?_assert(string:str(RebarOut, "myapp_mymod:") =:= 0)},
 
                {"Selected suite tests are only run once",
-                ?_assert(string:str(RebarOut, "All 4 tests passed") =/= 0)}]
+                ?_assert(string:str(RebarOut, "4 tests passed") =/= 0)}]
       end},
      {"Ensure EUnit runs selected _tests suites",
       setup, fun() ->
@@ -102,7 +102,7 @@ eunit_with_suites_and_tests_test_() ->
                 ?_assert(string:str(RebarOut, "myapp_mymod:") =:= 0)},
 
                {"Selected suite tests are only run once",
-                ?_assert(string:str(RebarOut, "All 2 tests passed") =/= 0)}]
+                ?_assert(string:str(RebarOut, "2 tests passed") =/= 0)}]
       end},
      {"Ensure EUnit runs a specific test defined in a selected suite",
       setup, fun() ->
@@ -154,7 +154,7 @@ eunit_with_suites_and_tests_test_() ->
                                "myapp_mymod2_tests:myfunc2_test/0") =/= 0)]},
 
                {"Selected suite tests are run once",
-                ?_assert(string:str(RebarOut, "All 3 tests passed") =/= 0)}]
+                ?_assert(string:str(RebarOut, "3 tests passed") =/= 0)}]
       end},
      {"Ensure EUnit runs specific test in a _tests suite",
       setup,
@@ -190,7 +190,7 @@ eunit_with_suites_and_tests_test_() ->
                           =/= 0)]},
 
                {"Selected suite tests is run once",
-                ?_assert(string:str(RebarOut, "All 2 tests passed") =/= 0)}]
+                ?_assert(string:str(RebarOut, "2 tests passed") =/= 0)}]
       end},
      {"Ensure EUnit runs a specific test by qualified function name",
       setup,
@@ -325,7 +325,11 @@ environment_test_() ->
 
 assert_rebar_runs() ->
     prepare_rebar_script(),
-    ?assert(string:str(os:cmd(filename:nativename("./" ++ ?TMP_DIR ++ "rebar")),
+    {ok, Cwd} = file:get_cwd(),
+    ok = file:set_cwd(?TMP_DIR),
+    RebarOut = os:cmd(filename:nativename("./rebar")),
+    ok = file:set_cwd(Cwd),
+    ?assert(string:str(RebarOut,
                        "No command to run specified!") =/= 0).
 
 basic_setup_test_() ->
diff --git a/test/rebar_file_utils_tests.erl b/test/rebar_file_utils_tests.erl
index fc76d58..c9b4192 100644
--- a/test/rebar_file_utils_tests.erl
+++ b/test/rebar_file_utils_tests.erl
@@ -36,7 +36,7 @@
 
 -define(TMP_DIR, "tmp_file_utils").
 
--define(SRC, "source dir?").
+-define(SRC, "source dir").
 -define(DST, "dest (dir)").
 -define(FILE1, "file 1").
 -define(FILE2, "file(2)").
diff --git a/test/rebar_require_vsn_tests.erl b/test/rebar_require_vsn_tests.erl
index a487586..a934e8e 100644
--- a/test/rebar_require_vsn_tests.erl
+++ b/test/rebar_require_vsn_tests.erl
@@ -8,17 +8,32 @@
 
 version_tuple_test_() ->
     [%% typical cases
-     ?_assert(check("R15B", "eunit") =:= {15, 0}),
-     ?_assert(check("R15B01", "eunit") =:= {15, 1}),
-     ?_assert(check("R15B02", "eunit") =:= {15, 2}),
-     ?_assert(check("R15B03-1", "eunit") =:= {15, 3}),
-     ?_assert(check("R15B03", "eunit") =:= {15, 3}),
-     ?_assert(check("R16B", "eunit") =:= {16, 0}),
-     ?_assert(check("R16B01", "eunit") =:= {16, 1}),
-     ?_assert(check("R16B02", "eunit") =:= {16, 2}),
-     ?_assert(check("R16B03", "eunit") =:= {16, 3}),
-     ?_assert(check("R16B03-1", "eunit") =:= {16, 3}),
-     ?_assert(check("17", "eunit") =:= {17, 0}),
+     ?_assert(check("R14A", "eunit") =:= {14, 0, 0}),
+     ?_assert(check("R14B", "eunit") =:= {14, 0, 0}),
+     ?_assert(check("R14B01", "eunit") =:= {14, 1, 0}),
+     ?_assert(check("R14B02", "eunit") =:= {14, 2, 0}),
+     ?_assert(check("R14B03", "eunit") =:= {14, 3, 0}),
+     ?_assert(check("R14B04", "eunit") =:= {14, 4, 0}),
+     ?_assert(check("R15B", "eunit") =:= {15, 0, 0}),
+     ?_assert(check("R15B01", "eunit") =:= {15, 1, 0}),
+     ?_assert(check("R15B02", "eunit") =:= {15, 2, 0}),
+     ?_assert(check("R15B03-1", "eunit") =:= {15, 3, 1}),
+     ?_assert(check("R15B03", "eunit") =:= {15, 3, 0}),
+     ?_assert(check("R16B", "eunit") =:= {16, 0, 0}),
+     ?_assert(check("R16B01", "eunit") =:= {16, 1, 0}),
+     ?_assert(check("R16B02", "eunit") =:= {16, 2, 0}),
+     ?_assert(check("R16B03", "eunit") =:= {16, 3, 0}),
+     ?_assert(check("R16B03-1", "eunit") =:= {16, 3, 1}),
+     ?_assert(check("17", "eunit") =:= {17, 0, 0}),
+     ?_assert(check("17.0", "eunit") =:= {17, 0, 0}),
+     ?_assert(check("17.1", "eunit") =:= {17, 1, 0}),
+     ?_assert(check("17.3", "eunit") =:= {17, 3, 0}),
+     ?_assert(check("17.4", "eunit") =:= {17, 4, 0}),
+     ?_assert(check("17.5", "eunit") =:= {17, 5, 0}),
+     ?_assert(check("18.0", "eunit") =:= {18, 0, 0}),
+     ?_assert(check("18.1", "eunit") =:= {18, 1, 0}),
+     ?_assert(check("18.2", "eunit") =:= {18, 2, 0}),
+     ?_assert(check("18.2.1", "eunit") =:= {18, 2, 1}),
      %% error cases
      ?_assertException(throw, rebar_abort, check("", "eunit")),
      ?_assertException(throw, rebar_abort, check("abc", "eunit"))
diff --git a/test/rebar_xref_eunit.erl b/test/rebar_xref_eunit.erl
index 341fe2e..f32ea46 100644
--- a/test/rebar_xref_eunit.erl
+++ b/test/rebar_xref_eunit.erl
@@ -192,8 +192,8 @@ prepare_rebar_script() ->
         {unix, _} ->
             [] = os:cmd("chmod u+x " ++ Rebar);
         {win32, _} ->
-            {ok, _} = file:copy(?REBAR_SCRIPT ++ ".bat",
-                                ?TMP_DIR ++ "rebar.bat")
+            {ok, _} = file:copy(?REBAR_SCRIPT ++ ".cmd",
+                                ?TMP_DIR ++ "rebar.cmd")
     end.
 
 rebar() ->
openSUSE Build Service is sponsored by