   system. Instead, you start one or more applications, each with their own
   initialization and termination logic.
 
-  Applications also provide an "application environment", which provides one
-  mechanism for configuring long running applications. We will learn more about
-  the tooling, start and shutdown and the application environment in the next
-  sections.
-
-  ## Start and shutdown
-
-  Starting an application is done via the "application module callback", which
-  is a module that defines the `start/2` function. The `start/2` function should
-  then start a supervisor, which is often called as the top-level supervisor, since
-  it sits at the root of a potentially long supervision tree. When the system is
-  shutting down, all applications shut down their top-level supervisor, which
-  terminates children in the opposite order they are started.
-
-  Shutting down a live system cleanly can be done by calling `System.stop/1`.
-  It will shut down all applications in the opposite order they are started.
-  Each application will then shutdown its top-level supervisor, if one is
-  available, [which then shuts down its children](Supervisor.html#module-start-and-shutdown).
+  When an application is started, the runtime loads it if it hasn't been loaded
+  yet (in the technical sense described above). Then, it checks if the
+  dependencies listed in the `applications` key of the resource file are already
+  started. Having at least one dependency not started is an error condition, but
+  when you start an application with `mix run`, Mix takes care of starting all
+  the dependencies for you, so in practice you don't need to worry about it
+  unless you are starting applications manually with the API provided by this
+  module.
+
+  If the application does not have a callback module configured, starting is
+  done at this point. Otherwise, its `c:start/2` callback if invoked. The PID of
+  the top-level supervisor returned by this function is stored by the runtime
+  for later use, and the returned application state is saved too, if any.
+
+  ### Stopping applications
+
+  Started applications are, finally, *stopped*:
+
+      Application.stop(:ex_unit)
+      #=> :ok
+
+  Stopping an application without a callback module is defined, but except for
+  some system tracing, it is in practice a no-op.
+
+  Stopping an application with a callback module has three steps:
+
+  1. If present, invoke the optional callback `c:prep_stop/1`.
+  2. Terminate the top-level supervisor.
+  3. Invoke the required callback `c:stop/1`.
+
+  The arguments passed to the callbacks are related to the state optionally
+  returned by `c:start/2`, and are documented in the section about the callback
+  module above.
+
+  It is important to highlight that step 2 is a blocking one. Termination of a
+  supervisor triggers a recursive chain of children terminations, therefore
+  orderly shutting down all descendant processes. The `c:stop/1` callback is
+  invoked only after termination of the whole supervision tree.
+
+  Shutting down a live system cleanly can be done by calling `System.stop/1`. It
+  will shut down every application in the opposite order they had been started.
 
   From Erlang/OTP 19.1, a SIGTERM from the operating system will automatically
   translate to `System.stop/0`. Erlang/OTP 20 gives user more explicit control
   over OS signals via the `:os.set_signal/2` function.
-
-  ### Application module callback
-
-  An application may start and stop a supervision tree when it boots via
-  the application module callback.
-
-  The first step is to pass the module callback in the application definition
-  in the `mix.exs` file:
-
-      def application do
-        [mod: {MyApp, []}]
-      end
-
-  Our application now requires the `MyApp` module to provide an application
-  callback. This can be done by invoking `use Application` in that module and
-  defining a `start/2` callback, for example:
-
-      defmodule MyApp do
-        use Application
-
-        def start(_type, _args) do
-          children = []
-          Supervisor.start_link(children, strategy: :one_for_one)
-        end
-      end
-
-  `start/2` typically returns `{:ok, pid}` or `{:ok, pid, state}` where
-  `pid` identifies the supervision tree and `state` is the application state.
-  `args` is the second element of the tuple given to the `:mod` option.
-
-  The `type` argument passed to `start/2` is usually `:normal` unless in a
-  distributed setup where application takeovers and failovers are configured.
-  Distributed applications is beyond the scope of this documentation. For those
-  interested on the topic, please access the Erlang/OTP documentation:
-
-    * [`:application` module](http://www.erlang.org/doc/man/application.html)
-    * [Applications – OTP Design Principles](http://www.erlang.org/doc/design_principles/applications.html)
-
-  When an application is shutting down, its `c:stop/1` callback is called after
-  the supervision tree has been stopped by the runtime. This callback allows the
-  application to do any final cleanup. The argument is the state returned by
-  `c:start/2`, if it did, or `[]` otherwise. The return value of `c:stop/1` is
-  ignored.
-
-  By using `Application`, modules get a default implementation of `c:stop/1`
-  that ignores its argument and returns `:ok`, but it can be overridden.
-
-  Application callback modules may also implement the optional callback
-  `c:prep_stop/1`. If present, `c:prep_stop/1` is invoked before the supervision
-  tree is terminated. Its argument is the state returned by `c:start/2`, if it did,
-  or `[]` otherwise, and its return value is passed to `c:stop/1`.
-
-  An application without a supervision tree doesn't define an application
-  module callback in the application definition in `mix.exs` file. Even though
-  there is no module with application callbacks such as `start/2` and
-  `stop/1`, the application can be started and stopped the same way as an
-  application with a supervision tree.
 
   ## Tooling
 

  when tools must be shared between developers and not as deployment options.
  See `mix help archive.build` and `mix help escript.build` for more detail.

  ## Application environment

  Once an application is started, OTP provides an application environment
  that can be used to configure the application.

  Assuming you are inside a Mix project, you can edit the `application/0`
  function in the `mix.exs` file to the following:

      def application do
        [env: [hello: :world]]
      end

  In the application function, we can define the default environment values
  for our application. By starting your application with `iex -S mix`, you
  can access the default value:

      Application.get_env(:APP_NAME, :hello)
      #=> :world

  Applications and dependencies in Mix projects are typically configured
  via the `config/config.exs` file. For example, someone using your
  application can configure the `:hello` key as follows:

      config :APP_NAME, hello: :brand_new_world

  Keep in mind configuration files are only useful to configure static
  values. For example, if you need to configure your applications based
  on the system environment, the file system or on database entries,
  then those configurations are better placed at runtime. For example,
  one may configure applications dynamically via `put_env/3`.

  Keep in mind that each application is responsible for its environment.
  Do not use the functions in this module for directly accessing or modifying
  the environment of other applications (as it may lead to inconsistent
  data in the application environment).
  """

  @doc """

  @moduledoc """
  A module for working with applications and defining application callbacks.

  Applications are the idiomatic way to package software in Erlang/OTP. To get
  the idea, they are similar to the "library" concept common in other
  programming languages, but with some additional characteristics.

  An application is a component implementing some specific functionality, with a
  standardized directory structure, configuration, and lifecycle. Applications
  are *loaded*, *started*, and *stopped*.

  ## The application resource file

  Applications are specified in their [*resource
  file*](http://erlang.org/doc/man/app.html), which is a file called `APP.app`,
  where `APP` is the application name. For example, the application resource
  file of the OTP application `ex_unit` is called `ex_unit.app`.

  You'll find the resource file of an application in its `ebin` directory, it is
  generated automatically by Mix. Some of its keys are taken from the keyword
  lists returned by the `project/0` and `application/0` functions defined in
  `mix.exs`, and others are generated by Mix itself.

  You can learn more about the generation of application resource files in the
  documentation of `Mix.Tasks.Compile.App`, available as well by running `mix
  help compile.app`.

  ## The application environment

  The key `env` of an application resource file has a list of tuples that map
  atoms to terms, and its contents are known as the application *environment*.
  Note that this environment is unrelated to the operating system environment.

  By default, the environment of an application is an empty list. In a Mix
  project you can set that key in `application/0`:

      def application do
        [env: [redis_host: "localhost"]]
      end

  and the generated application resource file is going to have it included.

  The environment is available after loading the application, which is a process
  explained later:

      Application.load(:APP_NAME)
      #=> :ok

      Application.get_env(:APP_NAME, :redis_host)
      #=> "localhost"

  In Mix projects, the environment of the application and its dependencies can
  be overridden via the `config/config.exs` file. If you start the application
  with Mix, that configuration is available at compile time, and at runtime too,
  but take into account it is not included in the generated application resource
  file, and it is not available if you start the application without Mix.

  For example, someone using your application can override its `:redis_host`
  environment variable as follows:

      config :APP_NAME, redis_host: "redis.local"

  The function `put_env/3` allows dynamic configuration of the application
  environment, but as a rule of thumb each application is responsible for its
  own environment. Please do not use the functions in this module for directly
  accessing or modifying the environment of other applications.

  The application environment can be overriden via the `-config` option of
  `erl`, as well as command-line flags, as we are going to see below.

  ## The application callback module

  The `mod` key of an application resource file configures an application
  callback module and start argument:

      def application do
        [mod: {MyApp, []}]
      end

  This key is optional, only needed for applications that start a supervision tree.

  The `MyApp` module given to `:mod` needs to implement the `Application` behaviour.
  This can be done by putting `use Application` in that module and implementing the
  `c:start/2` callback, for example:

      defmodule MyApp do
        use Application

        def start(_type, _args) do
          children = []
          Supervisor.start_link(children, strategy: :one_for_one)
        end
      end

  The `c:start/2` callback has to spawn and link a supervisor and return `{:ok,
  pid}` or `{:ok, pid, state}`, where `pid` is the PID of the supervisor, and
  `state` is an optional application state. `args` is the second element of the
  tuple given to the `:mod` option.

  The `type` argument passed to `c:start/2` is usually `:normal` unless in a
  distributed setup where application takeovers and failovers are configured.
  Distributed applications are beyond the scope of this documentation.

  When an application is shutting down, its `c:stop/1` callback is called after
  the supervision tree has been stopped by the runtime. This callback allows the
  application to do any final cleanup. The argument is the state returned by
  `c:start/2`, if it did, or `[]` otherwise. The return value of `c:stop/1` is
  ignored.

  By using `Application`, modules get a default implementation of `c:stop/1`
  that ignores its argument and returns `:ok`, but it can be overridden.

  Application callback modules may also implement the optional callback
  `c:prep_stop/1`. If present, `c:prep_stop/1` is invoked before the supervision
  tree is terminated. Its argument is the state returned by `c:start/2`, if it did,
  or `[]` otherwise, and its return value is passed to `c:stop/1`.

  ## The application lifecycle

  ### Loading applications

  Applications are *loaded*, which means that the runtime finds and processes
  their resource files:

      Application.load(:ex_unit)
      #=> :ok

  If an application has included applications, they are also loaded. And the
  procedure recurses if they in turn have included applications. Included
  applications are unrelated to applications in Mix umbrella projects, they are
  an Erlang/OTP concept that has to do with coordinated starts.

  When an application is loaded, the environment specified in its resource file
  is merged with any overrides from config files passed to `erl` via the
  `-config` option. It is worth highlighting that releases pass `sys.config`
  this way. The resulting environment can still be overridden again via specific
  `-Application` flags passed to `erl`.

  Loading an application *does not* load its modules.

  In practice, you rarely load applications by hand because that is part of the
  start process, explained next.

  ### Starting applications

  Applications are also *started*:

      Application.start(:ex_unit)
      #=> :ok

  Once your application is compiled, running your system is a matter of starting
  your current application and its dependencies. Differently from other languages,
