You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2022/02/25 02:59:34 UTC

[tapestry-5] branch latest-java-tests updated: TAP5-2700: Tests covering new Java features from versions 9 to 17

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

thiagohp pushed a commit to branch latest-java-tests
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git


The following commit(s) were added to refs/heads/latest-java-tests by this push:
     new 0d4e5cb  TAP5-2700: Tests covering new Java features from versions 9 to 17
0d4e5cb is described below

commit 0d4e5cbc959650b6f4ee1b6650e0b22c968959f8
Author: Thiago H. de Paula Figueiredo <th...@arsmachina.com.br>
AuthorDate: Thu Feb 24 23:59:23 2022 -0300

    TAP5-2700: Tests covering new Java features from versions 9 to 17
---
 build.gradle                                       |   3 +-
 tapestry-core/build.gradle                         |   1 -
 tapestry-latest-java-tests/build.gradle            |  16 +-
 .../tapestry5/ioc/services/AndExpression.java      |  32 ++++
 .../apache/tapestry5/ioc/services/Appliance.java   |  33 ++++
 .../tapestry5/ioc/services/BinaryExpression.java   |  20 +++
 .../ioc/services/ConsolePortableHybrid.java        |  24 +++
 .../ioc/services/ConstantBinaryExpression.java     |  31 ++++
 .../ioc/services/ConstantIntExpression.java        |  24 +++
 .../tapestry5/ioc/services/CoolingMachine.java     |  23 +++
 .../org/apache/tapestry5/ioc/services/Freezer.java |  23 +++
 .../apache/tapestry5/ioc/services/HomeConsole.java |  24 +++
 .../tapestry5/ioc/services/IntExpression.java      |  20 +++
 .../apache/tapestry5/ioc/services/IntTuple.java    |  20 +++
 .../ioc/services/Java10And11ConcreteService.java   |  68 +++++++++
 .../ioc/services/Java10And11NewFeatureTests.java   |  54 +++++++
 .../tapestry5/ioc/services/Java10And11Service.java |  17 +++
 .../ioc/services/Java10And11ServiceImpl.java       |  69 +++++++++
 .../ioc/services/Java12And13ConcreteService.java   |  71 +++++++++
 .../ioc/services/Java12And13NewFeatureTests.java   |  69 +++++++++
 .../tapestry5/ioc/services/Java12And13Service.java |  28 ++++
 .../ioc/services/Java12And13ServiceImpl.java       |  69 +++++++++
 .../ioc/services/Java14ConcreteService.java        |  73 +++++++++
 .../ioc/services/Java14NewFeatureTests.java        | 101 ++++++++++++
 .../tapestry5/ioc/services/Java14Service.java      |  37 +++++
 .../tapestry5/ioc/services/Java14ServiceImpl.java  |  71 +++++++++
 .../ioc/services/Java15To17ConcreteService.java    |  63 ++++++++
 .../ioc/services/Java15To17NewFeatureTests.java    | 169 +++++++++++++++++++++
 .../tapestry5/ioc/services/Java15To17Service.java  |  34 +++++
 .../ioc/services/Java15To17ServiceImpl.java        |  66 ++++++++
 .../ioc/services/Java9ConcreteService.java         |  69 +++++++++
 .../ioc/services/Java9NewFeatureTests.java         |  60 ++++++++
 .../tapestry5/ioc/services/Java9Service.java       |  33 ++++
 .../tapestry5/ioc/services/Java9ServiceImpl.java   |  70 +++++++++
 .../tapestry5/ioc/services/OrExpression.java       |  32 ++++
 .../tapestry5/ioc/services/PlusExpression.java     |  24 +++
 .../tapestry5/ioc/services/Refrigerator.java       |  23 +++
 .../tapestry5/ioc/services/SquareExpression.java   |  24 +++
 .../apache/tapestry5/ioc/services/Videogame.java   |  19 +++
 .../tapestry5/ioc/services/WashingMachine.java     |  23 +++
 40 files changed, 1726 insertions(+), 4 deletions(-)

diff --git a/build.gradle b/build.gradle
index 2d7a05a..484f990 100755
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ apply from: "sha256.gradle"
 project.ext.versions = [
     jetty: "8.1.19.v20160209",
     tomcat: "7.0.70",
-    testng: "6.8.21",
+    testng: "6.14.3",
     easymock: "3.3.1",
     servletapi: "3.0.1",
     spock: "2.1-M2-groovy-3.0",
@@ -221,7 +221,6 @@ subprojects {
     
         // Needed to have XMLTokenStreamTests.testStreamEncoding() passing on Java 9+
         if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_1_9)) {
-            println "Java 9+ JVM arg: --add-opens=java.base/java.nio.charset=ALL-UNNAMED"
             jvmArgs("--add-opens=java.base/java.nio.charset=ALL-UNNAMED");
         }
     
