Implementing your own ObservableOperator (as well as FlowableTransformer) is more involved than creating an ObservableTransformer. Instead of composing a series of existing operators, you intercept the onNext(), onComplete(), onError(), and onSubscribe() calls from the upstream by implementing your own Observer instead. This Observer will then logically pass the onNext(), onComplete(), and onError() events to the downstream Observer in a way that fulfills the desired operation.
Say, you want to create your own doOnEmpty() operator that will execute an Action when onComplete() is called and no emissions have occurred. To create your own ObservableOperator<Downstream,Upstream> (where Upstream is the upstream ...