Minor refactoring: Extract common logic and move classes
diff --git a/src/main/java/org/apache/groovy/util/concurrent/LazyInitializable.java b/src/main/java/org/apache/groovy/util/concurrent/LazyInitializable.java
new file mode 100644
index 0000000..7374d37
--- /dev/null
+++ b/src/main/java/org/apache/groovy/util/concurrent/LazyInitializable.java
@@ -0,0 +1,56 @@
+/*
+ *  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.groovy.util.concurrent;
+
+/**
+ *  A {@code LazyInitializable} is an object that can be initialized lazily.
+ *  Note: the instance field {@code initialized} of sub-class should be {@code volatile} to avoid JVM instructions re-ordering
+ *
+ * @since 3.0.0
+ */
+public interface LazyInitializable {
+    default void lazyInit() {
+        if (isInitialized()) return;
+
+        synchronized (this) {
+            if (isInitialized()) return;
+            doInit();
+            setInitialized(true);
+        }
+    }
+
+    /**
+     * do initialization
+     */
+    void doInit();
+
+    /**
+     * Check if the object is initialized.
+     *
+     * @return the check result
+     */
+    boolean isInitialized();
+
+    /**
+     * Mark the object initialized.
+     *
+     * @param initialized initialized
+     */
+    void setInitialized(boolean initialized);
+}
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
similarity index 96%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
index 522b3f6..db1c6c2 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import org.apache.groovy.util.ObjectHolder;
 
@@ -47,9 +47,9 @@
 
 import static java.util.Collections.unmodifiableMap;
 import static java.util.Collections.unmodifiableSet;
-import static org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.IDLE;
-import static org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.PROCESSING;
-import static org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.REQUIRED;
+import static org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.IDLE;
+import static org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.PROCESSING;
+import static org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap.DrainStatus.REQUIRED;
 
 /**
  * A hash table supporting full concurrency of retrievals, adjustable expected
@@ -70,7 +70,7 @@
  * modifies its weight requires that an update operation is performed on the
  * map.
  * <p>
- * An {@link EvictionListener} may be supplied for notification when an entry
+ * An {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener} may be supplied for notification when an entry
  * is evicted from the map. This listener is invoked on a caller's thread and
  * will not block other threads from operating on the map. An implementation
  * should be aware that the caller's thread will not expect long execution
@@ -205,7 +205,7 @@
 
   // These fields provide support for notifying a listener.
   final Queue<Node<K, V>> pendingNotifications;
-  final EvictionListener<K, V> listener;
+  final org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener<K, V> listener;
 
   transient Set<K> keySet;
   transient Collection<V> values;
@@ -1024,7 +1024,7 @@
     try {
       drainBuffers();
 
-      final int initialCapacity = (weigher == Weighers.entrySingleton())
+      final int initialCapacity = (weigher == org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.entrySingleton())
           ? Math.min(limit, (int) weightedSize())
           : 16;
       final Set<K> keys = new LinkedHashSet<K>(initialCapacity);
@@ -1134,7 +1134,7 @@
     try {
       drainBuffers();
 
-      final int initialCapacity = (weigher == Weighers.entrySingleton())
+      final int initialCapacity = (weigher == org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.entrySingleton())
           ? Math.min(limit, (int) weightedSize())
           : 16;
       final Map<K, V> map = new LinkedHashMap<K, V>(initialCapacity);
@@ -1510,7 +1510,7 @@
   }
 
   /** A listener that ignores all notifications. */
