class MouseInputHandler extends MotionInputHandler<K> {

    @Override
    public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
        if (mHandledTapUp) {
            if (VERBOSE) {
                Log.v(TAG,
                        "Ignoring onSingleTapConfirmed, previously handled in onSingleTapUp.");
            }
            mHandledTapUp = false;
            return false;
        }

        if (mSelectionTracker.hasSelection()) {
            return false;  // should have been handled by onSingleTapUp.
        }

        if (!mDetailsLookup.overItem(e)) {
            if (DEBUG) Log.d(TAG, "Ignoring Confirmed Tap on non-item.");
            return false;
        }

        if (MotionEvents.isTertiaryMouseButtonPressed(e)) {
            if (DEBUG) Log.d(TAG, "Ignoring middle click");
            return false;
        }

        @Nullable ItemDetails<K> item = mDetailsLookup.getItemDetails(e);
        if (item == null || !item.hasSelectionKey()) {
            return false;
        }

        if (mFocusDelegate.hasFocusedItem() && MotionEvents.isShiftKeyPressed(e)) {
            mSelectionTracker.startRange(mFocusDelegate.getFocusedPosition());
            mSelectionTracker.extendRange(item.getPosition());
        } else {
            selectOrFocusItem(item, e);
        }
        return true;
    }

      MouseInputHandler(
            @NonNull SelectionTracker<K> selectionTracker,
            @NonNull ItemKeyProvider<K> keyProvider,
            @NonNull ItemDetailsLookup<K> detailsLookup,
            @NonNull OnContextClickListener onContextClickListener,
            @NonNull OnItemActivatedListener<K> onItemActivatedListener,
            @NonNull FocusDelegate<K> focusDelegate);

}