anchor.diff:  %% Internal functions
   %% ===================================================================
   
  +new({Name, Vsn, Source})->
  +    #dep{name=to_binary(Name), vsn=to_binary(Vsn), source=Source};
  +new(Name) ->
  +    #dep{name=to_binary(Name)}.
  +
  +-spec name(record(dep)) -> binary().
  +name(#dep{name=Name}) ->
  +    Name.
  +
  +-spec vsn(record(dep)) -> binary().
  +vsn(#dep{vsn=Vsn}) ->
  +    Vsn.
  +
  +-spec source(record(dep)) -> tuple().
  +source(#dep{source=Source}) ->
  +    Source.
  +
  +to_binary(X) when is_binary(X) ->
  +    X;
  +to_binary(X) when is_atom(X) ->
  +    atom_to_binary(X, utf8);
  +to_binary(X) when is_list(X) ->
  +    iolist_to_binary(X).
  +
  +parse_deps(Deps) ->
  +    lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, GoalsAcc}) ->
  +                        {SrcDepsAcc, [{to_binary(Name), to_binary(Vsn)} | GoalsAcc]};
  +                   (Name, {SrcDepsAcc, GoalsAcc}) when is_atom(Name) ->
  +                        {SrcDepsAcc, [to_binary(Name) | GoalsAcc]};
  +                   (SrcDep, {SrcDepsAcc, GoalsAcc}) ->
  +                        Dep = new(SrcDep),
  +                        {dict:store(name(Dep), Dep, SrcDepsAcc), GoalsAcc}
  +                end, {dict:new(), []}, Deps).
  +
   get_packages(State) ->
       RebarDir = rebar_state:get(State, global_rebar_dir, filename:join(os:getenv("HOME"), ".rebar")),
       PackagesFile = filename:join(RebarDir, "packages"),
  
positive.code: do(State) ->
      %% Read in package index and dep graph
      {Packages, Graph} = get_packages(State),
      PtDeps = rebar_state:get(State, pt_deps, []),
      SrcDeps = rebar_state:get(State, src_deps, []),
      {State1, _PtDeps1} = update_deps(State, PtDeps),
      {State1, SrcDeps1} = update_deps(State, SrcDeps),
  
      case rebar_state:get(State1, deps, []) of
          [] ->
              {ok, rebar_state:set(State1, deps, SrcDeps1)};
          Deps ->
              Goals = lists:map(fun({Name, Vsn}) ->
                                        {atom_to_binary(Name, utf8), Vsn};
                                   (Name) ->
                                        atom_to_binary(Name, utf8)
                                end, Deps),
              {ok, Solved} = rlx_depsolver:solve(Graph, Goals),
              M = lists:map(fun({Name, Vsn}) ->
                                    FmtVsn = to_binary(rlx_depsolver:format_version(Vsn)),
                                    {ok, P} = dict:find({Name, FmtVsn}, Packages),
                                    Link = proplists:get_value(<<"link">>, P),
                                    {Name, Vsn, {Name
                                                ,FmtVsn
                                                ,Link}}
                            end, Solved),
  
              {State2, Deps1} = update_deps(State1, M),
              State3 = rebar_state:set(State2, deps, Deps1),
  
              {ok, rebar_state:set(State3, goals, Goals)}
      end.
  
  update_deps(State, Deps) ->
  
negative.code:     UnbuiltApps = rebar_app_discover:find_unbuilt_apps([DepsDir]),
      FoundApps = rebar_app_discover:find_apps([DepsDir]),
  
      download_missing_deps(State, DepsDir, FoundApps, UnbuiltApps, Deps).
  
  update_src_deps(State, Deps) ->
      DepsDir = get_deps_dir(State),
  
      %% Find available apps to fulfill dependencies
      %% Should only have to do this once, not every iteration
      UnbuiltApps = rebar_app_discover:find_unbuilt_apps([DepsDir]),
      FoundApps = rebar_app_discover:find_apps([DepsDir]),
  
      %% Resolve deps and their dependencies
      Deps1 = handle_src_deps(Deps, UnbuiltApps++FoundApps),
      {State1, Missing} = download_missing_deps(State, DepsDir, FoundApps, UnbuiltApps, Deps1),
      case dict:is_empty(Missing) of
          true ->
              {State1, Deps1};
          false ->
              update_src_deps(State1, Missing)
      end.
  
  handle_src_deps(Deps, Found) ->
      lists:foldl(fun(X, DepsAcc) ->
                          C = rebar_config:consult(rebar_app_info:dir(X)),
                          S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(X)),
                          {ParsedDeps, _Goals} = parse_deps(rebar_state:get(S, deps, [])),
                          dict:merge(fun(_K, V1, _V2) -> V1 end, DepsAcc, ParsedDeps)
                  end, Deps, Found).
  
  download_missing_deps(State, DepsDir, Found, Unbuilt, Deps) ->
      Missing =
          dict:filter(fun(Key, _) ->
                              not lists:any(fun(F) ->
                                                    Key =:= to_binary(rebar_app_info:name(F))
                                            end, Found++Unbuilt)
                      end, Deps),
      dict:map(fun(_Key, #dep{name=Name, source=Source}) ->
                       TargetDir = get_deps_dir(DepsDir, Name),
                       case filelib:is_dir(TargetDir) of
                           true ->
                               ok;
                           false ->
                               ?INFO("Fetching ~s ~s~n", [Name
                                                         ,element(2, Source)]),
                               rebar_fetch:download_source(TargetDir, Source),
                               case rebar_app_discover:find_unbuilt_apps([TargetDir]) of
                                   [AppSrc] ->
                                       C = rebar_config:consult(rebar_app_info:dir(AppSrc)),
                                       S = rebar_state:new(rebar_state:new()
                                                          ,C
                                                          ,rebar_app_info:dir(AppSrc)),
                                       rebar_prv_app_builder:build(S, AppSrc);
                                   [] ->
                                       []
                               end
                       end
               end, Missing),
  
      {State, Missing}.
  
  %% set REBAR_DEPS_DIR and ERL_LIBS environment variables
  setup_env(State) ->
  