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 2021/11/19 22:06:12 UTC

[isis] branch 2882_temporal_from_scratch created (now cca6298)

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

ahuber pushed a change to branch 2882_temporal_from_scratch
in repository https://gitbox.apache.org/repos/asf/isis.git.


      at cca6298  ISIS-2882: purge all the wicket temporal conversion stuff

This branch includes the following new commits:

     new cca6298  ISIS-2882: purge all the wicket temporal conversion stuff

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[isis] 01/01: ISIS-2882: purge all the wicket temporal conversion stuff

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cca62987f2b7e3775b5c44548b9bd38682cc54b0
Author: andi-huber <ah...@apache.org>
AuthorDate: Fri Nov 19 23:05:48 2021 +0100

    ISIS-2882: purge all the wicket temporal conversion stuff
    
    - start from scratch using value semantics
    - also purge legacy temporal value semantics
---
 .../org/apache/isis/applib/adapters/Parser.java    |   6 +
 .../applib/adapters}/TemporalValueSemantics.java   |  10 +-
 .../applib/adapters/ValueSemanticsAbstract.java    | 108 ++++++-
 .../apache/isis/core/config/IsisConfiguration.java | 186 +-----------
 .../core/metamodel/IsisModuleCoreMetamodel.java    |   9 -
 .../_testing/MetaModelContext_forTesting.java      |   9 +-
 .../temporal/LocalDateTimeValueSemantics.java      |  35 +--
 .../temporal/LocalDateValueSemantics.java          |  27 +-
 .../temporal/LocalTimeValueSemantics.java          |  32 +-
 .../temporal/OffsetDateTimeValueSemantics.java     |  33 +--
 .../temporal/OffsetTimeValueSemantics.java         |  30 +-
 .../temporal/TemporalValueSemanticsProvider.java   | 157 ++++------
 .../temporal/ZonedDateTimeValueSemantics.java      |  33 +--
 .../temporal/legacy/JavaSqlDateValueSemantics.java | 130 +--------
 .../legacy/JavaSqlTimeStampValueSemantics.java     | 110 +------
 .../temporal/legacy/JavaSqlTimeValueSemantics.java | 128 +-------
 .../legacy/JavaUtilDateValueSemantics.java         | 130 ++-------
 .../LegacyTemporalValueSemanticsAbstract.java      | 322 ---------------------
 .../legacy/joda/JodaDateTimeValueSemantics.java    | 182 ------------
 .../joda/JodaLocalDateTimeValueSemantics.java      | 230 ---------------
 .../legacy/joda/JodaLocalDateValueSemantics.java   | 232 ---------------
 .../temporal/legacy/joda/_JodaFunctions.java       |  42 ---
 .../legacy/joda/_JodaLocalDateTimeUtil.java        | 119 --------
 .../temporal/legacy/joda/_JodaLocalDateUtil.java   | 128 --------
 .../valuetypes/ValueSemanticsAdapter.java          | 110 +++++++
 .../object/mixin/MixinIntendedAsActionTest.java    |  67 +++--
 .../JavaSqlDateValueSemanticsProviderTest.java     |  32 +-
 .../JavaSqlTimeValueSemanticsProviderTest.java     |  48 +--
 .../JavaUtilDateValueSemanticsProviderTest.java    |  68 ++---
 .../components/temporal/TemporalFieldFactory.java  |   6 +-
 .../components/temporal/TemporalFieldFactory.java  |   6 +-
 valuetypes/jodatime/{ => integration}/pom.xml      |  33 ++-
 .../IsisModuleValJodatimeIntegration.java          |  25 +-
 .../valuesemantics/JodaDateTimeValueSemantics.java |  67 +++++
 .../JodaLocalDateTimeValueSemantics.java           |  65 +++++
 .../JodaLocalDateValueSemantics.java               |  65 +++++
 .../JodaLocalTimeValueSemantics.java               |   5 +-
 ...odaLocalDateTimeValueSemanticsProviderTest.java |  29 +-
 valuetypes/jodatime/pom.xml                        |   1 +
 valuetypes/pom.xml                                 |   7 +-
 .../converter/ConverterBasedOnValueSemantics.java  |  11 +-
 viewers/wicket/ui/pom.xml                          |   6 +
 .../viewer/wicket/ui/IsisModuleViewerWicketUi.java |   2 +
 .../ui/components/scalars/DateConverter.java       |  44 ---
 .../components/scalars/DateConverterAbstract.java  |  76 -----
 .../ui/components/scalars/DateFormatSettings.java  |  86 ------
 ...arPanelTextFieldWithTemporalPickerAbstract.java |  95 ++----
 ...ConverterPlugin.java => TemporalConverter.java} |  22 +-
 .../datepicker/TextFieldWithDateTimePicker.java    |  54 ++--
 .../jdk8time/DateConverterForJdk8Abstract.java     |  64 ----
 .../jdk8time/DateConverterForJdk8LocalDate.java    |  66 -----
 .../DateConverterForJdk8LocalDateTime.java         |  77 -----
 .../DateConverterForJdk8OffsetDateTime.java        |  94 ------
 .../scalars/jdk8time/Jdk8LocalDatePanel.java       |   1 -
 .../scalars/jdk8time/Jdk8LocalDateTimePanel.java   |   1 -
 .../scalars/jdk8time/Jdk8OffsetDateTimePanel.java  |   1 -
 .../jdkdates/DateConverterForJavaAbstract.java     | 105 -------
 .../jdkdates/DateConverterForJavaSqlDate.java      |  58 ----
 .../jdkdates/DateConverterForJavaSqlTimestamp.java |  60 ----
 .../jdkdates/DateConverterForJavaUtilDate.java     |  59 ----
 .../scalars/jdkdates/JavaSqlDatePanel.java         |   1 -
 .../scalars/jdkdates/JavaSqlTimestampPanel.java    |   6 -
 .../scalars/jdkdates/JavaUtilDatePanel.java        |   8 -
 .../jodatime/DateConverterForJodaAbstract.java     |  57 ----
 .../jodatime/DateConverterForJodaDateTime.java     |  63 ----
 .../jodatime/DateConverterForJodaLocalDate.java    |  63 ----
 .../DateConverterForJodaLocalDateTime.java         |  64 ----
 .../scalars/jodatime/JodaDateTimePanel.java        |   1 -
 .../scalars/jodatime/JodaLocalDatePanel.java       |   1 -
 .../scalars/jodatime/JodaLocalDateTimePanel.java   |   1 -
 .../ui/components/scalars/ConverterTester.java     |  41 ++-
 .../jdkdates/DateConverterForJavaSqlDateTest.java  |  77 -----
 .../jdkdates/DateConverterForJavaUtilDateTest.java | 101 -------
 .../scalars/jdkdates/JavaSqlDateConverterTest.java |  75 +++++
 .../jdkdates/JavaUtilDateConverterTest.java        |  77 +++++
 ...Converter.java => BigDecimalConverterTest.java} |   2 +-
 .../jodatime/DateConverterForJodaDateTimeTest.java |  97 -------
 .../DateConverterForJodaLocalDateTest.java         |  73 -----
 .../DateConverterForJodaLocalDateTimeTest.java     |  96 ------
 .../jodatime/JodaDateTimeConverterTest.java        |  78 +++++
 .../jodatime/JodaLocalDateConverterTest.java       |  76 +++++
 .../jodatime/JodaLocalDateTimeConverterTest.java   |  77 +++++
 .../DateConverterForJdk8LocalDateTest.java         |  75 -----
 .../DateConverterForJdk8LocalDateTimeTest.java     |  98 -------
 .../DateConverterForJdk8OffsetDateTimeTest.java    | 108 -------
 .../jodatime/jdk8time/LocalDateConverterTest.java  |  74 +++++
 .../jdk8time/LocalDateTimeConverterTest.java       |  74 +++++
 .../jdk8time/OffsetDateTimeConverterTest.java      |  81 ++++++
 88 files changed, 1467 insertions(+), 4222 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/adapters/Parser.java b/api/applib/src/main/java/org/apache/isis/applib/adapters/Parser.java
index cbca4ab..fd71267 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/adapters/Parser.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/adapters/Parser.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.applib.adapters;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
 /**
  * Provides a mechanism for parsing and rendering string representations of
  * objects.
@@ -99,4 +101,8 @@ public interface Parser<T> {
         return -1;
     }
 
+    default String getPattern(final ValueSemanticsProvider.Context context) {
+        throw _Exceptions.notImplemented(); // implement in sub classes
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemantics.java b/api/applib/src/main/java/org/apache/isis/applib/adapters/TemporalValueSemantics.java
similarity index 88%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemantics.java
rename to api/applib/src/main/java/org/apache/isis/applib/adapters/TemporalValueSemantics.java
index 8aa52c3..344f624 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemantics.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/adapters/TemporalValueSemantics.java
@@ -16,14 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.valuesemantics.temporal;
+package org.apache.isis.applib.adapters;
 
 import java.time.temporal.Temporal;
 
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.adapters.Parser;
-import org.apache.isis.applib.adapters.Renderer;
-
 /**
  * Common base for {@link java.time.temporal.Temporal} value types.
  *
@@ -65,7 +61,9 @@ extends
         /**
          * Temporal value type has time-zone data.
          */
-        OFFSET,
+        OFFSET;
+
+        public boolean isLocal() {return this == LOCAL;}
     }
 
     TemporalCharacteristic getTemporalCharacteristic();
diff --git a/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
index e5f3b1a..c2a0bb5 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
@@ -24,6 +24,9 @@ import java.text.DecimalFormat;
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.text.ParsePosition;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
 import java.util.Locale;
 import java.util.Optional;
 import java.util.function.Function;
@@ -33,8 +36,10 @@ import org.springframework.lang.Nullable;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
 import org.apache.isis.applib.services.iactnlayer.InteractionContext;
 import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.schema.common.v2.ValueType;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -105,7 +110,7 @@ implements
                 .orElse(NULL_REPRESENTATION);
     }
 
-    // -- NUMBER PARSING
+    // -- NUMBER FORMATTING/PARSING
 
     protected @Nullable BigInteger parseInteger(
             final @Nullable ValueSemanticsProvider.Context context,
@@ -161,4 +166,105 @@ implements
      */
     protected void configureDecimalFormat(final Context context, final DecimalFormat format) {}
 
+    // -- TEMPORAL FORMATTING/PARSING
+
+    protected DateTimeFormatter getTemporalRenderingFormat(
+            final @Nullable ValueSemanticsProvider.Context context,
+            final @NonNull TemporalValueSemantics.TemporalCharacteristic temporalCharacteristic,
+            final @NonNull TemporalValueSemantics.OffsetCharacteristic offsetCharacteristic,
+            final @NonNull FormatStyle dateFormatStyle,
+            final @NonNull FormatStyle timeFormatStyle) {
+
+        //FIXME[ISIS-2882] honor OffsetCharacteristic
+        switch (temporalCharacteristic) {
+        case DATE_TIME:
+            return DateTimeFormatter.ofLocalizedDateTime(dateFormatStyle, timeFormatStyle)
+                    .withLocale(getLocale(context));
+        case DATE_ONLY:
+            return DateTimeFormatter.ofLocalizedDate(dateFormatStyle)
+                    .withLocale(getLocale(context));
+        case TIME_ONLY:
+            return DateTimeFormatter.ofLocalizedTime(timeFormatStyle)
+                    .withLocale(getLocale(context));
+        default:
+            throw _Exceptions.unmatchedCase(temporalCharacteristic);
+        }
+    }
+
+    protected DateTimeFormatter getEditingFormat(
+            final @Nullable ValueSemanticsProvider.Context context,
+            final @NonNull TemporalValueSemantics.TemporalCharacteristic temporalCharacteristic,
+            final @NonNull TemporalValueSemantics.OffsetCharacteristic offsetCharacteristic,
+            final @NonNull String datePattern,
+            final @NonNull String timePattern,
+            final @NonNull String zonePattern) {
+
+        return getEditingFormatAsBuilder(
+                temporalCharacteristic, offsetCharacteristic, datePattern, timePattern, zonePattern)
+                .parseLenient()
+                .parseCaseInsensitive()
+                .toFormatter(getLocale(context));
+    }
+
+    protected DateTimeFormatterBuilder getEditingFormatAsBuilder(
+            final @NonNull TemporalValueSemantics.TemporalCharacteristic temporalCharacteristic,
+            final @NonNull TemporalValueSemantics.OffsetCharacteristic offsetCharacteristic,
+            final @NonNull String datePattern,
+            final @NonNull String timePattern,
+            final @NonNull String zonePattern) {
+
+        return new DateTimeFormatterBuilder()
+            .appendPattern(getEditingFormatAsPattern(temporalCharacteristic, offsetCharacteristic, datePattern, timePattern, zonePattern));
+    }
+
+    protected String getEditingFormatAsPattern(
+            final @NonNull TemporalValueSemantics.TemporalCharacteristic temporalCharacteristic,
+            final @NonNull TemporalValueSemantics.OffsetCharacteristic offsetCharacteristic,
+            final @NonNull String datePattern,
+            final @NonNull String timePattern,
+            final @NonNull String zonePattern) {
+
+        switch (temporalCharacteristic) {
+        case DATE_TIME:
+            return offsetCharacteristic.isLocal()
+                    ? datePattern + " " + timePattern
+                    : datePattern + " " + timePattern + " " + zonePattern;
+        case DATE_ONLY:
+            return offsetCharacteristic.isLocal()
+                    ? datePattern
+                    : datePattern + " " + zonePattern;
+        case TIME_ONLY:
+            return offsetCharacteristic.isLocal()
+                    ? timePattern
+                    : timePattern + " " + zonePattern;
+        default:
+            throw _Exceptions.unmatchedCase(temporalCharacteristic);
+        }
+    }
+
+
+    protected DateTimeFormatter getTemporalIsoFormat(
+            final @NonNull TemporalValueSemantics.TemporalCharacteristic temporalCharacteristic,
+            final @NonNull TemporalValueSemantics.OffsetCharacteristic offsetCharacteristic) {
+
+        switch (temporalCharacteristic) {
+        case DATE_TIME:
+            return offsetCharacteristic.isLocal()
+                    ? DateTimeFormatter.ISO_LOCAL_DATE_TIME
+                    : DateTimeFormatter.ISO_DATE_TIME;
+        case DATE_ONLY:
+            return offsetCharacteristic.isLocal()
+                    ? DateTimeFormatter.ISO_LOCAL_DATE
+                    : DateTimeFormatter.ISO_DATE;
+        case TIME_ONLY:
+            return offsetCharacteristic.isLocal()
+                    ? DateTimeFormatter.ISO_LOCAL_TIME
+                    : DateTimeFormatter.ISO_TIME;
+        default:
+            throw _Exceptions.unmatchedCase(temporalCharacteristic);
+        }
+    }
+
+
+
 }
diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index 27ee1a5..6af85e6 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -34,12 +34,6 @@ import java.util.Optional;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
 import javax.activation.DataSource;
 import javax.validation.Constraint;
 import javax.validation.ConstraintValidator;
@@ -68,6 +62,7 @@ import org.apache.isis.applib.services.userreg.UserRegistrationService;
 import org.apache.isis.applib.services.userui.UserMenu;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.context._Context;
+import org.apache.isis.core.config.IsisConfiguration.Viewer;
 import org.apache.isis.core.config.metamodel.facets.DefaultViewConfiguration;
 import org.apache.isis.core.config.metamodel.facets.EditingObjectsConfiguration;
 import org.apache.isis.core.config.metamodel.facets.PublishingPolicies.ActionPublishingPolicy;
@@ -77,6 +72,12 @@ import org.apache.isis.core.config.metamodel.services.ApplicationFeaturesInitCon
 import org.apache.isis.core.config.metamodel.specloader.IntrospectionMode;
 import org.apache.isis.core.config.viewer.web.DialogMode;
 
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 import lombok.Data;
 import lombok.Getter;
 import lombok.Setter;
@@ -2682,179 +2683,6 @@ public class IsisConfiguration {
             }
         }
 
-        private final JavaTime javaTime = new JavaTime();
-        @Data
-        public static class JavaTime {
-            private final LocalDateTime localDateTime = new LocalDateTime();
-            @Data
-            public static class LocalDateTime {
-                /**
-                 * Configures the formats understood by <code>LocalDateTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final OffsetDateTime offsetDateTime = new OffsetDateTime();
-            @Data
-            public static class OffsetDateTime {
-                /**
-                 * Configures the formats understood by <code>OffsetDateTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final OffsetTime offsetTime = new OffsetTime();
-            @Data
-            public static class OffsetTime {
-                /**
-                 * Configures the formats understood by <code>OffsetTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final LocalDate localDate = new LocalDate();
-            @Data
-            public static class LocalDate {
-                /**
-                 * Configures the formats understood by <code>LocalDateValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final LocalTime localTime = new LocalTime();
-            @Data
-            public static class LocalTime {
-                /**
-                 * Configures the formats understood by <code>LocalTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final ZonedDateTime zonedDateTime = new ZonedDateTime();
-            @Data
-            public static class ZonedDateTime {
-                /**
-                 * Configures the formats understood by <code>ZonedDateTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-        }
-
-        private final JavaUtil javaUtil = new JavaUtil();
-        @Data
-        public static class JavaUtil {
-
-            private final Date date = new Date();
-            @Data
-            public static class Date {
-                /**
-                 * Configures the formats understood by <code>JavaUtilDateValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-        }
-
-        private final JavaSql javaSql = new JavaSql();
-        @Data
-        public static class JavaSql {
-            private final Date date = new Date();
-            @Data
-            public static class Date {
-                /**
-                 * Configures the formats understood by <code>JavaSqlDateValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-            private final Time time = new Time();
-            @Data
-            public static class Time {
-                /**
-                 * Configures the formats understood by <code>JavaSqlTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "short";
-            }
-
-            private final Timestamp timestamp = new Timestamp();
-            @Data
-            public static class Timestamp {
-                /**
-                 * Configures the formats understood by <code>JavaSqlTimeStampValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "short";
-            }
-
-        }
-
-        private final Joda joda = new Joda();
-        @Data
-        public static class Joda {
-            private final LocalDateTime localDateTime = new LocalDateTime();
-            @Data
-            public static class LocalDateTime {
-                /**
-                 * Configures the formats understood by <code>JodaLocalDateTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final LocalDate localDate = new LocalDate();
-            @Data
-            public static class LocalDate {
-                /**
-                 * Configures the formats understood by <code>JodaLocalDateValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-
-            private final DateTime dateTime = new DateTime();
-            @Data
-            public static class DateTime {
-                /**
-                 * Configures the formats understood by <code>JodaDateTimeValueSemanticsProvider</code>.
-                 *
-                 * @deprecated
-                 */
-                @Deprecated
-                private String format = "medium";
-            }
-        }
     }
 
     private final Testing testing = new Testing();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisModuleCoreMetamodel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisModuleCoreMetamodel.java
index c56eae0..a56f16e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisModuleCoreMetamodel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisModuleCoreMetamodel.java
@@ -83,10 +83,6 @@ import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlDate
 import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlTimeStampValueSemantics;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlTimeValueSemantics;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaUtilDateValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda.JodaDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda.JodaLocalDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda.JodaLocalDateValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda.JodaLocalTimeValueSemantics;
 import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsRegistryDefault;
 import org.apache.isis.core.security.IsisModuleCoreSecurity;
 
@@ -147,11 +143,6 @@ import org.apache.isis.core.security.IsisModuleCoreSecurity;
         JavaSqlTimeValueSemantics.class,
         JavaSqlTimeStampValueSemantics.class,
         JavaUtilDateValueSemantics.class,
-        // Value Semantics (temporal joda)
-        JodaLocalTimeValueSemantics.class,
-        JodaDateTimeValueSemantics.class,
-        JodaLocalDateTimeValueSemantics.class,
-        JodaLocalDateValueSemantics.class,
 
         // @Service's
         ObjectManagerDefault.class,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/MetaModelContext_forTesting.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/MetaModelContext_forTesting.java
index 6e71b75..109a365 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/MetaModelContext_forTesting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/MetaModelContext_forTesting.java
@@ -208,7 +208,7 @@ implements MetaModelContext {
                 serviceRegistry,
                 metamodelEventService,
                 messageService,
-                specificationLoader,
+//                specificationLoader,
                 interactionProvider,
                 getTranslationService(),
                 authentication,
@@ -240,7 +240,8 @@ implements MetaModelContext {
                     _ManagedBeanAdapter.forTestingLazy(GridService.class, this::getGridService),
                     _ManagedBeanAdapter.forTestingLazy(JaxbService.class, this::getJaxbService),
                     _ManagedBeanAdapter.forTestingLazy(MenuBarsService.class, this::getMenuBarsService),
-                    _ManagedBeanAdapter.forTestingLazy(LayoutService.class, this::getLayoutService)
+                    _ManagedBeanAdapter.forTestingLazy(LayoutService.class, this::getLayoutService),
+                    _ManagedBeanAdapter.forTestingLazy(SpecificationLoader.class, this::getSpecificationLoader)
                 ),
                 singletonProviders.stream());
     }
