Working towards model separation: API, DSL and ConfigModel

Working towards model separation, from the user configuration perspective.

Current situation
=================
There is one model, which is the Groovy DSL that's used to configure the pipeline from the `project.pipe` file. This DSL is directly executed, which limits what can be done with the content of the DSL.

Wanted situation
================
The Pipeline DSL defines the pipeline configuration. From the DSL a model is configured, lets call the model `configuration-model` for now.

This has the advantages of:

- the DSL is decoupled from the rest of the application/services/tooling, because of which
    - the DSL can be purely focused on describing the pipeline domain
    - the DSL can come from multiple source, even in pieces
    - the DSL can be syntactically validated without anything more than the DSL API (aka very light weight)
    - the DSL can evolve independently from the rest of the application/services/tooling (as long as it configures a model the rest can work with)
    - different DSL implementations are possible
- the configuration model, that the Pipeline DSL configures, is an entry-point into the Pipeline services. An API.
    - the API implementation is provided to the DSL (aka, the DSL asks the API for an implementation of the API)
    - the Pipeline services can work with the configuration as it sees fit
    - the configuration model evolves with the Pipeline services
- as both DSL and configuration model can be versioned separately, backwards compatibility is easier to support by providing configuration model implementations for all major configuration model API versions and internally map them to latest model
- ease of usage of the users of the DSL
- ease of usage of the users of the configuration model

Of course, there are always disadvantages to be found:

- maintaining multiple configuration model versions can become a burden
    - possible fix for this could be a phasing out process/ruling
- plugin development is possibly two-sided, DSL and configuration model
- backwards compatibility testing of APIs


Scenarios
=========

DSL is API implementation agnostic
----------------------------------
_Given_ the API provides a way of getting an implementation for the API model
_And_ the DSL asks the API for an implementation of the API model
_When_ the DSL asks the API for an implementation of the API model
_Then_ then the DSL can be API model implementation agnostic

API entry point
---------------
_Given_ the API provides an entry-point to pass an API model
_And_ the DSL exports its content to the API model
_When_ the DSL provides the exported API model to the API
_Then_ the API handles the processing of the API model

Implementation ideas
--------------------

### DSL is API implementation agnostic

API:

    T ApiProvider#get(Class<T> clazz)

Usage:

    Pipeline line = ApiProvider.get(Pipeline.class)

### API entry point

API:

    void PipelineProcessor#process(Pipeline pipeline)

Usage:

    Pipeline line = ApiProvider.get(Pipeline.class)
    PipelineProcessor proc = ApiProvider.get(PipelineProcessor.class)
    proc.process(line)