anchor.diff:  to_bool(_) ->
       false.
   
  -%%-------------------------------------------------------------------
  +%% @doc
  +%%  Delete the directory and all of its sub directories.
  +%% @end
  +%% @private
  +-spec delete_dir(Dir::string()) -> ok.
  +delete_dir(Dir) ->
  +    case file:list_dir(Dir) of
  +	{ok, Files} ->
  +	    lists:foldl(fun (File, _Acc) ->
  +				NFile = filename:join([Dir, File]),
  +				case filelib:is_dir(NFile) of
  +				    true ->
  +					case is_symlink(NFile) of
  +					    true -> file:delete(NFile);
  +					    false -> delete_dir(NFile)
  +					end;
  +				    false -> file:delete(NFile)
  +				end
  +			end,
  +			[], Files),
  +	    file:del_dir(Dir);
  +	_ ->
  +	    ok
  +    end.
  +
   %% @doc
   %%  Get the ignore dirs
  -%%
  -%% @spec (BuildRef) -> IgnoreDirs
  -%% @end
  -%%-------------------------------------------------------------------
  -get_ignore_dirs(BuildRef) ->
  -    BuildDir = sin_build_config:get_value(BuildRef, "build.dir"),
  -    IgnoreDirs = sin_build_config:get_value(BuildRef, "ignore_dirs", []),
  +%% @end
  +-spec get_ignore_dirs(sin_build_config:build_config()) -> IgnoreDirs::[string()].
  +get_ignore_dirs(BuildConfig) ->
  +    BuildDir = sin_build_config:get_value(BuildConfig,
  +					  "build.dir"),
  +    IgnoreDirs = sin_build_config:get_value(BuildConfig,
  +					    "ignore_dirs", []),
       [BuildDir | IgnoreDirs].
   
  -%%-------------------------------------------------------------------
   %% @doc
   %%  Check to see if a file exists.
  -%%
  -%% @spec (FileName) -> true | false
  -%% @end
  -%%-------------------------------------------------------------------
  +%% @end
  +-spec file_exists(FileName::string()) -> boolean().
   file_exists(FileName) ->
       case file:read_file_info(FileName) of
  -        {error, enoent} ->
  -            false;
  -        Error = {error, _} ->
  -            throw(Error);
  -        _ ->
  -            true
  -    end.
  -
  -
  -
  -%%-------------------------------------------------------------------
  +	{error, enoent} ->
  +	    false;
  +	Error = {error, _} ->
  +	    throw(Error);
  +	_ ->
  +	    true
  +    end.
  +
   %% @doc
   %%  Copies the specified directory down to the build
   %%  dir on a file by file basis. It only copies if the file has .
  -%% @spec (BuilderDir, TargetDir, Subdirs) -> ok
  -%% @end
  -%%-------------------------------------------------------------------
  +%% @end
  +-spec copy_dir(BuilderDir::string(),
  +	       TargetDir::string()) -> ok.
  +copy_dir(BuildDir, TargetDir) ->
  +    copy_dir(BuildDir, TargetDir, [], []).
  +
  +-spec copy_dir(BuilderDir::string(),
  +	       TargetDir::string(),
  +	       Subdirs::string()) -> ok.
   copy_dir(BuildDir, TargetDir, Sub) ->
       copy_dir(BuildDir, TargetDir, Sub, []).
   
  -copy_dir(BuildDir, TargetDir) ->
  -    copy_dir(BuildDir, TargetDir, [], []).
  -
  -
  +-spec copy_dir(BuilderDir::string(),
  +	       TargetDir::string(),
  +	       Subdirs::string(),
  +	       Ignorables::string()) -> ok.
   copy_dir(BuildDir, TargetDir, SubDir, Ignorables) ->
       check_not_circular(BuildDir, TargetDir, SubDir),
       case are_dirs_ignorable(SubDir, Ignorables) of
  -        true ->
  -            ok;
  -        false ->
  -            Target = filename:join([BuildDir | SubDir]),
  -            filelib:ensure_dir(filename:join([Target, "tmp"])),
  -            CpyTarget = filename:join([TargetDir | SubDir]),
  -            {ok, Files} = file:list_dir(CpyTarget),
  -            lists:foldl(fun(IFile, _Acc) ->
  -                                File = filename:join([CpyTarget, IFile]),
  -                                case {is_dir_ignorable(IFile, Ignorables),
  -                                      filelib:is_dir(File)} of
  -                                    {true, _} ->
  -                                        ok;
  -                                    {_, true} ->
  -                                        copy_dir(BuildDir, TargetDir, SubDir ++
  -                                                 [IFile], Ignorables);
  -                                    {_, false} ->
  -                                        copy_file(Target, IFile, File)
  -                                end
  -                        end, [], Files)
  -    end.
  -
  -check_not_circular(Target, Source, SubDir) ->
  -    case filename:split(Source) ++ SubDir == filename:split(Target) of
  -	true ->
  -	    ewl_talk:say(
  -	      "Can't copy a directory to itself (~p to ~p)",
  -	      [filename:join([Source | SubDir]), Target]),
  -	    throw(circular_recursion);
  -	false ->
  -	    ok
  -    end.
  -
  -%%-------------------------------------------------------------------
  -%% @doc
  -%%  Given a directory returns the name of the parent directory.
  -%% @spec (Filename) -> DirName | top
  -%% @end
  -%%-------------------------------------------------------------------
  -parent_dir(Filename) ->
  -    parent_dir(filename:split(Filename), []).
  -
  -%%-------------------------------------------------------------------
  -%% @doc
  -%%  Given list of directories, splits the list and returns all
  -%% dirs but the last as a path.
  -%% @spec (List::list(), Acc::list()) -> DirName | top
  -%% @end
  -%%-------------------------------------------------------------------
  -parent_dir([_H], []) ->
  -    top;
  -parent_dir([], []) ->
  -    top;
  -parent_dir([_H], Acc) ->
  -    filename:join(lists:reverse(Acc));
  -parent_dir([H | T], Acc) ->
  -    parent_dir(T, [ H | Acc]).
  -
  -%%--------------------------------------------------------------------
  -%% @doc
  -%%  Remove the set code paths from the system.
  -%% @spec (Paths) -> ok
  -%% @end
  -%%--------------------------------------------------------------------
  +	true ->
  +	    ok;
  +	false ->
  +	    Target = filename:join([BuildDir | SubDir]),
  +	    filelib:ensure_dir(filename:join([Target, "tmp"])),
  +	    CpyTarget = filename:join([TargetDir | SubDir]),
  +	    {ok, Files} = file:list_dir(CpyTarget),
  +	    lists:foldl(fun (IFile, _Acc) ->
  +				File = filename:join([CpyTarget, IFile]),
  +				case {is_dir_ignorable(IFile, Ignorables),
  +				      filelib:is_dir(File)}
  +				    of
  +				    {true, _} ->
  +					ok;
  +				    {_, true} ->
  +					copy_dir(BuildDir, TargetDir,
  +						 SubDir ++ [IFile], Ignorables);
  +				    {_, false} ->
  +					copy_file(Target, IFile, File)
  +				end
  +			end,
  +			[], Files)
  +    end.
  +
  +%% @doc
  +%%  Remove the specified code paths from the system code paths.
  +%% @end
  +-spec remove_code_paths(Paths::[string()]) -> ok.
   remove_code_paths([Path | T]) ->
  -    code:del_path(Path),
  -    remove_code_paths(T);
  +    code:del_path(Path), remove_code_paths(T);
   remove_code_paths([]) ->
       ok.
   
  -%%--------------------------------------------------------------------
   %% @doc
   %%  Return wether the directory is in the list of ignorables. If it
   %%  is then return true, otherwise return false.
  -%% @spec (Directory, ListOfIgnores) -> true | false
  -%% @end
  -%% @private
  -%%--------------------------------------------------------------------
  +%% @end
  +-spec is_dir_ignorable(Directory::string(), ListOfIgnores::[string()]) ->
  +    boolean().
   is_dir_ignorable(Sub, [Ignore | Rest]) ->
       case ignore_dir(Sub, Ignore) of
  -        true ->
  -            true;
  -        false ->
  -            is_dir_ignorable(Sub, Rest)
  +	true ->
  +	    true;
  +	false ->
  +	    is_dir_ignorable(Sub, Rest)
       end;
   is_dir_ignorable(_Sub, []) ->
       false.
   
  -
  -
   %%====================================================================
   %% Internal functions
   %%====================================================================
  -%%-------------------------------------------------------------------
   %% @doc
   %%  Copies the file specified by file to the target specified by
   %%  ifile.
  -%% @spec (Target, IFile, File) -> ok
  -%% @end
  -%% @private
  -%%-------------------------------------------------------------------
  +%% @end
  +-spec copy_file(Target::string(), IFile::string(), File::string()) -> ok.
   copy_file(_Target, [$. | _], _File) ->
  -    ok;
  +	     ok;
   copy_file(Target, IFile, File) ->
       NFile = filename:join([Target, IFile]),
       case sin_sig:target_changed(File, NFile) of
  -        file_not_found ->
  -            ewl_talk:say("File ~s is not does not exist in the file "
  -                         "System. This shouldn't happen.", [File]),
  -            throw(file_not_on_disc);
  -        unable_to_access ->
  -            ewl_talk:say("File ~s exists but is inaccessable.", [File]),
  -            throw(file_inaccessable);
  -        true ->
  -            {ok, FileInfo} = file:read_file_info(File),
  -            file:copy(File, NFile),
  -            file:write_file_info(NFile, FileInfo);
  -        _ ->
  -            ok
  -    end.
  -
  -
  -%%--------------------------------------------------------------------
  -%% @doc
  -%%  Delete the directory and all of its sub directories.
  -%% @spec (Dir) -> ok
  -%% @end
  -%% @private
  -%%--------------------------------------------------------------------
  -delete_dir(Dir) ->
  -    case file:list_dir(Dir) of
  -        {ok, Files} ->
  -            lists:foldl(fun(File, _Acc) ->
  -                                NFile = filename:join([Dir, File]),
  -                                case filelib:is_dir(NFile) of
  -                                    true ->
  -                                        case is_symlink(NFile) of
  -                                            true ->
  -                                                file:delete(NFile);
  -                                            false ->
  -                                                delete_dir(NFile)
  -                                        end;
  -                                    false ->
  -                                        file:delete(NFile)
  -                                end
  -                        end, [], Files),
  -            file:del_dir(Dir);
  -        _ ->
  -            ok
  -    end.
  -
  -
  -%%--------------------------------------------------------------------
  +	file_not_found ->
  +	    ewl_talk:say("File ~s is not does not exist in the "
  +		       "file System. This shouldn't happen.",
  +			 [File]),
  +	    throw(file_not_on_disc);
  +	unable_to_access ->
  +	    ewl_talk:say("File ~s exists but is inaccessable.",
  +			 [File]),
  +	    throw(file_inaccessable);
  +	true ->
  +	    {ok, FileInfo} = file:read_file_info(File),
  +	    file:copy(File, NFile),
  +	    file:write_file_info(NFile, FileInfo);
  +	_ ->
  +	    ok
  +    end.
  +
   %% @doc
   %%  Check to see if the file is a symlink.
  -%% @spec (Name) -> true | false
  -%% @end
  -%%--------------------------------------------------------------------
  -is_symlink(Name) ->
  -    case catch file:read_link_info(Name) of
  -        {ok, Env} ->
  -            Env#file_info.type == symlink;
  -        _Else ->
  -            false
  -    end.
  -
  -%%--------------------------------------------------------------------
  -%% @doc
  -%%  Check the directory against teh possible ignores to see if the
  +%% @end
  +-spec is_symlink(FileName::string()) -> boolean.
  +is_symlink(FileName) ->
  +    case catch file:read_link_info(FileName) of
  +	{ok, Env} ->
  +	    Env#file_info.type == symlink;
  +	_Else ->
  +	    false
  +    end.
  +
  +%% @doc
  +%%  Check the directory against the possible ignores to see if the
   %%  prefix matches.
  -%% @spec (Directory, PossibleIgnorePrefix) -> true | false
  -%% @end
  -%% @private
  -%%--------------------------------------------------------------------
  +%% @end
  +-spec ignore_dir(Directory::string(), PossibleIgnorePrefix::[string()]) ->
  +    boolean().
   ignore_dir([Char | SubRest], [Char | IgRest]) ->
       ignore_dir(SubRest, IgRest);
   ignore_dir(_Sub, []) ->
  