@@ -274,10 +275,6 @@ implements MetaModelContext {
     public ServiceInjector getServiceInjector() {
         if(serviceInjector==null) {
             serviceInjector = new ServiceInjector_forTesting(this);
-            // hotfix
-            if(specificationLoader==null) {
-                getSpecificationLoader();
-            }
         }
         return serviceInjector;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
index 30c5710..d1c0c13 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
@@ -19,20 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
-import java.util.Locale;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.LocalDateTimeValueSemantics")
 //@Log4j2
@@ -52,37 +45,11 @@ extends TemporalValueSemanticsProvider<LocalDateTime> {
         return ValueType.LOCAL_DATE_TIME;
     }
 
-    public LocalDateTimeValueSemantics(final IsisConfiguration config) {
+    public LocalDateTimeValueSemantics() {
         super(TemporalCharacteristic.DATE_TIME, OffsetCharacteristic.LOCAL,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 LocalDateTime::from,
                 TemporalAdjust::adjustLocalDateTime);
-
-        val dateHourMinuteSecondMillis = "yyyy-MM-dd'T'HH:mm:ss.SSS";
-        val basicDateTimeNoMillis = "yyyyMMdd'T'HHmmssZ";
-        val basicDateTime = "yyyyMMdd'T'HHmmss.SSSZ";
-
-        super.addNamedFormat("iso", basicDateTimeNoMillis);
-        super.addNamedFormat("iso_encoding", basicDateTime);
-
-        super.updateParsers();
-
-        setEncodingFormatter(
-                DateTimeFormatter.ofPattern(dateHourMinuteSecondMillis, Locale.getDefault()));
-
-        val configuredNameOrPattern =
-                config.getValueTypes().getJavaTime().getLocalDateTime().getFormat();
-
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedDateTime),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));  // fallback
-
-        setTitleFormatter(formatter);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
index 131e728..88ca29e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
@@ -19,19 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.LocalDateValueSemantics")
 //@Log4j2
@@ -51,30 +45,11 @@ extends TemporalValueSemanticsProvider<LocalDate> {
         return ValueType.LOCAL_DATE;
     }
 
-    public LocalDateValueSemantics(final IsisConfiguration config) {
+    public LocalDateValueSemantics() {
         super(TemporalCharacteristic.DATE_ONLY, OffsetCharacteristic.LOCAL,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 LocalDate::from,
                 TemporalAdjust::adjustLocalDate);
-
-        super.addNamedFormat("iso", "yyyy-MM-dd");
-        super.addNamedFormat("iso_encoding", "yyyy-MM-dd");
-        super.updateParsers();
-
-        setEncodingFormatter(lookupNamedFormatterElseFail("iso_encoding"));
-
-        val configuredNameOrPattern = config.getValueTypes().getJavaTime().getLocalDate().getFormat();
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedDate),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));  // fallback
-
-        setTitleFormatter(formatter);
-
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
index ab67422..70cd643 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
@@ -19,20 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
-import java.util.Locale;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.LocalTimeValueSemantics")
 //@Log4j2
@@ -52,34 +45,11 @@ extends TemporalValueSemanticsProvider<LocalTime> {
         return ValueType.LOCAL_TIME;
     }
 
-    public LocalTimeValueSemantics(final IsisConfiguration config) {
+    public LocalTimeValueSemantics() {
         super(TemporalCharacteristic.TIME_ONLY, OffsetCharacteristic.LOCAL,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 LocalTime::from,
                 TemporalAdjust::adjustLocalTime);
-
-        val hourMinuteSecondMillis = "HH:mm:ss.SSS";
-        val basicTimeNoMillis = "HHmmssZ";
-        val basicTime = "HHmmss.SSSZ";
-
-        super.addNamedFormat("iso", basicTimeNoMillis);
-        super.addNamedFormat("iso_encoding", basicTime);
-        super.updateParsers();
-
-        setEncodingFormatter(DateTimeFormatter.ofPattern(hourMinuteSecondMillis, Locale.getDefault()));
-
-        val configuredNameOrPattern = config.getValueTypes().getJavaTime().getLocalTime().getFormat();
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedTime),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));  // fallback
-
-        setTitleFormatter(formatter);
-
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
index b2ee126..75a0a45 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
@@ -19,20 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.OffsetDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
-import java.util.Locale;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.OffsetDateTimeValueSemantics")
 //@Log4j2
@@ -52,35 +45,11 @@ extends TemporalValueSemanticsProvider<OffsetDateTime> {
         return ValueType.OFFSET_DATE_TIME;
     }
 
-    public OffsetDateTimeValueSemantics(final IsisConfiguration config) {
+    public OffsetDateTimeValueSemantics() {
         super(TemporalCharacteristic.DATE_TIME, OffsetCharacteristic.OFFSET,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 OffsetDateTime::from,
                 TemporalAdjust::adjustOffsetDateTime);
-
-        val basicDateTimeNoMillis = "yyyyMMdd'T'HHmmssZ";
-        val basicDateTime = "yyyyMMdd'T'HHmmss.SSSZ";
-
-        super.addNamedFormat("iso", basicDateTimeNoMillis);
-        super.addNamedFormat("iso_encoding", basicDateTime);
-
-        super.updateParsers();
-
-        setEncodingFormatter(DateTimeFormatter.ofPattern(basicDateTime, Locale.getDefault()));
-
-        val configuredNameOrPattern = config.getValueTypes().getJavaTime().getOffsetDateTime().getFormat();
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedDateTime),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));  // fallback
-
-        //TODO those FormatStyle based formatters potentially need additional zone information
-        setTitleFormatter(formatter);
-
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
index aa50ee2..97b265f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
@@ -19,19 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.OffsetTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.OffsetTimeValueSemantics")
 //@Log4j2
@@ -51,33 +45,11 @@ extends TemporalValueSemanticsProvider<OffsetTime> {
         return ValueType.OFFSET_TIME;
     }
 
-    public OffsetTimeValueSemantics(final IsisConfiguration config) {
+    public OffsetTimeValueSemantics() {
         super(TemporalCharacteristic.TIME_ONLY, OffsetCharacteristic.OFFSET,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 OffsetTime::from,
                 TemporalAdjust::adjustOffsetTime);
-
-        val basicTimeNoMillis = "HHmmssZ";
-        val basicTime = "HHmmss.SSSZ";
-
-        super.addNamedFormat("iso", basicTimeNoMillis);
-        super.addNamedFormat("iso_encoding", basicTime);
-        super.updateParsers();
-
-        setEncodingFormatter(lookupNamedFormatterElseFail("iso_encoding"));
-
-        val configuredNameOrPattern = config.getValueTypes().getJavaTime().getOffsetTime().getFormat();
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedTime),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));  // fallback
-
-        //TODO those FormatStyle based formatters potentially need additional zone information
-        setTitleFormatter(formatter);
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
index 1c307eb..54f56d4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
@@ -22,29 +22,18 @@ import java.time.format.DateTimeFormatter;
 import java.time.format.FormatStyle;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalQuery;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
 import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.stream.Stream;
 
-import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
 import org.apache.isis.applib.adapters.EncodingException;
+import org.apache.isis.applib.adapters.TemporalValueSemantics;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
 import org.apache.isis.applib.adapters.ValueSemanticsProvider;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.base._Strings;
 
 import lombok.Getter;
-import lombok.NonNull;
-import lombok.Setter;
 import lombok.val;
 import lombok.experimental.Accessors;
-import lombok.extern.log4j.Log4j2;
 
 /**
  * Common base for {@link java.time.temporal.Temporal} types.
@@ -53,7 +42,7 @@ import lombok.extern.log4j.Log4j2;
  *
  * @param <T> implementing {@link java.time.temporal.Temporal} type
  */
-@Log4j2
+//@Log4j2
 public abstract class TemporalValueSemanticsProvider<T extends Temporal>
 extends ValueSemanticsAbstract<T>
 implements TemporalValueSemantics<T> {
@@ -63,16 +52,10 @@ implements TemporalValueSemantics<T> {
     @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) protected final int typicalLength;
     @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) protected final int maxLength;
 
-    @Getter private DateTimeFormatter encodingFormatter;
-    @Getter @Setter private DateTimeFormatter titleFormatter;
-
     /**
      * Keys represent the values which can be configured,
      * and which are used for the rendering of dates.
      */
-    protected final Map<String, DateTimeFormatter> namedFormatters;
-    protected Can<Function<String, T>> parsers;
-
     protected final TemporalQuery<T> query;
     protected final BiFunction<TemporalAdjust, T, T> adjuster;
 
@@ -93,81 +76,25 @@ implements TemporalValueSemantics<T> {
 
         this.query = query;
         this.adjuster = adjuster;
-
-        namedFormatters = _Maps.newLinkedHashMap();
-        namedFormatters.put("internal_encoding", this.getEncodingFormatter());
-        updateParsers();
-    }
-
-
-    protected void setEncodingFormatter(final DateTimeFormatter encodingFormatter) {
-        this.encodingFormatter = encodingFormatter;
-    }
-
-    protected void addNamedFormat(final String name, final String pattern) {
-        namedFormatters.put(name, DateTimeFormatter.ofPattern(pattern, Locale.getDefault()));
-    }
-
-    protected Optional<FormatStyle> lookupFormatStyle(final String styleName) {
-        if(styleName==null) {
-            return Optional.empty();
-        }
-        return Stream.of(FormatStyle.values())
-        .filter(style->style.name().toLowerCase().equals(styleName))
-        .findFirst();
-    }
-
-    protected Optional<DateTimeFormatter> lookupNamedFormatter(final String formatName) {
-        return Optional.ofNullable(namedFormatters.get(formatName));
-    }
-
-    protected DateTimeFormatter lookupNamedFormatterElseFail(final String formatName) {
-        return lookupNamedFormatter(formatName)
-                .orElseThrow(()->_Exceptions.noSuchElement("unknown format name %s", formatName));
-    }
-
-    protected Optional<DateTimeFormatter> formatterFromPattern(final String pattern) {
-        try {
-            return Optional.of(DateTimeFormatter.ofPattern(pattern, Locale.getDefault()));
-        } catch (Exception e) {
-            log.warn("cannot parse pattern '{}'", pattern, e);
-        }
-        return Optional.empty();
-    }
-
-    protected void updateParsers() {
-        parsers = Can.ofCollection(namedFormatters.values())
-                .map(formatter->{
-                    return $->formatter.parse($, query);
-                });
-    }
-
-    protected Optional<DateTimeFormatter> formatterFirstOf(
-            final @NonNull Can<Supplier<Optional<DateTimeFormatter>>> formatterProviders) {
-        return formatterProviders.stream()
-        .map(Supplier::get)
-        .filter(Optional::isPresent)
-        .map(Optional::get)
-        .findFirst();
     }
 
     // -- ENCODER/DECODER
 
     @Override