-  enum DiscardingListener implements EvictionListener<Object, Object> {
+  enum DiscardingListener implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener<Object, Object> {
     INSTANCE;
 
     @Override public void onEviction(Object key, Object value) {}
@@ -1537,7 +1537,7 @@
    */
   static final class SerializationProxy<K, V> implements Serializable {
     final EntryWeigher<? super K, ? super V> weigher;
-    final EvictionListener<K, V> listener;
+    final org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener<K, V> listener;
     final int concurrencyLevel;
     final Map<K, V> data;
     final long capacity;
@@ -1581,7 +1581,7 @@
     static final int DEFAULT_CONCURRENCY_LEVEL = 16;
     static final int DEFAULT_INITIAL_CAPACITY = 16;
 
-    EvictionListener<K, V> listener;
+    org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener<K, V> listener;
     EntryWeigher<? super K, ? super V> weigher;
 
     int concurrencyLevel;
@@ -1591,10 +1591,10 @@
     @SuppressWarnings("unchecked")
     public Builder() {
       capacity = -1;
-      weigher = Weighers.entrySingleton();
+      weigher = org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.entrySingleton();
       initialCapacity = DEFAULT_INITIAL_CAPACITY;
       concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL;
-      listener = (EvictionListener<K, V>) DiscardingListener.INSTANCE;
+      listener = (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener<K, V>) DiscardingListener.INSTANCE;
     }
 
     /**
@@ -1664,9 +1664,9 @@
      * @throws NullPointerException if the weigher is null
      */
     public Builder<K, V> weigher(Weigher<? super V> weigher) {
-      this.weigher = (weigher == Weighers.singleton())
-          ? Weighers.<K, V>entrySingleton()
-          : new BoundedEntryWeigher<K, V>(Weighers.asEntryWeigher(weigher));
+      this.weigher = (weigher == org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.singleton())
+          ? org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.<K, V>entrySingleton()
+          : new BoundedEntryWeigher<K, V>(org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.asEntryWeigher(weigher));
       return this;
     }
 
@@ -1679,7 +1679,7 @@
      * @throws NullPointerException if the weigher is null
      */
     public Builder<K, V> weigher(EntryWeigher<? super K, ? super V> weigher) {
-      this.weigher = (weigher == Weighers.entrySingleton())
+      this.weigher = (weigher == org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers.entrySingleton())
           ? Weighers.<K, V>entrySingleton()
           : new BoundedEntryWeigher<K, V>(weigher);
       return this;
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EntryWeigher.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EntryWeigher.java
similarity index 94%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EntryWeigher.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EntryWeigher.java
index c4c34d6..df62fc2 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EntryWeigher.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EntryWeigher.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import javax.annotation.concurrent.ThreadSafe;
 
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EvictionListener.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EvictionListener.java
similarity index 96%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EvictionListener.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EvictionListener.java
index 74646c4..d8c5b10 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/EvictionListener.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/EvictionListener.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import javax.annotation.concurrent.ThreadSafe;
 
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/LinkedDeque.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/LinkedDeque.java
similarity index 99%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/LinkedDeque.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/LinkedDeque.java
index 27d8613..d2d3004 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/LinkedDeque.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/LinkedDeque.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import javax.annotation.concurrent.NotThreadSafe;
 import java.util.AbstractCollection;
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weigher.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weigher.java
similarity index 94%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weigher.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weigher.java
index ef3910d..96515ea 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weigher.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weigher.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import javax.annotation.concurrent.ThreadSafe;
 
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weighers.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weighers.java
similarity index 72%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weighers.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weighers.java
index 1fb654a..10c2fa1 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/Weighers.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/Weighers.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
 
 import java.io.Serializable;
 import java.util.Collection;
@@ -21,10 +21,8 @@
 import java.util.Map;
 import java.util.Set;
 
-import static org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap.checkNotNull;
-
 /**
- * A common set of {@link Weigher} and {@link EntryWeigher} implementations.
+ * A common set of {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher} and {@link EntryWeigher} implementations.
  *
  * @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
  *      http://code.google.com/p/concurrentlinkedhashmap/</a>
@@ -43,7 +41,7 @@
    * @return A entry weigher view of the specified weigher.
    */
   public static <K, V> EntryWeigher<K, V> asEntryWeigher(
-      final Weigher<? super V> weigher) {
+      final org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super V> weigher) {
     return (weigher == singleton())
         ? Weighers.<K, V>entrySingleton()
         : new EntryWeigherView<K, V>(weigher);
@@ -69,8 +67,8 @@
    * @return A weigher where a value takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <V> Weigher<V> singleton() {
-    return (Weigher<V>) SingletonWeigher.INSTANCE;
+  public static <V> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<V> singleton() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<V>) SingletonWeigher.INSTANCE;
   }
 
   /**
@@ -88,7 +86,7 @@
    *
    * @return A weigher where each byte takes one unit of capacity.
    */
-  public static Weigher<byte[]> byteArray() {
+  public static org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<byte[]> byteArray() {
     return ByteArrayWeigher.INSTANCE;
   }
 
@@ -107,8 +105,8 @@
    * @return A weigher where each element takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <E> Weigher<? super Iterable<E>> iterable() {
-    return (Weigher<Iterable<E>>) (Weigher<?>) IterableWeigher.INSTANCE;
+  public static <E> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super Iterable<E>> iterable() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Iterable<E>>) (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<?>) IterableWeigher.INSTANCE;
   }
 
   /**
@@ -125,8 +123,8 @@
    * @return A weigher where each element takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <E> Weigher<? super Collection<E>> collection() {
-    return (Weigher<Collection<E>>) (Weigher<?>) CollectionWeigher.INSTANCE;
+  public static <E> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super Collection<E>> collection() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Collection<E>>) (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<?>) CollectionWeigher.INSTANCE;
   }
 
   /**
@@ -143,8 +141,8 @@
    * @return A weigher where each element takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <E> Weigher<? super List<E>> list() {
-    return (Weigher<List<E>>) (Weigher<?>) ListWeigher.INSTANCE;
+  public static <E> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super List<E>> list() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<List<E>>) (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<?>) ListWeigher.INSTANCE;
   }
 
   /**
@@ -161,8 +159,8 @@
    * @return A weigher where each element takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <E> Weigher<? super Set<E>> set() {
-    return (Weigher<Set<E>>) (Weigher<?>) SetWeigher.INSTANCE;
+  public static <E> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super Set<E>> set() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Set<E>>) (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<?>) SetWeigher.INSTANCE;
   }
 
   /**
@@ -179,16 +177,16 @@
    * @return A weigher where each entry takes one unit of capacity.
    */
   @SuppressWarnings({"cast", "unchecked"})
-  public static <A, B> Weigher<? super Map<A, B>> map() {
-    return (Weigher<Map<A, B>>) (Weigher<?>) MapWeigher.INSTANCE;
+  public static <A, B> org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super Map<A, B>> map() {
+    return (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Map<A, B>>) (org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<?>) MapWeigher.INSTANCE;
   }
 
   static final class EntryWeigherView<K, V> implements EntryWeigher<K, V>, Serializable {
     static final long serialVersionUID = 1;
-    final Weigher<? super V> weigher;
+    final org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super V> weigher;
 
-    EntryWeigherView(Weigher<? super V> weigher) {
-      checkNotNull(weigher);
+    EntryWeigherView(org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<? super V> weigher) {
+      ConcurrentLinkedHashMap.checkNotNull(weigher);
       this.weigher = weigher;
     }
 
@@ -207,7 +205,7 @@
     }
   }
 
-  enum SingletonWeigher implements Weigher<Object> {
+  enum SingletonWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Object> {
     INSTANCE;
 
     @Override
@@ -216,7 +214,7 @@
     }
   }
 
-  enum ByteArrayWeigher implements Weigher<byte[]> {
+  enum ByteArrayWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<byte[]> {
     INSTANCE;
 
     @Override
@@ -225,7 +223,7 @@
     }
   }
 
-  enum IterableWeigher implements Weigher<Iterable<?>> {
+  enum IterableWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Iterable<?>> {
     INSTANCE;
 
     @Override
@@ -241,7 +239,7 @@
     }
   }
 
-  enum CollectionWeigher implements Weigher<Collection<?>> {
+  enum CollectionWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Collection<?>> {
     INSTANCE;
 
     @Override
@@ -250,7 +248,7 @@
     }
   }
 
-  enum ListWeigher implements Weigher<List<?>> {
+  enum ListWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<List<?>> {
     INSTANCE;
 
     @Override
@@ -259,7 +257,7 @@
     }
   }
 
-  enum SetWeigher implements Weigher<Set<?>> {
+  enum SetWeigher implements org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher<Set<?>> {
     INSTANCE;
 
     @Override
diff --git a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/package-info.java b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/package-info.java
similarity index 78%
rename from src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/package-info.java
rename to src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/package-info.java
index 665de2e..b20fbd3 100644
--- a/src/main/java/org/apache/groovy/util/concurrentlinkedhashmap/package-info.java
+++ b/src/main/java/org/apache/groovy/util/concurrent/concurrentlinkedhashmap/package-info.java
@@ -18,19 +18,19 @@
  * This package contains an implementation of a bounded
  * {@link java.util.concurrent.ConcurrentMap} data structure.
  * <p>
- * {@link org.apache.groovy.util.concurrentlinkedhashmap.Weigher} is a simple interface
+ * {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weigher} is a simple interface
  * for determining how many units of capacity an entry consumes. Depending on
  * which concrete Weigher class is used, an entry may consume a different amount
  * of space within the cache. The
- * {@link org.apache.groovy.util.concurrentlinkedhashmap.Weighers} class provides
+ * {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.Weighers} class provides
  * utility methods for obtaining the most common kinds of implementations.
  * <p>
- * {@link org.apache.groovy.util.concurrentlinkedhashmap.EvictionListener} provides the
+ * {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.EvictionListener} provides the
  * ability to be notified when an entry is evicted from the map. An eviction
  * occurs when the entry was automatically removed due to the map exceeding a
  * capacity threshold. It is not called when an entry was explicitly removed.
  * <p>
- * The {@link org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap}
+ * The {@link org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap}
  * class supplies an efficient, scalable, thread-safe, bounded map. As with the
  * <tt>Java Collections Framework</tt> the "Concurrent" prefix is used to
  * indicate that the map is not governed by a single exclusion lock.
@@ -38,4 +38,4 @@
  * @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
  *      http://code.google.com/p/concurrentlinkedhashmap/</a>
  */
-package org.apache.groovy.util.concurrentlinkedhashmap;
+package org.apache.groovy.util.concurrent.concurrentlinkedhashmap;
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
index 437f972..311579c 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.ast.decompiled;
 
 import groovy.lang.groovydoc.Groovydoc;
+import org.apache.groovy.util.concurrent.LazyInitializable;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -41,7 +42,7 @@
  *
  * @since 2.5.9
  */
-class LazyConstructorNode extends ConstructorNode {
+class LazyConstructorNode extends ConstructorNode implements LazyInitializable {
     private final Supplier<ConstructorNode> constructorNodeSupplier;
     private ConstructorNode delegate;
 
@@ -51,269 +52,271 @@
         this.constructorNodeSupplier = constructorNodeSupplier;
     }
 
-    private void init() {
-        if (initialized) return;
+    @Override
+    public void doInit() {
+        delegate = constructorNodeSupplier.get();
 
-        synchronized (this) {
-            if (initialized) return;
-            delegate = constructorNodeSupplier.get();
-
-            ClassNode declaringClass = super.getDeclaringClass();
-            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
-
-            initialized = true;
-        }
+        ClassNode declaringClass = super.getDeclaringClass();
+        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
+    }
+    @Override
+    public boolean isInitialized() {
+        return initialized;
+    }
+    @Override
+    public void setInitialized(boolean initialized) {
+        this.initialized = initialized;
     }
 
     @Override
     public boolean firstStatementIsSpecialConstructorCall() {
-        init();
+        lazyInit();
         return delegate.firstStatementIsSpecialConstructorCall();
     }
 
     @Override
     public String getTypeDescriptor() {
-        init();
+        lazyInit();
         return delegate.getTypeDescriptor();
     }
 
     @Override
     public Statement getCode() {
-        init();
+        lazyInit();
         return delegate.getCode();
     }
 
     @Override
     public void setCode(Statement code) {
-        init();
+        lazyInit();
         delegate.setCode(code);
     }
 
     @Override
     public int getModifiers() {
-        init();
+        lazyInit();
         return delegate.getModifiers();
     }
 
     @Override
     public void setModifiers(int modifiers) {
-        init();
+        lazyInit();
         delegate.setModifiers(modifiers);
     }
 
     @Override
     public String getName() {
-        init();
+        lazyInit();
         return delegate.getName();
     }
 
     @Override
     public Parameter[] getParameters() {
-        init();
+        lazyInit();
         return delegate.getParameters();
     }
 
     @Override
     public void setParameters(Parameter[] parameters) {
-        init();
+        lazyInit();
         delegate.setParameters(parameters);
     }
 
     @Override
     public boolean hasDefaultValue() {
-        init();
+        lazyInit();
         return delegate.hasDefaultValue();
     }
 
     @Override
     public ClassNode getReturnType() {
-        init();
+        lazyInit();
         return delegate.getReturnType();
     }
 
     @Override
     public void setReturnType(ClassNode returnType) {
-        init();
+        lazyInit();
         delegate.setReturnType(returnType);
     }
 
     @Override
     public boolean isDynamicReturnType() {
-        init();
+        lazyInit();
         return delegate.isDynamicReturnType();
     }
 
     @Override
     public boolean isVoidMethod() {
-        init();
+        lazyInit();
         return delegate.isVoidMethod();
     }
 
     @Override
     public VariableScope getVariableScope() {
-        init();
+        lazyInit();
         return delegate.getVariableScope();
     }
 
     @Override
     public void setVariableScope(VariableScope variableScope) {
-        init();
+        lazyInit();
         delegate.setVariableScope(variableScope);
     }
 
     @Override
     public boolean isAbstract() {
-        init();
+        lazyInit();
         return delegate.isAbstract();
     }
 
     @Override
     public boolean isDefault() {
-        init();
+        lazyInit();
         return delegate.isDefault();
     }
 
     @Override
     public boolean isFinal() {
-        init();
+        lazyInit();
         return delegate.isFinal();
     }
 
     @Override
     public boolean isStatic() {
-        init();
+        lazyInit();
         return delegate.isStatic();
     }
 
     @Override
     public boolean isPublic() {
-        init();
+        lazyInit();
         return delegate.isPublic();
     }
 
     @Override
     public boolean isPrivate() {
-        init();
+        lazyInit();
         return delegate.isPrivate();
     }
 
     @Override
     public boolean isProtected() {
-        init();
+        lazyInit();
         return delegate.isProtected();
     }
 
     @Override
     public boolean isPackageScope() {
-        init();
+        lazyInit();
         return delegate.isPackageScope();
     }
 
     @Override
     public ClassNode[] getExceptions() {
-        init();
+        lazyInit();
         return delegate.getExceptions();
     }
 
     @Override
     public Statement getFirstStatement() {
-        init();
+        lazyInit();
         return delegate.getFirstStatement();
     }
 
     @Override
     public GenericsType[] getGenericsTypes() {
-        init();
+        lazyInit();
         return delegate.getGenericsTypes();
     }
 
     @Override
     public void setGenericsTypes(GenericsType[] genericsTypes) {
-        init();
+        lazyInit();
         delegate.setGenericsTypes(genericsTypes);
     }
 
     @Override
     public boolean hasAnnotationDefault() {
-        init();
+        lazyInit();
         return delegate.hasAnnotationDefault();
     }
 
     @Override
     public void setAnnotationDefault(boolean hasDefaultValue) {
-        init();
+        lazyInit();
         delegate.setAnnotationDefault(hasDefaultValue);
     }
 
     @Override
     public boolean isScriptBody() {
-        init();
+        lazyInit();
         return delegate.isScriptBody();
     }
 
     @Override
     public void setIsScriptBody() {
-        init();
+        lazyInit();
         delegate.setIsScriptBody();
     }
 
     @Override
     public boolean isStaticConstructor() {
-        init();
+        lazyInit();
         return delegate.isStaticConstructor();
     }
 
     @Override
     public boolean isSyntheticPublic() {
-        init();
+        lazyInit();
         return delegate.isSyntheticPublic();
     }
 
     @Override
     public void setSyntheticPublic(boolean syntheticPublic) {
-        init();
+        lazyInit();
         delegate.setSyntheticPublic(syntheticPublic);
     }
 
     @Override
     public String getText() {
-        init();
+        lazyInit();
         return delegate.getText();
     }
 
     @Override
     public String toString() {
-        init();
+        lazyInit();
         return delegate.toString();
     }
 
     @Override
     public List<AnnotationNode> getAnnotations() {
-        init();
+        lazyInit();
         return delegate.getAnnotations();
     }
 
     @Override
     public List<AnnotationNode> getAnnotations(ClassNode type) {
-        init();
+        lazyInit();
         return delegate.getAnnotations(type);
     }
 
     @Override
     public void addAnnotation(AnnotationNode annotation) {
-        init();
+        lazyInit();
         delegate.addAnnotation(annotation);
     }
 
     @Override
     public void addAnnotations(List<AnnotationNode> annotations) {
-        init();
+        lazyInit();
         delegate.addAnnotations(annotations);
     }
 
     @Override
     public ClassNode getDeclaringClass() {
-        init();
+        lazyInit();
         return delegate.getDeclaringClass();
     }
 
@@ -324,169 +327,169 @@
 
     @Override
     public Groovydoc getGroovydoc() {
-        init();
+        lazyInit();
         return delegate.getGroovydoc();
     }
 
     @Override
     public AnnotatedNode getInstance() {
-        init();
+        lazyInit();
         return delegate.getInstance();
     }
 
     @Override
     public boolean hasNoRealSourcePosition() {
-        init();
+        lazyInit();
         return delegate.hasNoRealSourcePosition();
     }
 
     @Override
     public void setHasNoRealSourcePosition(boolean hasNoRealSourcePosition) {
-        init();
+        lazyInit();
         delegate.setHasNoRealSourcePosition(hasNoRealSourcePosition);
     }
 
     @Override
     public boolean isSynthetic() {
-        init();
+        lazyInit();
         return delegate.isSynthetic();
     }
 
     @Override
     public void setSynthetic(boolean synthetic) {
-        init();
+        lazyInit();
         delegate.setSynthetic(synthetic);
     }
 
     @Override
     public void visit(GroovyCodeVisitor visitor) {
-        init();
+        lazyInit();
         delegate.visit(visitor);
     }
 
     @Override
     public int getLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLineNumber();
     }
 
     @Override
     public void setLineNumber(int lineNumber) {
-        init();
+        lazyInit();
         delegate.setLineNumber(lineNumber);
     }
 
     @Override
     public int getColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getColumnNumber();
     }
 
     @Override
     public void setColumnNumber(int columnNumber) {
-        init();
+        lazyInit();
         delegate.setColumnNumber(columnNumber);
     }
 
     @Override
     public int getLastLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLastLineNumber();
     }
 
     @Override
     public void setLastLineNumber(int lastLineNumber) {
-        init();
+        lazyInit();
         delegate.setLastLineNumber(lastLineNumber);
     }
 
     @Override
     public int getLastColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getLastColumnNumber();
     }
 
     @Override
     public void setLastColumnNumber(int lastColumnNumber) {
-        init();
+        lazyInit();
         delegate.setLastColumnNumber(lastColumnNumber);
     }
 
     @Override
     public void setSourcePosition(ASTNode node) {
-        init();
+        lazyInit();
         delegate.setSourcePosition(node);
     }
 
     @Override
     public void copyNodeMetaData(ASTNode other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public Map<?, ?> getMetaDataMap() {
-        init();
+        lazyInit();
         return delegate.getMetaDataMap();
     }
 
     @Override
     public void setMetaDataMap(Map<?, ?> metaDataMap) {
-        init();
+        lazyInit();
         delegate.setMetaDataMap(metaDataMap);
     }
 
     @Override
     public int hashCode() {
-        init();
+        lazyInit();
         return delegate.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
-        init();
+        lazyInit();
         return delegate.equals(obj);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key, Function<?, ? extends T> valFn) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key, valFn);
     }
 
     @Override
     public void copyNodeMetaData(NodeMetaDataHandler other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public void setNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         delegate.setNodeMetaData(key, value);
     }
 
     @Override
     public Object putNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         return delegate.putNodeMetaData(key, value);
     }
 
     @Override
     public void removeNodeMetaData(Object key) {
-        init();
+        lazyInit();
         delegate.removeNodeMetaData(key);
     }
 
     @Override
     public Map<?, ?> getNodeMetaData() {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData();
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
index 0f0aa37..286e3a7 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.ast.decompiled;
 
 import groovy.lang.groovydoc.Groovydoc;
+import org.apache.groovy.util.concurrent.LazyInitializable;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -38,7 +39,7 @@
  *
  * @since 2.5.9
  */
-class LazyFieldNode extends FieldNode {
+class LazyFieldNode extends FieldNode implements LazyInitializable {
     private final Supplier<FieldNode> fieldNodeSupplier;
     private FieldNode delegate;
 
@@ -51,32 +52,34 @@
         this.name = name;
     }
 
-    private void init() {
-        if (initialized) return;
+    @Override
+    public void doInit() {
+        delegate = fieldNodeSupplier.get();
 
-        synchronized (this) {
-            if (initialized) return;
-            delegate = fieldNodeSupplier.get();
+        ClassNode declaringClass = super.getDeclaringClass();
+        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
 
-            ClassNode declaringClass = super.getDeclaringClass();
-            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
-
-            ClassNode owner = super.getOwner();
-            if (null != owner) delegate.setOwner(owner);
-
-            initialized = true;
-        }
+        ClassNode owner = super.getOwner();
+        if (null != owner) delegate.setOwner(owner);
+    }
+    @Override
+    public boolean isInitialized() {
+        return initialized;
+    }
+    @Override
+    public void setInitialized(boolean initialized) {
+        this.initialized = initialized;
     }
 
     @Override
     public Expression getInitialExpression() {
-        init();
+        lazyInit();
         return delegate.getInitialExpression();
     }
 
     @Override
     public int getModifiers() {
-        init();
+        lazyInit();
         return delegate.getModifiers();
     }
 
@@ -87,85 +90,85 @@
 
     @Override
     public ClassNode getType() {
-        init();
+        lazyInit();
         return delegate.getType();
     }
 
     @Override
     public void setType(ClassNode type) {
-        init();
+        lazyInit();
         delegate.setType(type);
     }
 
     @Override
     public ClassNode getOwner() {
-        init();
+        lazyInit();
         return delegate.getOwner();
     }
 
     @Override
     public boolean isHolder() {
-        init();
+        lazyInit();
         return delegate.isHolder();
     }
 
     @Override
     public void setHolder(boolean holder) {
-        init();
+        lazyInit();
         delegate.setHolder(holder);
     }
 
     @Override
     public boolean isDynamicTyped() {
-        init();
+        lazyInit();
         return delegate.isDynamicTyped();
     }
 
     @Override
     public void setModifiers(int modifiers) {
-        init();
+        lazyInit();
         delegate.setModifiers(modifiers);
     }
 
     @Override
     public boolean isStatic() {
-        init();
+        lazyInit();
         return delegate.isStatic();
     }
 
     @Override
     public boolean isEnum() {
-        init();
+        lazyInit();
         return delegate.isEnum();
     }
 
     @Override
     public boolean isFinal() {
-        init();
+        lazyInit();
         return delegate.isFinal();
     }
 
     @Override
     public boolean isVolatile() {
-        init();
+        lazyInit();
         return delegate.isVolatile();
     }
 
     @Override
     public boolean isPublic() {
-        init();
+        lazyInit();
         return delegate.isPublic();
     }
 
     @Override
     public boolean isProtected() {
-        init();
+        lazyInit();
         return delegate.isProtected();
     }
 
     @Override
     public boolean isPrivate() {
-        init();
+        lazyInit();
         return delegate.isPrivate();
     }
 
@@ -176,87 +179,87 @@
 
     @Override
     public boolean hasInitialExpression() {
-        init();
+        lazyInit();
         return delegate.hasInitialExpression();
     }
 
     @Override
     public boolean isInStaticContext() {
-        init();
+        lazyInit();
         return delegate.isInStaticContext();
     }
 
     @Override
     public Expression getInitialValueExpression() {
-        init();
+        lazyInit();
         return delegate.getInitialValueExpression();
     }
 
     @Override
     public void setInitialValueExpression(Expression initialValueExpression) {
-        init();
+        lazyInit();
         delegate.setInitialValueExpression(initialValueExpression);
     }
 
     @Override
     @Deprecated
     public boolean isClosureSharedVariable() {
-        init();
+        lazyInit();
         return delegate.isClosureSharedVariable();
     }
 
     @Override
     @Deprecated
     public void setClosureSharedVariable(boolean inClosure) {
-        init();
+        lazyInit();
         delegate.setClosureSharedVariable(inClosure);
     }
 
     @Override
     public ClassNode getOriginType() {
-        init();
+        lazyInit();
         return delegate.getOriginType();
     }
 
     @Override
     public void setOriginType(ClassNode cn) {
-        init();
+        lazyInit();
         delegate.setOriginType(cn);
     }
 
     @Override
     public void rename(String name) {
-        init();
+        lazyInit();
         delegate.rename(name);
     }
 
     @Override
     public List<AnnotationNode> getAnnotations() {
-        init();
+        lazyInit();
         return delegate.getAnnotations();
     }
 
     @Override
     public List<AnnotationNode> getAnnotations(ClassNode type) {
-        init();
+        lazyInit();
         return delegate.getAnnotations(type);
     }
 
     @Override
     public void addAnnotation(AnnotationNode annotation) {
-        init();
+        lazyInit();
         delegate.addAnnotation(annotation);
     }
 
     @Override
     public void addAnnotations(List<AnnotationNode> annotations) {
-        init();
+        lazyInit();
         delegate.addAnnotations(annotations);
     }
 
     @Override
     public ClassNode getDeclaringClass() {
-        init();
+        lazyInit();
         return delegate.getDeclaringClass();
     }
 
@@ -267,175 +270,175 @@
 
     @Override
     public Groovydoc getGroovydoc() {
-        init();
+        lazyInit();
         return delegate.getGroovydoc();
     }
 
     @Override
     public AnnotatedNode getInstance() {
-        init();
+        lazyInit();
         return delegate.getInstance();
     }
 
     @Override
     public boolean hasNoRealSourcePosition() {
-        init();
+        lazyInit();
         return delegate.hasNoRealSourcePosition();
     }
 
     @Override
     public void setHasNoRealSourcePosition(boolean hasNoRealSourcePosition) {
-        init();
+        lazyInit();
         delegate.setHasNoRealSourcePosition(hasNoRealSourcePosition);
     }
 
     @Override
     public boolean isSynthetic() {
-        init();
+        lazyInit();
         return delegate.isSynthetic();
     }
 
     @Override
     public void setSynthetic(boolean synthetic) {
-        init();
+        lazyInit();
         delegate.setSynthetic(synthetic);
     }
 
     @Override
     public void visit(GroovyCodeVisitor visitor) {
-        init();
+        lazyInit();
         delegate.visit(visitor);
     }
 
     @Override
     public String getText() {
-        init();
+        lazyInit();
         return delegate.getText();
     }
 
     @Override
     public int getLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLineNumber();
     }
 
     @Override
     public void setLineNumber(int lineNumber) {
-        init();
+        lazyInit();
         delegate.setLineNumber(lineNumber);
     }
 
     @Override
     public int getColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getColumnNumber();
     }
 
     @Override
     public void setColumnNumber(int columnNumber) {
-        init();
+        lazyInit();
         delegate.setColumnNumber(columnNumber);
     }
 
     @Override
     public int getLastLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLastLineNumber();
     }
 
     @Override
     public void setLastLineNumber(int lastLineNumber) {
-        init();
+        lazyInit();
         delegate.setLastLineNumber(lastLineNumber);
     }
 
     @Override
     public int getLastColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getLastColumnNumber();
     }
 
     @Override
     public void setLastColumnNumber(int lastColumnNumber) {
-        init();
+        lazyInit();
         delegate.setLastColumnNumber(lastColumnNumber);
     }
 
     @Override
     public void setSourcePosition(ASTNode node) {
-        init();
+        lazyInit();
         delegate.setSourcePosition(node);
     }
 
     @Override
     public void copyNodeMetaData(ASTNode other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public Map<?, ?> getMetaDataMap() {
-        init();
+        lazyInit();
         return delegate.getMetaDataMap();
     }
 
     @Override
     public void setMetaDataMap(Map<?, ?> metaDataMap) {
-        init();
+        lazyInit();
         delegate.setMetaDataMap(metaDataMap);
     }
 
     @Override
     public int hashCode() {
-        init();
+        lazyInit();
         return delegate.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
-        init();
+        lazyInit();
         return delegate.equals(obj);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key, Function<?, ? extends T> valFn) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key, valFn);
     }
 
     @Override
     public void copyNodeMetaData(NodeMetaDataHandler other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public void setNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         delegate.setNodeMetaData(key, value);
     }
 
     @Override
     public Object putNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         return delegate.putNodeMetaData(key, value);
     }
 
     @Override
     public void removeNodeMetaData(Object key) {
-        init();
+        lazyInit();
         delegate.removeNodeMetaData(key);
     }
 
     @Override
     public Map<?, ?> getNodeMetaData() {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData();
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
index 0874ea4..c85e3b5 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.ast.decompiled;
 
 import groovy.lang.groovydoc.Groovydoc;
+import org.apache.groovy.util.concurrent.LazyInitializable;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -41,7 +42,7 @@
  *
  * @since 2.5.9
  */
-class LazyMethodNode extends MethodNode {
+class LazyMethodNode extends MethodNode implements LazyInitializable {
     private final Supplier<MethodNode> methodNodeSupplier;
     private MethodNode delegate;
 
@@ -54,47 +55,49 @@
         this.name = name;
     }
 
-    private void init() {
-        if (initialized) return;
+    @Override
+    public void doInit() {
+        delegate = methodNodeSupplier.get();
 
-        synchronized (this) {
-            if (initialized) return;
-            delegate = methodNodeSupplier.get();
-
-            ClassNode declaringClass = super.getDeclaringClass();
-            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
-
-            initialized = true;
-        }
+        ClassNode declaringClass = super.getDeclaringClass();
+        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
+    }
+    @Override
+    public boolean isInitialized() {
+        return initialized;
+    }
+    @Override
+    public void setInitialized(boolean initialized) {
+        this.initialized = initialized;
     }
 
     @Override
     public String getTypeDescriptor() {
-        init();
+        lazyInit();
         return delegate.getTypeDescriptor();
     }
 
     @Override
     public Statement getCode() {
-        init();
+        lazyInit();
         return delegate.getCode();
     }
 
     @Override
     public void setCode(Statement code) {
-        init();
+        lazyInit();
         delegate.setCode(code);
     }
 
     @Override
     public int getModifiers() {
-        init();
+        lazyInit();
         return delegate.getModifiers();
     }
 
     @Override
     public void setModifiers(int modifiers) {
-        init();
+        lazyInit();
         delegate.setModifiers(modifiers);
     }
 
@@ -105,211 +108,211 @@
 
     @Override
     public Parameter[] getParameters() {
-        init();
+        lazyInit();
         return delegate.getParameters();
     }
 
     @Override
     public void setParameters(Parameter[] parameters) {
-        init();
+        lazyInit();
         delegate.setParameters(parameters);
     }
 
     @Override
     public boolean hasDefaultValue() {
-        init();
+        lazyInit();
         return delegate.hasDefaultValue();
     }
 
     @Override
     public ClassNode getReturnType() {
-        init();
+        lazyInit();
         return delegate.getReturnType();
     }
 
     @Override
     public void setReturnType(ClassNode returnType) {
-        init();
+        lazyInit();
         delegate.setReturnType(returnType);
     }
 
     @Override
     public boolean isDynamicReturnType() {
-        init();
+        lazyInit();
         return delegate.isDynamicReturnType();
     }
 
     @Override
     public boolean isVoidMethod() {
-        init();
+        lazyInit();
         return delegate.isVoidMethod();
     }
 
     @Override
     public VariableScope getVariableScope() {
-        init();
+        lazyInit();
         return delegate.getVariableScope();
     }
 
     @Override
     public void setVariableScope(VariableScope variableScope) {
-        init();
+        lazyInit();
         delegate.setVariableScope(variableScope);
     }
 
     @Override
     public boolean isAbstract() {
-        init();
+        lazyInit();
         return delegate.isAbstract();
     }
 
     @Override
     public boolean isDefault() {
-        init();
+        lazyInit();
         return delegate.isDefault();
     }
 
     @Override
     public boolean isFinal() {
-        init();
+        lazyInit();
         return delegate.isFinal();
     }
 
     @Override
     public boolean isStatic() {
-        init();
+        lazyInit();
         return delegate.isStatic();
     }
 
     @Override
     public boolean isPublic() {
-        init();
+        lazyInit();
         return delegate.isPublic();
     }
 
     @Override
     public boolean isPrivate() {
-        init();
+        lazyInit();
         return delegate.isPrivate();
     }
 
     @Override
     public boolean isProtected() {
-        init();
+        lazyInit();
         return delegate.isProtected();
     }
 
     @Override
     public boolean isPackageScope() {
-        init();
+        lazyInit();
         return delegate.isPackageScope();
     }
 
     @Override
     public ClassNode[] getExceptions() {
-        init();
+        lazyInit();
         return delegate.getExceptions();
     }
 
     @Override
     public Statement getFirstStatement() {
-        init();
+        lazyInit();
         return delegate.getFirstStatement();
     }
 
     @Override
     public GenericsType[] getGenericsTypes() {
-        init();
+        lazyInit();
         return delegate.getGenericsTypes();
     }
 
     @Override
     public void setGenericsTypes(GenericsType[] genericsTypes) {
-        init();
+        lazyInit();
         delegate.setGenericsTypes(genericsTypes);
     }
 
     @Override
     public boolean hasAnnotationDefault() {
-        init();
+        lazyInit();
         return delegate.hasAnnotationDefault();
     }
 
     @Override
     public void setAnnotationDefault(boolean hasDefaultValue) {
-        init();
+        lazyInit();
         delegate.setAnnotationDefault(hasDefaultValue);
     }
 
     @Override
     public boolean isScriptBody() {
-        init();
+        lazyInit();
         return delegate.isScriptBody();
     }
 
     @Override
     public void setIsScriptBody() {
-        init();
+        lazyInit();
         delegate.setIsScriptBody();
     }
 
     @Override
     public boolean isStaticConstructor() {
-        init();
+        lazyInit();
         return delegate.isStaticConstructor();
     }
 
     @Override
     public boolean isSyntheticPublic() {
-        init();
+        lazyInit();
         return delegate.isSyntheticPublic();
     }
 
     @Override
     public void setSyntheticPublic(boolean syntheticPublic) {
-        init();
+        lazyInit();
         delegate.setSyntheticPublic(syntheticPublic);
     }
 
     @Override
     public String getText() {
-        init();
+        lazyInit();
         return delegate.getText();
     }
 
     @Override
     public String toString() {
-        init();
+        lazyInit();
         return delegate.toString();
     }
 
     @Override
     public List<AnnotationNode> getAnnotations() {
-        init();
+        lazyInit();
         return delegate.getAnnotations();
     }
 
     @Override
     public List<AnnotationNode> getAnnotations(ClassNode type) {
-        init();
+        lazyInit();
         return delegate.getAnnotations(type);
     }
 
     @Override
     public void addAnnotation(AnnotationNode annotation) {
-        init();
+        lazyInit();
         delegate.addAnnotation(annotation);
     }
 
     @Override
     public void addAnnotations(List<AnnotationNode> annotations) {
-        init();
+        lazyInit();
         delegate.addAnnotations(annotations);
     }
 
     @Override
     public ClassNode getDeclaringClass() {
-        init();
+        lazyInit();
         return delegate.getDeclaringClass();
     }
 
@@ -320,169 +323,169 @@
 
     @Override
     public Groovydoc getGroovydoc() {
-        init();
+        lazyInit();
         return delegate.getGroovydoc();
     }
 
     @Override
     public AnnotatedNode getInstance() {
-        init();
+        lazyInit();
         return delegate.getInstance();
     }
 
     @Override
     public boolean hasNoRealSourcePosition() {
-        init();
+        lazyInit();
         return delegate.hasNoRealSourcePosition();
     }
 
     @Override
     public void setHasNoRealSourcePosition(boolean hasNoRealSourcePosition) {
-        init();
+        lazyInit();
         delegate.setHasNoRealSourcePosition(hasNoRealSourcePosition);
     }
 
     @Override
     public boolean isSynthetic() {
-        init();
+        lazyInit();
         return delegate.isSynthetic();
     }
 
     @Override
     public void setSynthetic(boolean synthetic) {
-        init();
+        lazyInit();
         delegate.setSynthetic(synthetic);
     }
 
     @Override
     public void visit(GroovyCodeVisitor visitor) {
-        init();
+        lazyInit();
         delegate.visit(visitor);
     }
 
     @Override
     public int getLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLineNumber();
     }
 
     @Override
     public void setLineNumber(int lineNumber) {
-        init();
+        lazyInit();
         delegate.setLineNumber(lineNumber);
     }
 
     @Override
     public int getColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getColumnNumber();
     }
 
     @Override
     public void setColumnNumber(int columnNumber) {
-        init();
+        lazyInit();
         delegate.setColumnNumber(columnNumber);
     }
 
     @Override
     public int getLastLineNumber() {
-        init();
+        lazyInit();
         return delegate.getLastLineNumber();
     }
 
     @Override
     public void setLastLineNumber(int lastLineNumber) {
-        init();
+        lazyInit();
         delegate.setLastLineNumber(lastLineNumber);
     }
 
     @Override
     public int getLastColumnNumber() {
-        init();
+        lazyInit();
         return delegate.getLastColumnNumber();
     }
 
     @Override
     public void setLastColumnNumber(int lastColumnNumber) {
-        init();
+        lazyInit();
         delegate.setLastColumnNumber(lastColumnNumber);
     }
 
     @Override
     public void setSourcePosition(ASTNode node) {
-        init();
+        lazyInit();
         delegate.setSourcePosition(node);
     }
 
     @Override
     public void copyNodeMetaData(ASTNode other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public Map<?, ?> getMetaDataMap() {
-        init();
+        lazyInit();
         return delegate.getMetaDataMap();
     }
 
     @Override
     public void setMetaDataMap(Map<?, ?> metaDataMap) {
-        init();
+        lazyInit();
         delegate.setMetaDataMap(metaDataMap);
     }
 
     @Override
     public int hashCode() {
-        init();
+        lazyInit();
         return delegate.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
-        init();
+        lazyInit();
         return delegate.equals(obj);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key);
     }
 
     @Override
     public <T> T getNodeMetaData(Object key, Function<?, ? extends T> valFn) {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData(key, valFn);
     }
 
     @Override
     public void copyNodeMetaData(NodeMetaDataHandler other) {
-        init();
+        lazyInit();
         delegate.copyNodeMetaData(other);
     }
 
     @Override
     public void setNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         delegate.setNodeMetaData(key, value);
     }
 
     @Override
     public Object putNodeMetaData(Object key, Object value) {
-        init();
+        lazyInit();
         return delegate.putNodeMetaData(key, value);
     }
 
     @Override
     public void removeNodeMetaData(Object key) {
-        init();
+        lazyInit();
         delegate.removeNodeMetaData(key);
     }
 
     @Override
     public Map<?, ?> getNodeMetaData() {
-        init();
+        lazyInit();
         return delegate.getNodeMetaData();
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/runtime/memoize/LRUCache.java b/src/main/java/org/codehaus/groovy/runtime/memoize/LRUCache.java
index 8a7af91..75b134c 100644
--- a/src/main/java/org/codehaus/groovy/runtime/memoize/LRUCache.java
+++ b/src/main/java/org/codehaus/groovy/runtime/memoize/LRUCache.java
@@ -18,7 +18,7 @@
  */
 package org.codehaus.groovy.runtime.memoize;
 
-import org.apache.groovy.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
+import org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 
 import javax.annotation.concurrent.ThreadSafe;
 import java.lang.ref.SoftReference;
diff --git a/src/test/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMapTest.java b/src/test/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMapTest.java
index 055b3c7..c29f46e 100644
--- a/src/test/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMapTest.java
+++ b/src/test/org/apache/groovy/util/concurrentlinkedhashmap/ConcurrentLinkedHashMapTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.groovy.util.concurrentlinkedhashmap;
 
+import org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 import org.junit.Test;
 
 import java.util.TreeSet;
@@ -31,7 +32,7 @@
 public class ConcurrentLinkedHashMapTest {
     @Test
     public void computeIfAbsent() {
-        ConcurrentLinkedHashMap m = new ConcurrentLinkedHashMap.Builder<>()
+        org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap m = new org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap.Builder<>()
                 .maximumWeightedCapacity(3)
                 .build();
 
@@ -51,7 +52,7 @@
 
     @Test
     public void computeIfAbsentConcurrently() throws InterruptedException {
-        final ConcurrentLinkedHashMap m = new ConcurrentLinkedHashMap.Builder<>()
+        final org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap m = new ConcurrentLinkedHashMap.Builder<>()
                 .maximumWeightedCapacity(3)
                 .build();