/*
 * Decompiled with CFR 0_110.
 * 
 * Could not load the following classes:
 *  java.io.IOException
 *  java.io.ObjectInputStream
 *  java.io.ObjectOutputStream
 *  java.io.Serializable
 *  java.lang.ClassNotFoundException
 *  java.lang.CloneNotSupportedException
 *  java.lang.Cloneable
 *  java.lang.IllegalArgumentException
 *  java.lang.IllegalStateException
 *  java.lang.InternalError
 *  java.lang.Math
 *  java.lang.NullPointerException
 *  java.lang.Object
 *  java.lang.String
 *  java.lang.StringBuffer
 *  java.util.AbstractCollection
 *  java.util.AbstractMap
 *  java.util.AbstractSet
 *  java.util.Collection
 *  java.util.Enumeration
 *  java.util.Iterator
 *  java.util.Map
 *  java.util.Map$Entry
 *  java.util.NoSuchElementException
 *  java.util.Set
 */
package org.dom4j.tree;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

class ConcurrentReaderHashMap
extends AbstractMap
implements Serializable,
Cloneable,
Map {
    public static int DEFAULT_INITIAL_CAPACITY = 0;
    public static final float DEFAULT_LOAD_FACTOR = 0.75f;
    private static final int MAXIMUM_CAPACITY = 1073741824;
    private static final int MINIMUM_CAPACITY = 4;
    protected final BarrierLock barrierLock;
    protected transient int count;
    protected transient Set entrySet;
    protected transient Set keySet;
    protected transient Object lastWrite;
    protected float loadFactor;
    protected transient Entry[] table;
    protected int threshold;
    protected transient Collection values;

    static {
        DEFAULT_INITIAL_CAPACITY = 32;
    }

    public ConcurrentReaderHashMap() {
        this(DEFAULT_INITIAL_CAPACITY, 0.75f);
    }

    public ConcurrentReaderHashMap(int n) {
        super(n, 0.75f);
    }

    public ConcurrentReaderHashMap(int n, float f) {
        this.barrierLock = new BarrierLock();
        this.keySet = null;
        this.entrySet = null;
        this.values = null;
        if (f <= 0.0f) {
            throw new IllegalArgumentException(new StringBuffer().append("Illegal Load factor: ").append(f).toString());
        }
        this.loadFactor = f;
        int n2 = super.p2capacity(n);
        this.table = new Entry[n2];
        this.threshold = (int)(f * (float)n2);
    }

    public ConcurrentReaderHashMap(Map map) {
        super(Math.max((int)(1 + (int)((float)map.size() / 0.75f)), (int)16), 0.75f);
        this.putAll(map);
    }

    private static int hash(Object object) {
        int n = object.hashCode();
        return (n << 7) - n + (n >>> 9) + (n >>> 17);
    }

    /*
     * Enabled force condition propagation
     * Lifted jumps to return sites
     */
    private int p2capacity(int n) {
        if (n > 1073741824) return 1073741824;
        if (n < 0) {
            return 1073741824;
        }
        int n2 = 4;
        while (n2 < n) {
            n2 <<= 1;
        }
        return n2;
    }

    private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        void var6_2 = this;
        synchronized (var6_2) {
            objectInputStream.defaultReadObject();
            this.table = new Entry[objectInputStream.readInt()];
            int n = objectInputStream.readInt();
            for (int i = 0; i < n; ++i) {
                this.put(objectInputStream.readObject(), objectInputStream.readObject());
            }
            return;
        }
    }

    private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
        void var5_2 = this;
        synchronized (var5_2) {
            objectOutputStream.defaultWriteObject();
            objectOutputStream.writeInt(this.table.length);
            objectOutputStream.writeInt(this.count);
            for (int i = -1 + this.table.length; i >= 0; --i) {
                Entry entry = this.table[i];
                while (entry != null) {
                    objectOutputStream.writeObject(entry.key);
                    objectOutputStream.writeObject(entry.value);
                    entry = entry.next;
                    continue;
                }
            }
            return;
        }
    }

    public int capacity() {
        ConcurrentReaderHashMap concurrentReaderHashMap = this;
        synchronized (concurrentReaderHashMap) {
            int n = this.table.length;
            return n;
        }
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public void clear() {
        ConcurrentReaderHashMap concurrentReaderHashMap = this;
        synchronized (concurrentReaderHashMap) {
            Entry[] arrentry = this.table;
            int n = 0;
            do {
                if (n >= arrentry.length) {
                    this.count = 0;
                    this.recordModification(arrentry);
                    return;
                }
                Entry entry = arrentry[n];
                while (entry != null) {
                    entry.value = null;
                    entry = entry.next;
                }
                arrentry[n] = null;
                ++n;
            } while (true);
        }
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public Object clone() {
        ConcurrentReaderHashMap concurrentReaderHashMap = this;
        synchronized (concurrentReaderHashMap) {
            Entry[] arrentry;
            int n;
            ConcurrentReaderHashMap concurrentReaderHashMap2;
            try {
                concurrentReaderHashMap2 = (ConcurrentReaderHashMap)((Object)super.clone());
                concurrentReaderHashMap2.keySet = null;
                concurrentReaderHashMap2.entrySet = null;
                concurrentReaderHashMap2.values = null;
                arrentry = this.table;
                Entry[] arrentry2 = concurrentReaderHashMap2.table = new Entry[arrentry.length];
                n = 0;
            }
            catch (CloneNotSupportedException var2_9) {
                throw new InternalError();
            }
            while (n < arrentry.length) {
                Entry entry = arrentry[n];
                Entry entry2 = null;
                while (entry != null) {
                    Entry entry3 = new Entry(entry.hash, entry.key, entry.value, entry2);
                    entry = entry.next;
                    entry2 = entry3;
                }
                arrentry2[n] = entry2;
                ++n;
            }
            return concurrentReaderHashMap2;
        }
    }

    public boolean contains(Object object) {
        return this.containsValue(object);
    }

    public boolean containsKey(Object object) {
        if (this.get(object) != null) {
            return true;
        }
        return false;
    }

    public boolean containsValue(Object object) {
        if (object == null) {
            throw new NullPointerException();
        }
        Entry[] arrentry = this.getTableForReading();
        for (int i = 0; i < arrentry.length; ++i) {
            Entry entry = arrentry[i];
            while (entry != null) {
                if (object.equals(entry.value)) {
                    return true;
                }
                entry = entry.next;
            }
        }
        return false;
    }

    public Enumeration elements() {
        return new ValueIterator(this);
    }

    public Set entrySet() {
        EntrySet entrySet;
        Set set = this.entrySet;
        if (set != null) {
            return set;
        }
        this.entrySet = entrySet = new EntrySet(this, null);
        return entrySet;
    }

    protected boolean eq(Object object, Object object2) {
        if (object == object2 || object.equals(object2)) {
            return true;
        }
        return false;
    }

    /*
     * Enabled force condition propagation
     * Lifted jumps to return sites
     */
    protected boolean findAndRemoveEntry(Map.Entry entry) {
        void var7_2 = this;
        synchronized (var7_2) {
            Object object = entry.getKey();
            Object object2 = this.get(object);
            if (object2 == null) return false;
            if (!object2.equals(entry.getValue())) return false;
            this.remove(object);
            return true;
        }
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public Object get(Object object) {
        Entry entry;
        int n = ConcurrentReaderHashMap.hash(object);
        Entry[] arrentry = this.table;
        int n2 = n & -1 + arrentry.length;
        Entry entry2 = entry = arrentry[n2];
        do {
            if (entry2 == null) {
                Entry[] arrentry2 = this.getTableForReading();
                if (arrentry == arrentry2 && entry == arrentry[n2]) {
                    return null;
                }
                arrentry = arrentry2;
                n2 = n & -1 + arrentry.length;
                entry2 = entry = arrentry[n2];
                continue;
            }
            if (entry2.hash == n && this.eq(object, entry2.key)) {
                Object object2 = entry2.value;
                if (object2 != null) return object2;
                void var10_8 = this;
                synchronized (var10_8) {
                    arrentry = this.table;
                }
                n2 = n & -1 + arrentry.length;
                entry2 = entry = arrentry[n2];
                continue;
            }
            entry2 = entry2.next;
        } while (true);
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    protected final Entry[] getTableForReading() {
        BarrierLock barrierLock;
        BarrierLock barrierLock2 = barrierLock = this.barrierLock;
        synchronized (barrierLock2) {
            return this.table;
        }
    }

    /*
     * Enabled force condition propagation
     * Lifted jumps to return sites
     */
    public boolean isEmpty() {
        ConcurrentReaderHashMap concurrentReaderHashMap = this;
        synchronized (concurrentReaderHashMap) {
            int n = this.count;
            if (n != 0) return false;
            return true;
        }
    }

    public Set keySet() {
        KeySet keySet;
        Set set = this.keySet;
        if (set != null) {
            return set;
        }
        this.keySet = keySet = new KeySet(this, null);
        return keySet;
    }

    public Enumeration keys() {
        return new KeyIterator(this);
    }

    public float loadFactor() {
        return this.loadFactor;
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public Object put(Object object, Object object2) {
        Entry entry;
        if (object2 == null) {
            throw new NullPointerException();
        }
        int n = ConcurrentReaderHashMap.hash(object);
        Entry[] arrentry = this.table;
        int n2 = n & -1 + arrentry.length;
        Entry entry2 = entry = arrentry[n2];
        do {
            if (entry2 == null || entry2.hash == n && this.eq(object, entry2.key)) {
                void var13_8 = this;
                synchronized (var13_8) {
                    Entry entry3;
                    int n3;
                    if (arrentry != this.table) return this.sput(object, object2, n);
                    if (entry2 != null) break;
                    if (entry != arrentry[n2]) return this.sput(object, object2, n);
                    arrentry[n2] = entry3 = new Entry(n, object, object2, entry);
                    this.count = n3 = 1 + this.count;
                    if (n3 >= this.threshold) {
                        this.rehash();
                    } else {
                        this.recordModification(entry3);
                    }
                    return null;
                }
            }
            entry2 = entry2.next;
        } while (true);
        {
            Object object3 = entry2.value;
            if (entry != arrentry[n2]) return this.sput(object, object2, n);
            if (object3 == null) return this.sput(object, object2, n);
            entry2.value = object2;
            return object3;
        }
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public void putAll(Map map) {
        void var7_2 = this;
        synchronized (var7_2) {
            int n = map.size();
            if (n != 0) {
                while (n >= this.threshold) {
                    this.rehash();
                }
                for (Map.Entry entry : map.entrySet()) {
                    this.put(entry.getKey(), entry.getValue());
                }
            }
            return;
        }
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    protected final void recordModification(Object object) {
        BarrierLock barrierLock;
        BarrierLock barrierLock2 = barrierLock = this.barrierLock;
        synchronized (barrierLock2) {
            this.lastWrite = object;
            return;
        }
    }

    /*
     * Enabled aggressive block sorting
     */
    protected void rehash() {
        Entry[] arrentry = this.table;
        int n = arrentry.length;
        if (n >= 1073741824) {
            this.threshold = Integer.MAX_VALUE;
            return;
        }
        int n2 = n << 1;
        int n3 = n2 - 1;
        this.threshold = (int)((float)n2 * this.loadFactor);
        Entry[] arrentry2 = new Entry[n2];
        int n4 = 0;
        do {
            if (n4 >= n) {
                this.table = arrentry2;
                this.recordModification(arrentry2);
                return;
            }
            Entry entry = arrentry[n4];
            if (entry != null) {
                int n5 = n3 & entry.hash;
                Entry entry2 = entry.next;
                if (entry2 == null) {
                    arrentry2[n5] = entry;
                } else {
                    Entry entry3 = entry;
                    int n6 = n5;
                    Entry entry4 = entry2;
                    while (entry4 != null) {
                        int n7 = n3 & entry4.hash;
                        if (n7 != n6) {
                            n6 = n7;
                            entry3 = entry4;
                        }
                        entry4 = entry4.next;
                    }
                    arrentry2[n6] = entry3;
                    Entry entry5 = entry;
                    while (entry5 != entry3) {
                        int n8 = n3 & entry5.hash;
                        arrentry2[n8] = new Entry(entry5.hash, entry5.key, entry5.value, arrentry2[n8]);
                        entry5 = entry5.next;
                    }
                }
            }
            ++n4;
        } while (true);
    }

    /*
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     */
    public Object remove(Object object) {
        Entry entry;
        int n = ConcurrentReaderHashMap.hash(object);
        Entry[] arrentry = this.table;
        int n2 = n & -1 + arrentry.length;
        Entry entry2 = entry = arrentry[n2];
        do {
            if (entry2 == null || entry2.hash == n && this.eq(object, entry2.key)) {
                void var14_7 = this;
                synchronized (var14_7) {
                    if (arrentry != this.table) return this.sremove(object, n);
                    if (entry2 != null) break;
                    if (entry != arrentry[n2]) return this.sremove(object, n);
                    return null;
                }
            }
            entry2 = entry2.next;
        } while (true);
        {
            Object object2 = entry2.value;
            if (entry != arrentry[n2]) return this.sremove(object, n);
            if (object2 == null) return this.sremove(object, n);
            entry2.value = null;
            this.count = -1 + this.count;
            Entry entry3 = entry2.next;
            Entry entry4 = entry;
            Entry entry5 = entry3;
            do {
                if (entry4 == entry2) {
                    arrentry[n2] = entry5;
                    this.recordModification(entry5);
                    return object2;
                }
                Entry entry6 = new Entry(entry4.hash, entry4.key, entry4.value, entry5);
                entry4 = entry4.next;
                entry5 = entry6;
            } while (true);
        }
    }

    public int size() {
        ConcurrentReaderHashMap concurrentReaderHashMap = this;
        synchronized (concurrentReaderHashMap) {
            int n = this.count;
            return n;
        }
    }

    /*
     * Enabled force condition propagation
     * Lifted jumps to return sites
     */
    protected Object sput(Object object, Object object2, int n) {
        Entry entry;
        Entry[] arrentry = this.table;
        int n2 = n & -1 + arrentry.length;
        Entry entry2 = entry = arrentry[n2];
        do {
            if (entry2 == null) {
                int n3;
                Entry entry3;
                arrentry[n2] = entry3 = new Entry(n, object, object2, entry);
                this.count = n3 = 1 + this.count;
                if (n3 >= this.threshold) {
                    this.rehash();
                    do {
                        return null;
                        break;
                    } while (true);
                }
                this.recordModification(entry3);
                return null;
            }
            if (entry2.hash == n && this.eq(object, entry2.key)) {
                Object object3 = entry2.value;
                entry2.value = object2;
                return object3;
            }
            entry2 = entry2.next;
        } while (true);
    }

    protected Object sremove(Object object, int n) {
        Entry entry;
        Entry[] arrentry = this.table;
        int n2 = n & -1 + arrentry.length;
        Entry entry2 = entry = arrentry[n2];
        while (entry2 != null) {
            if (entry2.hash == n && this.eq(object, entry2.key)) {
                Object object2 = entry2.value;
                entry2.value = null;
                this.count = -1 + this.count;
                Entry entry3 = entry2.next;
                Entry entry4 = entry;
                Entry entry5 = entry3;
                while (entry4 != entry2) {
                    Entry entry6 = new Entry(entry4.hash, entry4.key, entry4.value, entry5);
                    entry4 = entry4.next;
                    entry5 = entry6;
                }
                arrentry[n2] = entry5;
                this.recordModification(entry5);
                return object2;
            }
            entry2 = entry2.next;
        }
        return null;
    }

    public Collection values() {
        Values values;
        Collection collection = this.values;
        if (collection != null) {
            return collection;
        }
        this.values = values = new Values(this, null);
        return values;
    }

    protected static class BarrierLock
    implements Serializable {
        protected BarrierLock() {
        }
    }

    protected static class Entry
    implements Map.Entry {
        protected final int hash;
        protected final Object key;
        protected final Entry next;
        protected volatile Object value;

        Entry(int n, Object object, Object object2, Entry entry) {
            this.hash = n;
            this.key = object;
            this.next = entry;
            this.value = object2;
        }

        /*
         * Enabled aggressive block sorting
         */
        public boolean equals(Object object) {
            Map.Entry entry;
            if (!(object instanceof Map.Entry && this.key.equals((entry = (Map.Entry)object).getKey()) && this.value.equals(entry.getValue()))) {
                return false;
            }
            return true;
        }

        public Object getKey() {
            return this.key;
        }

        public Object getValue() {
            return this.value;
        }

        public int hashCode() {
            return this.key.hashCode() ^ this.value.hashCode();
        }

        public Object setValue(Object object) {
            if (object == null) {
                throw new NullPointerException();
            }
            Object object2 = this.value;
            this.value = object;
            return object2;
        }

        public String toString() {
            return new StringBuffer().append(this.key).append("=").append(this.value).toString();
        }
    }

    private class EntrySet
    extends AbstractSet {
        private final ConcurrentReaderHashMap this$0;

        private EntrySet(ConcurrentReaderHashMap concurrentReaderHashMap) {
            this.this$0 = concurrentReaderHashMap;
        }

        EntrySet(ConcurrentReaderHashMap concurrentReaderHashMap,  var2_2) {
            super(concurrentReaderHashMap);
        }

        public void clear() {
            this.this$0.clear();
        }

        /*
         * Enabled aggressive block sorting
         */
        public boolean contains(Object object) {
            Object object2;
            Map.Entry entry;
            if (!(object instanceof Map.Entry) || (object2 = this.this$0.get((entry = (Map.Entry)object).getKey())) == null || !object2.equals(entry.getValue())) {
                return false;
            }
            return true;
        }

        public Iterator iterator() {
            return new HashIterator(this.this$0);
        }

        public boolean remove(Object object) {
            if (!(object instanceof Map.Entry)) {
                return false;
            }
            return this.this$0.findAndRemoveEntry((Map.Entry)object);
        }

        public int size() {
            return this.this$0.size();
        }
    }

    protected class HashIterator
    implements Enumeration,
    Iterator {
        protected Object currentKey;
        protected Object currentValue;
        protected Entry entry;
        protected int index;
        protected Entry lastReturned;
        protected final Entry[] tab;
        private final ConcurrentReaderHashMap this$0;

        protected HashIterator(ConcurrentReaderHashMap concurrentReaderHashMap) {
            this.this$0 = concurrentReaderHashMap;
            this.entry = null;
            this.lastReturned = null;
            this.tab = concurrentReaderHashMap.getTableForReading();
            this.index = -1 + this.tab.length;
        }

        public boolean hasMoreElements() {
            return this.hasNext();
        }

        public boolean hasNext() {
            do {
                if (this.entry != null) {
                    Object object = this.entry.value;
                    if (object != null) {
                        this.currentKey = this.entry.key;
                        this.currentValue = object;
                        return true;
                    }
                    this.entry = this.entry.next;
                }
                while (this.entry == null && this.index >= 0) {
                    Entry[] arrentry = this.tab;
                    int n = this.index;
                    this.index = n - 1;
                    this.entry = arrentry[n];
                }
            } while (this.entry != null);
            this.currentValue = null;
            this.currentKey = null;
            return false;
        }

        public Object next() {
            if (this.currentKey == null && !this.hasNext()) {
                throw new NoSuchElementException();
            }
            Object object = this.returnValueOfNext();
            this.lastReturned = this.entry;
            this.currentValue = null;
            this.currentKey = null;
            this.entry = this.entry.next;
            return object;
        }

        public Object nextElement() {
            return this.next();
        }

        public void remove() {
            if (this.lastReturned == null) {
                throw new IllegalStateException();
            }
            this.this$0.remove(this.lastReturned.key);
            this.lastReturned = null;
        }

        protected Object returnValueOfNext() {
            return this.entry;
        }
    }

    protected class KeyIterator
    extends HashIterator {
        private final ConcurrentReaderHashMap this$0;

        protected KeyIterator(ConcurrentReaderHashMap concurrentReaderHashMap) {
            super(concurrentReaderHashMap);
            this.this$0 = concurrentReaderHashMap;
        }

        @Override
        protected Object returnValueOfNext() {
            return this.currentKey;
        }
    }

    private class KeySet
    extends AbstractSet {
        private final ConcurrentReaderHashMap this$0;

        private KeySet(ConcurrentReaderHashMap concurrentReaderHashMap) {
            this.this$0 = concurrentReaderHashMap;
        }

        KeySet(ConcurrentReaderHashMap concurrentReaderHashMap,  var2_2) {
            super(concurrentReaderHashMap);
        }

        public void clear() {
            this.this$0.clear();
        }

        public boolean contains(Object object) {
            return this.this$0.containsKey(object);
        }

        public Iterator iterator() {
            return new KeyIterator(this.this$0);
        }

        public boolean remove(Object object) {
            if (this.this$0.remove(object) != null) {
                return true;
            }
            return false;
        }

        public int size() {
            return this.this$0.size();
        }
    }

    protected class ValueIterator
    extends HashIterator {
        private final ConcurrentReaderHashMap this$0;

        protected ValueIterator(ConcurrentReaderHashMap concurrentReaderHashMap) {
            super(concurrentReaderHashMap);
            this.this$0 = concurrentReaderHashMap;
        }

        @Override
        protected Object returnValueOfNext() {
            return this.currentValue;
        }
    }

    private class Values
    extends AbstractCollection {
        private final ConcurrentReaderHashMap this$0;

        private Values(ConcurrentReaderHashMap concurrentReaderHashMap) {
            this.this$0 = concurrentReaderHashMap;
        }

        Values(ConcurrentReaderHashMap concurrentReaderHashMap,  var2_2) {
            super(concurrentReaderHashMap);
        }

        public void clear() {
            this.this$0.clear();
        }

        public boolean contains(Object object) {
            return this.this$0.containsValue(object);
        }

        public Iterator iterator() {
            return new ValueIterator(this.this$0);
        }

        public int size() {
            return this.this$0.size();
        }
    }

}

