You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/04/06 11:05:49 UTC

[isis] branch master updated: ISIS-2297: commons: promotes Either to non internal API

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 9166b93a97 ISIS-2297: commons: promotes Either<T> to non internal API
9166b93a97 is described below

commit 9166b93a9748c8eaf15a74cda5a9a29e59f8d027
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Apr 6 13:05:40 2022 +0200

    ISIS-2297: commons: promotes Either<T> to non internal API
    
    - also add Railway<T> pattern
---
 .../applib/value/semantics/ValueDecomposition.java |   4 +-
 .../base/_Either.java => functional/Either.java}   |  43 ++--
 .../apache/isis/commons/functional/Railway.java    | 220 +++++++++++++++++++++
 .../org/apache/isis/commons/functional/Try.java    |  46 ++++-
 .../facets/all/described/MemberDescribedFacet.java |   4 +-
 ...erDescribedFacetWithImperativeTextAbstract.java |   4 +-
 ...MemberDescribedFacetWithStaticTextAbstract.java |   4 +-
 .../facets/all/named/MemberNamedFacet.java         |   4 +-
 ...MemberNamedFacetWithImperativeTextAbstract.java |   4 +-
 .../MemberNamedFacetWithStaticTextAbstract.java    |   4 +-
 .../facets/members/cssclassfa/CssClassFaFacet.java |   4 +-
 .../CssClassFaImperativeFacetAbstract.java         |   4 +-
 .../cssclassfa/CssClassFaStaticFacetAbstract.java  |   4 +-
 .../interactions/managed/ActionInteraction.java    |  29 +--
 .../managed/ActionInteractionHead.java             |   8 +-
 .../managed/CollectionInteraction.java             |  10 +-
 .../interactions/managed/ManagedAction.java        |   8 +-
 .../interactions/managed/MemberInteraction.java    |  14 +-
 .../interactions/managed/PropertyInteraction.java  |  16 +-
 .../interactions/managed/_BindingUtil.java         |  12 +-
 .../managed/nonscalar/DataTableModel.java          |   3 +-
 .../core/metamodel/spec/feature/ObjectFeature.java |  14 +-
 .../objects/OneToManyAssociationDefaultTest.java   |   4 +-
 .../viewer/javafx/ui/main/UiActionHandlerFx.java   |   8 +-
 .../vaadin/ui/pages/main/UiActionHandlerVaa.java   |   8 +-
 .../testdomain/interact/ActionInteractionTest.java |  10 +-
 .../testdomain/interact/CommandArgumentTest.java   |   4 +-
 .../testdomain/interact/NewParameterModelTest.java |  20 +-
 .../interact/ScalarParamNegotiationTest.java       | 116 +++++------
 .../testdomain/interact/SimulatedUiSubmit.java     |  12 +-
 .../isis/testdomain/value/ValueSemanticsTest.java  |   2 +-
 .../interaction/DomainObjectTesterFactory.java     |  16 +-
 .../viewer/resources/ObjectActionArgHelper.java    |  15 +-
 .../viewer/resources/_DomainResourceHelper.java    |  34 ++--
 .../converter/ConverterBasedOnValueSemantics.java  |  12 +-
 .../wicket/model/models/InlinePromptContext.java   |   4 +-
 .../viewer/wicket/model/models/ScalarModel.java    |   8 +-
 .../components/actions/ActionParametersForm.java   |   6 +-
 .../ui/components/property/PropertyEditForm.java   |   6 +-
 .../ui/components/widgets/select2/Select2.java     |  10 +-
 .../wicket/ui/panels/FormExecutorDefault.java      |  12 +-
 .../wicket/ui/panels/PromptFormAbstract.java       |   4 +-
 42 files changed, 511 insertions(+), 263 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
index 5eca73d4cb..891855fce5 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
@@ -19,12 +19,12 @@
 package org.apache.isis.applib.value.semantics;
 
 import org.apache.isis.applib.util.schema.CommonDtoUtils;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.schema.common.v2.TypedTupleDto;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
