diff --git a/api/src/main/java/jakarta/json/AbstractJsonArray.java b/api/src/main/java/jakarta/json/AbstractJsonArray.java
new file mode 100644
index 00000000..857c70c8
--- /dev/null
+++ b/api/src/main/java/jakarta/json/AbstractJsonArray.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package jakarta.json;
+
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+/**
+ * Abstract JsonArray which delegates calls to an encapsulated
+ * JsonArray delegate.
+ *
+ * Extend this class when you want to implement your own JsonArray,
+ * based on another JsonArray, without having to reimplement
+ * all the methods yourself.
+ *
+ * Example usage: Encapsulation of utility method.
+ *
+ * //Instead of this utility method which pollutes the code and
+ * //will probably never be tested...
+ *
+ * public static JsonArray buildArray(JsonValue... values) {
+ * List<JsonValue> values = Arrays.asList(values);
+ * JsonArray array = values.stream().collect(
+ * JsonCollectors.toJsonArray()
+ * );
+ * }
+ *
+ * //There should be the following class. Logic becomes
+ * //decoupled, encapsulated and testable.
+ *
+ * public final class CollectedJsonArray extends AbstractJsonArray {
+ *
+ * public CollectedJsonArry(final JsonValue... values) {
+ * this(Arrays.asList(values));
+ * }
+ *
+ * public CollectedJsonArray(final List<JsonValue> values) {
+ * super(
+ * values.stream().collect(
+ * JsonCollectors.toJsonArray()
+ * )
+ * );
+ * }
+ * }
+ *
+ */
+public abstract class AbstractJsonArray implements JsonArray {
+
+ /**
+ * JsonArray delegate. You may also think of it as the
+ * "backbone" of your JsonArray implementation.
+ */
+ private final JsonArray delegate;
+
+ /**
+ * Constructor.
+ * @param delegate Delegate JsonArray. The "backbone" of your
+ * implementation.
+ */
+ public AbstractJsonArray(final JsonArray delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public JsonObject getJsonObject(int index) {
+ return this.delegate.getJsonObject(index);
+ }
+
+ @Override
+ public JsonArray getJsonArray(int index) {
+ return this.delegate.getJsonArray(index);
+ }
+
+ @Override
+ public JsonNumber getJsonNumber(int index) {
+ return this.delegate.getJsonNumber(index);
+ }
+
+ @Override
+ public JsonString getJsonString(int index) {
+ return this.delegate.getJsonString(index);
+ }
+
+ @Override
+ public
+ * //Container which is also a JsonObject.
+ * public interface Container extends JsonObject {
+ * //...other methods of Container.
+ * }
+ *
+ * public final class JsonContainer implements Container extends AbstractJsonObject {
+ *
+ * public ContainerImpl(final JsonObject representation) {
+ * super(representation);
+ * }
+ * }
+ *
+ */
+public abstract class AbstractJsonObject implements JsonObject {
+
+ /**
+ * JsonObject delegate. You may also think of it as the
+ * "backbone" of your JsonObject implementation.
+ */
+ private final JsonObject delegate;
+
+ /**
+ * Constructor.
+ * @param delegate Delegate JsonObject. The "backbone" of your
+ * implementation.
+ */
+ public AbstractJsonObject(final JsonObject delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public JsonArray getJsonArray(String name) {
+ return this.delegate.getJsonArray(name);
+ }
+
+ @Override
+ public JsonObject getJsonObject(String name) {
+ return this.delegate.getJsonObject(name);
+ }
+
+ @Override
+ public JsonNumber getJsonNumber(String name) {
+ return this.delegate.getJsonNumber(name);
+ }
+
+ @Override
+ public JsonString getJsonString(String name) {
+ return this.delegate.getJsonString(name);
+ }
+
+ @Override
+ public String getString(String name) {
+ return this.delegate.getString(name);
+ }
+
+ @Override
+ public String getString(String name, String defaultValue) {
+ return this.delegate.getString(name, defaultValue);
+ }
+
+ @Override
+ public int getInt(String name) {
+ return this.delegate.getInt(name);
+ }
+
+ @Override
+ public int getInt(String name, int defaultValue) {
+ return this.delegate.getInt(name, defaultValue);
+ }
+
+ @Override
+ public boolean getBoolean(String name) {
+ return this.delegate.getBoolean(name);
+ }
+
+ @Override
+ public boolean getBoolean(String name, boolean defaultValue) {
+ return this.delegate.getBoolean(name, defaultValue);
+ }
+
+ @Override
+ public boolean isNull(String name) {
+ return this.delegate.isNull(name);
+ }
+
+ @Override
+ public JsonValue getValue(String jsonPointer) {
+ return this.delegate.getValue(jsonPointer);
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return this.delegate.getValueType();
+ }
+
+ @Override
+ public JsonObject asJsonObject() {
+ return this.delegate.asJsonObject();
+ }
+
+ @Override
+ public JsonArray asJsonArray() {
+ return this.delegate.asJsonArray();
+ }
+
+ @Override
+ public String toString() {
+ return this.delegate.toString();
+ }
+
+ @Override
+ public int size() {
+ return this.delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.delegate.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return this.delegate.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return this.delegate.containsValue(value);
+ }
+
+ @Override
+ public JsonValue get(Object key) {
+ return this.delegate.get(key);
+ }
+
+ @Override
+ public JsonValue put(String key, JsonValue value) {
+ return this.delegate.put(key, value);
+ }
+
+ @Override
+ public JsonValue remove(Object key) {
+ return this.delegate.remove(key);
+ }
+
+ @Override
+ public void putAll(Map extends String, ? extends JsonValue> m) {
+ this.delegate.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ this.delegate.clear();
+ }
+
+ @Override
+ public Set