http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java
deleted file mode 100644
index e1c0e13..0000000
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.impl;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.util.BiConsumer;
-import org.apache.logging.log4j.core.util.Integers;
-import org.apache.logging.log4j.core.util.TriConsumer;
-import org.apache.logging.log4j.spi.ThreadContextMap;
-
-/**
- * Open hash map-based implementation of the {@code ContextData} interface.
- * Implementation based on <a 
href="http://fastutil.di.unimi.it/";>fastutil</a>'s
- * <a 
href="http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/objects/Object2ObjectOpenHashMap.html";>Object2ObjectOpenHashMap</a>.
- * <p>
- * A type-specific hash map with a fast, small-footprint implementation.
- *
- * <P>
- * Instances of this class use a hash table to represent a map. The table is
- * filled up to a specified <em>load factor</em>, and then doubled in size to
- * accommodate new entries. If the table is emptied below <em>one fourth</em> 
of
- * the load factor, it is halved in size. However, halving is not performed 
when
- * deleting entries from an iterator, as it would interfere with the iteration
- * process.
- *
- * <p>
- * Note that {@link #clear()} does not modify the hash table size. Rather, the
- * {@link #trim(int)} method lets you control the size of
- * the table; this is particularly useful if you reuse instances of this class.
- * <p>
- * <ul>
- *   <li>Garbage-free iteration over key-value pairs with {@code BiConsumer} 
and {@code TriConsumer}.</li>
- *   <li>Fast copy. If the ThreadContextMap is also an instance of {@code 
OpenHashMapContextData},
- *     the full thread context data can be transferred with two array copies 
and five field updates.</li>
- * </ul>
- *
- * @see ThreadContextDataInjector
- * @since 2.7
- */
-public class OpenHashMapContextData<K, V> implements MutableContextData, 
ThreadContextMap {
-    /** The initial default size of a hash table. */
-    public static final int DEFAULT_INITIAL_SIZE = 16;
-
-    /** The default load factor of a hash table. */
-    public static final float DEFAULT_LOAD_FACTOR = .75f;
-
-    private static final long serialVersionUID = -1486744623338827187L;
-
-    /** The array of keys. */
-    protected transient K[] keys;
-    /** The array of values. */
-    protected transient V[] values;
-    /** The mask for wrapping a position counter. */
-    protected transient int mask;
-    /** Whether this set contains the key zero. */
-    protected transient boolean containsNullKey;
-    /** The current table size. */
-    protected transient int arraySize;
-    /**
-     * Threshold after which we rehash. It must be the table size times {@link 
#loadFactor}.
-     */
-    protected transient int maxFill;
-    /** Number of entries in the set (including the key zero, if present). */
-    protected int size;
-    /** The acceptable load factor. */
-    protected final float loadFactor;
-
-    private V defRetValue = null;
-
-    /**
-     * Creates a new hash map with initial expected
-     * {@link #DEFAULT_INITIAL_SIZE} entries and
-     * {@link #DEFAULT_LOAD_FACTOR} as load factor.
-     */
-    public OpenHashMapContextData() {
-        this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR);
-    }
-    /**
-     * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load factor.
-     *
-     * @param expected
-     *            the expected number of elements in the hash map.
-     */
-    public OpenHashMapContextData(final int expected) {
-        this(expected, DEFAULT_LOAD_FACTOR);
-    }
-    /**
-     * Creates a new hash map.
-     *
-     * <p>
-     * The actual table size will be the least power of two greater than
-     * <code>expected</code>/<code>f</code>.
-     *
-     * @param expected
-     *            the expected number of elements in the hash set.
-     * @param f
-     *            the load factor.
-     */
-    @SuppressWarnings("unchecked")
-    public OpenHashMapContextData(final int expected, final float f) {
-        if (f <= 0 || f > 1) {
-            throw new IllegalArgumentException(
-                    "Load factor must be greater than 0 and smaller than or 
equal to 1");
-        }
-        if (expected < 0){
-            throw new IllegalArgumentException(
-                    "The expected number of elements must be nonnegative");
-        }
-        this.loadFactor = f;
-        arraySize = HashCommon.arraySize(expected, f);
-        mask = arraySize - 1;
-        maxFill = HashCommon.maxFill(arraySize, f);
-        keys = (K[]) new Object[arraySize + 1];
-        values = (V[]) new Object[arraySize + 1];
-    }
-    /**
-     * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load
-     * factor copying a given one.
-     *
-     * @param map
-     *            a {@link Map} to be copied into the new hash map.
-     */
-    public OpenHashMapContextData(final Map<? extends K, ? extends V> map) {
-        this(map, DEFAULT_LOAD_FACTOR);
-    }
-    /**
-     * Creates a new hash map copying a given one.
-     *
-     * @param map
-     *            a {@link Map} to be copied into the new hash map.
-     * @param f
-     *            the load factor.
-     */
-    public OpenHashMapContextData(final Map<? extends K, ? extends V> map, 
final float f) {
-        this(map.size(), f);
-        putAll(map);
-    }
-
-    /**
-     * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load
-     * factor copying a given type-specific one.
-     *
-     * @param contextData
-     *            a type-specific map to be copied into the new hash map.
-     */
-    public OpenHashMapContextData(final ContextData contextData) {
-        this(contextData, DEFAULT_LOAD_FACTOR);
-    }
-    /**
-     * Creates a new hash map copying a given type-specific one.
-     *
-     * @param contextData
-     *            a type-specific map to be copied into the new hash map.
-     * @param f
-     *            the load factor.
-     */
-    public OpenHashMapContextData(final ContextData contextData, final float 
f) {
-        this(contextData.size(), f);
-        if (contextData instanceof OpenHashMapContextData) {
-            initFrom0((OpenHashMapContextData) contextData);
-        } else {
-            contextData.forEach(PUT_ALL, this);
-        }
-    }
-    private static final TriConsumer<String, Object, MutableContextData> 
PUT_ALL =
-            new TriConsumer<String, Object, MutableContextData>() {
-        @Override
-        public void accept(final String key, final Object value, final 
MutableContextData contextData) {
-            contextData.putValue(key, value);
-        }
-    };
-
-    @SuppressWarnings("unchecked")
-    private void initFrom0(final OpenHashMapContextData other) {
-        // this.loadFactor = other.loadFactor; // final field
-        this.arraySize = other.arraySize;
-        this.size = other.size;
-        this.containsNullKey = other.containsNullKey;
-        this.mask = other.mask;
-        this.maxFill = other.maxFill;
-        keys = (K[]) Arrays.copyOf(other.keys, arraySize + 1);
-        values = (V[]) Arrays.copyOf(other.values, arraySize + 1);
-    }
-
-    private int realSize() {
-        return containsNullKey ? size - 1 : size;
-    }
-
-    private void ensureCapacity(final int capacity) {
-        final int needed = HashCommon.arraySize(capacity, loadFactor);
-        if (needed > arraySize) {
-            rehash(needed);
-        }
-    }
-
-    private void tryCapacity(final long capacity) {
-        final int needed = (int) Math.min(
-                1 << 30, Math.max(2, Integers.ceilingNextPowerOfTwo((int) 
Math.ceil(capacity / loadFactor))));
-        if (needed > arraySize) {
-            rehash(needed);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void putAll(Map<? extends K, ? extends V> map) {
-        if (loadFactor <= .5) {
-            // The resulting map will be sized for m.size() elements
-            ensureCapacity(map.size());
-        } else {
-            // The resulting map will be tentatively sized for size() +  
m.size() elements
-            tryCapacity(size() + map.size());
-        }
-        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
-            putObjectValue(entry.getKey(), entry.getValue());
-        }
-    }
-
-    @Override
-    public Map<String, String> asMap() {
-        final Map<String, String> result = new HashMap<>(size);
-        forEach(COPY_INTO_MAP, result);
-        return result;
-    }
-
-    private static final TriConsumer<String, Object, Map<String, String>> 
COPY_INTO_MAP =
-            new TriConsumer<String, Object, Map<String, String>>() {
-        @Override
-        public void accept(final String k, final Object v, final Map<String, 
String> map) {
-            map.put(k, v == null ? null : v.toString());
-        }
-    };
-
-    /*
-     * Removes all elements from this map.
-     *
-     * <P>To increase object reuse, this method does not change the table size.
-     * If you want to reduce the table size, you must use {@link #trim()}.
-     */
-    @Override
-    public void clear() {
-        if (size == 0) {
-            return;
-        }
-        size = 0;
-        containsNullKey = false;
-        Arrays.fill(keys, (null));
-        Arrays.fill(values, null);
-    }
-
-    @Override
-    public boolean containsKey(final String key) {
-        return containsObjectKey((Object) key);
-    }
-
-    @SuppressWarnings("unchecked")
-    private boolean containsObjectKey(final Object k) {
-        if (k == null) {
-            return containsNullKey;
-        }
-        K curr;
-        final K[] key = this.keys;
-        int pos;
-        // The starting point.
-        if ((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == null) {
-            return false;
-        }
-        if (k.equals(curr)) {
-            return true;
-        }
-        // There's always an unused entry.
-        while (true) {
-            if ((curr = key[pos = (pos + 1) & mask]) == null) {
-                return false;
-            }
-            if (k.equals(curr)) {
-                return true;
-            }
-        }
-    }
-
-    public boolean equals(final Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof ContextData)) {
-            return false;
-        }
-        final ContextData other = (ContextData) obj;
-        if (other.size() != size()) {
-            return false;
-        }
-        int pos = arraySize;
-        if (containsNullKey) {
-            if (!Objects.equals(getObjectValue(null), other.getValue(null))) {
-                return false;
-            }
-        }
-        --pos;
-        final K myKeys[] = this.keys;
-        for (; pos >= 0; pos--) {
-            K k;
-            if ((k = myKeys[pos]) != null) {
-                if (!Objects.equals(values[pos], other.getValue((String) k))) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <VAL> void forEach(final BiConsumer<String, ? super VAL> action) {
-        final int startSize = size;
-        final K myKeys[] = this.keys;
-        int pos = arraySize;
-        if (containsNullKey) {
-            action.accept((String) myKeys[pos], (VAL) values[pos]);
-            if (size != startSize) {
-                throw new ConcurrentModificationException();
-            }
-        }
-        --pos;
-        for (; pos >= 0; pos--) {
-            if (myKeys[pos] != null) {
-                action.accept((String) myKeys[pos], (VAL) values[pos]);
-                if (size != startSize) {
-                    throw new ConcurrentModificationException();
-                }
-            }
-        }
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <VAL, STATE> void forEach(final TriConsumer<String, ? super VAL, 
STATE> action, final STATE state) {
-        final int startSize = size;
-        final K myKeys[] = this.keys;
-        int pos = arraySize;
-        if (containsNullKey) {
-            action.accept((String) myKeys[pos], (VAL) values[pos], state);
-            if (size != startSize) {
-                throw new ConcurrentModificationException();
-            }
-        }
-        --pos;
-        for (; pos >= 0; pos--) {
-            if (myKeys[pos] != null) {
-                action.accept((String) myKeys[pos], (VAL) values[pos], state);
-                if (size != startSize) {
-                    throw new ConcurrentModificationException();
-                }
-            }
-        }
-    }
-
-    @Override
-    public String get(final String key) {
-        return (String) getObjectValue(key);
-    }
-
-    @SuppressWarnings("unchecked")
-    private V getObjectValue(final Object k) {
-        if (k == null) {
-            return containsNullKey ? values[arraySize] : defRetValue;
-        }
-        K curr;
-        final K[] key = this.keys;
-        int pos;
-        // The starting point.
-        if ((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == null) {
-            return defRetValue;
-        }
-        if (k.equals(curr)) {
-            return values[pos];
-        }
-        // There's always an unused entry.
-        while (true) {
-            if (((curr = key[pos = (pos + 1) & mask]) == null)) {
-                return defRetValue;
-            }
-            if (k.equals(curr)) {
-                return values[pos];
-            }
-        }
-    }
-
-    @Override
-    public Map<String, String> getCopy() {
-        return asMap();
-    }
-
-    @Override
-    public Map<String, String> getImmutableMapOrNull() {
-        return isEmpty() ? null : Collections.unmodifiableMap(asMap());
-    }
-
-    @Override
-    public <VAL> VAL getValue(final String key) {
-        return (VAL) getObjectValue((Object) key);
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return size == 0;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void put(final String key, final String value) {
-        putObjectValue((K) key, (V) value);
-    }
-
-    private int insert(final K k, final V v) {
-        int pos;
-        if (k == null) {
-            if (containsNullKey) {
-                return arraySize;
-            }
-            containsNullKey = true;
-            pos = arraySize;
-        } else {
-            K curr;
-            final K[] key = this.keys;
-            // The starting point.
-            if (!((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == 
null)) {
-                if (curr.equals(k)) {
-                    return pos;
-                }
-                while (!((curr = key[pos = (pos + 1) & mask]) == null)) {
-                    if (curr.equals(k)) {
-                        return pos;
-                    }
-                }
-            }
-        }
-        keys[pos] = k;
-        values[pos] = v;
-        if (size++ >= maxFill) {
-            rehash(HashCommon.arraySize(size + 1, loadFactor));
-        }
-        return -1;
-    }
-
-    @Override
-    public void putAll(final ContextData source) {
-        if (size() == 0 && source instanceof OpenHashMapContextData) {
-            initFrom0((OpenHashMapContextData) source);
-        } else if (source != null) {
-            source.forEach(PUT_ALL, this);
-        }
-    }
-
-    private V putObjectValue(final K k, final V v) {
-        final int pos = insert(k, v);
-        if (pos < 0) {
-            return defRetValue;
-        }
-        final V oldValue = values[pos];
-        values[pos] = v;
-        return oldValue;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void putValue(final String key, final Object value) {
-        putObjectValue((K) key, (V) value);
-    }
-
-    @Override
-    public void remove(final String key) {
-        removeObjectKey((Object) key);
-    }
-
-    @SuppressWarnings("unchecked")
-    private V removeObjectKey(final Object k) {
-        if (k == null) {
-            if (containsNullKey) {
-                return removeNullEntry();
-            }
-            return defRetValue;
-        }
-        final K[] key = this.keys;
-        int pos = HashCommon.mix(k.hashCode()) & mask;
-        K curr = key[pos & mask];
-        // The starting point.
-        if (curr == null) {
-            return defRetValue;
-        }
-        if (k.equals(curr)) {
-            return removeEntry(pos);
-        }
-        while (true) {
-            if ((curr = key[pos = (pos + 1) & mask]) == null) {
-                return defRetValue;
-            }
-            if (k.equals(curr)) {
-                return removeEntry(pos);
-            }
-        }
-    }
-    private V removeEntry(final int pos) {
-        final V oldValue = values[pos];
-        values[pos] = null;
-        size--;
-        shiftKeys(pos);
-        if (size < maxFill / 4 && arraySize > DEFAULT_INITIAL_SIZE) {
-            rehash(arraySize / 2);
-        }
-        return oldValue;
-    }
-    private V removeNullEntry() {
-        containsNullKey = false;
-        keys[arraySize] = null;
-        final V oldValue = values[arraySize];
-        values[arraySize] = null;
-        size--;
-        if (size < maxFill / 4 && arraySize > DEFAULT_INITIAL_SIZE) {
-            rehash(arraySize / 2);
-        }
-        return oldValue;
-    }
-    /**
-     * Shifts left entries with the specified hash code, starting at the
-     * specified position, and empties the resulting free entry.
-     *
-     * @param pos
-     *            a starting position.
-     */
-    private void shiftKeys(int pos) {
-        // Shift entries with the same hash.
-        int last, slot;
-        K curr;
-        final K[] myKeys = this.keys;
-        for (;;) {
-            pos = ((last = pos) + 1) & mask;
-            for (;;) {
-                if (((curr = myKeys[pos]) == null)) {
-                    myKeys[last] = (null);
-                    values[last] = null;
-                    return;
-                }
-                slot = HashCommon.mix(curr.hashCode()) & mask;
-                if (last <= pos ? (last >= slot || slot > pos) : (last >= slot 
&& slot > pos)) {
-                    break;
-                }
-                pos = (pos + 1) & mask;
-            }
-            myKeys[last] = curr;
-            values[last] = values[pos];
-        }
-    }
-
-    @Override
-    public int size() {
-        return size;
-    }
-
-    /**
-     * Rehashes this map if the table is too large.
-     *
-     * <P>
-     * Let <var>N</var> be the smallest table size that can hold
-     * <code>max(n,{@link #size()})</code> entries, still satisfying the load
-     * factor. If the current table size is smaller than or equal to
-     * <var>N</var>, this method does nothing. Otherwise, it rehashes this map
-     * in a table of size <var>N</var>.
-     *
-     * <P>
-     * This method is useful when reusing maps. {@linkplain #clear() Clearing a
-     * map} leaves the table size untouched. If you are reusing a map many 
times,
-     * you can call this method with a typical size to avoid keeping around a
-     * very large table just because of a few large transient maps.
-     *
-     * @param n
-     *            the threshold for the trimming.
-     * @return true if there was enough memory to trim the map.
-     */
-    public boolean trim(final int n) {
-        final int l = HashCommon.nextPowerOfTwo((int) Math.ceil(n / 
loadFactor));
-        if (l >= n || size > HashCommon.maxFill(l, loadFactor))
-            return true;
-        try {
-            rehash(l);
-        } catch (OutOfMemoryError cantDoIt) { // unusual to catch OOME but in 
this case appropriate
-            return false;
-        }
-        return true;
-    }
-    /**
-     * Rehashes the map.
-     *
-     * <P>
-     * This method implements the basic rehashing strategy, and may be 
overriden
-     * by subclasses implementing different rehashing strategies (e.g.,
-     * disk-based rehashing). However, you should not override this method
-     * unless you understand the internal workings of this class.
-     *
-     * @param newN
-     *            the new size
-     */
-    @SuppressWarnings("unchecked")
-    protected void rehash(final int newN) {
-        final K myKeys[] = this.keys;
-        final V myValues[] = this.values;
-        final int mask = newN - 1; // Note that this is used by the hashing
-        // macro
-        final K newKey[] = (K[]) new Object[newN + 1];
-        final V newValue[] = (V[]) new Object[newN + 1];
-        int i = arraySize, pos;
-        for (int j = realSize(); j-- != 0;) {
-            while (myKeys[--i] == null) {
-                // advance i until we find an existing key
-            }
-            if (newKey[pos = HashCommon.mix(myKeys[i].hashCode()) & mask] != 
null) { // rehash & check slot availability
-                while (newKey[pos = (pos + 1) & mask] != null) {
-                    // find available slot at (or immediately following) pos
-                }
-            }
-            newKey[pos] = myKeys[i];
-            newValue[pos] = myValues[i];
-        }
-        newValue[newN] = myValues[arraySize];
-        arraySize = newN;
-        this.mask = mask;
-        maxFill = HashCommon.maxFill(arraySize, loadFactor);
-        this.keys = newKey;
-        this.values = newValue;
-    }
-
-    /**
-     * Returns a hash code for this map.
-     *
-     * @return a hash code for this map.
-     */
-    public int hashCode() {
-        int result = 0;
-        for (int j = realSize(), i = 0, t = 0; j-- != 0;) {
-            while (keys[i] == null) {
-                i++;
-            }
-            if (this != keys[i]) {
-                t = keys[i].hashCode();
-            }
-            if (this != values[i]) {
-                t ^= (values[i] == null ? 0 : values[i].hashCode());
-            }
-            result += t;
-            i++;
-        }
-        // Zero / null keys have hash zero.
-        if (containsNullKey) {
-            result += (values[arraySize] == null ? 0 : 
values[arraySize].hashCode());
-        }
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    private void readObject(final ObjectInputStream s) throws IOException, 
ClassNotFoundException {
-        s.defaultReadObject();
-        arraySize = HashCommon.arraySize(size, loadFactor);
-        maxFill = HashCommon.maxFill(arraySize, loadFactor);
-        mask = arraySize - 1;
-        final K key[] = this.keys = (K[]) new Object[arraySize + 1];
-        final V value[] = this.values = (V[]) new Object[arraySize + 1];
-        K k;
-        V v;
-        for (int i = size, pos; i-- != 0;) {
-            k = (K) s.readObject();
-            v = (V) s.readObject();
-            if (k == null) {
-                pos = arraySize;
-                containsNullKey = true;
-            } else {
-                pos = HashCommon.mix(k.hashCode()) & mask;
-                while (key[pos] != null) {
-                    pos = (pos + 1) & mask;
-                }
-            }
-            key[pos] = k;
-            value[pos] = v;
-        }
-    }
-
-    private void writeObject(final ObjectOutputStream s) throws IOException {
-        s.defaultWriteObject();
-        try {
-            forEach(SERIALIZER, s);
-        } catch (final RuntimeException runex) {
-            if (runex.getCause() instanceof IOException) {
-                throw (IOException) runex.getCause();
-            }
-            throw runex;
-        }
-    }
-
-    private static final TriConsumer<String, Object, ObjectOutputStream> 
SERIALIZER =
-            new TriConsumer<String, Object, ObjectOutputStream>() {
-                @Override
-                public void accept(final String k, final Object v, final 
ObjectOutputStream objectOutputStream) {
-                    try {
-                        objectOutputStream.writeObject(k);
-                        objectOutputStream.writeObject(v);
-                    } catch (final IOException ioex) {
-                        throw new IllegalStateException(ioex);
-                    }
-                }
-            };
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder(256);
-        sb.append('{');
-        final K myKeys[] = this.keys;
-        int pos = arraySize;
-        boolean first = true;
-        if (containsNullKey) {
-            sb.append(myKeys[pos] == this ? "(this map)" : myKeys[pos]);
-            sb.append('=');
-            sb.append(values[pos] == this ? "(this map)" : values[pos]);
-            first = false;
-        }
-        --pos;
-        for (; pos >= 0; pos--) {
-            if (myKeys[pos] != null) {
-                if (first) {
-                    first = false;
-                } else {
-                    sb.append(", ");
-                }
-                sb.append(myKeys[pos] == this ? "(this map)" : myKeys[pos]);
-                sb.append('=');
-                sb.append(values[pos] == this ? "(this map)" : values[pos]);
-            }
-        }
-        sb.append('}');
-        return sb.toString();
-    }
-
-    private static class HashCommon {
-        private HashCommon() {}
-
-        /** 2<sup>32</sup> &middot; &phi;, &phi; = (&#x221A;5 &minus; 1)/2. */
-        private static final int INT_PHI = 0x9E3779B9;
-
-        /** The reciprocal of {@link #INT_PHI} modulo 2<sup>32</sup>. */
-        private static final int INV_INT_PHI = 0x144cbc89;
-
-        /** Avalanches the bits of an integer by applying the finalisation 
step of MurmurHash3.
-         *
-         * <p>This method implements the finalisation step of Austin Appleby's
-         * <a href="http://code.google.com/p/smhasher/";>MurmurHash3</a>.
-         * Its purpose is to avalanche the bits of the argument to within 
0.25% bias.
-         *
-         * @param x an integer.
-         * @return a hash value with good avalanching properties.
-         */
-        public static int murmurHash3(int x) {
-            x ^= x >>> 16;
-            x *= 0x85ebca6b;
-            x ^= x >>> 13;
-            x *= 0xc2b2ae35;
-            x ^= x >>> 16;
-            return x;
-        }
-
-        /**
-         * Quickly mixes the bits of an integer.
-         *
-         * <p>This method mixes the bits of the argument by multiplying by the 
golden ratio and
-         * xorshifting the result. It is borrowed from <a 
href="https://github.com/OpenHFT/Koloboke";>Koloboke</a>, and
-         * it has slightly worse behaviour than {@link #murmurHash3(int)} (in 
open-addressing hash tables the average
-         * number of probes is slightly larger), but it's much faster.
-         *
-         * @param x an integer.
-         * @return a hash value obtained by mixing the bits of {@code x}.
-         * @see #invMix(int)
-         */
-        public static int mix(final int x) {
-            final int h = x * INT_PHI;
-            return h ^ (h >>> 16);
-        }
-
-        /** The inverse of {@link #mix(int)}. This method is mainly useful to 
create unit tests.
-         *
-         * @param x an integer.
-         * @return a value that passed through {@link #mix(int)} would give 
{@code x}.
-         */
-        public static int invMix(final int x) {
-            return (x ^ x >>> 16) * INV_INT_PHI;
-        }
-
-        /** Return the least power of two greater than or equal to the 
specified value.
-         *
-         * <p>Note that this function will return 1 when the argument is 0.
-         *
-         * @param x an integer smaller than or equal to 2<sup>30</sup>.
-         * @return the least power of two greater than or equal to the 
specified value.
-         */
-        public static int nextPowerOfTwo(int x) {
-            if (x == 0) {
-                return 1;
-            }
-            x--;
-            x |= x >> 1;
-            x |= x >> 2;
-            x |= x >> 4;
-            x |= x >> 8;
-            return (x | x >> 16) + 1;
-        }
-
-        /** Return the least power of two greater than or equal to the 
specified value.
-         *
-         * <p>Note that this function will return 1 when the argument is 0.
-         *
-         * @param x a long integer smaller than or equal to 2<sup>62</sup>.
-         * @return the least power of two greater than or equal to the 
specified value.
-         */
-        public static long nextPowerOfTwo(long x) {
-            if (x == 0) {
-                return 1;
-            }
-            x--;
-            x |= x >> 1;
-            x |= x >> 2;
-            x |= x >> 4;
-            x |= x >> 8;
-            x |= x >> 16;
-            return (x | x >> 32) + 1;
-        }
-
-
-        /** Returns the maximum number of entries that can be filled before 
rehashing.
-         *
-         * @param n the size of the backing array.
-         * @param f the load factor.
-         * @return the maximum number of entries before rehashing.
-         */
-        public static int maxFill(final int n, final float f) {
-               /* We must guarantee that there is always at least
-                * one free entry (even with pathological load factors). */
-            return Math.min((int) Math.ceil(n * f), n - 1);
-        }
-
-        /**
-         * Returns the least power of two smaller than or equal to 
2<sup>30</sup> and larger than or equal to
-         * <code>Math.ceil( expected / f )</code>.
-         *
-         * @param expected the expected number of elements in a hash table.
-         * @param f the load factor.
-         * @return the minimum possible size for a backing array.
-         * @throws IllegalArgumentException if the necessary size is larger 
than 2<sup>30</sup>.
-         */
-        public static int arraySize(final int expected, final float f) {
-            final long result = Math.max(2, nextPowerOfTwo((long) 
Math.ceil(expected / f)));
-            if (result > (1 << 30)) {
-                throw new IllegalArgumentException("Too large (" + expected +
-                        " expected elements with load factor " + f + ")");
-            }
-            return (int) result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
index 93a160e..62608a5 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
@@ -28,6 +28,7 @@ import org.apache.logging.log4j.core.util.Clock;
 import org.apache.logging.log4j.core.util.ClockFactory;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.TimestampMessage;
+import org.apache.logging.log4j.spi.MutableContextData;
 
 /**
  * Garbage-free LogEventFactory that reuses a single mutable log event.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
index af534fb..786d23f 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
@@ -20,8 +20,10 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
 import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.spi.MutableContextData;
+import org.apache.logging.log4j.spi.ThreadContextMap;
 
 /**
  * {@code ThreadContextDataInjector} contains a number of strategies for 
copying key-value pairs from the various

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java
index 4b83fc7..c6d5245 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java
@@ -21,7 +21,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.logging.log4j.core.impl.ContextDataFactory;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java
index 8fbffdf..329c6fa 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java
@@ -19,8 +19,8 @@ package org.apache.logging.log4j.core.jackson;
 import java.io.IOException;
 import java.util.Map;
 
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.util.BiConsumer;
+import org.apache.logging.log4j.spi.ContextData;
+import org.apache.logging.log4j.util.BiConsumer;
 
 import com.fasterxml.jackson.core.JsonGenerationException;
 import com.fasterxml.jackson.core.JsonGenerator;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java
index 0988a98..c3dc827 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.util.Map;
 
 import org.apache.logging.log4j.core.impl.ContextDataFactory;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java
index 8868c0d..67d6c8b 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java
@@ -19,8 +19,8 @@ package org.apache.logging.log4j.core.jackson;
 import java.io.IOException;
 import java.util.Map;
 
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.util.TriConsumer;
+import org.apache.logging.log4j.spi.ContextData;
+import org.apache.logging.log4j.util.TriConsumer;
 
 import com.fasterxml.jackson.core.JsonGenerationException;
 import com.fasterxml.jackson.core.JsonGenerator;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java
index 2338cb0..30b01a8 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java
index e40c65a..c195001 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
index 9edd36b..2f4853c 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
@@ -38,7 +38,7 @@ import 
org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.net.Severity;
 import org.apache.logging.log4j.core.util.JsonUtils;
 import org.apache.logging.log4j.core.util.KeyValuePair;
-import org.apache.logging.log4j.core.util.TriConsumer;
+import org.apache.logging.log4j.util.TriConsumer;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.StringBuilderFormattable;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java
index bcbdbd8..1fc0512 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java
@@ -16,11 +16,11 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.core.util.TriConsumer;
+import org.apache.logging.log4j.util.TriConsumer;
 import org.apache.logging.log4j.util.StringBuilders;
 
 /**

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java
deleted file mode 100644
index 081b9c2..0000000
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.apache.logging.log4j.core.util;
-
-/**
- * An operation that accepts two input arguments and returns no result.
- *
- * @param <K> type of the first argument
- * @param <V> type of the second argument
- * @see org.apache.logging.log4j.core.ContextData
- * @since 2.7
- */
-public interface BiConsumer<K, V> {
-
-    /**
-     * Performs the operation given the specified arguments.
-     * @param k the first input argument
-     * @param v the second input argument
-     */
-    void accept(K k, V v);
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java
deleted file mode 100644
index a7d6213..0000000
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.apache.logging.log4j.core.util;
-
-/**
- * An operation that accepts three input arguments and returns no result.
- *
- * @param <K> type of the first argument
- * @param <V> type of the second argument
- * @param <S> type of the third argument
- * @see org.apache.logging.log4j.core.ContextData
- * @since 2.7
- */
-public interface TriConsumer<K, V, S> {
-
-    /**
-     * Performs the operation given the specified arguments.
-     * @param k the first input argument
-     * @param v the second input argument
-     * @param s the third input argument
-     */
-    void accept(K k, V v, S s);
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java
index f0e94ec..facb29d 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java
@@ -34,7 +34,7 @@ import javax.persistence.Transient;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
 import org.apache.logging.log4j.core.LogEvent;
 import 
org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
 import 
org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java
index 9f86d16..00ee55f 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.db.jpa.converter;
 
-import org.apache.logging.log4j.core.impl.ArrayContextData;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java
index 76ce5d2..6930ed5 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.logging.log4j.core.appender.db.jpa.converter;
 
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.impl.ArrayContextData;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.ContextData;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
index cb1de14..46de4ab 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
@@ -29,7 +29,7 @@ import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java
deleted file mode 100644
index 4613c04..0000000
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java
+++ /dev/null
@@ -1,568 +0,0 @@
-package org.apache.logging.log4j.core.impl;/*
- * 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.
- */
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.logging.log4j.core.util.BiConsumer;
-import org.apache.logging.log4j.core.util.TriConsumer;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests the ArrayContextData class.
- */
-public class ArrayContextDataTest {
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConstructorDisallowsNegativeCapacity() throws Exception {
-        new ArrayContextData(-1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConstructorDisallowsZeroCapacity() throws Exception {
-        new ArrayContextData(0);
-    }
-
-    @Test
-    public void testConstructorIgnoresNull() throws Exception {
-        assertEquals(0, new ArrayContextData(null).size());
-    }
-
-    @Test
-    public void testToString() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        assertEquals("{3=3value, B=Bvalue, a=avalue}", original.toString());
-    }
-
-    @Test
-    public void testSerialization() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        final byte[] binary = serialize(original);
-        final ArrayContextData copy = deserialize(binary);
-        assertEquals(original, copy);
-    }
-
-    private byte[] serialize(final ArrayContextData data) throws IOException {
-        final ByteArrayOutputStream arr = new ByteArrayOutputStream();
-        final ObjectOutputStream out = new ObjectOutputStream(arr);
-        out.writeObject(data);
-        return arr.toByteArray();
-    }
-
-    private ArrayContextData deserialize(final byte[] binary) throws 
IOException, ClassNotFoundException {
-        final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
-        final ObjectInputStream in = new ObjectInputStream(inArr);
-        final ArrayContextData result = (ArrayContextData) in.readObject();
-        return result;
-    }
-
-    @Test
-    public void testPutAll() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        final ArrayContextData other = new ArrayContextData();
-        other.putAll(original);
-        assertEquals(original, other);
-
-        other.putValue("3", "otherValue");
-        assertNotEquals(original, other);
-
-        other.putValue("3", null);
-        assertNotEquals(original, other);
-
-        other.putValue("3", "3value");
-        assertEquals(original, other);
-    }
-
-    @Test
-    public void testEquals() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        assertEquals(original, original); // equal to itself
-
-        final ArrayContextData other = new ArrayContextData();
-        other.putValue("a", "avalue");
-        assertNotEquals(original, other);
-
-        other.putValue("B", "Bvalue");
-        assertNotEquals(original, other);
-
-        other.putValue("3", "3value");
-        assertEquals(original, other);
-
-        other.putValue("3", "otherValue");
-        assertNotEquals(original, other);
-
-        other.putValue("3", null);
-        assertNotEquals(original, other);
-
-        other.putValue("3", "3value");
-        assertEquals(original, other);
-    }
-
-    @Test
-    public void testAsMap() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        final Map<String, Object> expected = new HashMap<>();
-        expected.put("a", "avalue");
-        expected.put("B", "Bvalue");
-        expected.put("3", "3value");
-
-        assertEquals(expected, original.asMap());
-    }
-
-    @Test
-    public void testGetCopyDelegatesToAsMap() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals(original.getCopy(), original.asMap());
-
-        original.putValue("B", "Bvalue");
-        assertEquals(original.getCopy(), original.asMap());
-
-        original.putValue("3", "3value");
-        assertEquals(original.getCopy(), original.asMap());
-    }
-
-    @Test
-    public void testGetImmutableMapOrNull() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals(original.getImmutableMapOrNull(), original.asMap());
-
-        original.putValue("B", "Bvalue");
-        assertEquals(original.getImmutableMapOrNull(), original.asMap());
-
-        original.putValue("3", "3value");
-        assertEquals(original.getImmutableMapOrNull(), original.asMap());
-
-        try {
-            original.getImmutableMapOrNull().put("abc", "xyz");
-            fail("Expected map to be immutable");
-        } catch (final UnsupportedOperationException ok) {
-            //ok
-        }
-    }
-
-    @Test
-    public void testPutInsertsInAlphabeticOrder() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.put("a", "avalue");
-        original.put("B", "Bvalue");
-        original.put("3", "3value");
-        original.put("c", "cvalue");
-        original.put("d", "dvalue");
-
-        assertEquals("avalue", original.getValue("a"));
-        assertEquals("avalue", original.getValueAt(2));
-
-        assertEquals("Bvalue", original.getValue("B"));
-        assertEquals("Bvalue", original.getValueAt(1));
-
-        assertEquals("3value", original.getValue("3"));
-        assertEquals("3value", original.getValueAt(0));
-
-        assertEquals("cvalue", original.getValue("c"));
-        assertEquals("cvalue", original.getValueAt(3));
-
-        assertEquals("dvalue", original.getValue("d"));
-        assertEquals("dvalue", original.getValueAt(4));
-    }
-
-    @Test
-    public void testPutValueInsertsInAlphabeticOrder() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        original.putValue("c", "cvalue");
-        original.putValue("d", "dvalue");
-
-        assertEquals("avalue", original.getValue("a"));
-        assertEquals("avalue", original.getValueAt(2));
-
-        assertEquals("Bvalue", original.getValue("B"));
-        assertEquals("Bvalue", original.getValueAt(1));
-
-        assertEquals("3value", original.getValue("3"));
-        assertEquals("3value", original.getValueAt(0));
-
-        assertEquals("cvalue", original.getValue("c"));
-        assertEquals("cvalue", original.getValueAt(3));
-
-        assertEquals("dvalue", original.getValue("d"));
-        assertEquals("dvalue", original.getValueAt(4));
-    }
-
-    @Test
-    public void testNullKeysAllowed() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        original.putValue("c", "cvalue");
-        original.putValue("d", "dvalue");
-        assertEquals(5, original.size());
-        assertEquals("{3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", 
original.toString());
-
-        original.putValue(null, "nullvalue");
-        assertEquals(6, original.size());
-        assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, 
d=dvalue}", original.toString());
-
-        original.putValue(null, "otherNullvalue");
-        assertEquals("{null=otherNullvalue, 3=3value, B=Bvalue, a=avalue, 
c=cvalue, d=dvalue}", original.toString());
-        assertEquals(6, original.size());
-
-        original.putValue(null, "nullvalue");
-        assertEquals(6, original.size());
-        assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, 
d=dvalue}", original.toString());
-
-        original.putValue(null, "abc");
-        assertEquals(6, original.size());
-        assertEquals("{null=abc, 3=3value, B=Bvalue, a=avalue, c=cvalue, 
d=dvalue}", original.toString());
-    }
-
-    @Test
-    public void testNullKeysCopiedToAsMap() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        original.putValue("c", "cvalue");
-        original.putValue("d", "dvalue");
-        assertEquals(5, original.size());
-
-        HashMap<String, String> expected = new HashMap<>();
-        expected.put("a", "avalue");
-        expected.put("B", "Bvalue");
-        expected.put("3", "3value");
-        expected.put("c", "cvalue");
-        expected.put("d", "dvalue");
-        assertEquals("initial", expected, original.asMap());
-
-        original.putValue(null, "nullvalue");
-        expected.put(null, "nullvalue");
-        assertEquals(6, original.size());
-        assertEquals("with null key", expected, original.asMap());
-
-        original.putValue(null, "otherNullvalue");
-        expected.put(null, "otherNullvalue");
-        assertEquals(6, original.size());
-        assertEquals("with null key value2", expected, original.asMap());
-
-        original.putValue(null, "nullvalue");
-        expected.put(null, "nullvalue");
-        assertEquals(6, original.size());
-        assertEquals("with null key value1 again", expected, original.asMap());
-
-        original.putValue(null, "abc");
-        expected.put(null, "abc");
-        assertEquals(6, original.size());
-        assertEquals("with null key value3", expected, original.asMap());
-    }
-
-    @Test
-    public void testRemove() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals(1, original.size());
-        assertEquals("avalue", original.getValue("a"));
-
-        original.remove("a");
-        assertEquals(0, original.size());
-        assertNull("no a val", original.getValue("a"));
-
-        original.remove("B");
-        assertEquals(0, original.size());
-        assertNull("no B val", original.getValue("B"));
-    }
-
-    @Test
-    public void testNullValuesArePreserved() {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals(1, original.size());
-        assertEquals("avalue", original.getValue("a"));
-
-        original.putValue("a", null);
-        assertEquals(1, original.size());
-        assertNull("no a val", original.getValue("a"));
-
-        original.putValue("B", null);
-        assertEquals(2, original.size());
-        assertNull("no B val", original.getValue("B"));
-    }
-
-    @Test
-    public void testGet() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.put("a", "avalue");
-        original.put("B", "Bvalue");
-        original.put("3", "3value");
-
-        assertEquals("avalue", original.get("a"));
-        assertEquals("Bvalue", original.get("B"));
-        assertEquals("3value", original.get("3"));
-
-        original.putValue("0", "0value");
-        assertEquals("0value", original.get("0"));
-        assertEquals("3value", original.get("3"));
-        assertEquals("Bvalue", original.get("B"));
-        assertEquals("avalue", original.get("a"));
-    }
-
-    @Test
-    public void testGetValue_GetValueAt() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        assertEquals("avalue", original.getValue("a"));
-        assertEquals("avalue", original.getValueAt(2));
-
-        assertEquals("Bvalue", original.getValue("B"));
-        assertEquals("Bvalue", original.getValueAt(1));
-
-        assertEquals("3value", original.getValue("3"));
-        assertEquals("3value", original.getValueAt(0));
-
-        original.putValue("0", "0value");
-        assertEquals("0value", original.getValue("0"));
-        assertEquals("0value", original.getValueAt(0));
-        assertEquals("3value", original.getValue("3"));
-        assertEquals("3value", original.getValueAt(1));
-        assertEquals("Bvalue", original.getValue("B"));
-        assertEquals("Bvalue", original.getValueAt(2));
-        assertEquals("avalue", original.getValue("a"));
-        assertEquals("avalue", original.getValueAt(3));
-    }
-
-    @Test
-    public void testClear() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-        assertEquals(3, original.size());
-
-        original.clear();
-        assertEquals(0, original.size());
-
-        // ensure slots in the values array are nulled out
-        Field f = ArrayContextData.class.getDeclaredField("values");
-        f.setAccessible(true);
-        Object[] values = (Object[]) f.get(original);
-        for (int i = 0; i < values.length; i++) {
-            assertNull(values[i]);
-        }
-    }
-
-    @Test
-    public void testIndexOfKey() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals(0, original.indexOfKey("a"));
-
-        original.putValue("B", "Bvalue");
-        assertEquals(1, original.indexOfKey("a"));
-        assertEquals(0, original.indexOfKey("B"));
-
-        original.putValue("3", "3value");
-        assertEquals(2, original.indexOfKey("a"));
-        assertEquals(1, original.indexOfKey("B"));
-        assertEquals(0, original.indexOfKey("3"));
-
-        original.putValue("A", "AAA");
-        assertEquals(3, original.indexOfKey("a"));
-        assertEquals(2, original.indexOfKey("B"));
-        assertEquals(1, original.indexOfKey("A"));
-        assertEquals(0, original.indexOfKey("3"));
-
-        original.putValue("C", "CCC");
-        assertEquals(4, original.indexOfKey("a"));
-        assertEquals(3, original.indexOfKey("C"));
-        assertEquals(2, original.indexOfKey("B"));
-        assertEquals(1, original.indexOfKey("A"));
-        assertEquals(0, original.indexOfKey("3"));
-
-        original.putValue("2", "222");
-        assertEquals(5, original.indexOfKey("a"));
-        assertEquals(4, original.indexOfKey("C"));
-        assertEquals(3, original.indexOfKey("B"));
-        assertEquals(2, original.indexOfKey("A"));
-        assertEquals(1, original.indexOfKey("3"));
-        assertEquals(0, original.indexOfKey("2"));
-    }
-
-    @Test
-    public void testContainsKey() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        assertFalse("a", original.containsKey("a"));
-        assertFalse("B", original.containsKey("B"));
-        assertFalse("3", original.containsKey("3"));
-        assertFalse("A", original.containsKey("A"));
-
-        original.putValue("a", "avalue");
-        assertTrue("a", original.containsKey("a"));
-        assertFalse("B", original.containsKey("B"));
-        assertFalse("3", original.containsKey("3"));
-        assertFalse("A", original.containsKey("A"));
-
-        original.putValue("B", "Bvalue");
-        assertTrue("a", original.containsKey("a"));
-        assertTrue("B", original.containsKey("B"));
-        assertFalse("3", original.containsKey("3"));
-        assertFalse("A", original.containsKey("A"));
-
-        original.putValue("3", "3value");
-        assertTrue("a", original.containsKey("a"));
-        assertTrue("B", original.containsKey("B"));
-        assertTrue("3", original.containsKey("3"));
-        assertFalse("A", original.containsKey("A"));
-
-        original.putValue("A", "AAA");
-        assertTrue("a", original.containsKey("a"));
-        assertTrue("B", original.containsKey("B"));
-        assertTrue("3", original.containsKey("3"));
-        assertTrue("A", original.containsKey("A"));
-    }
-
-    @Test
-    public void testGetValueAt() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        assertEquals("a", original.getKeyAt(0));
-        assertEquals("avalue", original.getValueAt(0));
-
-        original.putValue("B", "Bvalue");
-        assertEquals("B", original.getKeyAt(0));
-        assertEquals("Bvalue", original.getValueAt(0));
-        assertEquals("a", original.getKeyAt(1));
-        assertEquals("avalue", original.getValueAt(1));
-
-        original.putValue("3", "3value");
-        assertEquals("3", original.getKeyAt(0));
-        assertEquals("3value", original.getValueAt(0));
-        assertEquals("B", original.getKeyAt(1));
-        assertEquals("Bvalue", original.getValueAt(1));
-        assertEquals("a", original.getKeyAt(2));
-        assertEquals("avalue", original.getValueAt(2));
-    }
-
-    @Test
-    public void testSizeAndIsEmpty() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        assertEquals(0, original.size());
-        assertTrue("initial", original.isEmpty());
-
-        original.putValue("a", "avalue");
-        assertEquals(1, original.size());
-        assertFalse("size=" + original.size(), original.isEmpty());
-
-        original.putValue("B", "Bvalue");
-        assertEquals(2, original.size());
-        assertFalse("size=" + original.size(), original.isEmpty());
-
-        original.putValue("3", "3value");
-        assertEquals(3, original.size());
-        assertFalse("size=" + original.size(), original.isEmpty());
-
-        original.remove("B");
-        assertEquals(2, original.size());
-        assertFalse("size=" + original.size(), original.isEmpty());
-
-        original.remove("3");
-        assertEquals(1, original.size());
-        assertFalse("size=" + original.size(), original.isEmpty());
-
-        original.remove("a");
-        assertEquals(0, original.size());
-        assertTrue("size=" + original.size(), original.isEmpty());
-    }
-
-    @Test
-    public void testForEachBiConsumer() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        original.forEach(new BiConsumer<String, String>() {
-            int count = 0;
-            @Override
-            public void accept(final String key, final String value) {
-                assertEquals("key", key, original.getKeyAt(count));
-                assertEquals("val", value, original.getValueAt(count));
-                count++;
-                assertTrue("count should not exceed size but was " + count, 
count <= original.size());
-            }
-        });
-    }
-
-    static class State {
-        ArrayContextData data;
-        int count;
-    }
-    static TriConsumer<String, String, State> COUNTER = new 
TriConsumer<String, String, State>() {
-        @Override
-        public void accept(final String key, final String value, final State 
state) {
-            assertEquals("key", key, state.data.getKeyAt(state.count));
-            assertEquals("val", value, state.data.getValueAt(state.count));
-            state.count++;
-            assertTrue("count should not exceed size but was " + state.count,
-                    state.count <= state.data.size());
-        }
-    };
-
-    @Test
-    public void testForEachTriConsumer() throws Exception {
-        final ArrayContextData original = new ArrayContextData();
-        original.putValue("a", "avalue");
-        original.putValue("B", "Bvalue");
-        original.putValue("3", "3value");
-
-        final State state = new State();
-        state.data = original;
-        original.forEach(COUNTER, state);
-        assertEquals(state.count, original.size());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
index 964a017..931fb15 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
@@ -40,6 +40,8 @@ import org.apache.logging.log4j.core.util.DummyNanoClock;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ObjectMessage;
 import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
index e531adc..0b2babf 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
@@ -29,6 +29,8 @@ import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
 import org.apache.logging.log4j.spi.MutableThreadContextStack;
 import org.junit.Test;
 

Reply via email to