-public final class ValueDecomposition extends _Either<ValueWithTypeDto, TypedTupleDto> {
+public final class ValueDecomposition extends Either<ValueWithTypeDto, TypedTupleDto> {
     private static final long serialVersionUID = 1L;
 
     public static ValueDecomposition ofFundamental(final ValueWithTypeDto valueWithTypeDto) {
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Either.java b/commons/src/main/java/org/apache/isis/commons/functional/Either.java
similarity index 71%
rename from commons/src/main/java/org/apache/isis/commons/internal/base/_Either.java
rename to commons/src/main/java/org/apache/isis/commons/functional/Either.java
index 0f2cf76770..97849987ca 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Either.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Either.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.internal.base;
+package org.apache.isis.commons.functional;
 
 import java.io.Serializable;
 import java.util.Optional;
@@ -31,20 +31,17 @@ import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 
 /**
- * <h1>- internal use only -</h1>
+ * The {@link Either} type represents a value of one of two possible types (a disjoint union),
+ * referred to by {@code left} or {@code right}.
  * <p>
- *      A holder of either a left or right reference, only one of both can be present.
- * </p>
- * <p>
- * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
- * These may be changed or removed without notice!
- * </p>
+ * Factory methods {@link Either#left(Object)} and {@link Either#right(Object)}
+ * correspond to the two possible values.
  *
- * @since 2.0
+ * @since 2.0 {@index}
  */
 @RequiredArgsConstructor(access=AccessLevel.PROTECTED)
 @ToString @EqualsAndHashCode
-public class _Either<L, R> implements Serializable {
+public class Either<L, R> implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
@@ -53,12 +50,12 @@ public class _Either<L, R> implements Serializable {
 
     // -- FACTORIES
 
-    public static <L, R> _Either<L, R> left(final @NonNull L left) {
-        return new _Either<>(left, null);
+    public static <L, R> Either<L, R> left(final @NonNull L left) {
+        return new Either<>(left, null);
     }
 
-    public static <L, R> _Either<L, R> right(final @NonNull R right) {
-        return new _Either<>(null, right);
+    public static <L, R> Either<L, R> right(final @NonNull R right) {
+        return new Either<>(null, right);
     }
 
     // -- ACCESSORS
@@ -91,19 +88,19 @@ public class _Either<L, R> implements Serializable {
 
     // -- MAPPING
 
-    public final <T> _Either<T, R> mapLeft(final @NonNull Function<L, T> leftMapper){
+    public final <T> Either<T, R> mapLeft(final @NonNull Function<L, T> leftMapper){
         return isLeft()
-                ? _Either.left(leftMapper.apply(left))
-                : _Either.right(right);
+                ? Either.left(leftMapper.apply(left))
+                : Either.right(right);
     }
 
-    public final <T> _Either<L, T> mapRight(final @NonNull Function<R, T> rightMapper){
+    public final <T> Either<L, T> mapRight(final @NonNull Function<R, T> rightMapper){
         return isLeft()
-                ? _Either.left(left)
-                : _Either.right(rightMapper.apply(right));
+                ? Either.left(left)
+                : Either.right(rightMapper.apply(right));
     }
 
-    public final <X, Y> _Either<X, Y> map(
+    public final <X, Y> Either<X, Y> map(
             final @NonNull Function<L, X> leftMapper,
             final @NonNull Function<R, Y> rightMapper){
         return isLeft()
@@ -111,13 +108,13 @@ public class _Either<L, R> implements Serializable {
                 : right(rightMapper.apply(right));
     }
 
-    public final _Either<L, R> mapIfLeft(final @NonNull Function<L, _Either<L, R>> leftRemapper){
+    public final Either<L, R> mapIfLeft(final @NonNull Function<L, Either<L, R>> leftRemapper){
         return isLeft()
                 ? leftRemapper.apply(left)
                 : this;
     }
 
-    public final _Either<L, R> mapIfRight(final @NonNull Function<R, _Either<L, R>> rightRemapper){
+    public final Either<L, R> mapIfRight(final @NonNull Function<R, Either<L, R>> rightRemapper){
         return isLeft()
                 ? this
                 : rightRemapper.apply(right);
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Railway.java b/commons/src/main/java/org/apache/isis/commons/functional/Railway.java
new file mode 100644
index 0000000000..5644e01a3a
--- /dev/null
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Railway.java
@@ -0,0 +1,220 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.commons.functional;
+
+import java.io.Serializable;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.springframework.lang.Nullable;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * The {@link Railway} type represents a value of one of two possible types (a disjoint union)
+ * of {@link Success} or {@link Failure}.
+ * <p>
+ * Factory methods {@link Railway#success(Object)} and {@link Railway#failure(Object)}
+ * correspond to the two possible values.
+ *
+ * @apiNote It is a common functional programming convention, to map the success value <i>right</i>.
+ *
+ * @since 2.0 {@index}
+ */
+public interface Railway<F, S> {
+
+    // -- FACTORIES
+
+    public static <F, S> Success<F, S> success(final @Nullable S success) {
+        return new Success<>(success);
+    }
+
+    public static <F, S> Failure<F, S> failure(final @NonNull F failure) {
+        return new Failure<>(failure);
+    }
+
+    // -- PREDICATES
+
+    boolean isSuccess();
+    boolean isFailure();
+
+    // -- ACCESSORS
+
+    /**
+     * Optionally returns the contained {@code value} based on presence,
+     * that is, if its a {@link Success}.
+     */
+    Optional<S> getSuccess();
+    default S getSuccessElseFail() { return getSuccess().orElseThrow(); }
+    /**
+     * Optionally returns the contained {@code failure} based on presence,
+     * that is, if its a {@link Failure}.
+     */
+    Optional<F> getFailure();
+    default F getFailureElseFail() { return getFailure().orElseThrow(); }
+
+    // -- PEEKING
+
+    /**
+     * Peeks into the contained {@code success} if its a {@link Success}.
+     */
+    Railway<F, S> ifSuccess(final @NonNull Consumer<S> valueConsumer);
+    /**
+     * Peeks into the contained {@code failure} if its a {@link Failure}.
+     */
+    Railway<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer);
+
+    // -- MAPPING
+
+    /**
+     * Maps this {@link Railway} to another if its a {@link Success}.
+     * Otherwise if its a {@link Failure} acts as identity operator.
+     */
+    <R> Railway<F, R> mapSuccess(final @NonNull Function<S, R> successMapper);
+    /**
+     * Maps this {@link Railway} to another if its a {@link Failure}.
+     * Otherwise if its a {@link Success} acts as identity operator.
+     */
+    <R> Railway<R, S> mapFailure(final @NonNull Function<F, R> failureMapper);
+
+
+    // -- FOLDING
+
+    /**
+     * Maps the contained {@code success} or {@code failure} to a new value of type {@code R}
+     * using according mapping function {@code successMapper} or {@code failureMapper}.
+     */
+    <R> R fold(
+            final @NonNull Function<F, R> failureMapper,
+            final @NonNull Function<S, R> successMapper);
+
+    // -- CONCATENATION
+
+    /**
+     * <h1>Railway Pattern</h1>
+     * If this is a {@link Success}, the result is {@code other}.
+     * Otherwise if this is a {@link Failure} returns this.
+     * <p>
+     * In other words: if once failed stays failed
+     */
+    Railway<F, S> concatenate(final @NonNull Railway<F, S> other);
+
+    // -- SUCCESS
+
+    @lombok.Value
+    @RequiredArgsConstructor
+    final class Success<F, S> implements Railway<F, S>, Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final @NonNull S success;
+
+        @Override public boolean isSuccess() { return true; }
+        @Override public boolean isFailure() { return false; }
+
+        @Override public Optional<S> getSuccess() { return Optional.of(success); }
+        @Override public Optional<F> getFailure() { return Optional.empty(); }
+
+        @Override
+        public Success<F, S> ifSuccess(final @NonNull Consumer<S> valueConsumer) {
+            valueConsumer.accept(success);
+            return this;
+        }
+
+        @Override
+        public Success<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer) {
+            return this;
+        }
+
+        @Override
+        public <R> Success<F, R> mapSuccess(final @NonNull Function<S, R> successMapper) {
+            return Railway.success(successMapper.apply(success));
+        }
+
+        @Override
+        public <R> Success<R, S> mapFailure(final @NonNull Function<F, R> failureMapper) {
+            return Railway.success(success);
+        }
+
+        @Override
+        public <R> R fold(
+                final @NonNull Function<F, R> failureMapper,
+                final @NonNull Function<S, R> successMapper) {
+            return successMapper.apply(success);
+        }
+
+        @Override
+        public Railway<F, S> concatenate(final @NonNull Railway<F, S> other) {
+            return other;
+        }
+
+    }
+
+    // -- FAILURE
+
+    @lombok.Value
+    @RequiredArgsConstructor
+    final class Failure<F, S> implements Railway<F, S>, Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final @NonNull F failure;
+
+        @Override public boolean isSuccess() { return false; }
+        @Override public boolean isFailure() { return true; }
+
+        @Override public Optional<S> getSuccess() { return Optional.empty(); }
+        @Override public Optional<F> getFailure() { return Optional.of(failure); }
+
+        @Override
+        public Failure<F, S> ifSuccess(final @NonNull Consumer<S> valueConsumer) {
+            return this;
+        }
+
+        @Override
+        public Failure<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer) {
+            failureConsumer.accept(failure);
+            return this;
+        }
+
+        @Override
+        public <R> Failure<F, R> mapSuccess(final @NonNull Function<S, R> successMapper) {
+            return Railway.failure(failure);
+        }
+
+        @Override
+        public <R> Failure<R, S> mapFailure(final @NonNull Function<F, R> failureMapper) {
+            return Railway.failure(failureMapper.apply(failure));
+        }
+
+        @Override
+        public <R> R fold(
+                final @NonNull Function<F, R> failureMapper,
+                final @NonNull Function<S, R> successMapper) {
+            return failureMapper.apply(failure);
+        }
+
+        @Override
+        public Failure<F, S> concatenate(final @NonNull Railway<F, S> callable) {
+            return this;
+        }
+
+    }
+
+}
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Try.java b/commons/src/main/java/org/apache/isis/commons/functional/Try.java
index df78305561..f881dbe32e 100644
--- a/commons/src/main/java/org/apache/isis/commons/functional/Try.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Try.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.commons.functional;
 
+import java.io.Serializable;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.concurrent.Callable;
@@ -80,12 +81,12 @@ public interface Try<T> {
 
     /**
      * Optionally returns the contained {@code value} based on presence,
-     * this is, if its a {@link Success} and the value is not {@code null}.
+     * that is, if its a {@link Success} and the value is not {@code null}.
      */
     Optional<T> getValue();
     /**
      * Optionally returns the contained {@code failure} based on presence,
-     * this is, if its a {@link Failure}.
+     * that is, if its a {@link Failure}.
      */
     Optional<Throwable> getFailure();
 
@@ -124,16 +125,25 @@ public interface Try<T> {
      * Otherwise acts as identity operator.
      */
     Try<T> mapEmptyToFailure();
+    /**
+     * Maps this {@link Try} to {@link Either}
+     * using according mapping function {@code successMapper} or {@code failureMapper}.
+     * @apiNote It is a common functional programming convention, to map the success value <i>right</i>.
+     */
+    <L, R> Either<L, R> map(
+            final @NonNull Function<Throwable, L> failureMapper,
+            final @NonNull Function<Optional<T>, R> successMapper);
 
     // -- FOLDING
 
     /**
      * Maps the contained {@code value} or {@code failure} to a new value of type {@code R}
      * using according mapping function {@code successMapper} or {@code failureMapper}.
+     * @apiNote Order of arguments conforms to {@link #map(Function, Function)}
      */
     <R> R fold(
-            final @NonNull Function<Optional<T>, R> successMapper,
-            final @NonNull Function<Throwable, R> failureMapper);
+            final @NonNull Function<Throwable, R> failureMapper,
+            final @NonNull Function<Optional<T>, R> successMapper);
 
     // -- CONCATENATION
 
@@ -152,7 +162,8 @@ public interface Try<T> {
 
     @lombok.Value
     @RequiredArgsConstructor
-    final class Success<T> implements Try<T> {
+    final class Success<T> implements Try<T>, Serializable {
+        private static final long serialVersionUID = 1L;
 
         private final @Nullable T value;
 
@@ -213,18 +224,26 @@ public interface Try<T> {
 
         @Override
         public <R> R fold(
-                final @NonNull Function<Optional<T>, R> successMapper,
-                final @NonNull Function<Throwable, R> failureMapper) {
+                final @NonNull Function<Throwable, R> failureMapper,
+                final @NonNull Function<Optional<T>, R> successMapper) {
             return successMapper.apply(getValue());
         }
 
+        @Override
+        public <L, R> Either<L, R> map(
+                final @NonNull Function<Throwable, L> failureMapper,
+                final @NonNull Function<Optional<T>, R> successMapper) {
+            return Either.right(successMapper.apply(getValue()));
+        }
+
     }
 
     // -- FAILURE
 
     @lombok.Value
     @RequiredArgsConstructor
-    final class Failure<T> implements Try<T> {
+    final class Failure<T> implements Try<T>, Serializable {
+        private static final long serialVersionUID = 1L;
 
         private final @NonNull Throwable throwable;
 
@@ -286,11 +305,18 @@ public interface Try<T> {
 
         @Override
         public <R> R fold(
-                final @NonNull Function<Optional<T>, R> successMapper,
-                final @NonNull Function<Throwable, R> failureMapper) {
+                final @NonNull Function<Throwable, R> failureMapper,
+                final @NonNull Function<Optional<T>, R> successMapper) {
             return failureMapper.apply(throwable);
         }
 
+        @Override
+        public <L, R> Either<L, R> map(
+                final @NonNull Function<Throwable, L> failureMapper,
+                final @NonNull Function<Optional<T>, R> successMapper) {
+            return Either.left(failureMapper.apply(throwable));
+        }
+
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacet.java
index 26e83af67d..512f99e493 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacet.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.core.metamodel.facets.all.described;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
 import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
@@ -27,7 +27,7 @@ public interface MemberDescribedFacet
 extends
     Facet {
 
-    _Either<HasStaticText, HasImperativeText> getSpecialization();
+    Either<HasStaticText, HasImperativeText> getSpecialization();
 
     @Override
     default boolean isPopulateAllFacetRanks() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithImperativeTextAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithImperativeTextAbstract.java
index 174c4ad07b..926a9efc07 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithImperativeTextAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithImperativeTextAbstract.java
@@ -21,7 +21,7 @@ package org.apache.isis.core.metamodel.facets.all.described;
 import java.lang.reflect.Method;
 
 import org.apache.isis.applib.services.i18n.TranslationContext;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
@@ -45,7 +45,7 @@ implements MemberDescribedFacet {
     }
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<HasStaticText, HasImperativeText> specialization = _Either.right(this);
+    private final Either<HasStaticText, HasImperativeText> specialization = Either.right(this);
 
     protected MemberDescribedFacetWithImperativeTextAbstract(
             final Method method,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithStaticTextAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithStaticTextAbstract.java
index f9ba6e79c7..656b50474f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithStaticTextAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/MemberDescribedFacetWithStaticTextAbstract.java
@@ -19,7 +19,7 @@
 package org.apache.isis.core.metamodel.facets.all.described;
 
 import org.apache.isis.applib.services.i18n.TranslationContext;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
 import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
@@ -42,7 +42,7 @@ implements MemberDescribedFacet {
     }
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<HasStaticText, HasImperativeText> specialization = _Either.left(this);
+    private final Either<HasStaticText, HasImperativeText> specialization = Either.left(this);
 
     protected MemberDescribedFacetWithStaticTextAbstract(
             final String originalText,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacet.java
index ba7a6bfba4..8871cfc390 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacet.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.core.metamodel.facets.all.named;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
 import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
@@ -27,7 +27,7 @@ public interface MemberNamedFacet
 extends
     Facet {
 
-    _Either<HasStaticText, HasImperativeText> getSpecialization();
+    Either<HasStaticText, HasImperativeText> getSpecialization();
 
     @Override
     default boolean isPopulateAllFacetRanks() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithImperativeTextAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithImperativeTextAbstract.java
index 7b757fe971..f248ea4594 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithImperativeTextAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithImperativeTextAbstract.java
@@ -21,7 +21,7 @@ package org.apache.isis.core.metamodel.facets.all.named;
 import java.lang.reflect.Method;
 
 import org.apache.isis.applib.services.i18n.TranslationContext;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
@@ -45,7 +45,7 @@ implements MemberNamedFacet {
     }
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<HasStaticText, HasImperativeText> specialization = _Either.right(this);
+    private final Either<HasStaticText, HasImperativeText> specialization = Either.right(this);
 
     protected MemberNamedFacetWithImperativeTextAbstract(
             final Method method,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithStaticTextAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithStaticTextAbstract.java
index 04095ea7c4..f844f2dec4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithStaticTextAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/MemberNamedFacetWithStaticTextAbstract.java
@@ -19,7 +19,7 @@
 package org.apache.isis.core.metamodel.facets.all.named;
 
 import org.apache.isis.applib.services.i18n.TranslationContext;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.i8n.imperative.HasImperativeText;
 import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
@@ -42,7 +42,7 @@ implements MemberNamedFacet {
     }
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<HasStaticText, HasImperativeText> specialization = _Either.left(this);
+    private final Either<HasStaticText, HasImperativeText> specialization = Either.left(this);
 
     protected MemberNamedFacetWithStaticTextAbstract(
             final String originalText,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaFacet.java
index a0e8fb4687..ecb4b5c4ab 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaFacet.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.core.metamodel.facets.members.cssclassfa;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 
 /**
@@ -30,7 +30,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
  */
 public interface CssClassFaFacet extends Facet {
 
-    _Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> getSpecialization();
+    Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> getSpecialization();
 
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaImperativeFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaImperativeFacetAbstract.java
index 9c193eff03..955cc5bcfb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaImperativeFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaImperativeFacetAbstract.java
@@ -18,7 +18,7 @@ package org.apache.isis.core.metamodel.facets.members.cssclassfa;
 
 import java.util.function.BiConsumer;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -40,7 +40,7 @@ implements CssClassFaImperativeFacet {
     }
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> specialization = _Either.right(this);
+    private final Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> specialization = Either.right(this);
 
     protected CssClassFaImperativeFacetAbstract(
             final FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaStaticFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaStaticFacetAbstract.java
index 9ed8adc8c8..815f8eb391 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaStaticFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaStaticFacetAbstract.java
@@ -23,7 +23,7 @@ import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.layout.component.CssClassFaPosition;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -54,7 +54,7 @@ implements CssClassFaStaticFacet {
     private static final String DEFAULT_PRIMARY_PREFIX = "fa";
 
     @Getter(onMethod_ = {@Override})
-    private final _Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> specialization = _Either.left(this);
+    private final Either<CssClassFaStaticFacet, CssClassFaImperativeFacet> specialization = Either.left(this);
 
     @Getter(onMethod_ = {@Override}) private CssClassFaPosition position;
     private final List<String> cssClasses; // serializable list implementation
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
index 6f06a79946..6360f5405c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
@@ -23,7 +23,8 @@ import java.util.function.Function;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
+import org.apache.isis.commons.functional.Railway;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedMember.MemberType;
@@ -70,9 +71,9 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
 
         val managedAction = ManagedAction.lookupActionWithMultiselect(owner, memberId, where, multiselectChoices);
 
-        final _Either<ManagedAction, InteractionVeto> chain = managedAction.isPresent()
-                ? _Either.left(managedAction.get())
-                : _Either.right(InteractionVeto.notFound(MemberType.ACTION, memberId));
+        final Either<ManagedAction, InteractionVeto> chain = managedAction.isPresent()
+                ? Either.left(managedAction.get())
+                : Either.right(InteractionVeto.notFound(MemberType.ACTION, memberId));
 
         return new ActionInteraction(
                 managedAction.map(ManagedAction::getAction),
@@ -82,18 +83,18 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
     public static ActionInteraction wrap(final @NonNull ManagedAction managedAction) {
         return new ActionInteraction(
                 Optional.of(managedAction.getAction()),
-                _Either.left(managedAction));
+                Either.left(managedAction));
     }
 
     public static ActionInteraction empty(final String actionId) {
         return new ActionInteraction(
                 Optional.empty(),
-                _Either.right(InteractionVeto.notFound(MemberType.ACTION, actionId)));
+                Either.right(InteractionVeto.notFound(MemberType.ACTION, actionId)));
     }
 
     ActionInteraction(
             final @NonNull Optional<ObjectAction> metamodel,
-            final @NonNull _Either<ManagedAction, InteractionVeto> chain) {
+            final @NonNull Either<ManagedAction, InteractionVeto> chain) {
         super(chain);
         this.metamodel = metamodel;
     }
@@ -112,16 +113,16 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
 
             switch(semanticConstraint) {
             case NONE:
-                return _Either.left(action);
+                return Either.left(action);
 
             case IDEMPOTENT:
                 return actionSemantics.isIdempotentInNature()
-                        ? _Either.left(action)
-                        : _Either.right(InteractionVeto.actionNotIdempotent(action)) ;
+                        ? Either.left(action)
+                        : Either.right(InteractionVeto.actionNotIdempotent(action)) ;
             case SAFE:
                 return actionSemantics.isSafeInNature()
-                        ? _Either.left(action)
-                        : _Either.right(InteractionVeto.actionNotSafe(action));
+                        ? Either.left(action)
+                        : Either.right(InteractionVeto.actionNotSafe(action));
             default:
                 throw _Exceptions.unmatchedCase(semanticConstraint); // unexpected code reach
             }
@@ -140,11 +141,11 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
         void onParameterInvalid(ManagedParameter managedParameter, InteractionVeto veto);
     }
 
-    public _Either<ManagedObject, InteractionVeto> invokeWith(final ParameterNegotiationModel pendingArgs) {
+    public Railway<InteractionVeto, ManagedObject> invokeWith(final ParameterNegotiationModel pendingArgs) {
         pendingArgs.activateValidationFeedback();
         val veto = validate(pendingArgs);
         if(veto.isPresent()) {
-            return _Either.right(veto.get());
+            return Railway.failure(veto.get());
         }
         val action = chain.leftIfAny();
         val actionResultOrVeto = action.invoke(pendingArgs.getParamValues());
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteractionHead.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteractionHead.java
index 9b443fa8ea..4241baef6d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteractionHead.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteractionHead.java
@@ -24,8 +24,8 @@ import java.util.function.UnaryOperator;
 import org.springframework.lang.Nullable;
 
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -157,7 +157,7 @@ implements HasMetaModel<ObjectAction> {
     /**
      * Returns either a fixed point or the last iteration.
      */
-    private static <T> _Either<T, T> fixedPointSearch(
+    private static <T> Either<T, T> fixedPointSearch(
             final T start,
             final UnaryOperator<T> f,
             final int maxIterations) {
@@ -166,12 +166,12 @@ implements HasMetaModel<ObjectAction> {
         for(int i=0; i<maxIterations; ++i) {
             t1 = f.apply(t0);
             if(t1.equals(t0)) {
-                return _Either.left(t1);
+                return Either.left(t1);
             }
             t0 = t1;
         }
 
-        return _Either.right(t0);
+        return Either.right(t0);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
index af8b1cf1d6..87f889949a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
@@ -22,7 +22,7 @@ import java.util.Optional;
 import java.util.function.Function;
 
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedMember.MemberType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 
@@ -39,14 +39,14 @@ extends MemberInteraction<ManagedCollection, CollectionInteraction> {
 
         val managedCollection = ManagedCollection.lookupCollection(owner, memberId, where);
 
-        final _Either<ManagedCollection, InteractionVeto> chain = managedCollection.isPresent()
-                ? _Either.left(managedCollection.get())
-                : _Either.right(InteractionVeto.notFound(MemberType.COLLECTION, memberId));
+        final Either<ManagedCollection, InteractionVeto> chain = managedCollection.isPresent()
+                ? Either.left(managedCollection.get())
+                : Either.right(InteractionVeto.notFound(MemberType.COLLECTION, memberId));
 
         return new CollectionInteraction(chain);
     }
 
-    CollectionInteraction(@NonNull final _Either<ManagedCollection, InteractionVeto> chain) {
+    CollectionInteraction(@NonNull final Either<ManagedCollection, InteractionVeto> chain) {
         super(chain);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedAction.java
index 8ce88128f8..c0a21c9708 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedAction.java
@@ -28,8 +28,8 @@ import org.apache.isis.applib.services.inject.ServiceInjector;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.applib.services.routing.RoutingService;
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.functional.Railway;
 import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -123,7 +123,7 @@ public final class ManagedAction extends ManagedMember {
 
     // -- INTERACTION
 
-    public _Either<ManagedObject, InteractionVeto> invoke(
+    public Railway<InteractionVeto, ManagedObject> invoke(
             final @NonNull Can<ManagedObject> actionParameters,
             final @NonNull InteractionInitiatedBy interactionInitiatedBy) {
 
@@ -132,10 +132,10 @@ public final class ManagedAction extends ManagedMember {
                 // executions on value-types have no rule checking and trigger no domain events
                 .execute(interactionHead(), actionParameters, interactionInitiatedBy);
 
-        return _Either.left(route(actionResult));
+        return Railway.success(route(actionResult));
     }
 
-    public _Either<ManagedObject, InteractionVeto> invoke(
+    public Railway<InteractionVeto, ManagedObject> invoke(
             final @NonNull Can<ManagedObject> actionParameters) {
         return invoke(actionParameters, InteractionInitiatedBy.USER);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
index 27ac3fa4e7..94ace414ff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
@@ -21,8 +21,8 @@ package org.apache.isis.core.metamodel.interactions.managed;
 import java.util.Optional;
 import java.util.function.Function;
 
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Either;
 
 import lombok.NonNull;
 import lombok.val;
@@ -37,9 +37,9 @@ public abstract class MemberInteraction<T extends ManagedMember, H extends Membe
         }
     }
 
-    @NonNull protected _Either<T, InteractionVeto> chain;
+    @NonNull protected Either<T, InteractionVeto> chain;
 
-    protected MemberInteraction(@NonNull _Either<T, InteractionVeto> chain) {
+    protected MemberInteraction(@NonNull Either<T, InteractionVeto> chain) {
         this.chain = chain;
     }
 
@@ -47,8 +47,8 @@ public abstract class MemberInteraction<T extends ManagedMember, H extends Membe
         chain = chain.mapIfLeft(property->{
             val visibilityVeto = property.checkVisibility();
             return visibilityVeto.isPresent()
-                ? _Either.right(visibilityVeto.get())
-                : _Either.left(property);
+                ? Either.right(visibilityVeto.get())
+                : Either.left(property);
         });
         return _Casts.uncheckedCast(this);
     }
@@ -57,8 +57,8 @@ public abstract class MemberInteraction<T extends ManagedMember, H extends Membe
         chain = chain.mapIfLeft(property->{
             val usablitiyVeto = property.checkUsability();
             return usablitiyVeto.isPresent()
-                ? _Either.right(usablitiyVeto.get())
-                : _Either.left(property);
+                ? Either.right(usablitiyVeto.get())
+                : Either.left(property);
         });
         return _Casts.uncheckedCast(this);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
index e87cf5a0f9..6f22194456 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
@@ -22,7 +22,7 @@ import java.util.Optional;
 import java.util.function.Function;
 
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedMember.MemberType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 
@@ -39,18 +39,18 @@ extends MemberInteraction<ManagedProperty, PropertyInteraction> {
 
         val managedProperty = ManagedProperty.lookupProperty(owner, memberId, where);
 
-        final _Either<ManagedProperty, InteractionVeto> chain = managedProperty.isPresent()
-                ? _Either.left(managedProperty.get())
-                : _Either.right(InteractionVeto.notFound(MemberType.PROPERTY, memberId));
+        final Either<ManagedProperty, InteractionVeto> chain = managedProperty.isPresent()
+                ? Either.left(managedProperty.get())
+                : Either.right(InteractionVeto.notFound(MemberType.PROPERTY, memberId));
 
         return new PropertyInteraction(chain);
     }
 
     public static PropertyInteraction wrap(final @NonNull ManagedProperty managedProperty) {
-        return new PropertyInteraction(_Either.left(managedProperty));
+        return new PropertyInteraction(Either.left(managedProperty));
     }
 
-    PropertyInteraction(@NonNull final _Either<ManagedProperty, InteractionVeto> chain) {
+    PropertyInteraction(@NonNull final Either<ManagedProperty, InteractionVeto> chain) {
         super(chain);
     }
 
@@ -65,8 +65,8 @@ extends MemberInteraction<ManagedProperty, PropertyInteraction> {
         chain = chain.mapIfLeft(property->{
             val validityVeto = property.modifyProperty(newProperyValueProvider.apply(property));
             return validityVeto.isPresent()
-                ? _Either.right(validityVeto.get())
-                : _Either.left(property);
+                ? Either.right(validityVeto.get())
+                : Either.left(property);
         });
         return this;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
index cca181edec..2fd24dcf5d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
@@ -22,7 +22,7 @@ import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueSemanticsProvider.Context;
 import org.apache.isis.commons.binding.Observable;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.binding._BindableAbstract;
 import org.apache.isis.commons.internal.binding._Bindables;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -66,8 +66,8 @@ class _BindingUtil {
         return spec.lookupFacet(ValueFacet.class)
         .map(valueFacet->{
             val eitherRendererOrParser = format.requiresRenderer()
-                ? _Either.<Renderer, Parser>left(valueFacet.selectRendererForPropertyElseFallback(prop))
-                : _Either.<Renderer, Parser>right(valueFacet.selectParserForPropertyElseFallback(prop));
+                ? Either.<Renderer, Parser>left(valueFacet.selectRendererForPropertyElseFallback(prop))
+                : Either.<Renderer, Parser>right(valueFacet.selectParserForPropertyElseFallback(prop));
             val ctx = valueFacet.createValueSemanticsContext(prop);
 
             return bindAsFormated(format, spec, bindablePropertyValue, eitherRendererOrParser, ctx);
@@ -95,8 +95,8 @@ class _BindingUtil {
         return spec.lookupFacet(ValueFacet.class)
         .map(valueFacet->{
             val eitherRendererOrParser = format.requiresRenderer()
-                ? _Either.<Renderer, Parser>left(valueFacet.selectRendererForParameterElseFallback(param))
-                : _Either.<Renderer, Parser>right(valueFacet.selectParserForParameterElseFallback(param));
+                ? Either.<Renderer, Parser>left(valueFacet.selectRendererForParameterElseFallback(param))
+                : Either.<Renderer, Parser>right(valueFacet.selectParserForParameterElseFallback(param));
             val ctx = valueFacet.createValueSemanticsContext(param);
 
             return bindAsFormated(format, spec, bindableParamValue, eitherRendererOrParser, ctx);
@@ -147,7 +147,7 @@ class _BindingUtil {
             final @NonNull TargetFormat format,
             final @NonNull ObjectSpecification spec,
             final @NonNull _BindableAbstract<ManagedObject> bindableValue,
-            final @NonNull _Either<Renderer, Parser> eitherRendererOrParser,
+            final @NonNull Either<Renderer, Parser> eitherRendererOrParser,
             final @NonNull Context context) {
 
         switch (format) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
index cede0432fc..df7c3b758d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
@@ -291,7 +291,8 @@ implements MultiselectChoices {
             val managedAction = actionInteraction.getManagedActionElseFail();
             val args = argsMemento.getArgumentList(managedAction.getMetaModel());
             // invocation bypassing domain events (pass-through)
-            val actionResult = managedAction.invoke(args, InteractionInitiatedBy.PASS_THROUGH).left().orElseThrow();
+            val actionResult = managedAction.invoke(args, InteractionInitiatedBy.PASS_THROUGH)
+                    .getSuccessElseFail();
             return forAction(managedAction, args, actionResult);
         }
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
index 956694ae06..fb1e1a5f56 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
@@ -22,7 +22,7 @@ import java.util.Optional;
 import java.util.function.Supplier;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -92,11 +92,11 @@ public interface ObjectFeature extends Specification {
      * @see #getCanonicalFriendlyName()
      * @since 2.0
      */
-    default _Either<String, String> getStaticOrCanonicalFriendlyName() {
+    default Either<String, String> getStaticOrCanonicalFriendlyName() {
         val staticFriendlyName = getStaticFriendlyName();
         return staticFriendlyName.isPresent()
-                ? _Either.left(staticFriendlyName.get())
-                : _Either.right(getCanonicalFriendlyName());
+                ? Either.left(staticFriendlyName.get())
+                : Either.right(getCanonicalFriendlyName());
     }
 
     /**
@@ -138,12 +138,12 @@ public interface ObjectFeature extends Specification {
      * @see #getCanonicalDescription()
      * @since 2.0
      */
-    default Optional<_Either<String, String>> getStaticOrCanonicalDescription() {
+    default Optional<Either<String, String>> getStaticOrCanonicalDescription() {
         val staticDescription = getStaticDescription();
         return staticDescription.isPresent()
-                ? Optional.of(_Either.left(staticDescription.get()))
+                ? Optional.of(Either.left(staticDescription.get()))
                 : getCanonicalDescription()
-                    .map(_Either::right);
+                    .map(Either::right);
     }
 
     /**
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
index ca0fb2a04a..edb35f1ac9 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
@@ -21,7 +21,7 @@ package org.apache.isis.core.metamodel.objects;
 import org.junit.Test;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.MetaModelTestAbstract;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
 import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
@@ -58,7 +58,7 @@ extends MetaModelTestAbstract {
         when(mockHasStaticText.translated()).thenReturn("My name");
 
         val mockNamedFacet = mock(MemberNamedFacet.class);
-        when(mockNamedFacet.getSpecialization()).thenReturn(_Either.left(mockHasStaticText));
+        when(mockNamedFacet.getSpecialization()).thenReturn(Either.left(mockHasStaticText));
 
         val mockPeer = mock(FacetedMethod.class);
         doReturn(COLLECTION_TYPE).when(mockPeer).getType();
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiActionHandlerFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiActionHandlerFx.java
index 0b60646e8d..f07af88e34 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiActionHandlerFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiActionHandlerFx.java
@@ -49,7 +49,7 @@ public class UiActionHandlerFx {
     private final InteractionService interactionService;
     private final UiComponentFactoryFx uiComponentFactory;
 
-    public void handleActionLinkClicked(ManagedAction managedAction) {
+    public void handleActionLinkClicked(final ManagedAction managedAction) {
 
         log.info("about to build an action prompt for {}", managedAction.getIdentifier());
 
@@ -104,8 +104,8 @@ public class UiActionHandlerFx {
     }
 
     private void invoke(
-            ManagedAction managedAction,
-            Can<ManagedObject> params) {
+            final ManagedAction managedAction,
+            final Can<ManagedObject> params) {
 
         interactionService.runAnonymous(()->{
 
@@ -113,7 +113,7 @@ public class UiActionHandlerFx {
 
             val actionResultOrVeto = managedAction.invoke(params);
 
-            actionResultOrVeto.left()
+            actionResultOrVeto.getSuccess()
             .ifPresent(actionResult->uiContext.route(actionResult));
 
         });
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/UiActionHandlerVaa.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/UiActionHandlerVaa.java
index fdee429b78..98b4be9d8b 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/UiActionHandlerVaa.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/UiActionHandlerVaa.java
@@ -43,7 +43,7 @@ public class UiActionHandlerVaa {
     private final InteractionService interactionService;
     private final UiComponentFactoryVaa uiComponentFactory;
 
-    public void handleActionLinkClicked(ManagedAction managedAction) {
+    public void handleActionLinkClicked(final ManagedAction managedAction) {
 
         log.info("about to build an action prompt for {}", managedAction.getIdentifier());
 
@@ -71,8 +71,8 @@ public class UiActionHandlerVaa {
     }
 
     private void invoke(
-            ManagedAction managedAction,
-            Can<ManagedObject> params) {
+            final ManagedAction managedAction,
+            final Can<ManagedObject> params) {
 
         interactionService.runAnonymous(()->{
 
@@ -80,7 +80,7 @@ public class UiActionHandlerVaa {
 
             val actionResultOrVeto = managedAction.invoke(params);
 
-            actionResultOrVeto.left()
+            actionResultOrVeto.getSuccess()
             .ifPresent(actionResult->uiContext.route(actionResult));
 
         });
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ActionInteractionTest.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ActionInteractionTest.java
index 44c122dfdf..67ad257387 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ActionInteractionTest.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ActionInteractionTest.java
@@ -152,7 +152,7 @@ class ActionInteractionTest extends InteractionTestAbstract {
 
         // we should not be able to invoke the action
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isRight());
+        assertTrue(resultOrVeto.isFailure());
 
         val tester =
                 testerFactory.actionTester(InteractionDemo.class, "noArgDisabled", Where.OBJECT_FORMS);
@@ -196,9 +196,9 @@ class ActionInteractionTest extends InteractionTestAbstract {
         pendingArgs.setParamValues(params);
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        assertEquals(46, (int)resultOrVeto.leftIfAny().getPojo());
+        assertEquals(46, (int)resultOrVeto.getSuccessElseFail().getPojo());
     }
 
     @Test
@@ -214,9 +214,9 @@ class ActionInteractionTest extends InteractionTestAbstract {
         pendingArgs.setParamValues(params);
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        assertEquals(12, (int)resultOrVeto.leftIfAny().getPojo());
+        assertEquals(12, (int)resultOrVeto.getSuccessElseFail().getPojo());
 
     }
 
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/CommandArgumentTest.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/CommandArgumentTest.java
index 079b49576a..a9f2afb0a8 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/CommandArgumentTest.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/CommandArgumentTest.java
@@ -106,9 +106,9 @@ class CommandArgumentTest extends InteractionTestAbstract {
         pendingArgs.setParamValue(0, objectManager.adapt(Arrays.asList(1L, 2L, 3L)));
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        val stringified = resultOrVeto.left()
+        val stringified = resultOrVeto.getSuccess()
                 .map(ManagedObject::getPojo)
                 .map(CommandResult.class::cast)
                 .map(CommandResult::getResultAsString)
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/NewParameterModelTest.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/NewParameterModelTest.java
index ff27c92a93..9e819bc4c4 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/NewParameterModelTest.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/NewParameterModelTest.java
@@ -24,6 +24,10 @@ import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.TestPropertySource;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.config.presets.IsisPresets;
@@ -37,10 +41,6 @@ import org.apache.isis.testdomain.model.interaction.InteractionNpmDemo;
 import org.apache.isis.testdomain.model.interaction.InteractionNpmDemo_biArgEnabled;
 import org.apache.isis.testdomain.util.interaction.InteractionTestAbstract;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 import lombok.val;
 
 @SpringBootTest(
@@ -101,9 +101,9 @@ class NewParameterModelTest extends InteractionTestAbstract {
         pendingArgs.setParamValues(params);
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        assertEquals(46, (int)resultOrVeto.leftIfAny().getPojo());
+        assertEquals(46, (int)resultOrVeto.getSuccessElseFail().getPojo());
     }
 
     @Test
@@ -119,9 +119,9 @@ class NewParameterModelTest extends InteractionTestAbstract {
         pendingArgs.setParamValues(params);
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        assertEquals(46, (int)resultOrVeto.leftIfAny().getPojo());
+        assertEquals(46, (int)resultOrVeto.getSuccessElseFail().getPojo());
     }
 
     @Test
@@ -137,9 +137,9 @@ class NewParameterModelTest extends InteractionTestAbstract {
         pendingArgs.setParamValues(params);
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-        assertTrue(resultOrVeto.isLeft());
+        assertTrue(resultOrVeto.isSuccess());
 
-        assertEquals(5, (int)resultOrVeto.leftIfAny().getPojo());
+        assertEquals(5, (int)resultOrVeto.getSuccessElseFail().getPojo());
     }
 
     @Test
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ScalarParamNegotiationTest.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ScalarParamNegotiationTest.java
index 8b7ddb5306..34f8010839 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ScalarParamNegotiationTest.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/ScalarParamNegotiationTest.java
@@ -39,10 +39,10 @@ import org.apache.isis.testdomain.util.interaction.InteractionTestAbstract;
 import lombok.val;
 
 @SpringBootTest(
-        classes = { 
+        classes = {
                 Configuration_headless.class,
                 Configuration_usingInteractionDomain.class
-        }, 
+        },
         properties = {
                 "isis.core.meta-model.introspector.mode=FULL",
                 "isis.applib.annotation.domain-object.editing=TRUE",
@@ -62,19 +62,19 @@ class ScalarParamNegotiationTest extends InteractionTestAbstract {
         RANGE_C,
         C;
     }
-    
+
     ParameterNegotiationModel pendingArgs;
-    
+
     SimulatedUiChoices uiParamRangeA;
     SimulatedUiChoices uiParamRangeB;
     SimulatedUiChoices uiParamRangeC;
-    
+
     SimulatedUiChoices uiParamA;
     SimulatedUiChoices uiParamB;
     SimulatedUiAutoComplete uiParamC;
-    
+
     SimulatedUiSubmit uiSubmit;
-    
+
     @BeforeEach
     void setUpSimulatedUi() {
 
@@ -83,81 +83,81 @@ class ScalarParamNegotiationTest extends InteractionTestAbstract {
                 .checkUsability();
 
         assertTrue(actionInteraction.getManagedAction().isPresent(), "action is expected to be usable");
-        
+
         val managedAction = actionInteraction.getManagedAction().get();
         pendingArgs = managedAction.startParameterNegotiation();
-        
+
         // setting up and binding all the simulated UI components
-        
+
         uiParamRangeA = new SimulatedUiChoices();
         uiParamRangeB = new SimulatedUiChoices();
         uiParamRangeC = new SimulatedUiChoices();
-        
+
         uiParamA = new SimulatedUiChoices();
         uiParamB = new SimulatedUiChoices();
         uiParamC = new SimulatedUiAutoComplete();
-        
+
         uiSubmit = new SimulatedUiSubmit();
-        
+
         uiParamRangeA.bind(pendingArgs, NegotiationParams.RANGE_A.ordinal());
         uiParamRangeB.bind(pendingArgs, NegotiationParams.RANGE_B.ordinal());
         uiParamRangeC.bind(pendingArgs, NegotiationParams.RANGE_C.ordinal());
-        
+
         uiParamA.bind(pendingArgs, NegotiationParams.A.ordinal());
         uiParamB.bind(pendingArgs, NegotiationParams.B.ordinal());
         uiParamC.bind(pendingArgs, NegotiationParams.C.ordinal());
-        
+
         uiSubmit.bind(actionInteraction, pendingArgs);
-        
+
         // verify that initial defaults are as expected
-        
+
         assertEquals(NumberRange.POSITITVE, uiParamRangeA.getValue().getPojo());
         assertEquals(NumberRange.NEGATIVE, uiParamRangeB.getValue().getPojo());
         assertEquals(NumberRange.ODD, uiParamRangeC.getValue().getPojo());
-        
+
         assertEquals(1, uiParamA.getValue().getPojo());
         assertEquals(-1, uiParamB.getValue().getPojo());
         assertEquals(-3, uiParamC.getValue().getPojo());
-        
+
         // verify that initial choices are as expected
-        
+
         assertComponentWiseUnwrappedEquals(NumberRange.POSITITVE.numbers(), uiParamA.getChoices());
         assertComponentWiseUnwrappedEquals(NumberRange.NEGATIVE.numbers(), uiParamB.getChoices());
         assertEmpty(uiParamC.getChoices()); // empty because the search argument is also empty
-        
-        // verify that initial validation messages are all empty, 
-        // because we don't validate anything until a user initiated submit attempt occurs 
-        
+
+        // verify that initial validation messages are all empty,
+        // because we don't validate anything until a user initiated submit attempt occurs
+
         assertEmpty(uiParamRangeA.getValidationMessage());
         assertEmpty(uiParamRangeB.getValidationMessage());
         assertEmpty(uiParamRangeC.getValidationMessage());
-        
+
         assertEmpty(uiParamA.getValidationMessage());
         assertEmpty(uiParamB.getValidationMessage());
         assertEmpty(uiParamC.getValidationMessage());
-        
+
         assertEmpty(uiSubmit.getValidationMessage());
-        
+
         // verify that validation feedback is not active
-        
+
         assertFalse(pendingArgs.getObservableValidationFeedbackActive().getValue());
-        
+
     }
-    
+
     @Test
     void paramC_whenSettingSearchArgument_shouldProvideChoices() {
-        
+
         // verify that changing the search argument fires change event
         assertDoesIncrement(
                 uiParamC::getChoiceBoxUpdateEventCount,
                 ()->uiParamC.setSimulatedSearchArgument("-")); // select for all negative and odd numbers
-                        
-        
+
+
         // verify that no additional changes are triggered
-        assertDoesNotIncrement(        
+        assertDoesNotIncrement(
                 uiParamC::getChoiceBoxUpdateEventCount,
                 ()->assertComponentWiseUnwrappedEquals(new int[] {-3, -1}, uiParamC.getChoices()));
-        
+
         // TODO such a change might set or clear paramC validation message once validation feedback is active
     }
 
@@ -168,50 +168,50 @@ class ScalarParamNegotiationTest extends InteractionTestAbstract {
         assertDoesIncrement(
                 uiParamRangeA::getSelectedItemUpdateEventCount,
                 ()->uiParamRangeA.simulateChoiceSelect(NumberRange.NEGATIVE.ordinal()));
-        
+
         assertEquals(NumberRange.NEGATIVE, uiParamRangeA.getValue().getPojo());
         assertComponentWiseUnwrappedEquals(NumberRange.NEGATIVE.numbers(), uiParamA.getChoices());
 
         // TODO such a change might set or clear paramA validation message once validation feedback is active
     }
-    
+
     @Test
     void whenSimulatedSubmit_shouldActivateValidationFeedback_andPassAfterChangingParam() {
-        
+
         // failed simulated submit attempt should trigger validation change listeners on the 'action'
         assertDoesIncrement(
                 uiSubmit::getValidationUpdateEventCount,
                 ()->uiSubmit.simulateSubmit());
-        
+
         // simulated submit attempt, should have activate validation feedback
         assertTrue(pendingArgs.getObservableValidationFeedbackActive().getValue());
 
         // unless all validations give green light, submission must be vetoed
-        assertEquals(null, uiSubmit.getResult().leftIfAny());
-        assertEquals("invalid, sum must be zero, got -3", ""+uiSubmit.getResult().rightIfAny());
-        
+        assertEquals(null, uiSubmit.getResult().getSuccessElseFail());
+        assertEquals("invalid, sum must be zero, got -3", ""+uiSubmit.getResult().getFailureElseFail());
+
         // verify that changing paramA triggers validation change listeners on the 'action'
         assertDoesIncrement(
                 uiSubmit::getValidationUpdateEventCount,
                 ()->{
-                    
+
                     // verify that changing paramA does not triggers validation change listeners on paramA,
                     // since paramA is already valid before the change
                     assertDoesNotIncrement(
                             uiParamA::getValidationUpdateEventCount,
-                            ()->uiParamA.simulateChoiceSelect(3)); // change parameters, so we pass validation                    
-                    
+                            ()->uiParamA.simulateChoiceSelect(3)); // change parameters, so we pass validation
+
                 });
 
         // verify that submission is granted now
         uiSubmit.simulateSubmit();
 
-        // verify that we have the expected result returned from the action invocation 
-        assertTrue(uiSubmit.getResult().isLeft());
-        assertEquals(0, uiSubmit.getResult().leftIfAny().getPojo());
-        
-        //TODO exceptions that occur during action invocation could either be rendered 
-        //     as message, error page or action validation message 
+        // verify that we have the expected result returned from the action invocation
+        assertTrue(uiSubmit.getResult().isSuccess());
+        assertEquals(0, uiSubmit.getResult().getSuccessElseFail().getPojo());
+
+        //TODO exceptions that occur during action invocation could either be rendered
+        //     as message, error page or action validation message
     }
 
     @Test
@@ -219,20 +219,20 @@ class ScalarParamNegotiationTest extends InteractionTestAbstract {
 
         pendingArgs.activateValidationFeedback(); // turn on validation feedback for testing
         assertEquals(null, uiParamA.getValidationMessage()); // expected pre condition
-        
+
         // verify that changing paramRangeA triggers validation change listeners on paramA
         assertDoesIncrement(
                 uiParamA::getValidationUpdateEventCount,
                 ()->uiParamRangeA.simulateChoiceSelect(NumberRange.NEGATIVE.ordinal()));
-    
+
         // not only verify that paramA is invalid, but also that all pending args were considered
         assertEquals(
-                "invalid, element not contained in NEGATIVE got 1, param set [1, -1, -3]", 
+                "invalid, element not contained in NEGATIVE got 1, param set [1, -1, -3]",
                 uiParamA.getValidationMessage());
-        
+
     }
-    
-    
-    
+
+
+
 
 }
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiSubmit.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiSubmit.java
index 7a8836035e..38de48a8f9 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiSubmit.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiSubmit.java
@@ -20,7 +20,7 @@ package org.apache.isis.testdomain.interact;
 
 import java.util.function.Supplier;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Railway;
 import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
 import org.apache.isis.core.metamodel.interactions.managed.InteractionVeto;
 import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
@@ -31,16 +31,16 @@ import lombok.Getter;
 public class SimulatedUiSubmit extends HasActionValidation {
 
     // might require a weak reference when actually implementing
-    private Supplier<_Either<ManagedObject, InteractionVeto>> doSubmit; 
-    @Getter private _Either<ManagedObject, InteractionVeto> result;
-    
+    private Supplier<Railway<InteractionVeto, ManagedObject>> doSubmit;
+    @Getter private Railway<InteractionVeto, ManagedObject> result;
+
     public void bind(final ActionInteraction interaction, final ParameterNegotiationModel pendingArgs) {
         super.bind(pendingArgs);
         doSubmit = ()->interaction.invokeWith(pendingArgs);
     }
-    
+
     public void simulateSubmit() {
         result = doSubmit.get();
     }
-    
+
 }
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
index 3e5055f840..6bf04425ef 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
@@ -176,7 +176,7 @@ class ValueSemanticsTest {
 
                                 val recoveredValue = managedAction
                                         .invoke(typedTuple, InteractionInitiatedBy.PASS_THROUGH)
-                                        .leftIfAny()
+                                        .getSuccessElseFail()
                                         .getPojo();
 
                                 tester.assertValueEquals(
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
index 4d0e82a5a3..25bb19957d 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
@@ -313,9 +313,9 @@ public class DomainObjectTesterFactory {
                 //pendingArgs.validateParameterSetForParameters();
 
                 val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-                assertTrue(resultOrVeto.isLeft()); // assert action did not throw
+                assertTrue(resultOrVeto.isSuccess()); // assert action did not throw
 
-                val actionResultAsPojo = resultOrVeto.leftIfAny().getPojo();
+                val actionResultAsPojo = resultOrVeto.getSuccessElseFail().getPojo();
                 assertEquals(expectedResult, actionResultAsPojo);
 
                 captureCommand();
@@ -345,11 +345,11 @@ public class DomainObjectTesterFactory {
                 //pendingArgs.validateParameterSetForParameters();
 
                 val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-                assertTrue(resultOrVeto.isLeft()); // assert action did not throw
+                assertTrue(resultOrVeto.isSuccess()); // assert action did not throw
 
                 captureCommand();
 
-                return resultOrVeto.leftIfAny().getPojo();
+                return resultOrVeto.getSuccessElseFail().getPojo();
             });
         }
 
@@ -379,9 +379,9 @@ public class DomainObjectTesterFactory {
                 // spawns its own transactional boundary, or reuses an existing one if available
                 val either = managedAction.invoke(pendingArgs.getParamValues());
 
-                assertTrue(either.isLeft()); // assert action did not throw
+                assertTrue(either.isSuccess()); // assert action did not throw
 
-                val actionResultAsPojo = either.leftIfAny().getPojo();
+                val actionResultAsPojo = either.getSuccessElseFail().getPojo();
 
                 assertEquals(expectedResult, actionResultAsPojo);
 
@@ -561,9 +561,9 @@ public class DomainObjectTesterFactory {
                 //pendingArgs.validateParameterSetForParameters();
 
                 val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
-                assertTrue(resultOrVeto.isLeft()); // assert action did not throw
+                assertTrue(resultOrVeto.isSuccess()); // assert action did not throw
 
-                val actionResult = resultOrVeto.leftIfAny();
+                val actionResult = resultOrVeto.getSuccessElseFail();
 
                 val table = DataTableModel
                         .forAction(managedAction, pendingArgs.getParamValues(), actionResult);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
index 3c33b00214..31481ceda0 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
@@ -22,8 +22,8 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.functional.Railway;
 import org.apache.isis.commons.functional.Try;
-import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.interactions.managed.InteractionVeto;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -44,14 +44,14 @@ import lombok.val;
 @RequiredArgsConstructor(staticName = "of")
 public class ObjectActionArgHelper {
 
-    public static Can<_Either<ManagedObject, InteractionVeto>> parseArguments(
+    public static Can<Railway<InteractionVeto, ManagedObject>> parseArguments(
             final IResourceContext resourceContext,
             final ObjectAction action,
             final JsonRepresentation arguments) {
 
         val jsonArgList = argListFor(action, arguments);
 
-        final List<_Either<ManagedObject, InteractionVeto>> argAdapters = _Lists.newArrayList();
+        final List<Railway<InteractionVeto, ManagedObject>> argAdapters = _Lists.newArrayList();
         val parameters = action.getParameters();
         for (int i = 0; i < jsonArgList.size(); i++) {
             final JsonRepresentation argRepr = jsonArgList.get(i);
@@ -64,12 +64,13 @@ public class ObjectActionArgHelper {
                     ? ManagedObject.empty(paramSpec)
                     : new JsonParserHelper(resourceContext, paramSpec)
                             .objectAdapterFor(argRepr))
-            .<_Either<ManagedObject, InteractionVeto>>fold(
-                    success->_Either.left(success.orElseThrow()),
-                    exception->_Either.right(
+            .<Railway<InteractionVeto, ManagedObject>>fold(
+                    exception->Railway.failure(
                             InteractionVeto.actionParamInvalid(
                                     String.format("exception when parsing paramNr %d [%s]: %s",
-                                            argIndex, argRepr, exception))));
+                                            argIndex, argRepr, exception))),
+                    success->Railway.success(success.orElseThrow()))
+            ;
 
             argAdapters.add(objectOrVeto);
         }
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
index 0537b26750..53ce0d3b09 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.Response;
 
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Railway;
 import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
 import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction.Result;
 import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction.SemanticConstraint;
@@ -53,14 +53,14 @@ class _DomainResourceHelper {
     private final TransactionService transactionService;
 
     public static _DomainResourceHelper ofObjectResource(
-            IResourceContext resourceContext,
-            ManagedObject objectAdapter) {
+            final IResourceContext resourceContext,
+            final ManagedObject objectAdapter) {
         return new _DomainResourceHelper(resourceContext, objectAdapter, new DomainObjectLinkTo());
     }
 
     public static _DomainResourceHelper ofServiceResource(
-            IResourceContext resourceContext,
-            ManagedObject objectAdapter) {
+            final IResourceContext resourceContext,
+            final ManagedObject objectAdapter) {
         return new _DomainResourceHelper(resourceContext, objectAdapter, new DomainServiceLinkTo());
     }
 
@@ -205,7 +205,7 @@ class _DomainResourceHelper {
         val where = resourceContext.getWhere();
 
         // lombok issue, needs explicit cast here
-        val actionInteraction = (ActionInteraction) ActionInteraction.start(objectAdapter, actionId, where)
+        val actionInteraction = ActionInteraction.start(objectAdapter, actionId, where)
         .checkVisibility()
         .checkUsability(intent)
         .checkSemanticConstraint(semanticConstraint);
@@ -233,11 +233,13 @@ class _DomainResourceHelper {
                     .parseArguments(resourceContext, action, arguments);
 
             pendingArgs.getParamModels().zip(paramsOrVetos, (managedParam, paramOrVeto)->{
-                if(paramOrVeto.isRight()) {
-                    val veto = paramOrVeto.rightIfAny();
-                    InteractionFailureHandler.collectParameterInvalid(managedParam.getMetaModel(), veto, arguments);
+
+                paramOrVeto.ifFailure(veto->{
+                    InteractionFailureHandler
+                        .collectParameterInvalid(managedParam.getMetaModel(), veto, arguments);
                     vetoCount.increment();
-                }
+                });
+
             });
 
             if(vetoCount.intValue()>0) {
@@ -245,7 +247,7 @@ class _DomainResourceHelper {
                         InteractionVeto.actionParamInvalid("error parsing arguments"), arguments);
             }
 
-            val argAdapters = paramsOrVetos.map(_Either::leftIfAny);
+            val argAdapters = paramsOrVetos.map(Railway::getSuccessElseFail);
             pendingArgs.setParamValues(argAdapters);
 
             // validate parameters ...
@@ -282,14 +284,14 @@ class _DomainResourceHelper {
 
         val resultOrVeto = actionInteraction.invokeWith(pendingArgs);
 
-        if(resultOrVeto.isRight()) {
-            throw InteractionFailureHandler.onFailure(resultOrVeto.rightIfAny());
-        }
+        resultOrVeto.ifFailure(veto->{
+            throw InteractionFailureHandler.onFailure(veto);
+        });
 
         val actionInteractionResult = Result.of(
                 actionInteraction.getManagedAction().orElse(null),
                 pendingArgs.getParamValues(),
-                resultOrVeto.leftIfAny());
+                resultOrVeto.getSuccessElseFail());
 
         val objectAndActionInvocation = ObjectAndActionInvocation.of(actionInteractionResult, arguments, selfLink);
 
@@ -303,7 +305,7 @@ class _DomainResourceHelper {
     // dependencies (from context)
     // //////////////////////////////////////
 
-    private <T> T lookupService(Class<T> serviceType) {
+    private <T> T lookupService(final Class<T> serviceType) {
         return resourceContext.getMetaModelContext().getServiceRegistry().lookupServiceElseFail(serviceType);
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
index 0b3633d213..30e62fcd23 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
@@ -24,7 +24,7 @@ import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
@@ -48,7 +48,7 @@ implements
 
     private final Identifier featureIdentifier;
     private final ScalarRepresentation scalarRepresentation;
-    private transient _Either<OneToOneAssociation, ObjectActionParameter> propOrParam;
+    private transient Either<OneToOneAssociation, ObjectActionParameter> propOrParam;
     private transient IsisAppCommonContext commonContext;
 
     public ConverterBasedOnValueSemantics(
@@ -56,8 +56,8 @@ implements
             final @NonNull ScalarRepresentation scalarRepresentation) {
         this.scalarRepresentation = scalarRepresentation;
         this.propOrParam = propOrParam instanceof OneToOneAssociation // memoize
-                ? _Either.left((OneToOneAssociation)propOrParam)
-                : _Either.right((ObjectActionParameter)propOrParam);
+                ? Either.left((OneToOneAssociation)propOrParam)
+                : Either.right((ObjectActionParameter)propOrParam);
         this.featureIdentifier = propOrParam.getFeatureIdentifier();
     }
 
@@ -138,8 +138,8 @@ implements
         if(propOrParam==null) {
             val feature = getSpecificationLoader().loadFeature(featureIdentifier).orElse(null);
             this.propOrParam = (feature instanceof OneToOneAssociation)
-                    ? _Either.left((OneToOneAssociation)feature)
-                    : _Either.right(((ObjectActionParameter)feature));
+                    ? Either.left((OneToOneAssociation)feature)
+                    : Either.right(((ObjectActionParameter)feature));
         }
         return propOrParam.fold(
                 ObjectFeature.class::cast,
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/InlinePromptContext.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/InlinePromptContext.java
index fffe4d7589..c531bccea9 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/InlinePromptContext.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/InlinePromptContext.java
@@ -24,7 +24,7 @@ import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.functions._Functions;
 
 import lombok.Getter;
@@ -49,7 +49,7 @@ public class InlinePromptContext implements Serializable {
         scalarIfRegularInlinePromptForm.setVisible(true);
     }
 
-    public void onCancel(final _Either<ActionModel, ScalarPropertyModel> memberModel) {
+    public void onCancel(final Either<ActionModel, ScalarPropertyModel> memberModel) {
 
         memberModel
         .accept(_Functions.noopConsumer(), prop->{
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index e6defdb626..a3530147d5 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -26,7 +26,7 @@ import org.apache.wicket.model.IModel;
 
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.debug._Debug;
@@ -135,10 +135,10 @@ implements HasRenderingHints, ScalarUiModel, LinksProvider, FormExecutorContext
      * <p>
      * Corresponds to the enum {@link #getParamOrProp()}.
      */
-    public final _Either<ScalarParameterModel, ScalarPropertyModel> getSpecialization() {
+    public final Either<ScalarParameterModel, ScalarPropertyModel> getSpecialization() {
         switch(getParamOrProp()) {
-        case PARAMETER: return _Either.left((ScalarParameterModel) this);
-        case PROPERTY: return _Either.right((ScalarPropertyModel) this);
+        case PARAMETER: return Either.left((ScalarParameterModel) this);
+        case PROPERTY: return Either.right((ScalarPropertyModel) this);
         default:
             throw _Exceptions.unmatchedCase(getParamOrProp());
         }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
index 7650a19da9..efaf8b6e74 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
@@ -28,8 +28,8 @@ import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.repeater.RepeatingView;
 
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.commons.internal.debug.xray.XrayUi;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -196,8 +196,8 @@ extends PromptFormAbstract<ActionModel> {
     }
 
     @Override
-    protected _Either<ActionModel, ScalarPropertyModel> getMemberModel() {
-        return _Either.left(actionModel());
+    protected Either<ActionModel, ScalarPropertyModel> getMemberModel() {
+        return Either.left(actionModel());
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditForm.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditForm.java
index e2ca424dfa..01251a332a 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditForm.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditForm.java
@@ -22,8 +22,8 @@ import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
 
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.viewer.common.model.components.ComponentType;
 import org.apache.isis.viewer.wicket.model.hints.IsisPropertyEditCompletedEvent;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
@@ -75,8 +75,8 @@ class PropertyEditForm extends PromptFormAbstract<ScalarPropertyModel> {
     }
 
     @Override
-    protected _Either<ActionModel, ScalarPropertyModel> getMemberModel() {
-        return _Either.right(scalarPropertyModel());
+    protected Either<ActionModel, ScalarPropertyModel> getMemberModel() {
+        return Either.right(scalarPropertyModel());
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
index 8ffe5c2a44..93f8ba5d22 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
@@ -32,7 +32,7 @@ import org.wicketstuff.select2.Select2Choice;
 import org.wicketstuff.select2.Select2MultiChoice;
 import org.wicketstuff.select2.Settings;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.core.metamodel.objectmanager.memento.ObjectMemento;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
@@ -55,19 +55,19 @@ implements
 
     private static final long serialVersionUID = 1L;
 
-    final _Either<Select2ChoiceExt, Select2MultiChoiceExt> select2Choice;
+    final Either<Select2ChoiceExt, Select2MultiChoiceExt> select2Choice;
 
     public static Select2 createSelect2(final String id, final ScalarModel scalarModel) {
         return new Select2(!scalarModel.isCollection()
-                ? _Either.left(
+                ? Either.left(
                         Select2ChoiceExt.create(id,
                                 ScalarModelWithSingleChoice.chain(scalarModel), scalarModel))
-                : _Either.right(
+                : Either.right(
                         Select2MultiChoiceExt.create(id,
                                 ScalarModelWithMultiChoice.chain(scalarModel), scalarModel)));
     }
 
-    private Select2(final @NonNull _Either<Select2ChoiceExt, Select2MultiChoiceExt> select2Choice) {
+    private Select2(final @NonNull Either<Select2ChoiceExt, Select2MultiChoiceExt> select2Choice) {
         this.select2Choice = select2Choice;
         asComponent().setOutputMarkupId(true);
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
index 3bbf8ec2d8..cf440a8104 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
@@ -30,7 +30,7 @@ import org.apache.isis.applib.services.exceprecog.Recognition;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.commons.internal.debug.xray.XrayUi;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
@@ -55,24 +55,24 @@ implements FormExecutor {
     // -- FACTORIES
 
     public static FormExecutor forAction(final ActionModel actionModel) {
-        return new FormExecutorDefault(_Either.left(actionModel));
+        return new FormExecutorDefault(Either.left(actionModel));
     }
 
     public static FormExecutor forProperty(final ScalarPropertyModel propertyModel) {
-        return new FormExecutorDefault(_Either.right(propertyModel));
+        return new FormExecutorDefault(Either.right(propertyModel));
     }
 
-    public static FormExecutor forMember(final _Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel) {
+    public static FormExecutor forMember(final Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel) {
         return new FormExecutorDefault(actionOrPropertyModel);
     }
 
     // -- CONSTRUCTION
 
     protected final WicketViewerSettings settings;
-    private final _Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel;
+    private final Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel;
 
     private FormExecutorDefault(
-            final _Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel) {
+            final Either<ActionModel, ScalarPropertyModel> actionOrPropertyModel) {
         this.actionOrPropertyModel = actionOrPropertyModel;
         this.settings = getSettings();
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
index 6a8200f2b6..02e24cc041 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
@@ -31,7 +31,7 @@ import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.model.IModel;
 
-import org.apache.isis.commons.internal.base._Either;
+import org.apache.isis.commons.functional.Either;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.debug._Probe;
 import org.apache.isis.commons.internal.debug._Probe.EntryPoint;
@@ -84,7 +84,7 @@ implements ScalarModelSubscriber {
     // -- SETUP
 
     protected abstract void addParameters();
-    protected abstract _Either<ActionModel, ScalarPropertyModel> getMemberModel();
+    protected abstract Either<ActionModel, ScalarPropertyModel> getMemberModel();
     protected abstract Object newCompletedEvent(AjaxRequestTarget target, Form<?> form);
 
     @Override