diff --git a/aggregate/pom.xml b/aggregate/pom.xml
index 1fc1a84e..6da5ee89 100644
--- a/aggregate/pom.xml
+++ b/aggregate/pom.xml
@@ -5,7 +5,7 @@
pom
20220608.2-SNAPSHOT
- ../parent
+ ..
com.googlecode.owasp-java-html-sanitizer
parent
20220608.2-SNAPSHOT
@@ -13,7 +13,8 @@
..
- ../html-types
- ../parent
+ ../java8-shim
+ ../java10-shim
+ ../owasp-java-html-sanitizer
diff --git a/empiricism/pom.xml b/empiricism/pom.xml
index 2a5d1c8f..0679df4b 100644
--- a/empiricism/pom.xml
+++ b/empiricism/pom.xml
@@ -5,7 +5,7 @@
20220608.2-SNAPSHOT
jar
- ../parent
+ ..
com.googlecode.owasp-java-html-sanitizer
parent
20220608.2-SNAPSHOT
diff --git a/html-types/pom.xml b/html-types/pom.xml
index 97f9eb19..c3fdcc79 100644
--- a/html-types/pom.xml
+++ b/html-types/pom.xml
@@ -5,7 +5,7 @@
20220608.2-SNAPSHOT
bundle
- ../parent
+ ..
com.googlecode.owasp-java-html-sanitizer
parent
20220608.2-SNAPSHOT
diff --git a/java10-shim/pom.xml b/java10-shim/pom.xml
new file mode 100644
index 00000000..21b96c35
--- /dev/null
+++ b/java10-shim/pom.xml
@@ -0,0 +1,41 @@
+
+ 4.0.0
+ java10-shim
+ jar
+
+ ..
+ com.googlecode.owasp-java-html-sanitizer
+ parent
+ 20220608.2-SNAPSHOT
+
+
+ Java 10 Shim
+
+ Provides an implementation of java8-shim that interoperates with
+ Java >= 10 idioms for immutable collections.
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 10
+
+
+
+
+
+
+
+ com.googlecode.owasp-java-html-sanitizer
+ java8-shim
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/java10-shim/src/main/java/org/owasp/shim/ForJava9AndLater.java b/java10-shim/src/main/java/org/owasp/shim/ForJava9AndLater.java
new file mode 100644
index 00000000..78de9746
--- /dev/null
+++ b/java10-shim/src/main/java/org/owasp/shim/ForJava9AndLater.java
@@ -0,0 +1,67 @@
+package org.owasp.shim;
+
+import java.util.*;
+
+@SuppressWarnings("Since15") // We're compiling two versions to handle @since problems.
+final class ForJava9AndLater extends Java8Shim {
+
+ @Override public List listOf() {
+ return List.of();
+ }
+
+ @Override public List listOf(T a) {
+ return List.of(a);
+ }
+
+ @Override public List listOf(T a, T b) {
+ return List.of(a, b);
+ }
+
+ @Override public List listOf(T a, T b, T c) {
+ return List.of(a, b, c);
+ }
+
+ @Override public List listOf(T... els) {
+ return List.of(els);
+ }
+
+ @Override public List listCopyOf(Collection extends T> c) {
+ return List.copyOf(c);
+ }
+
+ @Override public Map mapCopyOf(Map extends K, ? extends V> m) {
+ return Map.copyOf(m);
+ }
+
+ @Override public Map.Entry mapEntry(K key, V value) {
+ return Map.entry(key, value);
+ }
+
+ @Override public Map mapOfEntries(Map.Entry... entries) {
+ return Map.ofEntries(entries);
+ }
+
+ @Override public Set setOf() {
+ return Set.of();
+ }
+
+ @Override public Set setOf(T a) {
+ return Set.of(a);
+ }
+
+ @Override public Set setOf(T a, T b) {
+ return Set.of(a, b);
+ }
+
+ @Override public Set setOf(T a, T b, T c) {
+ return Set.of(a, b, c);
+ }
+
+ @Override public Set setOf(T... els) {
+ return Set.of(els);
+ }
+
+ @Override public Set setCopyOf(Collection extends T> c) {
+ return Set.copyOf(c);
+ }
+}
diff --git a/java8-shim/pom.xml b/java8-shim/pom.xml
new file mode 100644
index 00000000..c414253b
--- /dev/null
+++ b/java8-shim/pom.xml
@@ -0,0 +1,38 @@
+
+ 4.0.0
+ java8-shim
+ jar
+
+ ..
+ com.googlecode.owasp-java-html-sanitizer
+ parent
+ 20220608.2-SNAPSHOT
+
+
+ Java 8 Shim
+
+ Backports @since Java 9 collection factories like List.of onto
+ Java8 in a way that uses the real ones where available, falls back
+ to a conforming implementation on Java8 and JIT compiles well.
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+
+
+
+
+
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/java8-shim/src/main/java/org/owasp/shim/ForJava8.java b/java8-shim/src/main/java/org/owasp/shim/ForJava8.java
new file mode 100644
index 00000000..34805a77
--- /dev/null
+++ b/java8-shim/src/main/java/org/owasp/shim/ForJava8.java
@@ -0,0 +1,256 @@
+package org.owasp.shim;
+
+import java.util.*;
+
+class ForJava8 extends Java8Shim {
+ @Override public List listOf() {
+ return ImmutableListShim.empty();
+ }
+
+ @Override public List listOf(T a) {
+ return new ImmutableListShim<>(Collections.singletonList(a));
+ }
+
+ @Override public List listOf(T a, T b) {
+ ArrayList ls = new ArrayList<>(2);
+ ls.add(a);
+ ls.add(b);
+ return new ImmutableListShim<>(ls);
+ }
+
+ @Override public List listOf(T a, T b, T c) {
+ ArrayList ls = new ArrayList<>(3);
+ ls.add(a);
+ ls.add(b);
+ ls.add(c);
+ return new ImmutableListShim<>(ls);
+ }
+
+ @Override public List listOf(T... els) {
+ return new ImmutableListShim<>(Arrays.asList(els));
+ }
+
+ @SuppressWarnings("unchecked") // Immutable collections aren't invariant
+ @Override public List listCopyOf(Collection extends T> c) {
+ if (c instanceof ImmutableListShim) {
+ return (ImmutableListShim) c;
+ }
+ return new ImmutableListShim<>(new ArrayList<>(c));
+ }
+
+ @SuppressWarnings("unchecked") // Immutable collections aren't invariant
+ @Override public Map mapCopyOf(Map extends K, ? extends V> m) {
+ if (m instanceof ImmutableMapShim) {
+ return (ImmutableMapShim) m;
+ }
+ return new ImmutableMapShim<>(new LinkedHashMap<>(m));
+ }
+
+ @Override public Map.Entry mapEntry(K key, V value) {
+ return new ImmutableEntryShim<>(key, value);
+ }
+
+ @Override public Map mapOfEntries(Map.Entry... entries) {
+ Map m = new LinkedHashMap<>(entries.length);
+ for (Map.Entry e : entries) {
+ m.put(e.getKey(), e.getValue());
+ }
+ return new ImmutableMapShim<>(m);
+ }
+
+ @Override public Set setOf() {
+ return new ImmutableSetShim<>(Collections.emptySet());
+ }
+
+ @Override public Set setOf(T a) {
+ return new ImmutableSetShim<>(Collections.singleton(a));
+ }
+
+ @Override public Set setOf(T a, T b) {
+ LinkedHashSet ls = new LinkedHashSet<>(2);
+ ls.add(a);
+ ls.add(b);
+ return new ImmutableSetShim<>(ls);
+ }
+
+ @Override public Set setOf(T a, T b, T c) {
+ LinkedHashSet ls = new LinkedHashSet<>(3);
+ ls.add(a);
+ ls.add(b);
+ ls.add(c);
+ return new ImmutableSetShim<>(ls);
+ }
+
+ @Override public Set setOf(T... els) {
+ return new ImmutableSetShim<>(new LinkedHashSet<>(Arrays.asList(els)));
+ }
+
+ @SuppressWarnings("unchecked") // Immutable collections aren't invariant
+ @Override public Set setCopyOf(Collection extends T> c) {
+ if (c instanceof ImmutableSetShim) {
+
+ return (ImmutableSetShim) c;
+ }
+ return new ImmutableSetShim<>(new LinkedHashSet<>(c));
+ }
+
+ private static final class ImmutableListShim extends AbstractList {
+ private final List underlying;
+
+ ImmutableListShim(List underlying) {
+ this.underlying = underlying;
+ }
+
+ @Override
+ public T get(int index) {
+ return underlying.get(index);
+ }
+
+ @Override
+ public int size() {
+ return underlying.size();
+ }
+
+ private static final ImmutableListShim