positive.code: %%% @doc
  %%%  A group of utility functions for project automation.
  %%% @end
  %%% @copyright (C) 2007, Erlware
  %%%---------------------------------------------------------------------------
  -module(sin_utils).
  
  -include_lib("kernel/include/file.hrl").
  -include_lib("eunit/include/eunit.hrl").
  
  -include("internal.hrl").
  
  %% API
  -export([copy_dir/2,
  	 copy_dir/3,
           copy_dir/4,
  	 to_bool/1,
           parent_dir/1,
           delete_dir/1,
           remove_code_paths/1,
  	 get_application_env/1,
           is_dir_ignorable/2,
           file_exists/1,
           find_project_root/1,
  	 term_to_list/1,
  	 get_ignore_dirs/1]).
  
  
  %%====================================================================
  %% API
  %%====================================================================
  %%-------------------------------------------------------------------
  %% @doc
  %%  Trivially convert a value to a boolean
  %%
  %% @spec (Values) -> true | false
  %% @end
  %%-------------------------------------------------------------------
  to_bool(true) ->
      true;
  to_bool("True") ->
  
negative.code:     % Create a directory in /tmp for the test. Clean everything afterwards
      {ok, BaseDir} = ewl_file:create_tmp_dir("/tmp"),
      {setup,
       fun () ->
  	     ok = file:make_dir(filename:join(BaseDir, "app_name")),
  	     ok = file:make_dir(filename:join(BaseDir, "ebin")),
  	     ok = file:make_dir(filename:join(BaseDir, "doc"))
       end,
       fun (_) ->
  	     ewl_file:delete_dir(BaseDir) end,
       fun (_) ->
  	     TargetDir = filename:join(BaseDir, "app_name"),
  	     BuildDir = filename:join(TargetDir,
  				      "_build/development/apps/app_name"),
  	     {timeout, 2,
  	      ?_assertThrow(circular_recursion,
  			    (sin_utils:copy_dir(BuildDir, TargetDir, [],
  						["."])))}
       end}.
  