-    public String toEncodedString(final T temporal) {
+    public final String toEncodedString(final T temporal) {
         if(temporal==null) {
             return null;
         }
-        return encodingFormatter.format(temporal);
+        return getIsoFormat().format(temporal);
     }
 
     @Override
-    public T fromEncodedString(final String data) {
+    public final T fromEncodedString(final String data) {
         if(data==null) {
             return null;
         }
         try {
-            return encodingFormatter.parse(data, query);
+            return getIsoFormat().parse(data, query);
         } catch (final IllegalArgumentException e) {
             throw new EncodingException(e);
         }
@@ -176,24 +103,27 @@ implements TemporalValueSemantics<T> {
     // -- RENDERER
 
     @Override
-    public String simpleTextPresentation(
+    public final String simpleTextPresentation(
             final ValueSemanticsProvider.Context context,
             final T value) {
-        val temporal = _Casts.<T>uncheckedCast(value);
-        return render(temporal, titleFormatter::format);
+        return render(value, getRenderingFormat(context)::format);
     }
 
     // -- PARSER
 
     @Override
-    public String parseableTextRepresentation(final ValueSemanticsProvider.Context context, final T value) {
-        return toEncodedString(value);
+    public final String parseableTextRepresentation(final ValueSemanticsProvider.Context context, final T value) {
+        return value==null ? "" : getEditingFormat(context).format(value);
     }
 
     @Override
-    public T parseTextRepresentation(final ValueSemanticsProvider.Context context, final String text) {
-        T contextTemporal = _Casts.uncheckedCast(context);
-        val temporalString = text.trim().toUpperCase();
+    public final T parseTextRepresentation(final ValueSemanticsProvider.Context context, final String text) {
+        val temporalString = _Strings.blankToNullOrTrim(text);
+        if(temporalString==null) {
+            return null;
+        }
+
+        T contextTemporal = null; //FIXME[ISIS-2882] not implemented yet
         if(contextTemporal != null) {
             val adjusted = TemporalAdjust
                     .parseAdjustment(adjuster, contextTemporal, temporalString);
@@ -201,17 +131,46 @@ implements TemporalValueSemantics<T> {
                 return adjusted;
             }
         }
-        for(val parser: parsers) {
-            try {
-                return parser.apply(temporalString);
-            } catch (final IllegalArgumentException e) {
-                // continue to next
-            }
+
+        val format = getEditingFormat(context);
+
+        try {
+            return format.parse(temporalString, query);
+        } catch (final Exception e) {
+            throw new TextEntryParseException(String.format("Not recognised as a %s: %s",
+                    getCorrespondingClass().getName(),
+                    temporalString), e);
         }
-        val msg = String.format("Not recognised as a %s: %s",
-                getCorrespondingClass().getName(),
-                temporalString);
-        throw new TextEntryParseException(msg);
+
+    }
+
+    /**
+     * Format for pretty rendering, not used for parsing/editing.
+     */
+    protected DateTimeFormatter getRenderingFormat(final ValueSemanticsProvider.Context context) {
+        return getTemporalRenderingFormat(
+                context, temporalCharacteristic, offsetCharacteristic, FormatStyle.MEDIUM, FormatStyle.MEDIUM);
+    }
+
+    /**
+     * Format used for editing.
+     */
+    protected DateTimeFormatter getEditingFormat(final ValueSemanticsProvider.Context context) {
+        return getEditingFormat(context, temporalCharacteristic, offsetCharacteristic,
+                "yyyy-MM-dd", "HH:mm:ss", "Z");
+    }
+
+    @Override
+    public String getPattern(final ValueSemanticsProvider.Context context) {
+        return getEditingFormatAsPattern(temporalCharacteristic, offsetCharacteristic,
+                "yyyy-MM-dd", "HH:mm:ss", "Z");
+    }
+
+    /**
+     * ISO format used for serializing.
+     */
+    protected DateTimeFormatter getIsoFormat() {
+        return getTemporalIsoFormat(temporalCharacteristic, offsetCharacteristic);
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
index d00e12e..9301b0b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
@@ -19,19 +19,13 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
 import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.ZonedDateTimeValueSemantics")
 //@Log4j2
@@ -51,36 +45,11 @@ extends TemporalValueSemanticsProvider<ZonedDateTime> {
         return ValueType.ZONED_DATE_TIME;
     }
 
-    public ZonedDateTimeValueSemantics(final IsisConfiguration config) {
+    public ZonedDateTimeValueSemantics() {
         super(TemporalCharacteristic.DATE_TIME, OffsetCharacteristic.OFFSET,
                 TYPICAL_LENGTH, MAX_LENGTH,
                 ZonedDateTime::from,
                 TemporalAdjust::adjustZonedDateTime);
-
-        val basicDateTimeNoMillis = "yyyyMMdd'T'HHmmssZ";
-        val basicDateTime = "yyyyMMdd'T'HHmmss.SSSZ";
-
-        super.addNamedFormat("iso", basicDateTimeNoMillis);
-        super.addNamedFormat("iso_encoding", basicDateTime);
-
-        super.updateParsers();
-
-        setEncodingFormatter(lookupNamedFormatterElseFail("iso_encoding"));
-
-        val configuredNameOrPattern = config.getValueTypes().getJavaTime().getZonedDateTime().getFormat();
-
-        // walk through 3 methods of generating a formatter, first one to return non empty wins
-        val formatter = formatterFirstOf(Can.of(
-                ()->lookupFormatStyle(configuredNameOrPattern).map(DateTimeFormatter::ofLocalizedDateTime),
-                ()->lookupNamedFormatter(configuredNameOrPattern),
-                ()->formatterFromPattern(configuredNameOrPattern)
-                ))
-        .orElseGet(()->DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));  // fallback
-
-        //TODO those FormatStyle based formatters potentially need additional zone information
-        setTitleFormatter(formatter);
-
     }
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
index 60a1e17..0953a67 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
@@ -19,28 +19,18 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal.legacy;
 
 import java.sql.Date;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
+import java.time.LocalDate;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.applib.clock.VirtualClock;
-import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * An adapter that handles {@link java.sql.Date} with only date component.
  *
@@ -50,125 +40,33 @@ import lombok.Setter;
 @Component
 @Named("isis.val.JavaSqlDateValueSemantics")
 public class JavaSqlDateValueSemantics
-extends LegacyTemporalValueSemanticsAbstract<Date> {
-
-    private static Map<String, DateFormat> formats = _Maps.newHashMap();
+extends ValueSemanticsAdapter<Date, LocalDate>  {
 
-    @Inject ClockService clockService;
-
-    static {
-        formats.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("yyyyMMdd"));
-        formats.put("iso", createDateFormat("yyyy-MM-dd"));
-        formats.put("medium", DateFormat.getDateInstance(DateFormat.MEDIUM));
-    }
+    @Inject LocalDateValueSemantics localDateValueSemantics;
 
     @Override
     public Class<Date> getCorrespondingClass() {
-        return Date.class;
+        return java.sql.Date.class;
     }
 
     @Override
     public ValueType getSchemaValueType() {
-        return ValueType.LOCAL_DATE;
-    }
-
-    @Getter @Setter
-    private String configuredFormat;
-
-    public JavaSqlDateValueSemantics(final IsisConfiguration config) {
-        super(Date.class, 12);
-
-        final Map<String, DateFormat> formats = formats();
-        configuredFormat = config.getValueTypes().getJavaSql().getDate().getFormat();
-        format = formats.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-
-    @Override
-    protected void clearFields(final Calendar cal) {
-        cal.set(Calendar.HOUR, 0);
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.AM_PM, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-    }
-
-
-    @Override
-    protected boolean ignoreTimeZone() {
-        return true;
-    }
-
-    @Override
-    protected Map<String, DateFormat> formats() {
-        return formats;
-    }
-
-    @Override
-    protected DateFormat format() {
-        final Locale locale = Locale.getDefault();
-        final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
-        dateFormat.setTimeZone(UTC_TIME_ZONE);
-        return dateFormat;
-    }
-
-    @Override
-    protected List<DateFormat> formatsToTry() {
-        List<DateFormat> formats = new ArrayList<DateFormat>();
-
-        Locale locale = Locale.getDefault();
-        formats.add(DateFormat.getDateInstance(DateFormat.LONG, locale));
-        formats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, locale));
-        formats.add(DateFormat.getDateInstance(DateFormat.SHORT, locale));
-        formats.add(createDateFormat("yyyy-MM-dd"));
-        formats.add(createDateFormat("yyyyMMdd"));
-
-        for (DateFormat format : formats) {
-            format.setTimeZone(UTC_TIME_ZONE);
-        }
-
-        return formats;
-    }
-
-    @Override
-    protected Date add(final Date original, final int years, final int months, final int days, final int hours, final int minutes) {
-        final Date date = original;
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        cal.set(Calendar.HOUR, 0);
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.AM_PM, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-
-        cal.add(Calendar.YEAR, years);
-        cal.add(Calendar.MONTH, months);
-        cal.add(Calendar.DAY_OF_MONTH, days);
-        return setDate(cal.getTime());
+        return UNREPRESENTED;
     }
 
     @Override
-    protected java.util.Date dateValue(final Object value) {
-        return (java.util.Date) value;
+    public ValueSemanticsAbstract<LocalDate> getDelegate() {
+        return localDateValueSemantics;
     }
 
     @Override
-    protected Date setDate(final java.util.Date date) {
-        return new Date(date.getTime());
+    public Date fromDelegateValue(final LocalDate delegateValue) {
+        return java.sql.Date.valueOf(delegateValue);
     }
 
     @Override
-    protected Date now() {
-        return Optional.ofNullable(clockService)
-                .map(ClockService::getClock)
-                .map(VirtualClock::nowAsEpochMilli)
-                .map(Date::new)
-                .orElseGet(()->new Date(System.currentTimeMillis())); // fallback to system time
+    public LocalDate toDelegateValue(final java.sql.Date value) {
+        return value.toLocalDate();
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
index 1b56981..485a787 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
@@ -19,40 +19,28 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal.legacy;
 
 import java.sql.Timestamp;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
+import java.time.LocalDateTime;
 
+import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.applib.exceptions.recoverable.InvalidEntryException;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.Getter;
-import lombok.Setter;
-
 @Component
 @Named("isis.val.JavaSqlTimeStampValueSemantics")
 public class JavaSqlTimeStampValueSemantics
-extends LegacyTemporalValueSemanticsAbstract<Timestamp> {
+extends ValueSemanticsAdapter<Timestamp, LocalDateTime>  {
 
-    protected static void initFormats(final Map<String, DateFormat> formats) {
-        formats.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("yyyyMMdd'T'HHmmssSSS"));
-        formats.put("short", DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG));
-    }
+    @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
 
     @Override
     public Class<Timestamp> getCorrespondingClass() {
-        return Timestamp.class;
+        return java.sql.Timestamp.class;
     }
 
     @Override
@@ -60,89 +48,19 @@ extends LegacyTemporalValueSemanticsAbstract<Timestamp> {
         return ValueType.JAVA_SQL_TIMESTAMP;
     }
 
-    @Getter @Setter
-    private String configuredFormat;
-
-    public JavaSqlTimeStampValueSemantics(final IsisConfiguration config) {
-        super(java.sql.Timestamp.class, 25);
-
-        configuredFormat = config.getValueTypes().getJavaSql().getTimestamp().getFormat();
-
-        final Map<String, DateFormat> formats1 = formats();
-        format = formats1.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-    @Override
-    protected Timestamp add(final Timestamp original, final int years, final int months, final int days, final int hours, final int minutes) {
-        return original;
-    }
-
-    @Override
-    protected DateFormat format() {
-
-        final Locale locale = Locale.getDefault();
-        final TimeZone timeZone = TimeZone.getDefault();
-
-        final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);
-        dateFormat.setTimeZone(timeZone);
-
-        return dateFormat;
-    }
-
-    @Override
-    protected List<DateFormat> formatsToTry() {
-        final List<DateFormat> formats = new ArrayList<DateFormat>();
-
-        final Locale locale = Locale.getDefault();
-        final TimeZone timeZone = TimeZone.getDefault();
-
-        formats.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG, locale));
-        formats.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale));
-        formats.add(createDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
-
-        for (final DateFormat format : formats) {
-            format.setTimeZone(timeZone);
-        }
-
-        return formats;
-    }
-
-    public static final boolean isAPropertyDefaultFacet() {
-        return PropertyDefaultFacet.class.isAssignableFrom(JavaSqlTimeStampValueSemantics.class);
-    }
-
-    private static Map<String, DateFormat> formats = _Maps.newHashMap();
-
-    static {
-        initFormats(formats);
-    }
-
-
-    // //////////////////////////////////////////////////////////////////
-    // temporal-specific stuff
-    // //////////////////////////////////////////////////////////////////
-
-    @Override
-    protected Date dateValue(final Object value) {
-        return new Date(((java.sql.Timestamp) value).getTime());
-    }
-
     @Override
-    protected Map<String, DateFormat> formats() {
-        return formats;
+    public ValueSemanticsAbstract<LocalDateTime> getDelegate() {
+        return localDateTimeValueSemantics;
     }
 
     @Override
-    protected Timestamp now() {
-        throw new InvalidEntryException("Can't change a timestamp.");
+    public Timestamp fromDelegateValue(final LocalDateTime delegateValue) {
+        return Timestamp.valueOf(delegateValue);
     }
 
     @Override
-    protected Timestamp setDate(final Date date) {
-        return new Timestamp(date.getTime());
+    public LocalDateTime toDelegateValue(final Timestamp value) {
+        return value.toLocalDateTime();
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
index 2e5301a..8d8ec14 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
@@ -19,29 +19,18 @@
 package org.apache.isis.core.metamodel.valuesemantics.temporal.legacy;
 
 import java.sql.Time;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
+import java.time.LocalTime;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.applib.clock.VirtualClock;
-import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * Treats {@link java.sql.Time} as a time-only value type.
  *
@@ -49,122 +38,33 @@ import lombok.Setter;
 @Component
 @Named("isis.val.JavaSqlTimeValueSemantics")
 public class JavaSqlTimeValueSemantics
-extends LegacyTemporalValueSemanticsAbstract<Time> {
-
-    protected static void initFormats(final Map<String, DateFormat> formats) {
-        formats.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("HHmmssSSS"));
-        formats.put("short", DateFormat.getTimeInstance(DateFormat.SHORT));
-    }
+extends ValueSemanticsAdapter<Time, LocalTime>  {
 
-    @Inject ClockService clockService;
+    @Inject LocalTimeValueSemantics localTimeValueSemantics;
 
     @Override
     public Class<Time> getCorrespondingClass() {
-        return Time.class;
+        return java.sql.Time.class;
     }
 
     @Override
     public ValueType getSchemaValueType() {
-        return ValueType.LOCAL_TIME;
-    }
-
-    @Getter @Setter
-    private String configuredFormat;
-
-    public JavaSqlTimeValueSemantics(final IsisConfiguration config) {
-        super(java.sql.Time.class, 8);
-
-        final Map<String, DateFormat> formats = formats();
-        configuredFormat = config.getValueTypes().getJavaSql().getTime().getFormat();
-        format = formats.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-    @Override
-    protected void clearFields(final Calendar cal) {
-        cal.set(Calendar.YEAR, 1970);
-        cal.set(Calendar.MONTH, 0);
-        cal.set(Calendar.DAY_OF_MONTH, 1);
-    }
-
-    @Override
-    protected DateFormat format() {
-
-        final Locale locale = Locale.getDefault();
-        final DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
-        dateFormat.setTimeZone(UTC_TIME_ZONE);
-        return dateFormat;
-    }
-
-    @Override
-    protected List<DateFormat> formatsToTry() {
-        List<DateFormat> formats = new ArrayList<DateFormat>();
-
-        final Locale locale = Locale.getDefault();
-
-        formats.add(DateFormat.getTimeInstance(DateFormat.LONG, locale));
-        formats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, locale));
-        formats.add(DateFormat.getTimeInstance(DateFormat.SHORT, locale));
-        formats.add(createDateFormat("HH:mm:ss.SSS"));
-        formats.add(createDateFormat("HHmmssSSS"));
-        formats.add(createDateFormat("HH:mm:ss"));
-        formats.add(createDateFormat("HHmmss"));
-
-        for (DateFormat format : formats) {
-            format.setTimeZone(UTC_TIME_ZONE);
-        }
-
-        return formats;
-    }
-
-    private static Map<String, DateFormat> formats = _Maps.newHashMap();
-
-    static {
-        initFormats(formats);
-    }
-
-
-    @Override
-    public Time add(final Time original, final int years, final int months, final int days, final int hours, final int minutes) {
-        final java.sql.Time time = original;
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(time);
-        cal.set(Calendar.YEAR, 0);
-        cal.set(Calendar.MONTH, 0);
-        cal.set(Calendar.DAY_OF_MONTH, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-
-        cal.add(Calendar.HOUR, hours);
-        cal.add(Calendar.MINUTE, minutes);
-
-        return setDate(cal.getTime());
-    }
-
-    @Override
-    public java.util.Date dateValue(final Object object) {
-        final java.sql.Time time = (Time) object;
-        return time == null ? null : new java.util.Date(time.getTime());
+        return UNREPRESENTED;
     }
 
     @Override
-    protected Map<String, DateFormat> formats() {
-        return formats;
+    public ValueSemanticsAbstract<LocalTime> getDelegate() {
+        return localTimeValueSemantics;
     }
 
     @Override
-    protected Time now() {
-        return Optional.ofNullable(clockService)
-                .map(ClockService::getClock)
-                .map(VirtualClock::nowAsEpochMilli)
-                .map(Time::new)
-                .orElseGet(()->new Time(System.currentTimeMillis())); // fallback to system time
+    public Time fromDelegateValue(final LocalTime delegateValue) {
+        return Time.valueOf(delegateValue);
     }
 
     @Override
-    protected Time setDate(final Date date) {
-        return new java.sql.Time(date.getTime());
+    public LocalTime toDelegateValue(final Time value) {
+        return value.toLocalTime();
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
index d64c88d..f915d5a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
@@ -18,30 +18,20 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal.legacy;
 
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.TimeZone;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
-import org.apache.isis.applib.clock.VirtualClock;
-import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * An adapter that handles {@link java.util.Date} as both a date AND time
  * component.
@@ -52,120 +42,36 @@ import lombok.Setter;
 @Component
 @Named("isis.val.JavaUtilDateValueSemantics")
 public class JavaUtilDateValueSemantics
-extends LegacyTemporalValueSemanticsAbstract<java.util.Date> {
-
-    private static Map<String, DateFormat> formats = _Maps.newHashMap();
+extends ValueSemanticsAdapter<Date, LocalDateTime>  {
 
-    @Inject ClockService clockService;
-
-    static {
-        formats.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("yyyyMMdd'T'HHmmssSSS"));
-        formats.put("iso", createDateFormat("yyyy-MM-dd HH:mm"));
-        formats.put("medium", DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT));
-    }
+    @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
 
     @Override
     public Class<Date> getCorrespondingClass() {
-        return Date.class;
+        return java.util.Date.class;
     }
 
     @Override
     public ValueType getSchemaValueType() {
-        return ValueType.LOCAL_DATE;
-    }
-
-    @Getter @Setter
-    private String configuredFormat;
-
-    public JavaUtilDateValueSemantics(final IsisConfiguration config) {
-        super(Date.class, 18);
-
-        final Map<String, DateFormat> formats = formats();
-        configuredFormat = config.getValueTypes().getJavaUtil().getDate().getFormat();
-        format = formats.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // temporal-specific stuff
-    // //////////////////////////////////////////////////////////////////
-
-    @Override
-    protected Map<String, DateFormat> formats() {
-        return formats;
-    }
-
-    @Override
-    protected DateFormat format() {
-        final Locale locale = Locale.getDefault();
-        final TimeZone timeZone = TimeZone.getDefault();
-
-        final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale);
-        dateFormat.setTimeZone(timeZone);
-        return dateFormat;
-    }
-
-    @Override
-    protected List<DateFormat> formatsToTry() {
-        List<DateFormat> formats = new ArrayList<>();
-
-        final Locale locale = Locale.getDefault();
-        final TimeZone timeZone = TimeZone.getDefault();
-
-        formats.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale));
-        formats.add(createDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
-        formats.add(createDateFormat("yyyyMMdd'T'HHmmssSSS"));
-        formats.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale));
-        formats.add(createDateFormat("yyyy-MM-dd HH:mm:ss"));
-        formats.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale));
-        formats.add(createDateFormat("yyyyMMdd'T'HHmmss"));
-        formats.add(createDateFormat("yyyy-MM-dd HH:mm"));
-        formats.add(createDateFormat("yyyyMMdd'T'HHmm"));
-        formats.add(createDateFormat("dd-MMM-yyyy HH:mm"));
-
-        for (DateFormat format : formats) {
-            format.setTimeZone(timeZone);
-        }
-
-        return formats;
+        return UNREPRESENTED;
     }
 
-
     @Override
-    protected Date dateValue(final Object value) {
-        return value == null ? null : (Date) value;
+    public ValueSemanticsAbstract<LocalDateTime> getDelegate() {
+        return localDateTimeValueSemantics;
     }
 
     @Override
-    protected Date add(final Date original, final int years, final int months, final int days, final int hours, final int minutes) {
-        final Date date = original;
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-
-        cal.add(Calendar.YEAR, years);
-        cal.add(Calendar.MONTH, months);
-        cal.add(Calendar.DAY_OF_MONTH, days);
-        cal.add(Calendar.HOUR, hours);
-        cal.add(Calendar.MINUTE, minutes);
-
-        return setDate(cal.getTime());
+    public Date fromDelegateValue(final LocalDateTime delegateValue) {
+        return java.util.Date.from(delegateValue
+                    .atZone(ZoneId.systemDefault())
+                    .toInstant());
     }
 
     @Override
-    protected Date now() {
-        return Optional.ofNullable(clockService)
-                .map(ClockService::getClock)
-                .map(VirtualClock::nowAsEpochMilli)
-                .map(Date::new)
-                .orElseGet(Date::new); // fallback to system time
+    public LocalDateTime toDelegateValue(final java.util.Date value) {
+        return LocalDateTime.ofInstant(
+                        value.toInstant(), ZoneId.systemDefault());
     }
 
-    @Override
-    protected Date setDate(final Date date) {
-        return date;
-    }
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/LegacyTemporalValueSemanticsAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/LegacyTemporalValueSemanticsAbstract.java
deleted file mode 100644
index e9e98df..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/LegacyTemporalValueSemanticsAbstract.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.adapters.EncodingException;
-import org.apache.isis.applib.adapters.Parser;
-import org.apache.isis.applib.adapters.Renderer;
-import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
-import org.apache.isis.applib.adapters.ValueSemanticsProvider;
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Strings;
-
-import lombok.Getter;
-import lombok.val;
-import lombok.experimental.Accessors;
-
-public abstract class LegacyTemporalValueSemanticsAbstract<T>
-extends ValueSemanticsAbstract<T>
-implements
-    EncoderDecoder<T>,
-    Parser<T>,
-    Renderer<T> {
-
-    protected static final String ISO_ENCODING_FORMAT = "iso_encoding";
-    protected static final TimeZone UTC_TIME_ZONE;
-
-    static {
-        TimeZone timeZone = TimeZone.getTimeZone("Etc/UTC");
-        if (timeZone == null) {
-            timeZone = TimeZone.getTimeZone("UTC");
-        }
-        UTC_TIME_ZONE = timeZone;
-    }
-
-    protected static DateFormat createDateFormat(final String mask) {
-        return new SimpleDateFormat(mask);
-    }
-
-    /**
-     * for encoding always use UTC.
-     */
-    protected static DateFormat createDateEncodingFormat(final String mask) {
-        DateFormat encodingFormat = createDateFormat(mask);
-        encodingFormat.setTimeZone(UTC_TIME_ZONE);
-        return encodingFormat;
-    }
-
-    @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) protected final int typicalLength;
-    //@Getter(onMethod_ = {@Override}) @Accessors(fluent = true) protected final int maxLength;
-
-    private final DateFormat encodingFormat;
-    protected DateFormat format;
-
-    protected LegacyTemporalValueSemanticsAbstract(
-            final Class<T> adaptedClass,
-            final int typicalLength) {
-        super();
-        configureFormats();
-
-        this.typicalLength = typicalLength;
-
-        encodingFormat = formats().get(ISO_ENCODING_FORMAT);
-    }
-
-    // -- ENCODER/DECODER
-
-    @Override
-    public String toEncodedString(final T temporal) {
-        final Date date = dateValue(temporal);
-        return encodingFormat.format(date);
-    }
-
-    @Override
-    public T fromEncodedString(final String data) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTimeZone(UTC_TIME_ZONE);
-
-        // TODO allow restoring of dates where datetime expected, and datetimes where date expected - to allow for changing of field types.
-        try {
-            cal.setTime(parse(data));
-            clearFields(cal);
-            return setDate(cal.getTime());
-        } catch (final ParseException e) {
-            if (data.charAt(0) == 'T') {
-                final long millis = Long.parseLong(data.substring(1));
-                cal.setTimeInMillis(millis);
-                clearFields(cal);
-                return setDate(cal.getTime());
-            } else {
-                throw new EncodingException(e);
-            }
-        }
-    }
-
-    // -- RENDERER
-
-    @Override
-    public String simpleTextPresentation(final Context context, final T value) {
-        return render(value, v->asTitleString(v));
-    }
-
-    // -- PARSER
-
-    @Override
-    public String parseableTextRepresentation(final Context context, final T value) {
-        return toEncodedString(value);
-    }
-
-    @Override
-    public T parseTextRepresentation(final Context context, final String text) {
-        val input = _Strings.blankToNullOrTrim(text);
-        if(input==null) {
-            return null;
-        }
-        return doParse(context, input);
-    }
-
-    // --
-
-    protected void configureFormats() {
-        final Map<String, DateFormat> formats = formats();
-        for (final Map.Entry<String, DateFormat> mapEntry : formats.entrySet()) {
-            final DateFormat format = mapEntry.getValue();
-            format.setLenient(false);
-            if (ignoreTimeZone()) {
-                format.setTimeZone(UTC_TIME_ZONE);
-            }
-        }
-    }
-
-    protected void buildDefaultFormatIfRequired() {
-        // (re)create format
-        buildFormat(getConfiguredFormat());
-    }
-
-    protected abstract String getConfiguredFormat();
-    protected abstract void setConfiguredFormat(final String configuredFormat);
-
-    protected void buildFormat(final String configuredFormat) {
-        final Map<String, DateFormat> formats = formats();
-        format = formats.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // Parsing
-    // //////////////////////////////////////////////////////////////////
-
-    //@Override
-    protected T doParse(
-            final ValueSemanticsProvider.Context context,
-            final String entry) {
-
-        buildDefaultFormatIfRequired();
-        final String dateString = entry.trim();
-        final String str = dateString.toLowerCase();
-        if (str.equals("today") || str.equals("now")) {
-            return now();
-        } else if (dateString.startsWith("+")) {
-            return relativeDate(context == null ? now() : context, dateString, true);
-        } else if (dateString.startsWith("-")) {
-            return relativeDate(context == null ? now() : context, dateString, false);
-        } else {
-            return parseDate(dateString);
-        }
-    }
-
-    private T parseDate(final String dateString) {
-        List<DateFormat> elements = formatsToTry();
-        return setDate(parseDate(dateString, elements.iterator()));
-    }
-
-    protected abstract List<DateFormat> formatsToTry();
-
-    private Date parseDate(final String dateString, final Iterator<DateFormat> elements) {
-        final DateFormat format = elements.next();
-        try {
-            return format.parse(dateString);
-        } catch (final ParseException e) {
-            if (elements.hasNext()) {
-                return parseDate(dateString, elements);
-            } else {
-                throw new TextEntryParseException("Not recognised as a date: " + dateString);
-            }
-        }
-    }
-
-    private T relativeDate(final Object object, final String str, final boolean add) {
-        if (str.equals("")) {
-            return now();
-        }
-
-        try {
-            T date = _Casts.uncheckedCast(object);
-            final StringTokenizer st = new StringTokenizer(str.substring(1), " ");
-            while (st.hasMoreTokens()) {
-                final String token = st.nextToken();
-                date = relativeDate2(date, token, add);
-            }
-            return date;
-        } catch (final Exception e) {
-            return now();
-        }
-    }
-
-    private T relativeDate2(final T original, String str, final boolean add) {
-        int hours = 0;
-        int minutes = 0;
-        int days = 0;
-        int months = 0;
-        int years = 0;
-
-        if (str.endsWith("H")) {
-            str = str.substring(0, str.length() - 1);
-            hours = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("M")) {
-            str = str.substring(0, str.length() - 1);
-            minutes = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("w")) {
-            str = str.substring(0, str.length() - 1);
-            days = 7 * Integer.valueOf(str).intValue();
-        } else if (str.endsWith("y")) {
-            str = str.substring(0, str.length() - 1);
-            years = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("m")) {
-            str = str.substring(0, str.length() - 1);
-            months = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("d")) {
-            str = str.substring(0, str.length() - 1);
-            days = Integer.valueOf(str).intValue();
-        } else {
-            days = Integer.valueOf(str).intValue();
-        }
-
-        if (add) {
-            return add(original, years, months, days, hours, minutes);
-        } else {
-            return add(original, -years, -months, -days, -hours, -minutes);
-        }
-    }
-
-    // ///////////////////////////////////////////////////////////////////////////
-    // TitleProvider
-    // ///////////////////////////////////////////////////////////////////////////
-
-    //@Override
-    protected String asTitleString(final T value) {
-        if (value == null) {
-            return null;
-        }
-        final Date date = dateValue(value);
-        final DateFormat f = format();
-        return titleString(f, date);
-    }
-
-    protected DateFormat format() {
-        return format;
-    }
-
-    private String titleString(final DateFormat formatter, final Date date) {
-        return date == null ? "" : formatter.format(date);
-    }
-
-    private synchronized Date parse(final String data) throws ParseException {
-        return encodingFormat.parse(data);
-    }
-
-    protected abstract T add(T original, int years, int months, int days, int hours, int minutes);
-
-    protected void clearFields(final Calendar cal) {
-    }
-
-    protected abstract Date dateValue(Object value);
-
-    protected abstract Map<String, DateFormat> formats();
-
-    protected boolean ignoreTimeZone() {
-        return false;
-    }
-
-    protected abstract T now();
-
-    protected abstract T setDate(Date date);
-
-    public void setMask(final String mask) {
-        format = new SimpleDateFormat(mask);
-        format.setTimeZone(UTC_TIME_ZONE);
-        format.setLenient(false);
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaDateTimeValueSemantics.java
deleted file mode 100644
index e596843..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaDateTimeValueSemantics.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.inject.Named;
-
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.ISODateTimeFormat;
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.adapters.EncodingException;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.LegacyTemporalValueSemanticsAbstract;
-import org.apache.isis.schema.common.v2.ValueType;
-
-import lombok.Getter;
-import lombok.Setter;
-
-@Component
-@Named("isis.val.JodaDateTimeValueSemantics")
-public class JodaDateTimeValueSemantics
-extends LegacyTemporalValueSemanticsAbstract<DateTime> {
-
-    private static final Map<String, DateFormat> FORMATS = _Maps.newHashMap();
-
-    static {
-        FORMATS.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("yyyyMMdd"));
-        FORMATS.put("iso", createDateFormat("yyyy-MM-dd"));
-        FORMATS.put("medium", DateFormat.getDateInstance(DateFormat.MEDIUM));
-    }
-
-    @Override
-    public Class<DateTime> getCorrespondingClass() {
-        return DateTime.class;
-    }
-
-    @Override
-    public ValueType getSchemaValueType() {
-        return ValueType.JODA_DATE_TIME;
-    }
-
-    @Getter @Setter
-    private String configuredFormat;
-
-    public JodaDateTimeValueSemantics(
-            final IsisConfiguration config) {
-        super(DateTime.class, 12);
-
-        final Map<String, DateFormat> formats = formats();
-        configuredFormat = config.getValueTypes().getJoda().getDateTime().getFormat();
-        format = formats.get(configuredFormat);
-        if (format == null) {
-            setMask(configuredFormat);
-        }
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // temporal-specific stuff
-    // //////////////////////////////////////////////////////////////////
-
-    @Override
-    protected void clearFields(final Calendar cal) {
-        cal.set(Calendar.HOUR, 0);
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.AM_PM, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-    }
-
-    @Override
-    protected boolean ignoreTimeZone() {
-        return true;
-    }
-
-    @Override
-    protected Map<String, DateFormat> formats() {
-        return FORMATS;
-    }
-
-    @Override
-    protected DateFormat format() {
-        final Locale locale = Locale.getDefault();
-
-        final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
-        dateFormat.setTimeZone(UTC_TIME_ZONE);
-        return dateFormat;
-    }
-
-    @Override
-    protected List<DateFormat> formatsToTry() {
-
-        final Locale locale = Locale.getDefault();
-
-        List<DateFormat> formats = new ArrayList<>();
-
-        formats.add(DateFormat.getDateInstance(DateFormat.LONG, locale));
-        formats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, locale));
-        formats.add(DateFormat.getDateInstance(DateFormat.SHORT, locale));
-        formats.add(createDateFormat("yyyy-MM-dd"));
-        formats.add(createDateFormat("yyyyMMdd"));
-
-        for (DateFormat format : formats) {
-            format.setTimeZone(UTC_TIME_ZONE);
-        }
-
-        return formats;
-    }
-
-    @Override
-    protected DateTime add(final DateTime original, final int years, final int months, final int days, final int hours, final int minutes) {
-        if(hours != 0 || minutes != 0) {
-            throw new IllegalArgumentException("cannot add non-zero hours or minutes to a DateTime");
-        }
-        return original.plusYears(years).plusMonths(months).plusDays(days);
-    }
-
-    @Override
-    protected DateTime now() {
-        return new DateTime();
-    }
-
-    @Override
-    protected Date dateValue(final Object value) {
-        return ((DateTime) value).toDateTime().toDate();
-    }
-
-    @Override
-    protected DateTime setDate(final Date date) {
-        return new DateTime(date.getTime());
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // EncoderDecoder
-    // //////////////////////////////////////////////////////////////////
-
-    private static final DateTimeFormatter encodingFormatter() {
-        return ISODateTimeFormat.basicDateTime();
-    }
-
-    @Override
-    public String toEncodedString(final DateTime dateTime) {
-        return encodingFormatter().print(dateTime);
-    }
-
-    @Override
-    public DateTime fromEncodedString(final String data) {
-        try {
-            return encodingFormatter().parseDateTime(data);
-        } catch (final IllegalArgumentException e) {
-            throw new EncodingException(e);
-        }
-    }
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateTimeValueSemantics.java
deleted file mode 100644
index 62f2179..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateTimeValueSemantics.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.inject.Named;
-
-import org.joda.time.LocalDateTime;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.ISODateTimeFormat;
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.adapters.EncodingException;
-import org.apache.isis.applib.adapters.Parser;
-import org.apache.isis.applib.adapters.Renderer;
-import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
-import org.apache.isis.applib.adapters.ValueSemanticsProvider;
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.schema.common.v2.ValueType;
-
-@Component
-@Named("isis.val.JodaLocalDateTimeValueSemantics")
-public class JodaLocalDateTimeValueSemantics
-extends ValueSemanticsAbstract<LocalDateTime>
-implements
-    EncoderDecoder<LocalDateTime>,
-    Parser<LocalDateTime>,
-    Renderer<LocalDateTime> {
-
-    public static final int MAX_LENGTH = 36;
-    public static final int TYPICAL_LENGTH = 22;
-
-    @Override
-    public Class<LocalDateTime> getCorrespondingClass() {
-        return LocalDateTime.class;
-    }
-
-    @Override
-    public ValueType getSchemaValueType() {
-        return ValueType.JODA_LOCAL_DATE_TIME;
-    }
-
-    /**
-     * Introduced to allow BDD tests to provide a different format string "mid-flight".
-     *
-     * <p>
-     * REVIEW: This seems only to have any effect if 'propertyType' is set to 'date'.
-     *
-     * @see #setTitlePatternOverride(String)
-     * @deprecated - because 'propertyType' parameter is never used
-     */
-    @Deprecated
-    public static void setFormat(final String propertyType, final String pattern) {
-        setTitlePatternOverride(pattern);
-    }
-    /**
-     * A replacement for {@link #setFormat(String, String)}.
-     */
-    public static void setTitlePatternOverride(final String pattern) {
-        OVERRIDE_TITLE_PATTERN.set(pattern);
-    }
-
-    /**
-     * Keys represent the values which can be configured, and which are used for the rendering of dates.
-     *
-     */
-    private static Map<String, DateTimeFormatter> NAMED_TITLE_FORMATTERS = _Maps.newHashMap();
-    static {
-        NAMED_TITLE_FORMATTERS.put("iso_encoding", ISODateTimeFormat.basicDateTime());
-        NAMED_TITLE_FORMATTERS.put("iso", ISODateTimeFormat.basicDateTimeNoMillis());
-        NAMED_TITLE_FORMATTERS.put("long", DateTimeFormat.forStyle("LL"));
-        NAMED_TITLE_FORMATTERS.put("medium", DateTimeFormat.forStyle("MM"));
-        NAMED_TITLE_FORMATTERS.put("short", DateTimeFormat.forStyle("SS"));
-    }
-
-    /**
-     * @deprecated possible memory leak issue, because this one is never cleared up
-     */
-    @Deprecated
-    private static final ThreadLocal<String> OVERRIDE_TITLE_PATTERN = ThreadLocal.withInitial(()->null);
-
-    private static final List<DateTimeFormatter> PARSE_FORMATTERS = _Lists.newArrayList();
-    static {
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("LL"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("MM"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("SS"));
-        PARSE_FORMATTERS.add(ISODateTimeFormat.basicDateTimeNoMillis());
-        PARSE_FORMATTERS.add(ISODateTimeFormat.basicDateTime());
-    }
-
-    private final DateTimeFormatter encodingFormatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
-
-    private DateTimeFormatter titleStringFormatter;
-    private String titleStringFormatNameOrPattern;
-
-    // //////////////////////////////////////
-    // constructor
-    // //////////////////////////////////////
-
-    public JodaLocalDateTimeValueSemantics(final IsisConfiguration config) {
-        String configuredNameOrPattern = config
-                .getValueTypes().getJoda().getLocalDateTime().getFormat();
-        updateTitleStringFormatter(configuredNameOrPattern);
-    }
-
-    @Override
-    public int typicalLength() {
-        return TYPICAL_LENGTH;
-    }
-
-    @Override
-    public int maxLength() {
-        return MAX_LENGTH;
-    }
-
-    private void updateTitleStringFormatter(final String titleStringFormatNameOrPattern) {
-        titleStringFormatter = NAMED_TITLE_FORMATTERS.get(titleStringFormatNameOrPattern);
-        if (titleStringFormatter == null) {
-            titleStringFormatter = DateTimeFormat.forPattern(titleStringFormatNameOrPattern);
-        }
-        this.titleStringFormatNameOrPattern = titleStringFormatNameOrPattern;
-    }
-
-    // -- PARSER
-
-    @Override
-    public String parseableTextRepresentation(final Context context, final LocalDateTime value) {
-        return toEncodedString(value);
-    }
-
-    @Override
-    public LocalDateTime parseTextRepresentation(
-            final ValueSemanticsProvider.Context context,
-            final String entry) {
-
-        updateTitleStringFormatterIfOverridden();
-
-        //LocalDateTime contextDateTime = (LocalDateTime) context;
-
-        final String dateString = entry.trim().toUpperCase();
-//        if (dateString.startsWith("+") && contextDateTime != null) {
-//            return JodaLocalDateTimeUtil.relativeDateTime(contextDateTime, dateString, true);
-//        } else if (dateString.startsWith("-")  && contextDateTime != null) {
-//            return JodaLocalDateTimeUtil.relativeDateTime(contextDateTime, dateString, false);
-//        } else {
-            return parseDateTime(dateString);
-//        }
-    }
-
-    private void updateTitleStringFormatterIfOverridden() {
-        final String overridePattern = OVERRIDE_TITLE_PATTERN.get();
-        if (overridePattern == null ||
-                titleStringFormatNameOrPattern.equals(overridePattern)) {
-            return;
-        }
-
-        // (re)create format
-        updateTitleStringFormatter(overridePattern);
-    }
-
-    private LocalDateTime parseDateTime(final String dateStr) {
-        return _JodaLocalDateTimeUtil.parseDate(dateStr, PARSE_FORMATTERS);
-    }
-
-
-    // ///////////////////////////////////////////////////////////////////////////
-    // TitleProvider
-    // ///////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public String simpleTextPresentation(final Context context, final LocalDateTime value) {
-        if (value == null) {
-            return null;
-        }
-        final LocalDateTime dateTime = value;
-        final DateTimeFormatter f = titleStringFormatter.withLocale(Locale.getDefault());
-        return _JodaLocalDateTimeUtil.titleString(f, dateTime);
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // EncoderDecoder
-    // //////////////////////////////////////////////////////////////////
-
-    @Override
-    public String toEncodedString(final LocalDateTime localDateTime) {
-        return encode(localDateTime);
-    }
-
-    private synchronized String encode(final LocalDateTime date) {
-        return encodingFormatter.print(date);
-    }
-
-    @Override
-    public LocalDateTime fromEncodedString(final String data) {
-        try {
-            return parse(data);
-        } catch (final IllegalArgumentException e) {
-            throw new EncodingException(e);
-        }
-    }
-
-    private synchronized LocalDateTime parse(final String data) {
-        return encodingFormatter.parseLocalDateTime(data);
-    }
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateValueSemantics.java
deleted file mode 100644
index 3470505..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalDateValueSemantics.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.inject.Named;
-
-import org.joda.time.LocalDate;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.adapters.EncodingException;
-import org.apache.isis.applib.adapters.Parser;
-import org.apache.isis.applib.adapters.Renderer;
-import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
-import org.apache.isis.applib.adapters.ValueSemanticsProvider;
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.schema.common.v2.ValueType;
-
-@Component
-@Named("isis.val.JodaLocalDateValueSemantics")
-public class JodaLocalDateValueSemantics
-extends ValueSemanticsAbstract<LocalDate>
-implements
-    EncoderDecoder<LocalDate>,
-    Parser<LocalDate>,
-    Renderer<LocalDate> {
-
-    public static final int MAX_LENGTH = 12;
-    public static final int TYPICAL_LENGTH = MAX_LENGTH;
-
-    @Override
-    public Class<LocalDate> getCorrespondingClass() {
-        return LocalDate.class;
-    }
-
-    @Override
-    public ValueType getSchemaValueType() {
-        return ValueType.JODA_LOCAL_DATE;
-    }
-
-    /**
-     * Introduced to allow BDD tests to provide a different format string "mid-flight".
-     *
-     * <p>
-     * REVIEW: This seems only to have any effect if 'propertyType' is set to 'date'.
-     *
-     * @see #setTitlePatternOverride(String)
-     * @deprecated - because 'propertyType' parameter is never used
-     */
-    @Deprecated
-    public static void setFormat(final String propertyType, final String pattern) {
-        setTitlePatternOverride(pattern);
-    }
-    /**
-     * A replacement for {@link #setFormat(String, String)}.
-     */
-    public static void setTitlePatternOverride(final String pattern) {
-        OVERRIDE_TITLE_PATTERN.set(pattern);
-    }
-
-    /**
-     * Keys represent the values which can be configured, and which are used for the rendering of dates.
-     *
-     */
-    private static Map<String, DateTimeFormatter> NAMED_TITLE_FORMATTERS = _Maps.newHashMap();
-    static {
-        NAMED_TITLE_FORMATTERS.put("iso_encoding", DateTimeFormat.forPattern("yyyyMMdd"));
-        NAMED_TITLE_FORMATTERS.put("iso", DateTimeFormat.forPattern("yyyy-MM-dd"));
-        NAMED_TITLE_FORMATTERS.put("long", DateTimeFormat.forStyle("L-"));
-        NAMED_TITLE_FORMATTERS.put("medium", DateTimeFormat.forStyle("M-"));
-        NAMED_TITLE_FORMATTERS.put("short", DateTimeFormat.forStyle("S-"));
-    }
-
-    /**
-     * @deprecated possible memory leak issue, because this one is never cleared up
-     */
-    @Deprecated
-    private static final ThreadLocal<String> OVERRIDE_TITLE_PATTERN = ThreadLocal.withInitial(()->null);
-
-
-    private static final List<DateTimeFormatter> PARSE_FORMATTERS = _Lists.newArrayList();
-    static {
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("L-"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("M-"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forStyle("S-"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forPattern("yyyy-MM-dd"));
-        PARSE_FORMATTERS.add(DateTimeFormat.forPattern("yyyyMMdd"));
-    }
-
-    private final DateTimeFormatter encodingFormatter = DateTimeFormat.forPattern("yyyyMMdd");
-
-    private DateTimeFormatter titleStringFormatter;
-    private String titleStringFormatNameOrPattern;
-
-
-    // //////////////////////////////////////
-    // constructor
-    // //////////////////////////////////////
-
-    public JodaLocalDateValueSemantics(final IsisConfiguration config) {
-        String configuredNameOrPattern = config
-                .getValueTypes().getJoda().getLocalDate().getFormat();
-
-        updateTitleStringFormatter(configuredNameOrPattern);
-    }
-
-    @Override
-    public int typicalLength() {
-        return TYPICAL_LENGTH;
-    }
-
-    @Override
-    public int maxLength() {
-        return MAX_LENGTH;
-    }
-
-
-    private void updateTitleStringFormatter(final String titleStringFormatNameOrPattern) {
-        titleStringFormatter = NAMED_TITLE_FORMATTERS.get(titleStringFormatNameOrPattern);
-        if (titleStringFormatter == null) {
-            titleStringFormatter = DateTimeFormat.forPattern(titleStringFormatNameOrPattern);
-        }
-        this.titleStringFormatNameOrPattern = titleStringFormatNameOrPattern;
-    }
-
-    // -- PARSER
-
-    @Override
-    public String parseableTextRepresentation(final Context context, final LocalDate value) {
-        return toEncodedString(value);
-    }
-
-    @Override
-    public LocalDate parseTextRepresentation(
-            final ValueSemanticsProvider.Context context,
-            final String entry) {
-
-        updateTitleStringFormatterIfOverridden();
-
-        //LocalDate contextDate = (LocalDate) context;
-
-        final String dateString = entry.trim().toUpperCase();
-//        if (dateString.startsWith("+") && contextDate != null) {
-//            return JodaLocalDateUtil.relativeDate(contextDate, dateString, true);
-//        } else if (dateString.startsWith("-")  && contextDate != null) {
-//            return JodaLocalDateUtil.relativeDate(contextDate, dateString, false);
-//        } else {
-            return parseDate(dateString);
-//        }
-    }
-
-    private void updateTitleStringFormatterIfOverridden() {
-        final String overridePattern = OVERRIDE_TITLE_PATTERN.get();
-        if (overridePattern == null ||
-                titleStringFormatNameOrPattern.equals(overridePattern)) {
-            return;
-        }
-
-        // (re)create format
-        updateTitleStringFormatter(overridePattern);
-    }
-
-    private LocalDate parseDate(final String dateStr) {
-        return _JodaLocalDateUtil.parseDate(dateStr, PARSE_FORMATTERS);
-    }
-
-
-    // ///////////////////////////////////////////////////////////////////////////
-    // TitleProvider
-    // ///////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public String simpleTextPresentation(final Context context, final LocalDate value) {
-        if (value == null) {
-            return null;
-        }
-        final LocalDate date = value;
-        DateTimeFormatter f = titleStringFormatter.withLocale(Locale.getDefault());
-        return _JodaLocalDateUtil.titleString(f, date);
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    // EncoderDecoder
-    // //////////////////////////////////////////////////////////////////
-
-    @Override
-    public String toEncodedString(final LocalDate date) {
-        return encode(date);
-    }
-
-    private synchronized String encode(final LocalDate date) {
-        return encodingFormatter.print(date);
-    }
-
-    @Override
-    public LocalDate fromEncodedString(final String data) {
-        try {
-            return parse(data);
-        } catch (final IllegalArgumentException e) {
-            throw new EncodingException(e);
-        }
-    }
-
-    private synchronized LocalDate parse(final String data) {
-        return encodingFormatter.parseLocalDate(data);
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaFunctions.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaFunctions.java
deleted file mode 100644
index f14bfc6..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaFunctions.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.util.Locale;
-import java.util.function.Function;
-
-import org.joda.time.format.DateTimeFormatter;
-
-final class _JodaFunctions  {
-
-    private _JodaFunctions(){}
-
-    public static Function<DateTimeFormatter, DateTimeFormatter> withLocale(final Locale locale) {
-        return new Function<DateTimeFormatter, DateTimeFormatter>() {
-            @Override
-            public DateTimeFormatter apply(final DateTimeFormatter input) {
-                if (locale == null) {
-                    return input;
-                }
-                return input.withLocale(locale);
-            }
-        };
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateTimeUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateTimeUtil.java
deleted file mode 100644
index 194db73..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateTimeUtil.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-import org.joda.time.LocalDateTime;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.commons.internal.collections._Lists;
-
-final class _JodaLocalDateTimeUtil  {
-
-    static String titleString(final DateTimeFormatter formatter, final LocalDateTime date) {
-        return date == null ? "" : formatter.print(date);
-    }
-
-    static LocalDateTime parseDate(
-            final String dateStr,
-            final List<DateTimeFormatter> parseFormatters) {
-        final Locale locale = Locale.getDefault();
-
-        Iterable<DateTimeFormatter> elements = _Lists.map(parseFormatters, _JodaFunctions.withLocale(locale));
-        return parseDateTime(dateStr, elements);
-    }
-
-    static LocalDateTime relativeDateTime(final LocalDateTime contextDate, final String str, final boolean add) {
-        LocalDateTime relativeDate = contextDate;
-        if (str.equals("")) {
-            return contextDate;
-        }
-
-        try {
-            final StringTokenizer st = new StringTokenizer(str.substring(1), " ");
-            while (st.hasMoreTokens()) {
-                final String token = st.nextToken();
-                relativeDate = adjustDateTime(relativeDate, token, add);
-            }
-            return relativeDate;
-        } catch (final Exception e) {
-            return contextDate;
-        }
-    }
-
-    // -- HELPER
-
-    private static LocalDateTime parseDateTime(final String dateStr, final Iterable<DateTimeFormatter> formatters) {
-        for(DateTimeFormatter formatter: formatters) {
-            try {
-                return formatter.parseLocalDateTime(dateStr);
-            } catch (final IllegalArgumentException e) {
-                // continue to next
-            }
-        }
-        throw new TextEntryParseException("Not recognised as a date: " + dateStr);
-    }
-
-    private static LocalDateTime adjustDateTime(final LocalDateTime contextDateTime, String str, final boolean add) {
-        int hours = 0;
-        int minutes = 0;
-        int days = 0;
-        int months = 0;
-        int years = 0;
-
-        if (str.endsWith("H")) {
-            str = str.substring(0, str.length() - 1);
-            hours = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("M")) {
-            str = str.substring(0, str.length() - 1);
-            minutes = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("w")) {
-            str = str.substring(0, str.length() - 1);
-            days = 7 * Integer.valueOf(str).intValue();
-        } else if (str.endsWith("y")) {
-            str = str.substring(0, str.length() - 1);
-            years = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("m")) {
-            str = str.substring(0, str.length() - 1);
-            months = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("d")) {
-            str = str.substring(0, str.length() - 1);
-            days = Integer.valueOf(str).intValue();
-        } else {
-            days = Integer.valueOf(str).intValue();
-        }
-
-        if (add) {
-            return add(contextDateTime, years, months, days, hours, minutes);
-        } else {
-            return add(contextDateTime, -years, -months, -days, -hours, -minutes);
-        }
-    }
-
-    private static LocalDateTime add(final LocalDateTime original, final int years, final int months, final int days, final int hours, final int minutes) {
-        return original.plusYears(years).plusMonths(months).plusDays(days).plusHours(hours).plusMinutes(minutes);
-    }
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateUtil.java
deleted file mode 100644
index 94b8825..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/_JodaLocalDateUtil.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  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.core.metamodel.valuesemantics.temporal.legacy.joda;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-import org.joda.time.LocalDate;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.commons.internal.collections._Lists;
-
-final class _JodaLocalDateUtil  {
-
-    private _JodaLocalDateUtil(){}
-
-    static LocalDate parseDate(
-            final String dateStr,
-            final List<DateTimeFormatter> parseFormatters) {
-        final Locale locale = Locale.getDefault();
-
-        Iterable<DateTimeFormatter> elements = _Lists.map(parseFormatters, _JodaFunctions.withLocale(locale));
-        LocalDate parsedDate = parseDate(dateStr, elements);
-        return parsedDate;
-    }
-
-
-    private static LocalDate parseDate(final String dateStr, final Iterable<DateTimeFormatter> formatters) {
-        for(DateTimeFormatter formatter: formatters) {
-            try {
-                return formatter.parseLocalDate(dateStr);
-            } catch (final IllegalArgumentException e) {
-                // continue to next
-            }
-        }
-        throw new TextEntryParseException("Not recognised as a date: " + dateStr);
-    }
-
-    // //////////////////////////////////////
-
-    static LocalDate relativeDate(final LocalDate contextDate, final String str, final boolean add) {
-        LocalDate relativeDate = contextDate;
-        if (str.equals("")) {
-            return contextDate;
-        }
-
-        try {
-            final StringTokenizer st = new StringTokenizer(str.substring(1), " ");
-            while (st.hasMoreTokens()) {
-                final String token = st.nextToken();
-                relativeDate = adjustDate(relativeDate, token, add);
-            }
-            return relativeDate;
-        } catch (final Exception e) {
-            return contextDate;
-        }
-    }
-
-    private static LocalDate adjustDate(final LocalDate contextDate, String str, final boolean add) {
-        int hours = 0;
-        int minutes = 0;
-        int days = 0;
-        int months = 0;
-        int years = 0;
-
-        if (str.endsWith("H")) {
-            str = str.substring(0, str.length() - 1);
-            hours = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("M")) {
-            str = str.substring(0, str.length() - 1);
-            minutes = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("w")) {
-            str = str.substring(0, str.length() - 1);
-            days = 7 * Integer.valueOf(str).intValue();
-        } else if (str.endsWith("y")) {
-            str = str.substring(0, str.length() - 1);
-            years = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("m")) {
-            str = str.substring(0, str.length() - 1);
-            months = Integer.valueOf(str).intValue();
-        } else if (str.endsWith("d")) {
-            str = str.substring(0, str.length() - 1);
-            days = Integer.valueOf(str).intValue();
-        } else {
-            days = Integer.valueOf(str).intValue();
-        }
-
-        if (add) {
-            return add(contextDate, years, months, days, hours, minutes);
-        } else {
-            return add(contextDate, -years, -months, -days, -hours, -minutes);
-        }
-    }
-
-    private static LocalDate add(final LocalDate original, final int years, final int months, final int days, final int hours, final int minutes) {
-        if(hours != 0 || minutes != 0) {
-            throw new IllegalArgumentException("cannot add non-zero hours or minutes to a LocalDate");
-        }
-        return original.plusYears(years).plusMonths(months).plusDays(days);
-    }
-
-
-    // //////////////////////////////////////
-
-    public static String titleString(final DateTimeFormatter formatter, final LocalDate date) {
-        return date == null ? "" : formatter.print(date);
-    }
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java
new file mode 100644
index 0000000..a0ccf37
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java
@@ -0,0 +1,110 @@
+/*
+ *  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.core.metamodel.valuetypes;
+
+import org.apache.isis.applib.adapters.EncoderDecoder;
+import org.apache.isis.applib.adapters.Parser;
+import org.apache.isis.applib.adapters.Renderer;
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.applib.adapters.ValueSemanticsProvider;
+
+import lombok.val;
+
+public abstract class ValueSemanticsAdapter<T, D>
+extends ValueSemanticsAbstract<T>
+implements
+    EncoderDecoder<T>,
+    Parser<T>,
+    Renderer<T> {
+
+    public abstract ValueSemanticsAbstract<D> getDelegate();
+
+    public abstract T fromDelegateValue(D value);
+    public abstract D toDelegateValue(T value);
+
+    // -- ENCODER DECODER
+
+    @Override
+    public String toEncodedString(final T object) {
+        val delegateValue = toDelegateValue(object);
+        return delegateEncoderDecoder().toEncodedString(delegateValue);
+    }
+
+    @Override
+    public T fromEncodedString(final String data) {
+        val delegateValue = delegateEncoderDecoder().fromEncodedString(data);
+        return fromDelegateValue(delegateValue);
+    }
+
+    // -- RENDERER
+
+    @Override
+    public String simpleTextPresentation(final ValueSemanticsProvider.Context context, final T value) {
+        val delegateValue = value!=null
+                ? toDelegateValue(value)
+                : null;
+        return delegateRenderer().simpleTextPresentation(context, delegateValue);
+    }
+
+    // -- PARSER
+
+    @Override
+    public String parseableTextRepresentation(final ValueSemanticsProvider.Context context, final T value) {
+        val delegateValue = value!=null
+                ? toDelegateValue(value)
+                : null;
+        return delegateParser().parseableTextRepresentation(context, delegateValue);
+    }
+
+    @Override
+    public T parseTextRepresentation(final ValueSemanticsProvider.Context context, final String text) {
+        val delegateValue = delegateParser().parseTextRepresentation(context, text);
+        return delegateValue!=null
+                ? fromDelegateValue(delegateValue)
+                : null;
+    }
+
+    @Override
+    public int typicalLength() {
+        return delegateParser().typicalLength();
+    }
+
+    @Override
+    public int maxLength() {
+        return delegateParser().maxLength();
+    }
+
+    // -- HELPER
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private Parser<D> delegateParser() {
+        return ((Parser)getDelegate());
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private Renderer<D> delegateRenderer() {
+        return ((Renderer)getDelegate());
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private EncoderDecoder<D> delegateEncoderDecoder() {
+        return ((EncoderDecoder)getDelegate());
+    }
+
+}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAsActionTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAsActionTest.java
index 1e7ac82..209634b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAsActionTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAsActionTest.java
@@ -36,7 +36,6 @@ import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@SuppressWarnings("unused")
 class MixinIntendedAsActionTest extends MixinIntendedAs {
 
     @BeforeEach
@@ -52,69 +51,69 @@ class MixinIntendedAsActionTest extends MixinIntendedAs {
     // the non holder
     @DomainObject
     static class NoCustomer {
-        
+
     }
-    
+
     // the (shared) holder
     @DomainObject @Data
     static class Customer {
         String name;
     }
-    
+
     // ------------------------------
     // -- classic mix-in declaration
     // ------------------------------
-    
-    @Action @RequiredArgsConstructor 
+
+    @Action @RequiredArgsConstructor
     static class Customer_mixin {
-        
+
         private final Customer holder;
-        
-        public void act(String newName) { holder.setName(newName); }
+
+        public void act(final String newName) { holder.setName(newName); }
     }
-    
+
     @Test
     void classicMixin_shouldHaveProperFacet() {
 
         val mixinFacet = super.runTypeContextOn(Customer_mixin.class)
                 .getFacet(MixinFacet.class);
-        
+
         // proper predicates
         assertNotNull(mixinFacet);
         assertTrue(mixinFacet.isMixinFor(Customer.class));
         assertFalse(mixinFacet.isMixinFor(NoCustomer.class));
-        
+
         // proper instantiation
         val holderPojo = new Customer();
         val mixinPojo = mixinFacet.instantiate(holderPojo);
         ((Customer_mixin)mixinPojo).act("hello");
         assertEquals("hello", holderPojo.getName());
-        
+
     }
-    
+
     // ------------------------------------------
     // -- advanced mix-in declaration ... @Action
     // ------------------------------------------
-    
-    @Action @RequiredArgsConstructor 
+
+    @Action @RequiredArgsConstructor
     static class Customer_action {
-        
+
         private final Customer holder;
 
-        public void $$(String newName) { holder.setName(newName); }
+        public void $$(final String newName) { holder.setName(newName); }
     }
-    
+
     @Test
     void actionMixin_shouldHaveProperFacet() {
 
         val mixinFacet = super.runTypeContextOn(Customer_action.class)
                 .getFacet(MixinFacet.class);
-        
+
         // proper predicates
         assertNotNull(mixinFacet);
         assertTrue(mixinFacet.isMixinFor(Customer.class));
         assertFalse(mixinFacet.isMixinFor(NoCustomer.class));
-        
+
         // proper instantiation
         val holderPojo = new Customer();
         val mixinPojo = mixinFacet.instantiate(holderPojo);
@@ -125,46 +124,46 @@ class MixinIntendedAsActionTest extends MixinIntendedAs {
     // ------------------------------------------
     // -- advanced mix-in declaration ... @Property
     // ------------------------------------------
-    
-    @Property @RequiredArgsConstructor 
+
+    @Property @RequiredArgsConstructor
     static class Customer_property {
-        
+
         private final Customer holder;
 
-        public void $$(String newName) { holder.setName(newName); }
+        public void $$(final String newName) { holder.setName(newName); }
     }
-    
+
     @Test
     void propertyMixin_shouldHaveProperFacet() {
 
         val mixinFacet = super.runTypeContextOn(Customer_property.class)
                 .getFacet(MixinFacet.class);
-        
+
         // proper predicates
         assertNotNull(mixinFacet);
         assertTrue(mixinFacet.isMixinFor(Customer.class));
         assertFalse(mixinFacet.isMixinFor(NoCustomer.class));
 
     }
-    
+
     // ------------------------------------------
     // -- advanced mix-in declaration ... @Property
     // ------------------------------------------
-    
-    @Collection @RequiredArgsConstructor 
+
+    @Collection @RequiredArgsConstructor
     static class Customer_collection {
-        
+
         private final Customer holder;
 
-        public void $$(String newName) { holder.setName(newName); }
+        public void $$(final String newName) { holder.setName(newName); }
     }
-    
+
     @Test
     void collectionMixin_shouldHaveProperFacet() {
 
         val mixinFacet = super.runTypeContextOn(Customer_collection.class)
                 .getFacet(MixinFacet.class);
-        
+
         // proper predicates
         assertNotNull(mixinFacet);
         assertTrue(mixinFacet.isMixinFor(Customer.class));
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlDateValueSemanticsProviderTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlDateValueSemanticsProviderTest.java
index 4273e8a..bbebd02 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlDateValueSemanticsProviderTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlDateValueSemanticsProviderTest.java
@@ -21,17 +21,20 @@ package org.apache.isis.core.metamodel.facets.value;
 import java.sql.Date;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.TimeZone;
+import java.time.LocalDate;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlDateValueSemantics;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlDateValueSemantics;
+import lombok.val;
 
 public class JavaSqlDateValueSemanticsProviderTest extends ValueSemanticsProviderAbstractTestCase {
 
@@ -43,7 +46,16 @@ public class JavaSqlDateValueSemanticsProviderTest extends ValueSemanticsProvide
 
         date = new Date(0);
 
-        setSemantics(value = new JavaSqlDateValueSemantics(metaModelContext.getConfiguration()) {
+        ValueSemanticsAbstract<LocalDate> delegate =
+                new LocalDateValueSemantics();
+
+        setSemantics(value = new JavaSqlDateValueSemantics() {
+
+            @Override
+            public ValueSemanticsAbstract<LocalDate> getDelegate() {
+                return delegate;
+            }
+
         });
     }
 
@@ -63,14 +75,8 @@ public class JavaSqlDateValueSemanticsProviderTest extends ValueSemanticsProvide
 
     @Test
     public void testParse() throws Exception {
-        final Object newValue = value.parseTextRepresentation(null, "1/1/1980");
-
-        final Calendar calendar = Calendar.getInstance();
-        calendar.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
-        calendar.set(1980, 0, 1, 0, 0, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-
-        assertEquals(calendar.getTime(), newValue);
+        val parsedDate = value.parseTextRepresentation(null, "1980-01-01");
+        assertEquals("1980-01-01", parsedDate.toString());
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlTimeValueSemanticsProviderTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlTimeValueSemanticsProviderTest.java
index e86b68e..040ad10 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlTimeValueSemanticsProviderTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaSqlTimeValueSemanticsProviderTest.java
@@ -19,6 +19,7 @@
 package org.apache.isis.core.metamodel.facets.value;
 
 import java.sql.Time;
+import java.time.LocalTime;
 import java.util.Calendar;
 import java.util.TimeZone;
 
@@ -26,15 +27,17 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalTimeValueSemantics;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlTimeValueSemantics;
 
+import static org.junit.Assert.assertEquals;
+
 public class JavaSqlTimeValueSemanticsProviderTest
 extends ValueSemanticsProviderAbstractTestCase {
 
     private Time twoOClock;
-    private JavaSqlTimeValueSemantics value;
+    private JavaSqlTimeValueSemantics valueSemantics;
 
     @Before
     public void setUpObjects() throws Exception {
@@ -54,27 +57,36 @@ extends ValueSemanticsProviderAbstractTestCase {
 
         twoOClock = new Time(c.getTimeInMillis());
 
-        setSemantics(value = new JavaSqlTimeValueSemantics(metaModelContext.getConfiguration()));
+        ValueSemanticsAbstract<LocalTime> delegate =
+                new LocalTimeValueSemantics();
+
+        setSemantics(valueSemantics = new JavaSqlTimeValueSemantics() {
+            @Override
+            public ValueSemanticsAbstract<LocalTime> getDelegate() {
+                return delegate;
+            }
+        });
+
     }
 
     @Ignore // flaky
     @Test
     public void testNewTime() {
-        final String asEncodedString = value.toEncodedString(twoOClock);
+        final String asEncodedString = valueSemantics.toEncodedString(twoOClock);
         assertEquals("140000000", asEncodedString);
     }
 
-    @Ignore // flaky
-    @Test
-    public void testAdd() {
-        final Object newValue = value.add(twoOClock, 0, 0, 0, 1, 15);
-        assertEquals("15:15:00", newValue.toString());
-    }
-
-    @Ignore // flaky
-    @Test
-    public void testAdd2() {
-        final Object newValue = value.add(twoOClock, 0, 0, 0, 0, 0);
-        assertEquals("14:00:00", newValue.toString());
-    }
+//    @Ignore // flaky
+//    @Test
+//    public void testAdd() {
+//        final Object newValue = value.add(twoOClock, 0, 0, 0, 1, 15);
+//        assertEquals("15:15:00", newValue.toString());
+//    }
+//
+//    @Ignore // flaky
+//    @Test
+//    public void testAdd2() {
+//        final Object newValue = value.add(twoOClock, 0, 0, 0, 0, 0);
+//        assertEquals("14:00:00", newValue.toString());
+//    }
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaUtilDateValueSemanticsProviderTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaUtilDateValueSemanticsProviderTest.java
index e6a47ea..d8d2adc 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaUtilDateValueSemanticsProviderTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaUtilDateValueSemanticsProviderTest.java
@@ -18,42 +18,49 @@
  */
 package org.apache.isis.core.metamodel.facets.value;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
+import java.time.LocalDateTime;
 import java.util.Locale;
-import java.util.TimeZone;
 
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.applib.adapters.ValueSemanticsProvider.Context;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.services.iactnlayer.InteractionContext;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaUtilDateValueSemantics;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
 import lombok.val;
 
-public class JavaUtilDateValueSemanticsProviderTest
+class JavaUtilDateValueSemanticsProviderTest
 extends ValueSemanticsProviderAbstractTestCase {
 
-    private java.util.Date date;
-    private JavaUtilDateValueSemantics value;
+    @SuppressWarnings("deprecation")
+    private final java.util.Date date = new java.util.Date(2013-1900, 03-1, 13, 17, 59);
+    private JavaUtilDateValueSemantics valueSemantics;
 
-    @Before
+    @BeforeEach
     public void setUpObjects() throws Exception {
 
-        date = new java.util.Date(0);
+        ValueSemanticsAbstract<LocalDateTime> delegate =
+                new LocalDateTimeValueSemantics();
 
-        setSemantics(value = new JavaUtilDateValueSemantics(metaModelContext.getConfiguration()) {
+        setSemantics(valueSemantics = new JavaUtilDateValueSemantics() {
+            @Override
+            public ValueSemanticsAbstract<LocalDateTime> getDelegate() {
+                return delegate;
+            }
         });
     }
 
     @Test
     public void testInvalidParse() throws Exception {
         try {
-            value.parseTextRepresentation(null, "invalid entry");
+            valueSemantics.parseTextRepresentation(null, "invalid entry");
             fail();
         } catch (final TextEntryParseException expected) {
         }
@@ -65,33 +72,16 @@ extends ValueSemanticsProviderAbstractTestCase {
      * don't know where that dependency is coming from.
      */
     @Test
-    public void testTitleOf() {
-        final String EXPECTED = DateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM, SimpleDateFormat.SHORT).format(new java.util.Date(0));
-        assertEquals(EXPECTED, value.simpleTextPresentation(null, date));
+    public void testRendering() {
+        val _context = Context.of(null, InteractionContext.builder().locale(Locale.ENGLISH).build());
+        assertEquals("Mar 13, 2013, 5:59:00 PM", valueSemantics.simpleTextPresentation(_context , date));
     }
 
     @Test
     public void testParse() throws Exception {
-
-        // prepare environment
-        val defaultLocale = Locale.getDefault();
-        val defaultTimezone = TimeZone.getDefault();
-        Locale.setDefault(Locale.UK);
-        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
-
-        val parsedDate = value.parseTextRepresentation(null, "1980-01-01 10:40");
-
-        // restore environment
-        Locale.setDefault(defaultLocale);
-        TimeZone.setDefault(defaultTimezone);
-
-
-        final Calendar calendar = Calendar.getInstance();
-        calendar.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
-        calendar.set(1980, 0, 1, 10, 40, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-
-        assertEquals(calendar.getTime(), parsedDate);
+        val _context = Context.of(null, InteractionContext.builder().locale(Locale.ENGLISH).build());
+        val parsedDate = valueSemantics.parseTextRepresentation(_context, "2013-03-13 17:59:00");
+        assertEquals(date.getTime(), parsedDate.getTime());
     }
 
 }
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/temporal/TemporalFieldFactory.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/temporal/TemporalFieldFactory.java
index ebfcfe3..e0617c9 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/temporal/TemporalFieldFactory.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/temporal/TemporalFieldFactory.java
@@ -22,11 +22,11 @@ import java.time.LocalDate;
 
 import javax.inject.Inject;
 
+import org.apache.isis.applib.adapters.TemporalValueSemantics;
+import org.apache.isis.applib.adapters.TemporalValueSemantics.OffsetCharacteristic;
+import org.apache.isis.applib.adapters.TemporalValueSemantics.TemporalCharacteristic;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics.OffsetCharacteristic;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics.TemporalCharacteristic;
 import org.apache.isis.incubator.viewer.javafx.model.binding.BindingsFx;
 import org.apache.isis.incubator.viewer.javafx.model.util._fx;
 import org.apache.isis.incubator.viewer.javafx.ui.components.UiComponentHandlerFx;
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/TemporalFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/TemporalFieldFactory.java
index 2ad92e7..868b909 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/TemporalFieldFactory.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/TemporalFieldFactory.java
@@ -25,12 +25,12 @@ import com.vaadin.flow.component.Component;
 import com.vaadin.flow.data.converter.DateToSqlDateConverter;
 import com.vaadin.flow.data.converter.LocalDateToDateConverter;
 
+import org.apache.isis.applib.adapters.TemporalValueSemantics;
+import org.apache.isis.applib.adapters.TemporalValueSemantics.OffsetCharacteristic;
+import org.apache.isis.applib.adapters.TemporalValueSemantics.TemporalCharacteristic;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics.OffsetCharacteristic;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.TemporalValueSemantics.TemporalCharacteristic;
 import org.apache.isis.incubator.viewer.vaadin.ui.binding.BindingsVaa;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentHandlerVaa;
 import org.apache.isis.viewer.common.model.components.UiComponentFactory.ComponentRequest;
diff --git a/valuetypes/jodatime/pom.xml b/valuetypes/jodatime/integration/pom.xml
similarity index 56%
copy from valuetypes/jodatime/pom.xml
copy to valuetypes/jodatime/integration/pom.xml
index f90a2f1..6b153ca 100644
--- a/valuetypes/jodatime/pom.xml
+++ b/valuetypes/jodatime/integration/pom.xml
@@ -16,18 +16,35 @@
 
 	<parent>
 		<groupId>org.apache.isis.valuetypes</groupId>
-		<artifactId>isis-valuetypes</artifactId>
+		<artifactId>isis-valuetypes-jodatime</artifactId>
 		<version>2.0.0-SNAPSHOT</version>
 	</parent>
 
-	<artifactId>isis-valuetypes-jodatime</artifactId>
-	<name>Apache Isis Val - Joda Time (parent)</name>
-	<description>Joda Time Library</description>
+	<artifactId>isis-valuetypes-jodatime-integration</artifactId>
+	<name>Apache Isis Val - Joda Time (integration)</name>
 
-	<packaging>pom</packaging>
+	<properties>
+		<jar-plugin.automaticModuleName>org.apache.isis.valuetypes.jodatime.integration</jar-plugin.automaticModuleName>
+		<git-plugin.propertiesDir>org/apache/isis/valuetypes/jodatime/integration</git-plugin.propertiesDir>
+	</properties>
 
-	<modules>
-		<module>applib</module>
-	</modules>
+	<dependencies>
+
+		<dependency>
+			<groupId>org.apache.isis.valuetypes</groupId>
+			<artifactId>isis-valuetypes-jodatime-applib</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.isis.core</groupId>
+			<artifactId>isis-core-metamodel</artifactId>
+		</dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-internaltestsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+		
+	</dependencies>
 
 </project>
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/IsisModuleValJodatimeIntegration.java
similarity index 58%
copy from viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java
copy to valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/IsisModuleValJodatimeIntegration.java
index dea0841..4b316ea 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/IsisModuleValJodatimeIntegration.java
@@ -16,28 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.viewer.wicket.ui;
+package org.apache.isis.valuetypes.jodatime.integration;
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
-import org.apache.isis.viewer.common.model.IsisModuleViewerCommon;
-import org.apache.isis.viewer.wicket.model.IsisModuleViewerWicketModel;
-import org.apache.isis.viewer.wicket.ui.app.logout.LogoutHandlerWkt;
-import org.apache.isis.viewer.wicket.ui.components.widgets.themepicker.IsisWicketThemeSupportDefault;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaDateTimeValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalDateTimeValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalDateValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalTimeValueSemantics;
 
 /**
- * @since 1.x {@index}
+ * @since 2.0 {@index}
  */
 @Configuration
 @Import({
-        // modules
-        IsisModuleViewerCommon.class,
-        IsisModuleViewerWicketModel.class,
-
-        // @Service's
-        IsisWicketThemeSupportDefault.class,
-        LogoutHandlerWkt.class,
+    JodaLocalTimeValueSemantics.class,
+    JodaLocalDateTimeValueSemantics.class,
+    JodaLocalDateValueSemantics.class,
+    JodaDateTimeValueSemantics.class,
 })
-public class IsisModuleViewerWicketUi {
+public class IsisModuleValJodatimeIntegration {
 }
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java
new file mode 100644
index 0000000..afafc0f
--- /dev/null
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java
@@ -0,0 +1,67 @@
+/*
+ *  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.valuetypes.jodatime.integration.valuesemantics;
+
+import java.time.ZonedDateTime;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.joda.time.DateTime;
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.ZonedDateTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.schema.common.v2.ValueType;
+import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
+
+@Component
+@Named("isis.val.JodaDateTimeValueSemantics")
+public class JodaDateTimeValueSemantics
+extends ValueSemanticsAdapter<org.joda.time.DateTime, ZonedDateTime>  {
+
+    @Inject ZonedDateTimeValueSemantics zonedDateTimeValueSemantics;
+
+    @Override
+    public Class<DateTime> getCorrespondingClass() {
+        return org.joda.time.DateTime.class;
+    }
+
+    @Override
+    public ValueType getSchemaValueType() {
+        return ValueType.JODA_DATE_TIME;
+    }
+
+    @Override
+    public ValueSemanticsAbstract<ZonedDateTime> getDelegate() {
+        return zonedDateTimeValueSemantics;
+    }
+
+    @Override
+    public DateTime fromDelegateValue(final ZonedDateTime delegateValue) {
+        return JodatimeConverters.toJoda(delegateValue);
+    }
+
+    @Override
+    public ZonedDateTime toDelegateValue(final DateTime value) {
+        return JodatimeConverters.fromJoda(value);
+    }
+
+}
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java
new file mode 100644
index 0000000..ade5f72
--- /dev/null
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java
@@ -0,0 +1,65 @@
+/*
+ *  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.valuetypes.jodatime.integration.valuesemantics;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.schema.common.v2.ValueType;
+import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
+
+@Component
+@Named("isis.val.JodaLocalDateTimeValueSemantics")
+public class JodaLocalDateTimeValueSemantics
+extends ValueSemanticsAdapter<org.joda.time.LocalDateTime, java.time.LocalDateTime>  {
+
+    @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
+
+    @Override
+    public Class<org.joda.time.LocalDateTime> getCorrespondingClass() {
+        return org.joda.time.LocalDateTime.class;
+    }
+
+    @Override
+    public ValueType getSchemaValueType() {
+        return ValueType.JODA_LOCAL_DATE_TIME;
+    }
+
+    @Override
+    public ValueSemanticsAbstract<java.time.LocalDateTime> getDelegate() {
+        return localDateTimeValueSemantics;
+    }
+
+    @Override
+    public org.joda.time.LocalDateTime fromDelegateValue(final java.time.LocalDateTime delegateValue) {
+        return JodatimeConverters.toJoda(delegateValue);
+    }
+
+    @Override
+    public java.time.LocalDateTime toDelegateValue(final org.joda.time.LocalDateTime value) {
+        return JodatimeConverters.fromJoda(value);
+    }
+
+}
+
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java
new file mode 100644
index 0000000..e172e86
--- /dev/null
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java
@@ -0,0 +1,65 @@
+/*
+ *  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.valuetypes.jodatime.integration.valuesemantics;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.schema.common.v2.ValueType;
+import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
+
+@Component
+@Named("isis.val.JodaLocalDateValueSemantics")
+public class JodaLocalDateValueSemantics
+extends ValueSemanticsAdapter<org.joda.time.LocalDate, java.time.LocalDate>  {
+
+    @Inject LocalDateValueSemantics localDateValueSemantics;
+
+    @Override
+    public Class<org.joda.time.LocalDate> getCorrespondingClass() {
+        return org.joda.time.LocalDate.class;
+    }
+
+    @Override
+    public ValueType getSchemaValueType() {
+        return ValueType.JODA_LOCAL_DATE;
+    }
+
+    @Override
+    public ValueSemanticsAbstract<java.time.LocalDate> getDelegate() {
+        return localDateValueSemantics;
+    }
+
+    @Override
+    public org.joda.time.LocalDate fromDelegateValue(final java.time.LocalDate delegateValue) {
+        return JodatimeConverters.toJoda(delegateValue);
+    }
+
+    @Override
+    public java.time.LocalDate toDelegateValue(final org.joda.time.LocalDate value) {
+        return JodatimeConverters.fromJoda(value);
+    }
+
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
similarity index 86%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalTimeValueSemantics.java
rename to valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
index 5954a84..5f0e6e3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/joda/JodaLocalTimeValueSemantics.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda;
+package org.apache.isis.valuetypes.jodatime.integration.valuesemantics;
 
 import javax.inject.Named;
 
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Component;
 import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
 import org.apache.isis.schema.common.v2.ValueType;
 
+//FIXME[ISIS-2882] convert to ValueSemanticsAdapter once java.time.LocalTime has a ValueSemantics
 @Component
 @Named("isis.val.JodaLocalTimeValueSemantics")
 public class JodaLocalTimeValueSemantics
@@ -38,7 +39,7 @@ extends ValueSemanticsAbstract<org.joda.time.LocalTime> {
 
     @Override
     public ValueType getSchemaValueType() {
-        return UNREPRESENTED;
+        return ValueType.JODA_LOCAL_TIME;
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/datetimejodalocal/JodaLocalDateTimeValueSemanticsProviderTest.java b/valuetypes/jodatime/integration/src/test/java/org/apache/isis/valuetypes/jodatime/integration/JodaLocalDateTimeValueSemanticsProviderTest.java
similarity index 62%
rename from core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/datetimejodalocal/JodaLocalDateTimeValueSemanticsProviderTest.java
rename to valuetypes/jodatime/integration/src/test/java/org/apache/isis/valuetypes/jodatime/integration/JodaLocalDateTimeValueSemanticsProviderTest.java
index 54bc474..06fe998 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/datetimejodalocal/JodaLocalDateTimeValueSemanticsProviderTest.java
+++ b/valuetypes/jodatime/integration/src/test/java/org/apache/isis/valuetypes/jodatime/integration/JodaLocalDateTimeValueSemanticsProviderTest.java
@@ -16,34 +16,37 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.facets.value.datetimejodalocal;
+package org.apache.isis.valuetypes.jodatime.integration;
 
 import org.joda.time.LocalDateTime;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalDateTimeValueSemantics;
+
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel._testing.MetaModelContext_forTesting;
-import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.joda.JodaLocalDateTimeValueSemantics;
+import lombok.val;
 
 public class JodaLocalDateTimeValueSemanticsProviderTest {
 
-    private JodaLocalDateTimeValueSemantics provider;
-    private MetaModelContext_forTesting metaModelContext;
+    private JodaLocalDateTimeValueSemantics valueSemantics;
 
     @BeforeEach
     public void setUp() throws Exception {
 
-        metaModelContext = MetaModelContext_forTesting.builder()
-                .build();
-
-        metaModelContext.getConfiguration();
-
-        provider = new JodaLocalDateTimeValueSemantics(metaModelContext.getConfiguration());
+        val delegate = new LocalDateTimeValueSemantics();
 
+        valueSemantics = new JodaLocalDateTimeValueSemantics() {
+            @Override
+            public ValueSemanticsAbstract<java.time.LocalDateTime> getDelegate() {
+                return delegate;
+            }
+        };
     }
 
     @Test
@@ -51,8 +54,8 @@ public class JodaLocalDateTimeValueSemanticsProviderTest {
 
         final LocalDateTime t0 = LocalDateTime.now();
 
-        final String encoded = provider.toEncodedString(t0);
-        final LocalDateTime t1 = provider.fromEncodedString(encoded);
+        final String encoded = valueSemantics.toEncodedString(t0);
+        final LocalDateTime t1 = valueSemantics.fromEncodedString(encoded);
 
         assertThat(t0, is(equalTo(t1)));
     }
diff --git a/valuetypes/jodatime/pom.xml b/valuetypes/jodatime/pom.xml
index f90a2f1..ccd8305 100644
--- a/valuetypes/jodatime/pom.xml
+++ b/valuetypes/jodatime/pom.xml
@@ -28,6 +28,7 @@
 
 	<modules>
 		<module>applib</module>
+		<module>integration</module>
 	</modules>
 
 </project>
diff --git a/valuetypes/pom.xml b/valuetypes/pom.xml
index dc2664b..98ce3af 100644
--- a/valuetypes/pom.xml
+++ b/valuetypes/pom.xml
@@ -66,7 +66,12 @@
 				<artifactId>isis-valuetypes-jodatime-applib</artifactId>
 				<version>2.0.0-SNAPSHOT</version>
 			</dependency>
-
+			<dependency>
+				<groupId>org.apache.isis.valuetypes</groupId>
+				<artifactId>isis-valuetypes-jodatime-integration</artifactId>
+				<version>2.0.0-SNAPSHOT</version>
+			</dependency>
+			
 			<dependency>
 				<groupId>org.apache.isis.valuetypes</groupId>
 				<artifactId>isis-valuetypes-asciidoc-applib</artifactId>
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 7ebbfac..acdaa26 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
@@ -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(
@@ -122,6 +122,15 @@ implements
         throw _Exceptions.unmatchedCase(scalarRepresentation);
     }
 
+    public String getEditingPattern() {
+        val feature = feature();
+        val valueFacet = valueFacet();
+        val context = valueFacet
+                .createValueSemanticsContext(feature);
+        return valueFacet.selectParserForFeatureElseFallback(feature)
+                .getPattern(context);
+    }
+
     // -- HELPER
 
     @Synchronized
diff --git a/viewers/wicket/ui/pom.xml b/viewers/wicket/ui/pom.xml
index 0fd0cef..c4c0981 100644
--- a/viewers/wicket/ui/pom.xml
+++ b/viewers/wicket/ui/pom.xml
@@ -71,6 +71,12 @@
 			<groupId>org.apache.isis.viewer</groupId>
 			<artifactId>isis-viewer-wicket-model</artifactId>
 		</dependency>
+		
+		<dependency>
+			<groupId>org.apache.isis.valuetypes</groupId>
+			<artifactId>isis-valuetypes-jodatime-integration</artifactId>
+			<version>${project.version}</version>
+		</dependency>
 
 		<dependency>
 			<groupId>org.apache.wicket</groupId>
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java
index dea0841..aaee58a 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/IsisModuleViewerWicketUi.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.wicket.ui;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
+import org.apache.isis.valuetypes.jodatime.integration.IsisModuleValJodatimeIntegration;
 import org.apache.isis.viewer.common.model.IsisModuleViewerCommon;
 import org.apache.isis.viewer.wicket.model.IsisModuleViewerWicketModel;
 import org.apache.isis.viewer.wicket.ui.app.logout.LogoutHandlerWkt;
@@ -34,6 +35,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.themepicker.IsisWicke
         // modules
         IsisModuleViewerCommon.class,
         IsisModuleViewerWicketModel.class,
+        IsisModuleValJodatimeIntegration.class, //XXX should ultimately be removed
 
         // @Service's
         IsisWicketThemeSupportDefault.class,
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverter.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverter.java
deleted file mode 100644
index 8dba0e4..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars;
-
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.IConverter;
-
-public interface DateConverter<T> extends IConverter<T> {
-    Class<T> getConvertableClass();
-
-    /**
-     * The date pattern, without a time component.
-     *
-     * <p>
-     * For example, <tt>dd-MM-yyyy</tt> for <tt>13-05-2013</tt> for the 13 May 2013.
-     */
-    String getDatePattern(Locale locale);
-
-    /**
-     * The date pattern, with a time component.
-     *
-     * <p>
-     * For example, <tt>dd-MM-yyyy HH:mm</tt> for <tt>13-05-2013 09:15</tt> for the 13 May 2013 at 9:15am.
-     */
-    String getDateTimePattern(Locale locale);
-
-}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java
deleted file mode 100644
index 15f494d..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars;
-
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-
-
-public abstract class DateConverterAbstract<T> implements DateConverter<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    private final Class<T> cls;
-    protected final DateFormatSettings dateFormatSettings;
-
-    protected DateConverterAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
-        this.cls = cls;
-        this.dateFormatSettings = dateFormatSettings;
-    }
-
-    @Override
-    public Class<T> getConvertableClass() {
-        return cls;
-    }
-
-    @Override
-    public String getDatePattern(Locale locale) {
-        return dateFormatSettings.getDatePattern();
-    }
-
-    @Override
-    public String getDateTimePattern(Locale locale) {
-        return dateFormatSettings.getDateTimePattern();
-    }
-
-    protected DateTimeFormatter getFormatterForDatePattern() {
-        return DateTimeFormat.forPattern(dateFormatSettings.getDatePattern());
-    }
-
-    protected DateTimeFormatter getFormatterForDateTimePattern() {
-        return DateTimeFormat.forPattern(dateFormatSettings.getDateTimePattern());
-    }
-
-    @Override
-    public T convertToObject(String value, Locale locale) throws ConversionException {
-        return value != null? doConvertToObject(value, locale): null;
-    }
-    @Override
-    public String convertToString(T value, Locale locale) {
-        return value != null? doConvertToString(value, locale): null;
-    }
-
-    protected abstract T doConvertToObject(String value, Locale locale) throws ConversionException;
-
-
-    protected abstract String doConvertToString(T value, Locale locale);
-}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java
deleted file mode 100644
index 57744ca..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars;
-
-import java.io.Serializable;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateFormatSettings implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    private final String datePattern;
-    private final String dateTimePattern;
-    private final int adjustBy;
-
-    // -- FACTORIES
-
-    public static DateFormatSettings of(String datePattern, String dateTimePattern, int adjustBy) {
-        return new DateFormatSettings(datePattern, dateTimePattern, adjustBy);
-    }
-
-    public static DateFormatSettings of(String datePattern, String dateTimePattern) {
-        return of(datePattern, dateTimePattern, /*adjustBy*/ 0);
-    }
-
-    public static DateFormatSettings of(String datePattern) {
-        return of(datePattern, /*dateTimePattern same as*/ datePattern, /*adjustBy*/ 0);
-    }
-
-    public static DateFormatSettings ofDateAndTime(WicketViewerSettings settings, int adjustBy) {
-        return of(settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
-    }
-
-    public static DateFormatSettings ofDateOnly(WicketViewerSettings settings, int adjustBy) {
-        return of(settings.getDatePattern(), settings.getDatePattern(), adjustBy);
-    }
-
-    // -- IMPLEMENTATION
-
-    private DateFormatSettings(String datePattern, String dateTimePattern, int adjustBy) {
-        this.datePattern = datePattern;
-        this.dateTimePattern = dateTimePattern;
-        this.adjustBy = adjustBy;
-    }
-
-    public String getDatePattern() {
-        return datePattern;
-    }
-
-    public String getDateTimePattern() {
-        return dateTimePattern;
-    }
-
-    /**
-     * day offset
-     */
-    public int getAdjustBy() {
-        return adjustBy;
-    }
-
-    @Override
-    public String toString() {
-        return "DateFormatSettings [datePattern=" + datePattern + ", dateTimePattern=" + dateTimePattern + ", adjustBy="
-                + adjustBy + "]";
-    }
-
-
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPickerAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPickerAbstract.java
index 097d62e..655a532 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPickerAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPickerAbstract.java
@@ -20,49 +20,26 @@ package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.io.Serializable;
 
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Component;
-import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.util.convert.IConverter;
 
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
 import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacet;
-import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.datepicker.TextFieldWithDateTimePicker;
 
-import lombok.NonNull;
-
 /**
  * Panel for rendering scalars representing dates, along with a date picker.
  */
 public abstract class ScalarPanelTextFieldWithTemporalPickerAbstract<T extends Serializable>
-extends ScalarPanelTextFieldAbstract<T>  {
+extends ScalarPanelTextFieldWithValueSemanticsAbstract<T>  {
 
     private static final long serialVersionUID = 1L;
 
-    protected DateConverter<T> converter;
-
     public ScalarPanelTextFieldWithTemporalPickerAbstract(
             final String id, final ScalarModel scalarModel, final Class<T> cls) {
         super(id, scalarModel, cls);
     }
 
-    /**
-     * Expected to be in subclasses' constructor.
-     * <p>
-     * Is not passed into constructor only to allow subclass to read from injected
-     * {@link #getWicketViewerSettings()}.
-     */
-    protected void init(final DateConverter<T> converter) {
-        this.converter = converter;
-    }
-
     protected int getAdjustBy() {
         final RenderedAdjustedFacet facet = getModel().getFacet(RenderedAdjustedFacet.class);
         return facet != null? facet.value(): 0;
@@ -70,8 +47,8 @@ extends ScalarPanelTextFieldAbstract<T>  {
 
     @Override
     protected final TextField<T> createTextField(final String id) {
-        return new TextFieldWithDateTimePicker<>(
-                super.getCommonContext(), id, newTextFieldValueModel(), cls, converter);
+        return new TextFieldWithDateTimePicker<T>(
+                super.getCommonContext(), id, newTextFieldValueModel(), cls, getConverter(scalarModel));
     }
 
 
@@ -80,51 +57,35 @@ extends ScalarPanelTextFieldAbstract<T>  {
         return "date";
     }
 
-    @Override
-    protected Component createComponentForCompact() {
-        Fragment compactFragment = getCompactFragment(CompactType.SPAN);
-        final Label label = new Label(ID_SCALAR_IF_COMPACT, newTextFieldValueModel()) {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public <C> IConverter<C> getConverter(final Class<C> type) {
-                return _Casts.uncheckedCast(converter);
-            }
-        };
-        label.setEnabled(false);
-
-        // adding an amount because seemed to truncate in tables in certain circumstances
-        final int lengthAdjust =
-                getLengthAdjustHint() != null ? getLengthAdjustHint() : 1;
-
-        final String dateTimePattern = converter.getDateTimePattern(getLocale());
-        final int length = dateTimePattern.length() + lengthAdjust;
-        label.add(new AttributeModifier("size", Model.of("" + length)));
-
-        compactFragment.add(label);
-
-        return label;
-    }
+//    @Override
+//    protected Component createComponentForCompact() {
+//        Fragment compactFragment = getCompactFragment(CompactType.SPAN);
+//        final Label label = new Label(ID_SCALAR_IF_COMPACT, newTextFieldValueModel()) {
+//            private static final long serialVersionUID = 1L;
+//
+//            @Override
+//            public <C> IConverter<C> getConverter(final Class<C> type) {
+//                return _Casts.uncheckedCast(converter);
+//            }
+//        };
+//        label.setEnabled(false);
+//
+//        // adding an amount because seemed to truncate in tables in certain circumstances
+//        final int lengthAdjust = 1;
+//
+//        final String dateTimePattern = converter.getDateTimePattern(getLocale());
+//        final int length = dateTimePattern.length() + lengthAdjust;
+//        label.add(new AttributeModifier("size", Model.of("" + length)));
+//
+//        compactFragment.add(label);
+//
+//        return label;
+//    }
 
     @Override
     protected IModel<String> obtainInlinePromptModel() {
-        return super.toStringConvertingModelOf(converter);
+        return super.toStringConvertingModelOf(getConverter(scalarModel));
     }
 
-    /**
-     * Optional override for subclasses to explicitly indicate desired amount to adjust
-     * compact form of textField
-     */
-    protected Integer getLengthAdjustHint() {
-        return null;
-    }
-
-    //FIXME[ISIS-2882] wire up correctly
-    @Override
-    protected IConverter<T> getConverter(@NonNull final ObjectFeature propOrParam,
-            @NonNull final ScalarRepresentation scalarRepresentation) {
-        // TODO Auto-generated method stub
-        return null;
-    }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterPlugin.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TemporalConverter.java
similarity index 64%
rename from viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterPlugin.java
rename to viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TemporalConverter.java
index b39385e..5b6840c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterPlugin.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TemporalConverter.java
@@ -18,21 +18,15 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars;
 
-import org.springframework.stereotype.Component;
+import org.apache.wicket.util.convert.IConverter;
 
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+public interface TemporalConverter<T> extends IConverter<T> {
 
-/**
- *
- * @apiNote any implementing class must also be discovered/managed by Spring,
- * that is, it needs a direct- or meta-annotation of type {@link Component}
- *
- */
-public interface DateConverterPlugin {
+    Class<T> getTemporalClass();
 
-    public DateConverter<?> converterForClassIfAny(
-            Class<?> cls,
-            WicketViewerSettings wicketViewerSettings,
-            int adjustBy);
+    /**
+     * @see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE
+     */
+    String getTemporalPattern();
 
-}
+}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
index 9021fab..dea4326 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
@@ -34,7 +34,7 @@ import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.util.convert.IConverter;
 
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverter;
+import org.apache.isis.viewer.wicket.model.converter.ConverterBasedOnValueSemantics;
 
 import static de.agilecoders.wicket.jquery.JQuery.$;
 
@@ -47,20 +47,22 @@ import de.agilecoders.wicket.core.util.Attributes;
  *
  * @param <T> The type of the date/time
  */
-public class TextFieldWithDateTimePicker<T> extends TextField<T> implements IConverter<T> {
+public class TextFieldWithDateTimePicker<T>
+extends TextField<T>
+implements IConverter<T> {
 
     private static final long serialVersionUID = 1L;
 
-    protected final DateConverter<T> converter;
+    protected final IConverter<T> converter;
 
     private final DateTimeConfig config;
 
     public TextFieldWithDateTimePicker(
-            IsisAppCommonContext commonContext,
-            String id,
-            IModel<T> model,
-            Class<T> type,
-            DateConverter<T> converter) {
+            final IsisAppCommonContext commonContext,
+            final String id,
+            final IModel<T> model,
+            final Class<T> type,
+            final IConverter<T> converter) {
 
         super(id, model, type);
 
@@ -72,15 +74,15 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
 
         // if this text field is for a LocalDate, then note that pattern obtained will just be a simple date format
         // (with no hour/minute components).
-        final String dateTimePattern = converter.getDateTimePattern(getLocale());
+        final String dateTimePattern = ((ConverterBasedOnValueSemantics<T>)this.converter).getEditingPattern();
         final String pattern = convertToMomentJsFormat(dateTimePattern);
         config.withFormat(pattern);
 
-        boolean patternContainsTimeComponent = pattern.contains("HH");
-        if (patternContainsTimeComponent) {
-            // no longer do this, since for sidebar actions takes up too much real estate.
-            //config.sideBySide(true);
-        }
+//        boolean patternContainsTimeComponent = pattern.contains("HH");
+//        if (patternContainsTimeComponent) {
+//            // no longer do this, since for sidebar actions takes up too much real estate.
+//            //config.sideBySide(true);
+//        }
 
         config.calendarWeeks(true);
         config.useCurrent(false);
@@ -97,21 +99,21 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
 
         this.config = config;
 
-        //XXX ISIS-2834 
-        //Adding OnChangeAjaxBehavior registers a JavaScript event listener on change event. 
-        //Since OnChangeAjaxBehavior extends AjaxFormComponentUpdatingBehavior the Ajax request 
-        // also updates the Wicket model for this form component on the server side.  
-        // onUpdate() is a callback method that you could use to do something more or don't do anything 
+        //XXX ISIS-2834
+        //Adding OnChangeAjaxBehavior registers a JavaScript event listener on change event.
+        //Since OnChangeAjaxBehavior extends AjaxFormComponentUpdatingBehavior the Ajax request
+        // also updates the Wicket model for this form component on the server side.
+        // onUpdate() is a callback method that you could use to do something more or don't do anything
         add(new OnChangeAjaxBehavior() {
             private static final long serialVersionUID = 1L;
             @Override
-            protected void onUpdate(AjaxRequestTarget target) {
+            protected void onUpdate(final AjaxRequestTarget target) {
                 // nothing to do
             }
         });
     }
 
-    private String convertToMomentJsFormat(String javaDateTimeFormat) {
+    private String convertToMomentJsFormat(final String javaDateTimeFormat) {
         String momentJsFormat = javaDateTimeFormat;
         momentJsFormat = momentJsFormat.replace('d', 'D');
         momentJsFormat = momentJsFormat.replace('y', 'Y');
@@ -119,30 +121,30 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
     }
 
     @Override
-    public T convertToObject(String value, Locale locale) {
+    public T convertToObject(final String value, final Locale locale) {
         return converter.convertToObject(value, locale);
     }
 
     @Override
-    public String convertToString(T value, Locale locale) {
+    public String convertToString(final T value, final Locale locale) {
         return converter.convertToString(value, locale);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public <C> IConverter<C> getConverter(Class<C> type) {
+    public <C> IConverter<C> getConverter(final Class<C> type) {
         // we use isAssignableFrom rather than a simple == to handle
         // the persistence of JDO/DataNucleus:
         // if persisting a java.sql.Date, the object we are given is actually a
         // org.datanucleus.store.types.simple.SqlDate (a subclass of java.sql.Date)
-        if (converter.getConvertableClass().isAssignableFrom(type)) {
+        if (super.getType().isAssignableFrom(type)) {
             return (IConverter<C>) this;
         }
         return super.getConverter(type);
     }
 
     @Override
-    protected void onComponentTag(ComponentTag tag) {
+    protected void onComponentTag(final ComponentTag tag) {
         super.onComponentTag(tag);
 
         checkComponentTag(tag, "input");
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
deleted file mode 100644
index 04ef122..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdk8time;
-
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-abstract class DateConverterForJdk8Abstract<T> extends DateConverterAbstract<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    DateConverterForJdk8Abstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
-        super(cls, dateFormatSettings);
-    }
-
-    @Override
-    protected final T doConvertToObject(String value, Locale locale) {
-        T dateTime = convert(value);
-        return minusDays(dateTime, dateFormatSettings.getAdjustBy());
-    }
-
-    @Override
-    protected String doConvertToString(T value, Locale locale) {
-        // for JodaLocalDate, the date time pattern is same as date pattern, so can use either to convert to string.
-        T t = plusDays(value, dateFormatSettings.getAdjustBy());
-        return toString(t, DateTimeFormatter.ofPattern(dateFormatSettings.getDateTimePattern()));
-    }
-
-    protected DateTimeFormatter getFormatterForDatePattern8() {
-        return DateTimeFormatter.ofPattern(dateFormatSettings.getDatePattern());
-    }
-
-    protected DateTimeFormatter getFormatterForDateTimePattern8() {
-        return DateTimeFormatter.ofPattern(dateFormatSettings.getDateTimePattern());
-    }
-
-    protected abstract T minusDays(T value, int adjustBy);
-    protected abstract T plusDays(T value, int adjustBy);
-
-    protected abstract T convert(String value) throws ConversionException;
-    protected abstract String toString(T value, DateTimeFormatter dateTimeFormatter);
-
-}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
deleted file mode 100644
index 33c575f..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdk8time;
-
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-/**
- * Uses the same pattern for both date and date/time.  The only real consequence of this is that when converting a
- * string value to the date value, only a single pattern is used.
- */
-public class DateConverterForJdk8LocalDate extends DateConverterForJdk8Abstract<LocalDate> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJdk8LocalDate(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDate.class, DateFormatSettings.ofDateOnly(settings, adjustBy));
-    }
-
-    @Override
-    protected LocalDate minusDays(LocalDate value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDate plusDays(LocalDate value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDate convert(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern8().parse(value, LocalDate::from);
-        } catch(Exception ex) {
-            throw new ConversionException(String.format("Cannot convert '%s' into a date/time", value), ex);
-        }
-    }
-
-
-
-    @Override
-    protected String toString(LocalDate value, DateTimeFormatter dateTimeFormatter) {
-        return value.format(dateTimeFormatter);
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
deleted file mode 100644
index c0be0d4..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdk8time;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-public class DateConverterForJdk8LocalDateTime extends DateConverterForJdk8Abstract<LocalDateTime> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJdk8LocalDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    @Override
-    protected LocalDateTime minusDays(LocalDateTime value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDateTime plusDays(LocalDateTime value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-
-    @Override
-    protected LocalDateTime convert(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern8().parse(value, LocalDateTime::from);
-        } catch(Exception ex) {
-
-            try {
-
-                return LocalDateTime.of(
-                        getFormatterForDatePattern8().parse(value, LocalDate::from),
-                        LocalTime.of(0, 0)	);
-
-            } catch(Exception ex2) {
-
-                throw new ConversionException(
-                        String.format(
-                                "Cannot convert '%s' into a date/time using pattern '%s' or '%s'",
-                                value, dateFormatSettings.getDateTimePattern(), dateFormatSettings.getDatePattern()),
-                        ex2	);
-            }
-        }
-    }
-
-    @Override
-    protected String toString(LocalDateTime value, DateTimeFormatter dateTimeFormatter) {
-        return value.format(dateTimeFormatter);
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
deleted file mode 100644
index 519c734..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdk8time;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-public class DateConverterForJdk8OffsetDateTime extends DateConverterForJdk8Abstract<OffsetDateTime> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJdk8OffsetDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(OffsetDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    @Override
-    protected OffsetDateTime minusDays(OffsetDateTime value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected OffsetDateTime plusDays(OffsetDateTime value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-    @Override
-    protected OffsetDateTime convert(String value) throws ConversionException {
-
-        return OffsetDateTime.of(
-                convertToLocal(value),
-                defaultOffset()
-                );
-
-    }
-
-    @Override
-    protected String toString(OffsetDateTime value, DateTimeFormatter dateTimeFormatter) {
-        return value.format(dateTimeFormatter);
-    }
-
-    // -- HELPER
-
-    private LocalDateTime convertToLocal(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern8().parse(value, LocalDateTime::from);
-        } catch(Exception ex) {
-
-            try {
-
-                return LocalDateTime.of(
-                        getFormatterForDatePattern8().parse(value, LocalDate::from),
-                        LocalTime.of(0, 0)	);
-
-            } catch(Exception ex2) {
-
-                throw new ConversionException(
-                        String.format(
-                                "Cannot convert '%s' into a date/time using pattern '%s' or '%s'",
-                                value, dateFormatSettings.getDateTimePattern(), dateFormatSettings.getDatePattern()),
-                        ex2	);
-            }
-        }
-    }
-
-    private ZoneOffset defaultOffset() {
-        return OffsetDateTime.now().getOffset();
-
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java
index 191b98c..16208a4 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java
@@ -32,7 +32,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<LocalDate> {
 
     public Jdk8LocalDatePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, LocalDate.class);
-        init(new DateConverterForJdk8LocalDate(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java
index 16ec4a3..32beba1 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java
@@ -33,7 +33,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<LocalDateTime> {
 
     public Jdk8LocalDateTimePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, LocalDateTime.class);
-        init(new DateConverterForJdk8LocalDateTime(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java
index 8a0e944..b372c93 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java
@@ -33,7 +33,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<OffsetDateTime> {
 
     public Jdk8OffsetDateTimePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, OffsetDateTime.class);
-        init(new DateConverterForJdk8OffsetDateTime(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java
deleted file mode 100644
index b35ad6c..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-public abstract class DateConverterForJavaAbstract<T extends java.util.Date> extends DateConverterAbstract<T> {
-    private static final long serialVersionUID = 1L;
-
-    private transient SimpleDateFormat dateOnlyPattern;
-    private transient SimpleDateFormat dateTimePattern;
-
-    public DateConverterForJavaAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
-        super(cls, dateFormatSettings);
-    }
-
-    protected SimpleDateFormat getDateOnlyFormat() {
-        if(dateOnlyPattern==null) {
-            dateOnlyPattern = new SimpleDateFormat(dateFormatSettings.getDatePattern());
-        }
-        return dateOnlyPattern;
-    }
-
-    protected SimpleDateFormat getDateTimeFormat() {
-        if(dateTimePattern==null) {
-            dateTimePattern = new SimpleDateFormat(dateFormatSettings.getDateTimePattern());
-        }
-        return dateTimePattern;
-    }
-
-    protected <X extends java.util.Date> T adjustDaysForward(X value) {
-        final int days = dateFormatSettings.getAdjustBy();
-        if(days==0) {
-            return temporalValueOf(value);
-        }
-        return temporalValueOf(addDaysTo(value, days));
-    }
-
-    protected <X extends java.util.Date> T adjustDaysBackward(X value) {
-        final int days = dateFormatSettings.getAdjustBy();
-        if(days==0) {
-            return temporalValueOf(value);
-        }
-        return temporalValueOf(addDaysTo(value, -days));
-    }
-
-    protected T parseDateTime(String valueStr) {
-        try {
-            java.util.Date parsed = getDateTimeFormat().parse(valueStr);
-            return temporalValueOf(parsed);
-        } catch (ParseException ex) {
-            try {
-                java.util.Date parsed = getDateOnlyFormat().parse(valueStr);
-                return temporalValueOf(parsed);
-            } catch (ParseException ex2) {
-                throw new ConversionException("Value cannot be converted as a date/time", ex);
-            }
-        }
-    }
-
-    protected T parseDateOnly(String valueStr) {
-        try {
-            java.util.Date parsed =  getDateOnlyFormat().parse(valueStr);
-            return temporalValueOf(parsed);
-        } catch (ParseException e) {
-            throw new ConversionException("Cannot convert into a date", e);
-        }
-    }
-
-    protected abstract T temporalValueOf(java.util.Date date);
-
-    // -- HELPER
-
-    private final <X extends java.util.Date> T addDaysTo(X value, final int days) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(value);
-        cal.add(Calendar.DATE, days);
-        final java.util.Date adjusted = cal.getTime();
-        return temporalValueOf(adjusted);
-    }
-
-}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java
deleted file mode 100644
index 75ecae7..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-
-public class DateConverterForJavaSqlDate extends DateConverterForJavaAbstract<java.sql.Date> {
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJavaSqlDate(WicketViewerSettings settings, int adjustBy) {
-        this(DateFormatSettings.ofDateOnly(settings, adjustBy));
-    }
-
-    private DateConverterForJavaSqlDate(DateFormatSettings dateFormatSettings) {
-        super(java.sql.Date.class, dateFormatSettings);
-    }
-
-    @Override
-    protected java.sql.Date doConvertToObject(String value, Locale locale) throws ConversionException {
-        final java.sql.Date date = parseDateOnly(value);
-        final java.sql.Date adjustedDate = adjustDaysBackward(date);
-        return adjustedDate;
-    }
-
-    @Override
-    protected String doConvertToString(java.sql.Date value, Locale locale) {
-        final java.sql.Date adjustedDate = adjustDaysForward(value);
-        return getDateOnlyFormat().format(adjustedDate);
-    }
-
-    @Override
-    protected java.sql.Date temporalValueOf(java.util.Date date) {
-        return new java.sql.Date(date.getTime());
-    }
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java
deleted file mode 100644
index eb485c8..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import java.sql.Timestamp;
-import java.util.Date;
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-
-public class DateConverterForJavaSqlTimestamp extends DateConverterForJavaAbstract<java.sql.Timestamp> {
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJavaSqlTimestamp(WicketViewerSettings settings, int adjustBy) {
-        this(DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    private DateConverterForJavaSqlTimestamp(DateFormatSettings dateFormatSettings) {
-        super(java.sql.Timestamp.class, dateFormatSettings);
-    }
-
-    @Override
-    protected java.sql.Timestamp doConvertToObject(String value, Locale locale) throws ConversionException {
-        final java.sql.Timestamp date = parseDateTime(value);
-        final java.sql.Timestamp adjustedDate = adjustDaysBackward(date);
-        return adjustedDate;
-    }
-
-    @Override
-    protected String doConvertToString(java.sql.Timestamp value, Locale locale) throws ConversionException {
-        final java.sql.Timestamp adjustedDate = adjustDaysForward(value);
-        return getDateTimeFormat().format(adjustedDate);
-    }
-
-    @Override
-    protected Timestamp temporalValueOf(Date date) {
-        return new java.sql.Timestamp(date.getTime());
-    }
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java
deleted file mode 100644
index 6a633bb..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import java.util.Date;
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-
-public class DateConverterForJavaUtilDate extends DateConverterForJavaAbstract<java.util.Date> {
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJavaUtilDate(WicketViewerSettings settings, int adjustBy) {
-        this(DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    private DateConverterForJavaUtilDate(DateFormatSettings dateFormatSettings) {
-        super(java.util.Date.class, dateFormatSettings);
-    }
-
-    @Override
-    protected java.util.Date doConvertToObject(String value, Locale locale) throws ConversionException {
-        final Date date = parseDateTime(value);
-        final Date adjustedDate = adjustDaysBackward(date);
-        return adjustedDate;
-    }
-
-    @Override
-    protected String doConvertToString(java.util.Date value, Locale locale) throws ConversionException {
-        final Date adjustedDate = adjustDaysForward(value);
-        return getDateTimeFormat().format(adjustedDate);
-    }
-
-    @Override
-    protected Date temporalValueOf(Date date) {
-        return date; //[ahuber] immutable, so just returning the same object
-    }
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
index 4ea4fe8..862ac8c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
@@ -33,7 +33,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<java.sql.Date> {
 
     public JavaSqlDatePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, java.sql.Date.class);
-        init(new DateConverterForJavaSqlDate(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlTimestampPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlTimestampPanel.java
index 59e7051..041eafa 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlTimestampPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlTimestampPanel.java
@@ -34,12 +34,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<Timestamp> {
 
     public JavaSqlTimestampPanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, java.sql.Timestamp.class);
-        init(new DateConverterForJavaSqlTimestamp(getWicketViewerSettings(), getAdjustBy()));
-    }
-
-    @Override
-    protected Integer getLengthAdjustHint() {
-        return +3;
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
index 30ba2ef..cf5938e 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
-
-
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldWithTemporalPickerAbstract;
 
@@ -33,12 +31,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<java.util.Date> {
 
     public JavaUtilDatePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, java.util.Date.class);
-        init(new DateConverterForJavaUtilDate(getWicketViewerSettings(), getAdjustBy()));
-    }
-
-    @Override
-    protected Integer getLengthAdjustHint() {
-        return +3;
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java
deleted file mode 100644
index 998e52a..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-abstract class DateConverterForJodaAbstract<T> extends DateConverterAbstract<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    DateConverterForJodaAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
-        super(cls, dateFormatSettings);
-    }
-
-    @Override
-    protected final T doConvertToObject(String value, Locale locale) {
-        T dateTime = convert(value);
-        return minusDays(dateTime, dateFormatSettings.getAdjustBy());
-    }
-
-    @Override
-    protected String doConvertToString(T value, Locale locale) {
-        // for JodaLocalDate, the date time pattern is same as date pattern, so can use either to convert to string.
-        T t = plusDays(value, dateFormatSettings.getAdjustBy());
-        return toString(t, getFormatterForDateTimePattern());
-    }
-
-
-    protected abstract T minusDays(T value, int adjustBy);
-    protected abstract T plusDays(T value, int adjustBy);
-
-    protected abstract T convert(String value) throws ConversionException;
-    protected abstract String toString(T value, DateTimeFormatter dateTimeFormatter);
-
-}
\ No newline at end of file
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java
deleted file mode 100644
index 621e0ef..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-public class DateConverterForJodaDateTime extends DateConverterForJodaAbstract<DateTime> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJodaDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(DateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    @Override
-    protected DateTime minusDays(DateTime value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected DateTime plusDays(DateTime value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-    @Override
-    protected DateTime convert(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern().parseDateTime(value);
-        } catch(IllegalArgumentException ex) {
-            try {
-                return getFormatterForDatePattern().parseDateTime(value);
-            } catch(IllegalArgumentException ex2) {
-                throw new ConversionException(String.format("Cannot convert '%s' into a date/time", value), ex2);
-            }
-        }
-    }
-
-    @Override
-    protected String toString(DateTime value, DateTimeFormatter dateTimeFormatter) {
-        return value.toString(dateTimeFormatter);
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java
deleted file mode 100644
index 8402468..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.LocalDate;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-/**
- * Uses the same pattern for both date and date/time.  The only real consequence of this is that when converting a
- * string value to the date value, only a single pattern is used.
- */
-public class DateConverterForJodaLocalDate extends DateConverterForJodaAbstract<LocalDate> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJodaLocalDate(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDate.class, DateFormatSettings.ofDateOnly(settings, adjustBy));
-    }
-
-    @Override
-    protected LocalDate minusDays(LocalDate value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDate plusDays(LocalDate value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDate convert(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern().parseLocalDate(value);
-        } catch(IllegalArgumentException ex) {
-            throw new ConversionException(String.format("Cannot convert '%s' into a date/time", value), ex);
-        }
-    }
-
-    @Override
-    protected String toString(LocalDate value, DateTimeFormatter dateTimeFormatter) {
-        return value.toString(dateTimeFormatter);
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java
deleted file mode 100644
index a366847..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.LocalDateTime;
-import org.joda.time.format.DateTimeFormatter;
-
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
-
-public class DateConverterForJodaLocalDateTime extends DateConverterForJodaAbstract<LocalDateTime> {
-
-    private static final long serialVersionUID = 1L;
-
-    public DateConverterForJodaLocalDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
-    }
-
-    @Override
-    protected LocalDateTime minusDays(LocalDateTime value, int adjustBy) {
-        return value.minusDays(adjustBy);
-    }
-
-    @Override
-    protected LocalDateTime plusDays(LocalDateTime value, int adjustBy) {
-        return value.plusDays(adjustBy);
-    }
-
-
-    @Override
-    protected LocalDateTime convert(String value) throws ConversionException {
-        try {
-            return getFormatterForDateTimePattern().parseLocalDateTime(value);
-        } catch(IllegalArgumentException ex) {
-            try {
-                return getFormatterForDatePattern().parseLocalDateTime(value);
-            } catch(IllegalArgumentException ex2) {
-                throw new ConversionException(String.format("Cannot convert '%s' into a date/time", value), ex2);
-            }
-        }
-    }
-
-    @Override
-    protected String toString(LocalDateTime value, DateTimeFormatter dateTimeFormatter) {
-        return value.toString(dateTimeFormatter);
-    }
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimePanel.java
index faedd8b..3ae49b2 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimePanel.java
@@ -34,7 +34,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<DateTime> {
 
     public JodaDateTimePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, DateTime.class);
-        init(new DateConverterForJodaDateTime(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDatePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDatePanel.java
index 1f08525..850730c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDatePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDatePanel.java
@@ -33,7 +33,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<LocalDate> {
 
     public JodaLocalDatePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, LocalDate.class);
-        init(new DateConverterForJodaLocalDate(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimePanel.java
index d514297..1f02a93 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimePanel.java
@@ -33,7 +33,6 @@ extends ScalarPanelTextFieldWithTemporalPickerAbstract<LocalDateTime> {
 
     public JodaLocalDateTimePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, LocalDateTime.class);
-        init(new DateConverterForJodaLocalDateTime(getWicketViewerSettings(), getAdjustBy()));
     }
 
 }
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/ConverterTester.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/ConverterTester.java
index 0b78d5b..61d2ba5 100644
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/ConverterTester.java
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/ConverterTester.java
@@ -24,11 +24,15 @@ import java.util.Locale;
 import java.util.Objects;
 
 import org.apache.wicket.util.convert.ConversionException;
+import org.assertj.core.util.Arrays;
 
 import org.apache.isis.applib.adapters.ValueSemanticsAbstract;
+import org.apache.isis.applib.clock.VirtualClock;
+import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.services.iactnlayer.InteractionContext;
 import org.apache.isis.applib.services.iactnlayer.InteractionService;
 import org.apache.isis.commons.functional.ThrowingRunnable;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.config.valuetypes.ValueSemanticsRegistry;
 import org.apache.isis.core.metamodel._testing.MetaModelContext_forTesting;
 import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
@@ -60,10 +64,25 @@ public class ConverterTester<T extends Serializable> {
         ConverterBasedOnValueSemantics<T> converter;
     }
 
-    public ConverterTester(final Class<T> valueType, final ValueSemanticsAbstract<T> valueSemantics) {
+    public ConverterTester(final Class<T> valueType, final ValueSemanticsAbstract<T> valueSemantics,
+            final Object ...additionalSingletons) {
+        this(valueType, valueSemantics, VirtualClock.frozenTestClock(), additionalSingletons);
+    }
+
+    public ConverterTester(
+            final @NonNull Class<T> valueType,
+            final @NonNull ValueSemanticsAbstract<T> valueSemantics,
+            final @NonNull VirtualClock virtualClock,
+            final Object ...additionalSingletons) {
 
         mmc = MetaModelContext_forTesting.builder()
                 .valueSemantic(valueSemantics)
+                .singleton(new ClockService(null) {
+                    @Override public VirtualClock getClock() {
+                        return virtualClock;
+                    }
+                })
+                .singletons(Arrays.asList(additionalSingletons))
                 .interactionProvider(interactionService = new InteractionService_forTesting())
                 .build();
 
@@ -118,14 +137,17 @@ public class ConverterTester<T extends Serializable> {
             final @NonNull String expectedText) {
         runWithInteraction(()->{
 
-            if(value instanceof BigDecimal) {
+            val parsedValue = scenario.converter.convertToObject(valueAsText, LOCALE_NOT_USED);
 
+            if(value instanceof BigDecimal) {
                 assertNumberEquals(
-                        (BigDecimal)value, (BigDecimal)scenario.converter.convertToObject(valueAsText, LOCALE_NOT_USED));
-
+                        (BigDecimal)value, (BigDecimal)parsedValue);
+            } else if(value instanceof java.util.Date) {
+                assertTemporalEquals(
+                        (java.util.Date)value, (java.util.Date)parsedValue);
             } else {
                 assertEquals(
-                        value, scenario.converter.convertToObject(valueAsText, LOCALE_NOT_USED));
+                        value, parsedValue);
             }
 
             assertEquals(
@@ -137,7 +159,7 @@ public class ConverterTester<T extends Serializable> {
         runWithInteraction(()->{
             assertNull(scenario.converter.convertToObject(null, LOCALE_NOT_USED));
             assertNull(scenario.converter.convertToObject("", LOCALE_NOT_USED));
-            assertNull(scenario.converter.convertToString(null, LOCALE_NOT_USED));
+            assertTrue(_Strings.isEmpty(scenario.converter.convertToString(null, LOCALE_NOT_USED)));
         });
     }
 
@@ -161,5 +183,12 @@ public class ConverterTester<T extends Serializable> {
                 b.setScale(maxScale));
     }
 
+    @SuppressWarnings("deprecation")
+    private void assertTemporalEquals(final java.util.Date a, final java.util.Date b) {
+        assertEquals(a.getDay(), b.getDay());
+        assertEquals(a.getMonth(), b.getMonth());
+        assertEquals(a.getYear(), b.getYear());
+        assertEquals(a.getTime(), b.getTime());
+    }
 
 }
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDateTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDateTest.java
deleted file mode 100644
index 0ff1cf0..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDateTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateConverterForJavaSqlDateTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtrip() {
-        final DateConverterForJavaSqlDate converter = new DateConverterForJavaSqlDate(settings, 0);
-        final java.sql.Date dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(newJavaSqlDate(2013, 5, 11)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-    @Test
-    public void roundtripWithAdjustBy() {
-        final DateConverterForJavaSqlDate converter = new DateConverterForJavaSqlDate(settings, -1);
-        final java.sql.Date dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(newJavaSqlDate(2013, 5, 12)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-    @SuppressWarnings("deprecation")
-    private java.sql.Date newJavaSqlDate(int yyyy, int mm, int dd) {
-        return new java.sql.Date(yyyy-1900, mm-1, dd);
-    }
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDateTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDateTest.java
deleted file mode 100644
index 3a10b79..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDateTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jdkdates;
-
-import java.util.Date;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateConverterForJavaUtilDateTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-                allowing(settings).getDateTimePattern();
-                will(returnValue("yyyy-MM-dd HH:mm"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormat() {
-        final DateConverterForJavaUtilDate converter = new DateConverterForJavaUtilDate(settings, 0);
-        final java.util.Date dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(newJavaUtilDate(2013, 5, 11)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormat() {
-        final DateConverterForJavaUtilDate converter = new DateConverterForJavaUtilDate(settings, 0);
-        final Date dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(newJavaUtilDate(2013, 5, 11)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormatWithAdjustBy() {
-        final DateConverterForJavaUtilDate converter = new DateConverterForJavaUtilDate(settings, -1);
-        final Date dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(newJavaUtilDate(2013, 5, 12)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
-        final DateConverterForJavaUtilDate converter = new DateConverterForJavaUtilDate(settings, -1);
-        final Date dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(newJavaUtilDate(2013, 5, 12)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @SuppressWarnings("deprecation")
-    private java.util.Date newJavaUtilDate(int yyyy, int mm, int dd) {
-        return new java.util.Date(yyyy-1900, mm-1, dd);
-    }
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDateConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDateConverterTest.java
new file mode 100644
index 0000000..c67d504
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDateConverterTest.java
@@ -0,0 +1,75 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jdkdates;
+
+import java.util.Locale;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaSqlDateValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class JavaSqlDateConverterTest {
+
+    final java.sql.Date valid = java.sql.Date.valueOf("2013-03-13");
+    ConverterTester<java.sql.Date> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<java.sql.Date>(java.sql.Date.class,
+                new JavaSqlDateValueSemantics(),
+                new LocalDateValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithJavaSqlDate.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-03-13");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDate: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithJavaSqlDate {
+        @Property @Getter @Setter
+        private java.sql.Date value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDateConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDateConverterTest.java
new file mode 100644
index 0000000..4e2b348
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDateConverterTest.java
@@ -0,0 +1,77 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jdkdates;
+
+import java.util.Locale;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaUtilDateValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class JavaUtilDateConverterTest {
+
+    @SuppressWarnings("deprecation")
+    final java.util.Date valid = new java.util.Date(2013-1900, 03-1, 13, 17, 15, 59);
+    ConverterTester<java.util.Date> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+
+        converterTester = new ConverterTester<java.util.Date>(java.util.Date.class,
+                new JavaUtilDateValueSemantics(),
+                new LocalDateTimeValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithJavaSqlDate.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-03-13 17:15:59");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDateTime: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithJavaSqlDate {
+        @Property @Getter @Setter
+        private java.sql.Date value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverter.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverterTest.java
similarity index 99%
rename from viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverter.java
rename to viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverterTest.java
index f562161..9efc046 100644
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverter.java
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkmath/BigDecimalConverterTest.java
@@ -36,7 +36,7 @@ import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
 import lombok.Getter;
 import lombok.Setter;
 
-class BigDecimalConverter {
+class BigDecimalConverterTest {
 
     final BigDecimal bd_123_45_scale2 = new BigDecimal("123.45").setScale(2);
     final BigDecimal bd_123_4500_scale2 = new BigDecimal("123.4500").setScale(2);
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTimeTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTimeTest.java
deleted file mode 100644
index 2bed4a0..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTimeTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.joda.time.DateTime;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateConverterForJodaDateTimeTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-                allowing(settings).getDateTimePattern();
-                will(returnValue("yyyy-MM-dd HH:mm"));
-            }
-        });
-    }
-
-
-    @Test
-    public void roundtripWhenParsingDateFormat() {
-        final DateConverterForJodaDateTime converter = new DateConverterForJodaDateTime(settings, 0);
-        final DateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new DateTime(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormat() {
-        final DateConverterForJodaDateTime converter = new DateConverterForJodaDateTime(settings, 0);
-        final DateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(new DateTime(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormatWithAdjustBy() {
-        final DateConverterForJodaDateTime converter = new DateConverterForJodaDateTime(settings, -1);
-        final DateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new DateTime(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
-        final DateConverterForJodaDateTime converter = new DateConverterForJodaDateTime(settings, -1);
-        final DateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(new DateTime(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTest.java
deleted file mode 100644
index 03262e3..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.joda.time.LocalDate;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateConverterForJodaLocalDateTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtrip() {
-        final DateConverterForJodaLocalDate converter = new DateConverterForJodaLocalDate(settings, 0);
-        final LocalDate dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new LocalDate(2013, 05, 11)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-    @Test
-    public void roundtripWithAdjustBy() {
-        final DateConverterForJodaLocalDate converter = new DateConverterForJodaLocalDate(settings, -1);
-        final LocalDate dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new LocalDate(2013, 05, 12)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTimeTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTimeTest.java
deleted file mode 100644
index 3962548..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTimeTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.joda.time.LocalDateTime;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-
-public class DateConverterForJodaLocalDateTimeTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-                allowing(settings).getDateTimePattern();
-                will(returnValue("yyyy-MM-dd HH:mm"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormat() {
-        final DateConverterForJodaLocalDateTime converter = new DateConverterForJodaLocalDateTime(settings, 0);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new LocalDateTime(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormat() {
-        final DateConverterForJodaLocalDateTime converter = new DateConverterForJodaLocalDateTime(settings, 0);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(new LocalDateTime(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormatWithAdjustBy() {
-        final DateConverterForJodaLocalDateTime converter = new DateConverterForJodaLocalDateTime(settings, -1);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(new LocalDateTime(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
-        final DateConverterForJodaLocalDateTime converter = new DateConverterForJodaLocalDateTime(settings, -1);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(new LocalDateTime(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimeConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimeConverterTest.java
new file mode 100644
index 0000000..b2486c1
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaDateTimeConverterTest.java
@@ -0,0 +1,78 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime;
+
+import java.util.Locale;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.ZonedDateTimeValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaDateTimeValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class JodaDateTimeConverterTest {
+
+    final org.joda.time.DateTime valid = new DateTime(2013, 05, 11, 17, 59, DateTimeZone.forOffsetHours(1));
+    ConverterTester<DateTime> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<org.joda.time.DateTime>(org.joda.time.DateTime.class,
+                new JodaDateTimeValueSemantics(),
+                new ZonedDateTimeValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithJodaDateTime.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-05-11 17:59:00 +0100");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.ZonedDateTime: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithJodaDateTime {
+        @Property @Getter @Setter
+        private org.joda.time.DateTime value;
+    }
+
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateConverterTest.java
new file mode 100644
index 0000000..44135ca
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateConverterTest.java
@@ -0,0 +1,76 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime;
+
+import java.util.Locale;
+
+import org.joda.time.LocalDate;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalDateValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class JodaLocalDateConverterTest {
+
+    final org.joda.time.LocalDate valid = new LocalDate(2013, 05, 11);
+    ConverterTester<LocalDate> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<org.joda.time.LocalDate>(org.joda.time.LocalDate.class,
+                new JodaLocalDateValueSemantics(),
+                new LocalDateValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithJodaLocalDate.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-05-11");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDate: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithJodaLocalDate {
+        @Property @Getter @Setter
+        private org.joda.time.LocalDate value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimeConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimeConverterTest.java
new file mode 100644
index 0000000..7c8a5e8
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/JodaLocalDateTimeConverterTest.java
@@ -0,0 +1,77 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime;
+
+import java.util.Locale;
+
+import org.joda.time.LocalDateTime;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.valuetypes.jodatime.integration.valuesemantics.JodaLocalDateTimeValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class JodaLocalDateTimeConverterTest {
+
+    final org.joda.time.LocalDateTime valid = new LocalDateTime(2013, 03, 13, 17, 59);
+    ConverterTester<LocalDateTime> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+
+        converterTester = new ConverterTester<org.joda.time.LocalDateTime>(org.joda.time.LocalDateTime.class,
+                new JodaLocalDateTimeValueSemantics(),
+                new LocalDateTimeValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithJodaDateTime.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-03-13 17:59:00");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDateTime: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithJodaDateTime {
+        @Property @Getter @Setter
+        private org.joda.time.LocalDateTime value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java
deleted file mode 100644
index 50478ea..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
-
-import java.time.LocalDate;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8LocalDate;
-
-public class DateConverterForJdk8LocalDateTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtrip() {
-        final DateConverterForJdk8LocalDate converter = new DateConverterForJdk8LocalDate(settings, 0);
-        final LocalDate dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(LocalDate.of(2013, 05, 11)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-    @Test
-    public void roundtripWithAdjustBy() {
-        final DateConverterForJdk8LocalDate converter = new DateConverterForJdk8LocalDate(settings, -1);
-        final LocalDate dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(LocalDate.of(2013, 05, 12)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11"));
-    }
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java
deleted file mode 100644
index 2ad2cdd..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
-
-import java.time.LocalDateTime;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8LocalDateTime;
-
-public class DateConverterForJdk8LocalDateTimeTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-                allowing(settings).getDateTimePattern();
-                will(returnValue("yyyy-MM-dd HH:mm"));
-            }
-        });
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormat() {
-        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, 0);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(LocalDateTime.of(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormat() {
-        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, 0);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(LocalDateTime.of(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormatWithAdjustBy() {
-        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, -1);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(LocalDateTime.of(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
-        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, -1);
-        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(LocalDateTime.of(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java
deleted file mode 100644
index 2d80572..0000000
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
-
-import java.time.OffsetDateTime;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8OffsetDateTime;
-
-public class DateConverterForJdk8OffsetDateTimeTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private WicketViewerSettings settings;
-
-    @Before
-    public void setUp() throws Exception {
-        context.checking(new Expectations() {
-            {
-                allowing(settings).getDatePattern();
-                will(returnValue("yyyy-MM-dd"));
-                allowing(settings).getDateTimePattern();
-                will(returnValue("yyyy-MM-dd HH:mm"));
-            }
-        });
-    }
-
-
-    @Test
-    public void roundtripWhenParsingDateFormat() {
-        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, 0);
-        final OffsetDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(sample(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormat() {
-        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, 0);
-        final OffsetDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(sample(2013, 05, 11, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateFormatWithAdjustBy() {
-        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, -1);
-        final OffsetDateTime dt = converter.convertToObject("2013-05-11", null);
-        assertThat(dt, is(sample(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-    @Test
-    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
-        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, -1);
-        final OffsetDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
-        assertThat(dt, is(sample(2013, 05, 12, 0, 0)));
-
-        final String str = converter.convertToString(dt, null);
-        assertThat(str, is("2013-05-11 00:00"));
-    }
-
-
-    private static OffsetDateTime sample( int year, int month, int dayOfMonth,
-            int hour, int minute) {
-        return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, 0, 0, 
-                OffsetDateTime.now().getOffset());
-    }
-
-
-
-
-}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateConverterTest.java
new file mode 100644
index 0000000..6614c49
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateConverterTest.java
@@ -0,0 +1,74 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
+
+import java.time.LocalDate;
+import java.util.Locale;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class LocalDateConverterTest {
+
+    final java.time.LocalDate valid = LocalDate.of(2013, 03, 13);
+    ConverterTester<LocalDate> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<LocalDate>(LocalDate.class,
+                new LocalDateValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithLocalDate.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-03-13");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDate: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithLocalDate {
+        @Property @Getter @Setter
+        private LocalDate value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateTimeConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateTimeConverterTest.java
new file mode 100644
index 0000000..0faeda9
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/LocalDateTimeConverterTest.java
@@ -0,0 +1,74 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
+
+import java.time.LocalDateTime;
+import java.util.Locale;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class LocalDateTimeConverterTest {
+
+    final java.time.LocalDateTime valid = LocalDateTime.of(2013, 03, 13, 17, 59);
+    ConverterTester<LocalDateTime> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<LocalDateTime>(LocalDateTime.class,
+                new LocalDateTimeValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithLocalDateTime.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-03-13 17:59:00");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.LocalDateTime: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithLocalDateTime {
+        @Property @Getter @Setter
+        private LocalDateTime value;
+    }
+
+}
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/OffsetDateTimeConverterTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/OffsetDateTimeConverterTest.java
new file mode 100644
index 0000000..3cf271b
--- /dev/null
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/OffsetDateTimeConverterTest.java
@@ -0,0 +1,81 @@
+/*
+ *  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.viewer.wicket.ui.components.scalars.jodatime.jdk8time;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.Locale;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.core.metamodel.commons.ScalarRepresentation;
+import org.apache.isis.core.metamodel.valuesemantics.temporal.OffsetDateTimeValueSemantics;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ConverterTester;
+
+import lombok.Getter;
+import lombok.Setter;
+
+class OffsetDateTimeConverterTest {
+
+    final java.time.OffsetDateTime valid = sample(2013, 05, 11, 17, 23, +03);
+    ConverterTester<OffsetDateTime> converterTester;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        converterTester = new ConverterTester<OffsetDateTime>(OffsetDateTime.class,
+                new OffsetDateTimeValueSemantics());
+        converterTester.setScenario(
+                Locale.ENGLISH,
+                converterTester.converterForProperty(
+                        CustomerWithOffsetDateTime.class, "value", ScalarRepresentation.EDITING));
+    }
+
+    @Test
+    void happy_case() {
+        converterTester.assertRoundtrip(valid, "2013-05-11 17:23:00 +0300");
+    }
+
+    @Test
+    void when_null() {
+        converterTester.assertHandlesEmpty();
+    }
+
+    @Test
+    void invalid() {
+        converterTester.assertConversionFailure("junk", "Not recognised as a java.time.OffsetDateTime: junk");
+    }
+
+    // -- SCENARIOS
+
+    @DomainObject
+    static class CustomerWithOffsetDateTime {
+        @Property @Getter @Setter
+        private OffsetDateTime value;
+    }
+
+    private static OffsetDateTime sample(final int year, final int month, final int dayOfMonth,
+            final int hour, final int minute, final int offsetHours) {
+        return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, 0, 0,
+                ZoneOffset.ofHours(offsetHours));
+    }
+
+}