This provides an abstraction which deals with configuring and running
programs. A Program is a static notion of a known program. A
ConfiguredProgram is a Program that has been found on the current
machine and is ready to be run (possibly with some user-supplied default
args). Configuring a program involves finding its location and if necessary
finding its version. There is also a ProgramConfiguration type which holds
configured and not-yet configured programs. It is the parameter to lots of
actions elsewhere in Cabal that need to look up and run programs. If we had
a Cabal monad, the ProgramConfiguration would probably be a reader or
state component of it.

One nice thing about using it is that any program that is
registered with Cabal will get some "configure" and ".cabal"
helpers like --with-foo-args --foo-path= and extra-foo-args.

There's also good default behavior for trying to find "foo" in
PATH, being able to override its location, etc.

There's also a hook for adding programs in a Setup.lhs script. See
hookedPrograms in UserHooks. This gives a
hook user the ability to get the above flags and such so that they
don't have to write all the PATH logic inside Setup.lhs.

A function to do any additional configuration after we have
located the program (and perhaps identified its version). It is
allowed to return additional flags that will be passed to the
program on every invocation.

Program invocations

This is used as an intermediate type between deciding how to call a program
and actually doing it. This provides the opportunity to the caller to
adjust how the program will be called. These invocations can either be run
directly or turned into shell or batch scripts.

Try to configure a specific program. If the program is already included in
the colleciton of unconfigured programs then we use any user-supplied
location and arguments. If the program gets configured sucessfully it gets
added to the configured collection.

Note that it is not a failure if the program cannot be configured. It's only
a failure if the user supplied a location and the program could not be found
at that location.

The reason for it not being a failure at this stage is that we don't know up
front all the programs we will need, so we try to configure them all.
To verify that a program was actually sucessfully configured use
requireProgram.