function buffer(event, flushAfterTimeout = false, _buffer = [], disposable) {
        let buffer = _buffer.slice();
        let listener = event(e => {
            if (buffer) {
                buffer.push(e);
            }
            else {
                emitter.fire(e);
            }
        });
        if (disposable) {
            disposable.add(listener);
        }
        const flush = () => {
            buffer === null || buffer === void 0 ? void 0 : buffer.forEach(e => emitter.fire(e));
            buffer = null;
        };
        const emitter = new Emitter({
            onWillAddFirstListener() {
                if (!listener) {
                    listener = event(e => emitter.fire(e));
                    if (disposable) {
                        disposable.add(listener);
                    }
                }
            },
            onDidAddFirstListener() {
                if (buffer) {
                    if (flushAfterTimeout) {
                        setTimeout(flush);
                    }
                    else {
                        flush();
                    }
                }
            },
            onDidRemoveLastListener() {
                if (listener) {
                    listener.dispose();
                }
                listener = null;
            }
        });
        if (disposable) {
            disposable.add(emitter);
        }
        return emitter.event;
    }
Buffers an event until it has a listener attached.

*NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned
event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the
returned event causes this utility to leak a listener on the original event.

@param event The event source for the new event.
@param flushAfterTimeout Determines whether to flush the buffer after a timeout immediately or after a
`setTimeout` when the first event listener is added.
@param _buffer Internal: A source event array used for tests.

@example
```
// Start accumulating events, when the first listener is attached, flush
// the event after a timeout such that multiple listeners attached before
// the timeout would receive the event
this.onInstallExtension = Event.buffer(service.onInstallExtension, true);
```