code: public final Stream<T> onClose(final Object... objects) {
          synchronized (this.state) {
              for (final Object object : objects) {
                  if (!(object instanceof Closeable) && !(object instanceof Runnable)
                          && !(object instanceof Callable)) {
                      throw new IllegalArgumentException("Illegal object: " + object);
                  } else if (this.state.closed) {
                      closeAction(object);
                  } else {
                      boolean alreadyContained = false;
                      for (final Object o : this.state.closeObjects) {
                          if (o == object) {
                              alreadyContained = true;
                              break;
                          }
                      }
                      if (!alreadyContained) {
                          this.state.closeObjects.add(object);
                      }
                  }
              }
          }
          return this;
      }
docs: Register zero or more objects for activation when this {@code Stream} will be closed. Each
  supplied object can be a {@code Closeable}, in which case method {@link Closeable#close()}
  will be called, a {@code Runnable}, in which case method {@link Runnable#run()} will be
  called, or a {@code Callable}, in which casle method {@link Callable#call()} will be
  called; any other type of object will be rejected resulting in an exception. In case the
  {@code Stream} has already been closed, activation of supplied objects will be done
  immediately.
  
  @param objects
  the objects to activate when the {@code Stream} will be closed
  @return this {@code Stream}, for call chaining.