Instantiate BufferWriter in RuntimeEnvironment

This commit removes the OutputGates and moves their functionality to
the BufferWriters.

The BufferWriters are instantiated not by the user code any longer, but
by the RuntimeEnvironment. The user code get get access to the writers
via the new environment methods getWriter(int) and getAllWriters().

Previously, the writers, output gates, and output channels were
instantiated as follows (which was hard to follow):

1. Runtime environment (RTE) instantiates AbstractInvokable (AI)
2. AI instantiates BufferWriters (BW)
3. BW instantiates OutputGate (OG)
   BW registers OG with RTE
4. RTE instantiates OutputChannels (OC)

Among other things, this resulted in the problem that the user code
could not access the number of output channels before their invoke()
call.

Now it looks like follows:

1. RTE instantiates BufferWriters (BW) with OCs.
2. AI gets writers from RTE
Introduce BufferPool class

A BufferPool is a convenience class implementing LocalBufferPoolOwner
and BufferProvider. It delegates all buffer related methods to a
LocalBufferPool.
Fixup
Move input buffer pools to RuntimeEnvironment

Every InputGate was implementing LocalBufferPoolOwner and InputChannels
were implementing BufferProvider, which delegated buffer requests to
their respective gate.

This logic has been unified at the RuntimeEnvironment, which now holds
the input buffer pools.