diff --git a/tapestry-core/build.gradle b/tapestry-core/build.gradle
index 6dd9956..35f5289 100644
--- a/tapestry-core/build.gradle
+++ b/tapestry-core/build.gradle
@@ -75,7 +75,6 @@ jar {
 // Needed to have XMLTokenStreamTests.testStreamEncoding() passing on Java 9+
 test {
     if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_1_9)) {
-        println "Java 9+ JVM arg: --add-opens=java.base/java.nio.charset=ALL-UNNAMED"
         jvmArgs("--add-opens=java.base/java.nio.charset=ALL-UNNAMED");
     }
 }
diff --git a/tapestry-latest-java-tests/build.gradle b/tapestry-latest-java-tests/build.gradle
index 54c9223..92267af 100644
--- a/tapestry-latest-java-tests/build.gradle
+++ b/tapestry-latest-java-tests/build.gradle
@@ -1,5 +1,19 @@
 description = "Test suite for making sure Tapestry runs on latest Java"
 
+sourceCompatibility = "17"
+targetCompatibility = "17"
+
+tasks.withType(JavaCompile).each { 
+    it.options.compilerArgs.add("--enable-preview")
+}
+
+test {
+    useTestNG()
+    jvmArgs(["--enable-preview"])
+}
+
 dependencies {
-    api project(':tapestry-ioc')
+    testImplementation project(':tapestry-ioc')
+    testImplementation "org.slf4j:slf4j-api:${versions.slf4j}"
+    testImplementation "org.testng:testng:${versions.testng}"
 }
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java
new file mode 100644
index 0000000..3696898
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java
@@ -0,0 +1,32 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class AndExpression implements BinaryExpression
+{
+    private final BinaryExpression operand1, operand2;
+    
+    public AndExpression(BinaryExpression operand1, BinaryExpression operand2) {
+        super();
+        this.operand1 = operand1;
+        this.operand2 = operand2;
+    }
+
+    @Override
+    public boolean evaluate()
+    {
+        return operand1.evaluate() && operand2.evaluate();
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java
new file mode 100644
index 0000000..8e25feea
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java
@@ -0,0 +1,33 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public sealed abstract class Appliance permits WashingMachine, CoolingMachine
+{
+
+    final String name;
+
+    public Appliance(String name) 
+    {
+        super();
+        this.name = name;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+    
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java
new file mode 100644
index 0000000..1202bf9
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java
@@ -0,0 +1,20 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public sealed interface BinaryExpression permits ConstantBinaryExpression, AndExpression, OrExpression
+{
+    boolean evaluate();
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java
new file mode 100644
index 0000000..3e0559b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java
@@ -0,0 +1,24 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public class ConsolePortableHybrid extends HomeConsole
+{
+    void turnEmbeddedScreenOn()
+    {
+        
+    }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java
new file mode 100644
index 0000000..6bc19ec
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java
@@ -0,0 +1,31 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class ConstantBinaryExpression implements BinaryExpression
+{
+    private final boolean value;
+    
+    public ConstantBinaryExpression(boolean value) 
+    {
+        this.value = value;
+    }
+
+    @Override
+    public boolean evaluate()
+    {
+        return value;
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java
new file mode 100644
index 0000000..ca0cad1
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record ConstantIntExpression(int value) implements IntExpression
+{
+    @Override
+    public int evaluate()
+    {
+        return value;
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java
new file mode 100644
index 0000000..6df55ae
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java
@@ -0,0 +1,23 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public non-sealed abstract class CoolingMachine extends Appliance 
+{
+    public CoolingMachine(String name)
+    {
+        super(name);
+    }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java
new file mode 100644
index 0000000..eae1a6b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java
@@ -0,0 +1,23 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class Freezer extends CoolingMachine
+{
+    public Freezer()
+    {
+        super("Freezer");
+    }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java
new file mode 100644
index 0000000..6179de3
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java
@@ -0,0 +1,24 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public class HomeConsole implements Videogame
+{
+    void turnConnectedTVOn()
+    {
+        
+    }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java
new file mode 100644
index 0000000..5538728
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java
@@ -0,0 +1,20 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public sealed interface IntExpression permits ConstantIntExpression, PlusExpression, SquareExpression
+{
+    int evaluate();
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java
new file mode 100644
index 0000000..69ef256
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java
@@ -0,0 +1,20 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just used for tests
+ */
+public record IntTuple(int x, int y) 
+{
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java
new file mode 100644
index 0000000..206dd88
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java
@@ -0,0 +1,68 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class Java10And11ConcreteService
+{
+    
+    public Java10And11ConcreteService() throws Exception 
+    {
+        localVariableTypeInference();
+    }
+
+    /**
+     * Tests Local Variable Type Inference.
+     * Examples taken from https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html.
+     */
+    @SuppressWarnings("unused")
+    public void localVariableTypeInference() throws Exception 
+    {
+        
+        var url = new URL("http://www.oracle.com/"); 
+        var conn = url.openConnection(); 
+        var reader = new BufferedReader(
+            new InputStreamReader(conn.getInputStream()));
+        
+        reader.close();
+        
+        
+        var fileName = "LICENSE.txt";
+        var list = new ArrayList<String>();    // infers ArrayList<String>
+        var stream = list.stream();            // infers Stream<String>
+        var path = Paths.get(fileName);        // infers Path
+        var bytes = Files.readAllBytes(path);  // infers bytes[]
+
+        List<String> myList = Arrays.asList("a", "b", "c");
+        for (var element : myList) { element += " " ;}  // infers String
+        
+        for (var counter = 0; counter < 10; counter++) { Math.max(counter, counter); }   // infers int
+        
+        try (var input = 
+                new FileInputStream(fileName)) {}   // infers FileInputStream
+        
+        BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
+        biFunction = (var a, var b) -> a + b;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java
new file mode 100644
index 0000000..f91db00
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java
@@ -0,0 +1,54 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and the only Java language feature introduced in Java SE 10 and 11,
+ * local variable type inference (introduced in 10 and improved in 11).
+ */
+public class Java10And11NewFeatureTests 
+{
+    
+    public static class Java10And11Module 
+    {
+        public static void bind(ServiceBinder binder)
+        {
+            binder.bind(Java10And11Service.class, Java10And11ServiceImpl.class);
+            binder.bind(Java10And11ConcreteService.class);
+        }
+    }
+    
+    private Java10And11Service java10And11Service;
+    
+    private Java10And11ConcreteService java10And11ConcreteService;
+    
+    @BeforeSuite
+    public void setup() 
+    {
+        var registry = RegistryBuilder.buildAndStartupRegistry(Java10And11Module.class);
+        java10And11Service = registry.getService(Java10And11Service.class);
+        java10And11ConcreteService = registry.getService(Java10And11ConcreteService.class);
+    }
+
+    @Test
+    public void localVariableTypeInference() throws Exception 
+    {
+        java10And11Service.localVariableTypeInference();
+        java10And11ConcreteService.localVariableTypeInference();;
+    }
+    
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java
new file mode 100644
index 0000000..b68e29e
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java
@@ -0,0 +1,17 @@
+// Licensed 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.tapestry5.ioc.services;
+
+public interface Java10And11Service 
+{
+    void localVariableTypeInference() throws Exception;
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java
new file mode 100644
index 0000000..1fdccfd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java
@@ -0,0 +1,69 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class Java10And11ServiceImpl implements Java10And11Service 
+{
+    
+    public Java10And11ServiceImpl() throws Exception 
+    {
+        localVariableTypeInference();
+    }
+
+    /**
+     * Tests Local Variable Type Inference.
+     * Examples taken from https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html.
+     */
+    @SuppressWarnings("unused")
+    @Override
+    public void localVariableTypeInference() throws Exception 
+    {
+        
+        var url = new URL("http://www.oracle.com/"); 
+        var conn = url.openConnection(); 
+        var reader = new BufferedReader(
+            new InputStreamReader(conn.getInputStream()));
+        
+        reader.close();
+        
+        
+        var fileName = "LICENSE.txt";
+        var list = new ArrayList<String>();    // infers ArrayList<String>
+        var stream = list.stream();            // infers Stream<String>
+        var path = Paths.get(fileName);        // infers Path
+        var bytes = Files.readAllBytes(path);  // infers bytes[]
+
+        List<String> myList = Arrays.asList("a", "b", "c");
+        for (var element : myList) { element += " " ;}  // infers String
+        
+        for (var counter = 0; counter < 10; counter++) { Math.max(counter, counter); }   // infers int
+        
+        try (var input = 
+                new FileInputStream(fileName)) {}   // infers FileInputStream
+        
+        BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
+        biFunction = (var a, var b) -> a + b;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java
new file mode 100644
index 0000000..38eb3c5
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java
@@ -0,0 +1,71 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.time.LocalDate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java12And13ConcreteService
+{
+    
+    private static final String DAY_OF_WEEK_STRING = "Work!";
+    private static final String WEEKEND_STRING = "Rest!";
+    private static final Logger LOGGER = LoggerFactory.getLogger(Java12And13ServiceImpl.class);
+    
+    public Java12And13ConcreteService()
+    {
+        textBlocks();
+        switchExpressions();
+    }
+
+    /**
+     * Tests Text Blocks
+     * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+     */
+    public void textBlocks() 
+    {
+        String string = """
+                <html>
+                    <body>
+                        <p>Hello, Tapestry world!>/p>
+                    </body>
+                </html>
+                """;
+        LOGGER.info("Text block: " + string);
+    }
+
+    /**
+     * Tests Switch Expressions
+     * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+     */
+    public void switchExpressions() 
+    {
+        LocalDate date = LocalDate.now();
+        String string = switch(date.getDayOfWeek())
+        {
+            case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> 
+            {
+                LOGGER.info(DAY_OF_WEEK_STRING);
+                yield DAY_OF_WEEK_STRING;
+            }
+            default -> 
+            {
+                LOGGER.info(WEEKEND_STRING);
+                yield WEEKEND_STRING;
+            }
+        };
+        LOGGER.info("Result: " + string);
+    }
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java
new file mode 100644
index 0000000..051b586
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java
@@ -0,0 +1,69 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and the Java language features introduced in Java SE 12 and 13,
+ * switch expressiosn and text blocks.
+ */
+public class Java12And13NewFeatureTests 
+{
+    
+    public static class Java12And13Module 
+    {
+        public static void bind(ServiceBinder binder)
+        {
+            binder.bind(Java12And13Service.class, Java12And13ServiceImpl.class);
+            binder.bind(Java12And13ConcreteService.class);
+        }
+    }
+    
+    private Java12And13Service java12And13Service;
+    
+    private Java12And13ConcreteService java12And13ConcreteService;
+    
+    @BeforeSuite
+    public void setup() 
+    {
+        var registry = RegistryBuilder.buildAndStartupRegistry(Java12And13Module.class);
+        java12And13Service = registry.getService(Java12And13Service.class);
+        java12And13ConcreteService = registry.getService(Java12And13ConcreteService.class);
+    }
+
+    /**
+     * Tests Text Blocks
+     * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+     */
+    @Test
+    public void textBlocks() throws Exception 
+    {
+        java12And13Service.textBlocks();
+        java12And13ConcreteService.textBlocks();
+    }
+
+    /**
+     * Tests Switch Expressions
+     * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+     */
+    @Test
+    public void switchExpressions() throws Exception 
+    {
+        java12And13Service.switchExpressions();
+        java12And13ConcreteService.switchExpressions();
+    }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java
new file mode 100644
index 0000000..0c97386
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java
@@ -0,0 +1,28 @@
+// Licensed 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.tapestry5.ioc.services;
+
+public interface Java12And13Service 
+{
+
+    /**
+     * Tests Text Blocks
+     * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+     */
+    void textBlocks();
+    
+    /**
+     * Tests Switch Expressions
+     * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+     */
+    void switchExpressions();
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java
new file mode 100644
index 0000000..76f22cd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java
@@ -0,0 +1,69 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.time.LocalDate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java12And13ServiceImpl implements Java12And13Service 
+{
+    
+    private static final String DAY_OF_WEEK_STRING = "Work!";
+    private static final String WEEKEND_STRING = "Rest!";
+    private static final Logger LOGGER = LoggerFactory.getLogger(Java12And13ServiceImpl.class);
+    
+    public Java12And13ServiceImpl()
+    {
+        textBlocks();
+        switchExpressions();
+    }
+
+    /**
+     * Tests Text Blocks
+     * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+     */
+    @Override
+    public void textBlocks() 
+    {
+        String string = """
+                <html>
+                    <body>
+                        <p>Hello, Tapestry world!>/p>
+                    </body>
+                </html>
+                """;
+        LOGGER.info("Text block: " + string);
+    }
+
+    @Override
+    public void switchExpressions() 
+    {
+        LocalDate date = LocalDate.now();
+        String string = switch(date.getDayOfWeek())
+        {
+            case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> 
+            {
+                LOGGER.info(DAY_OF_WEEK_STRING);
+                yield DAY_OF_WEEK_STRING;
+            }
+            default -> 
+            {
+                LOGGER.info(WEEKEND_STRING);
+                yield WEEKEND_STRING;
+            }
+        };
+        LOGGER.info("Result: " + string);
+    }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java
new file mode 100644
index 0000000..8c99405
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java
@@ -0,0 +1,73 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public class Java14ConcreteService
+{
+    
+    public Java14ConcreteService()
+    {
+        patternMatchingForTheInstanceOfOperator();
+        records();
+        localRecord();  
+    }
+
+    /**
+     * For testing Pattern Matching for the instanceof Operator
+     * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+     */
+    public void patternMatchingForTheInstanceOfOperator() 
+    {
+        handleVideogame(new HomeConsole());
+        handleVideogame(new ConsolePortableHybrid());
+    }
+    
+    @SuppressWarnings("preview")
+    private void handleVideogame(Videogame videogame)
+    {
+        if (videogame instanceof HomeConsole homeConsole)
+        {
+            homeConsole.turnConnectedTVOn();
+        }
+        if (videogame instanceof ConsolePortableHybrid hybrid)
+        {
+            hybrid.turnEmbeddedScreenOn();
+        }
+    }
+
+    /**
+     * For testing Records
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public IntTuple records() 
+    {
+        return new IntTuple(1, 1);
+    }
+    
+    /**
+     * For testing Local Record Classes
+     * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+     */
+    public void localRecord() 
+    {
+        
+        record Local(String name)
+        {
+            
+        }
+        
+        LoggerFactory.getLogger(this.getClass()).info("Local record " + new Local("test"));
+    }
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java
new file mode 100644
index 0000000..35746c2
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java
@@ -0,0 +1,101 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and Java language features introduced in Java SE 14: pattern matching for the
+ * <code>instanceof</code> operator and records.
+ */
+public class Java14NewFeatureTests 
+{
+    
+    private Registry registry;
+    
+    public static class Java14Module 
+    {
+        public static void bind(ServiceBinder binder)
+        {
+            binder.bind(Java14Service.class, Java14ServiceImpl.class);
+            binder.bind(Java14ConcreteService.class);
+        }
+        public static IntTuple buildIntTuple()
+        {
+            return new IntTuple(10, 15);
+        }
+    }
+    
+    private Java14Service java14Service;
+    
+    private Java14ConcreteService java14ConcreteService;
+    
+    @BeforeSuite
+    public void setup() 
+    {
+        registry = RegistryBuilder.buildAndStartupRegistry(Java14Module.class);
+        java14Service = registry.getService(Java14Service.class);
+        java14ConcreteService = registry.getService(Java14ConcreteService.class);
+    }
+
+    /**
+     * For testing Pattern Matching for the instanceof Operator
+     * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+     */
+    @Test
+    public void patternMatchingForTheInstanceOfOperator() 
+    {
+        java14Service.patternMatchingForTheInstanceOfOperator();
+        java14ConcreteService.patternMatchingForTheInstanceOfOperator();
+    }
+
+    /**
+     * For testing Records
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    @Test
+    public void records() 
+    {
+        process(java14Service.records());
+        process(java14ConcreteService.records());
+    }
+    
+    /**
+     * For testing services whose type is a record.
+     */
+    @Test
+    public void recordsAsServices()
+    {
+        process(registry.getService(IntTuple.class));
+    }
+
+    private void process(IntTuple record) {
+        LoggerFactory.getLogger(this.getClass()).info("Record: " + record);
+    }
+    
+    /**
+     * For testing Local Record Classes
+     * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+     */
+    @Test
+    public void localRecord() 
+    {
+        java14Service.localRecord();
+        java14ConcreteService.localRecord();
+    }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java
new file mode 100644
index 0000000..a0096c2
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java
@@ -0,0 +1,37 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public interface Java14Service 
+{
+    
+    /**
+     * For testing Pattern Matching for the instanceof Operator
+     * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+     */
+    void patternMatchingForTheInstanceOfOperator();
+    
+    /**
+     * For testing Records
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    IntTuple records();
+    
+    /**
+     * For testing Local Record Classes
+     * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+     */
+    void localRecord();    
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java
new file mode 100644
index 0000000..a35b10f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java
@@ -0,0 +1,71 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public class Java14ServiceImpl implements Java14Service 
+{
+    
+    public Java14ServiceImpl() 
+    {
+        patternMatchingForTheInstanceOfOperator();
+        records();
+    }
+
+    /**
+     * For testing Pattern Matching for the instanceof Operator
+     * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+     */
+    public void patternMatchingForTheInstanceOfOperator() 
+    {
+        handleVideogame(new HomeConsole());
+        handleVideogame(new ConsolePortableHybrid());
+    }
+    
+    @SuppressWarnings("preview")
+    private void handleVideogame(Videogame videogame)
+    {
+        if (videogame instanceof HomeConsole homeConsole)
+        {
+            homeConsole.turnConnectedTVOn();
+        }
+        if (videogame instanceof ConsolePortableHybrid hybrid)
+        {
+            hybrid.turnEmbeddedScreenOn();
+        }
+    }
+
+    /**
+     * For testing Records
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public IntTuple records() 
+    {
+        return new IntTuple(1, 1);
+    }
+    
+    /**
+     * For testing Local Record Classes
+     * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+     */
+    public void localRecord() {
+        
+        record Local(String name)
+        {
+            
+        }
+        LoggerFactory.getLogger(this.getClass()).info("Local record " + new Local("test"));
+    }
+
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java
new file mode 100644
index 0000000..f76a77f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java
@@ -0,0 +1,63 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java15To17ConcreteService
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17ConcreteService.class);
+    
+    public Java15To17ConcreteService() 
+    {
+        recordsWithoutInterfacesNorRecords();
+    }
+
+    /**
+     * Tests Record Classes, regular ones (no interfaces, no records).
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithoutInterfacesNorRecords() 
+    {
+        Appliance appliance = new WashingMachine();
+        CoolingMachine coolingMachine = new Freezer();
+        coolingMachine = new Refrigerator();
+        LOGGER.info("Appliance: " + appliance.getName());
+        LOGGER.info("Cooling machine: " + coolingMachine.getName());
+    }
+    
+    /**
+     * Tests Record Classes with interfaces but no records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesButNotRecords() 
+    {
+        BinaryExpression expression = new AndExpression(
+                new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true)),
+                new AndExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true))
+        );
+        LOGGER.info("Binary expression: " + expression.evaluate());
+    }
+
+    /**
+     * Tests Record Classes with interfaces and records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesAndRecords() 
+    {
+        IntExpression expression = new SquareExpression(
+                new PlusExpression(new ConstantIntExpression(2), new ConstantIntExpression(3)));
+        LOGGER.info("Int expression: " + expression.evaluate());
+    }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java
new file mode 100644
index 0000000..f8fb60d
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java
@@ -0,0 +1,169 @@
+// Licensed 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 To
+// limitations under the License.
+package org.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.annotations.Marker;
+import org.apache.tapestry5.ioc.annotations.Primary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC To the only Java language feature introduced in Java SE 10 To 11,
+ * local variable type inference (introduced in 10 To improved in 11).
+ */
+public class Java15To17NewFeatureTests 
+{
+    
+    // TODO: test ChainBuilder and company
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17NewFeatureTests.class);
+    
+    public static class Java15To17Module 
+    {
+        
+        public static void bind(ServiceBinder binder)
+        {
+            binder.bind(Java15To17Service.class, Java15To17ServiceImpl.class);
+            binder.bind(Java15To17ConcreteService.class);
+        }
+        
+        // Two service for each case of sealed classes (no record and no interface, interface 
+        // and no record, interface and record): one for the sealed class itself,
+        // another for the subclasses.
+        // 
+        @Marker(Primary.class)        
+        public static Appliance buildAppliance()
+        {
+            return new Freezer();
+        }
+
+        public static Refrigerator buildRefridgerator()
+        {
+            return new Refrigerator();
+        }
+
+        @Marker(Primary.class)
+        public static BinaryExpression buildBinaryExpression()
+        {
+            return new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true));
+        }
+        
+        public static ConstantBinaryExpression buildConstantBinaryExpression()
+        {
+            return new ConstantBinaryExpression(true);
+        }
+
+        @Marker(Primary.class)
+        public static IntExpression buildIntExpression()
+        {
+            return new SquareExpression(new ConstantIntExpression(42));
+        }
+        
+        public static ConstantIntExpression buildConstantIntExpression()
+        {
+            return new ConstantIntExpression(3);
+        }
+
+    }
+    
+    private Java15To17Service java15To17Service;
+    
+    private Java15To17ConcreteService java15To17ConcreteService;
+
+    private Registry registry;
+    
+    @BeforeSuite
+    public void setup() 
+    {
+        registry = RegistryBuilder.buildAndStartupRegistry(Java15To17Module.class);
+        java15To17Service = registry.getService(Java15To17Service.class);
+        java15To17ConcreteService = registry.getService(Java15To17ConcreteService.class);
+    }
+
+    /**
+     * Tests Record Classes, regular ones (no interfaces, no records).
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    @Test
+    public void recordsWithoutInterfacesNorRecords()
+    {
+        java15To17Service.recordsWithoutInterfacesNorRecords();
+        java15To17ConcreteService.recordsWithoutInterfacesNorRecords();
+    }
+    
+    /**
+     * Tests Record Classes with interfaces but no records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    @Test
+    public void recordsWithInterfacesButNotRecords()
+    {
+        java15To17Service.recordsWithInterfacesButNotRecords();
+        java15To17ConcreteService.recordsWithInterfacesButNotRecords();
+    }
+
+    /**
+     * Tests Record Classes with interfaces and records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    @Test
+    public void recordsWithInterfacesAndRecords()
+    {
+        java15To17Service.recordsWithInterfacesAndRecords();
+        java15To17ConcreteService.recordsWithInterfacesAndRecords();
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void recordsWithoutInterfacesNorRecords_service_sealedClass()
+    {
+        LOGGER.info(registry.getService(Appliance.class, Primary.class).getName());
+    }
+    
+    @Test
+    public void recordsWithoutInterfacesNorRecords_service_subclass()
+    {
+        LOGGER.info(registry.getService(Refrigerator.class).getName());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void recordsWithInterfacesButNotRecords_service_sealedClass()
+    {
+        LOGGER.info(String.valueOf(registry.getService(BinaryExpression.class, Primary.class).evaluate()));
+    }
+    
+    @Test
+    public void recordsWithInterfacesButNotRecords_service_subclass()
+    {
+        LOGGER.info(String.valueOf(registry.getService(ConstantBinaryExpression.class).evaluate()));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void recordsWithInterfacesAndRecords_service_sealedClass()
+    {
+        LOGGER.info(String.valueOf(registry.getService(IntExpression.class, Primary.class).evaluate()));
+    }
+    
+    @Test
+    public void recordsWithInterfacesAndRecords_service_subclass()
+    {
+        LOGGER.info(String.valueOf(registry.getService(ConstantIntExpression.class).evaluate()));
+    }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java
new file mode 100644
index 0000000..d18f8b3
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java
@@ -0,0 +1,34 @@
+// Licensed 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.tapestry5.ioc.services;
+
+public interface Java15To17Service 
+{
+    /**
+     * Tests Record Classes, regular ones (no interfaces, no records).
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithoutInterfacesNorRecords();  
+    
+    /**
+     * Tests Record Classes with interfaces but no records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesButNotRecords();
+
+    /**
+     * Tests Record Classes with interfaces and records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesAndRecords();
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java
new file mode 100644
index 0000000..942aecd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java
@@ -0,0 +1,66 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java15To17ServiceImpl implements Java15To17Service
+{
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17ServiceImpl.class);
+    
+    public Java15To17ServiceImpl() 
+    {
+        recordsWithInterfacesAndRecords();
+        recordsWithInterfacesButNotRecords();
+        recordsWithoutInterfacesNorRecords();
+    }
+    
+    /**
+     * Tests Record Classes, regular ones (no interfaces, no records).
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithoutInterfacesNorRecords()
+    {
+        Appliance appliance = new WashingMachine();
+        CoolingMachine coolingMachine = new Freezer();
+        coolingMachine = new Refrigerator();
+        LOGGER.info("Appliance: " + appliance.getName());
+        LOGGER.info("Cooling machine: " + coolingMachine.getName());
+    }
+    
+    /**
+     * Tests Record Classes with interfaces but no records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesButNotRecords()
+    {
+        BinaryExpression expression = new AndExpression(
+                new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true)),
+                new AndExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true))
+        );
+        LOGGER.info("Binary expression: " + expression.evaluate());
+    }
+
+    /**
+     * Tests Record Classes with interfaces and records.
+     * https://docs.oracle.com/en/java/javase/17/language/records.html
+     */
+    public void recordsWithInterfacesAndRecords()
+    {
+        IntExpression expression = new SquareExpression(
+                new PlusExpression(new ConstantIntExpression(2), new ConstantIntExpression(3)));
+        LOGGER.info("Int expression: " + expression.evaluate());
+    }
+    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java
new file mode 100644
index 0000000..921a60e
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java
@@ -0,0 +1,69 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+public class Java9ConcreteService
+{
+    
+    public Java9ConcreteService()
+    {
+        tryWithResources();
+        callSafeVarArgs();
+        diamondSyntaxAndAnonymousInnerClasses();
+    }
+    
+    /**
+     * For resting More Concise try-with-resources Statements
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-A920DB06-0FD1-4F9C-8A9A-15FC979D5DA3
+     */
+    public void tryWithResources()
+    {
+        Formatter formatter = new Formatter();
+        try (formatter) 
+        {
+            formatter.format("nothing");
+        }
+    }
+    
+    public void callSafeVarArgs()
+    {
+        safeVarags("1");
+    }
+    
+    /**
+     * For testing @SafeVarargs Annotation Allowed on Proviate Instance Methods.
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+     */
+    @SafeVarargs
+    private void safeVarags( String...strings)
+    {
+        
+    }
+    
+    /**
+     * For testing Diamond Syntax and Anonymous Inner Classes
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-0DF89F53-9232-44E3-80A4-48DD0C2CF359
+     */
+    private class Inner
+    {
+        
+    }
+    
+    private void diamondSyntaxAndAnonymousInnerClasses() {
+        List<Inner> list = new ArrayList<>();
+        list.add(new Inner());
+    }    
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java
new file mode 100644
index 0000000..f2ddcc6
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java
@@ -0,0 +1,60 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and Java language features introduced in Java SE 9.
+ */
+public class Java9NewFeatureTests 
+{
+    
+    public static class Java9Module 
+    {
+        public static void bind(ServiceBinder binder)
+        {
+            binder.bind(Java9Service.class, Java9ServiceImpl.class);
+            binder.bind(Java9ConcreteService.class);
+        }
+    }
+    
+    private Java9Service java9Service;
+    
+    private Java9ConcreteService java9ConcreteService;
+    
+    @BeforeSuite
+    public void setup() 
+    {
+        var registry = RegistryBuilder.buildAndStartupRegistry(Java9Module.class);
+        java9Service = registry.getService(Java9Service.class);
+        java9ConcreteService = registry.getService(Java9ConcreteService.class);
+    }
+
+    @Test
+    public void safevarargs() 
+    {
+        java9Service.callSafeVarArgs();
+        java9ConcreteService.callSafeVarArgs();
+    }
+    
+    @Test
+    public void tryWithResources() 
+    {
+        java9Service.tryWithResources();
+        java9ConcreteService.tryWithResources();
+    }
+    
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java
new file mode 100644
index 0000000..15b3f77
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java
@@ -0,0 +1,33 @@
+// Licensed 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.tapestry5.ioc.services;
+
+public interface Java9Service 
+{
+    
+    void tryWithResources();
+    
+    void callSafeVarArgs();
+
+    default void defaultMethod()
+    {
+        privateMethodInInterface();
+    }
+    
+    /**
+     * For testing Support for Private Interface Methods
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+     */
+    private void privateMethodInInterface()
+    {
+    }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java
new file mode 100644
index 0000000..3fd2117
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java
@@ -0,0 +1,70 @@
+// Licensed 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.tapestry5.ioc.services;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+public class Java9ServiceImpl implements Java9Service 
+{
+    
+    public Java9ServiceImpl() 
+    {
+        diamondSyntaxAndAnonymousInnerClasses();
+        tryWithResources();
+        callSafeVarArgs();
+    }
+    
+    /**
+     * For testing More Concise try-with-resources Statements
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-A920DB06-0FD1-4F9C-8A9A-15FC979D5DA3
+     */
+    public void tryWithResources()
+    {
+        Formatter formatter = new Formatter();
+        try (formatter) 
+        {
+            formatter.format("nothing");
+        }
+    }
+    
+    public void callSafeVarArgs()
+    {
+        safeVarags("1");
+    }
+    
+    /**
+     * For testing @SafeVarargs Annotation Allowed on Proviate Instance Methods.
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+     */
+    @SafeVarargs
+    private void safeVarags(String...strings)
+    {
+        
+    }
+    
+    /**
+     * For testing Diamond Syntax and Anonymous Inner Classes
+     * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-0DF89F53-9232-44E3-80A4-48DD0C2CF359
+     */
+    private class Inner
+    {
+        
+    }
+    
+    private void diamondSyntaxAndAnonymousInnerClasses() {
+        List<Inner> list = new ArrayList<>();
+        list.add(new Inner());
+    }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java
new file mode 100644
index 0000000..632136b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java
@@ -0,0 +1,32 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class OrExpression implements BinaryExpression
+{
+    private final BinaryExpression operand1, operand2;
+    
+    public OrExpression(BinaryExpression operand1, BinaryExpression operand2) {
+        super();
+        this.operand1 = operand1;
+        this.operand2 = operand2;
+    }
+
+    @Override
+    public boolean evaluate()
+    {
+        return operand1.evaluate() || operand2.evaluate();
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java
new file mode 100644
index 0000000..7538231
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record PlusExpression(IntExpression operand1, IntExpression operand2) implements IntExpression
+{
+    @Override
+    public int evaluate()
+    {
+        return operand1.evaluate() + operand2.evaluate();
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java
new file mode 100644
index 0000000..1f02a6b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java
@@ -0,0 +1,23 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class Refrigerator extends CoolingMachine
+{
+    public Refrigerator()
+    {
+        super("Refrigerator");
+    }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java
new file mode 100644
index 0000000..94a5787
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record SquareExpression (IntExpression expression) implements IntExpression
+{
+    @Override
+    public int evaluate()
+    {
+        return expression.evaluate() * expression.evaluate();
+    }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java
new file mode 100644
index 0000000..c0a4e1d
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java
@@ -0,0 +1,19 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public interface Videogame 
+{
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java
new file mode 100644
index 0000000..df6dd5f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java
@@ -0,0 +1,23 @@
+// Licensed 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.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class WashingMachine extends Appliance 
+{
+    public WashingMachine()
+    {
+        super("Washing machine");
+    }
+}
\ No newline at end of file