private static Observable<PresenterEvent> setupNotificationAndIndicationBehaviour(RxBleConnection connection,
                                                                                      BluetoothGattCharacteristic characteristic,
                                                                                      Observable<Boolean> enableNotifyClicks,
                                                                                      Observable<Boolean> enablingNotifyClicks,
                                                                                      Observable<Boolean> disableNotifyClicks,
                                                                                      Observable<Boolean> enableIndicateClicks,
                                                                                      Observable<Boolean> enablingIndicateClicks,
                                                                                      Observable<Boolean> disableIndicateClicks) {
        // checking if characteristic will potentially need a compatibility mode notifications
        final NotificationSetupMode notificationSetupMode =
                characteristic.getDescriptor(clientCharacteristicConfigDescriptorUuid) == null
                        ? NotificationSetupMode.COMPAT
                        : NotificationSetupMode.DEFAULT;
        /*
         * wrapping observables for notifications and indications so they will emit FALSE and TRUE respectively.
         * this is needed because only one of them may be active at the same time and we need to differentiate
         * the clicks
         */
        final Observable<Boolean> enableNotifyClicksObservable = !hasProperty(characteristic, PROPERTY_NOTIFY)
                /*
                 * if property for notifications is not available return Observable.never() dummy observable.
                 * Observable.never() is needed because of the Observable.amb() below which repeats
                 * the behaviour of Observable that first emits or terminates and it will be checking both
                 * notifyClicks and indicateClicks
                 */
                ? Observable.never()
                // only the first click to enableNotifyClicks is taken to account
                : enableNotifyClicks.take(1).map(aBoolean -> Boolean.FALSE);
        final Observable<Boolean> enableIndicateClicksObservable =
                !hasProperty(characteristic, PROPERTY_INDICATE)
                        ? Observable.never()
                        : enableIndicateClicks.take(1).map(aBoolean -> Boolean.TRUE);

        // checking which notify or indicate will be clicked first the other is unsubscribed on click
        return Observable.amb(asList(
                enableNotifyClicksObservable,
                enableIndicateClicksObservable)
        )
                .flatMap(isIndication -> {
                    if (isIndication) { // if indication was clicked
                        return connection
                                // we setup indications
                                .setupIndication(characteristic, notificationSetupMode)
                                // use a convenience transformer for tearing down the notifications
                                .compose(takeUntil(enablingIndicateClicks, disableIndicateClicks))
                                // and wrap the emissions with a convenience function
                                .compose(transformToNotificationPresenterEvent(Type.INDICATE));
                    } else { // if notification was clicked
                        return connection
                                .setupNotification(characteristic, notificationSetupMode)
                                .compose(takeUntil(enablingNotifyClicks, disableNotifyClicks))
                                .compose(transformToNotificationPresenterEvent(Type.NOTIFY));
                    }
                })
                /*
                 * whenever the notification or indication is finished (by the user or an error) repeat from
                 * the clicks on notify / indicate
                 */
                .compose(repeatAfterCompleted())
                // at the beginning inform the activity about whether compat mode is being used
                .startWith(new CompatibilityModeEvent(
                        hasProperty(characteristic, PROPERTY_NOTIFY | PROPERTY_INDICATE)
                                && notificationSetupMode == NotificationSetupMode.COMPAT
                ));
    }
Presenter class for {@link AdvancedCharacteristicOperationExampleActivity}. Prepares the logic for the activity using passed
{@link Observable}s. Contains only static methods to show a purely reactive (stateless) approach.
<p>
The contract of the class is that it subscribes to the passed Observables only if a specific functionality is possible to use.
sample/src/main/java/com/polidea/rxandroidble2/sample/example4_characteristic/advanced/Presenter.java