src/stream/pipe.js
function _gpfStreamPipeToFlushableWrite (intermediate, destination) {
    var state = _gpfStreamPipeAllocateState(intermediate, destination),
        read = _gpfStreamPipeAllocateRead(state),
        iFlushableIntermediate = state.iFlushableIntermediate,
        iFlushableDestination = state.iFlushableDestination,
        iWritableIntermediate = state.iWritableIntermediate;

    read();

    return {

        flush: function () {
            return _gpfStreamPipeCheckIfReadError(state) || iFlushableIntermediate.flush()
                .then(function () {
                    return iFlushableDestination.flush();
                });
        },

        write: function (data) {
            read();
            return _gpfStreamPipeCheckIfReadError(state)
                || _gpfStreamPipeWrapWrite(state, iWritableIntermediate.write(data));
        }

    };
}
function _gpfStreamPipeToFlushableWrite (intermediate, destination) {
    var state = _gpfStreamPipeAllocateState(intermediate, destination),
        read = _gpfStreamPipeAllocateRead(state),
        iFlushableIntermediate = state.iFlushableIntermediate,
        iFlushableDestination = state.iFlushableDestination,
        iWritableIntermediate = state.iWritableIntermediate;

    read();

    return {

        flush: function () {
            return _gpfStreamPipeCheckIfReadError(state) || iFlushableIntermediate.flush()
                .then(function () {
                    return iFlushableDestination.flush();
                });
        },

        write: function (data) {
            read();
            return _gpfStreamPipeCheckIfReadError(state)
                || _gpfStreamPipeWrapWrite(state, iWritableIntermediate.write(data));
        }

    };
}
function _gpfStreamPipeToFlushableWrite ( intermediate , destination ) { var state = _gpfStreamPipeAllocateState ( intermediate , destination ) , read = _gpfStreamPipeAllocateRead ( state ) , iFlushableIntermediate = state . iFlushableIntermediate , iFlushableDestination = state . iFlushableDestination , iWritableIntermediate = state . iWritableIntermediate ; read ( ) ; return { flush : function ( ) { return _gpfStreamPipeCheckIfReadError ( state ) || iFlushableIntermediate . flush ( ) . then ( function ( ) { return iFlushableDestination . flush ( ) ; } ) ; } , write : function ( data ) { read ( ) ; return _gpfStreamPipeCheckIfReadError ( state ) || _gpfStreamPipeWrapWrite ( state , iWritableIntermediate . write ( data ) ) ; } } ; }
Create a flushable & writable stream by combining the intermediate stream with the writable destination

@param {Object} intermediate Must implements IReadableStream interface.
If it implements the IFlushableStream interface, it is assumed that it retains data
until it receives the Flush. Meaning, the read won't complete until the flush call.
If it does not implement the IFlushableStream, the read may end before the whole sequence
has finished. It means that the next write should trigger a new read and flush must be simulated at
least to pass it to the destination
@param {Object} destination Must implements IWritableStream interface.
If it implements the IFlushableStream, it will be called when the intermediate completes.

@return {Object} Implementing IWritableStream and IFlushableStream
@since 0.2.3
Create a flushable & writable stream by combining the intermediate stream with the writable destination