text:
package java.util;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serializable;
import libcore.util.Objects;

/**
 * HashMap is an implementation of {@link Map}. All optional operations are supported.
 *
 *
All elements are permitted as keys or values, including null.
 *
 *
Note that the iteration order for HashMap is non-deterministic. If you want
 * deterministic iteration, use {@link LinkedHashMap}.
 *
 *
Note: the implementation of {@code HashMap} is not synchronized.
 * If one thread of several threads accessing an instance modifies the map
 * structurally, access to the map needs to be synchronized. A structural
 * modification is an operation that adds or removes an entry. Changes in
 * the value of an entry are not structural changes.
 *
 *
The {@code Iterator} created by calling the {@code iterator} method
 * may throw a {@code ConcurrentModificationException} if the map is structurally
 * changed while an iterator is used to iterate over the elements. Only the
 * {@code remove} method that is provided by the iterator allows for removal of
 * elements during iteration. It is not possible to guarantee that this
 * mechanism works in all cases of unsynchronized concurrent modification. It
 * should only be used for debugging purposes.
 *
 * @param <K> the type of keys maintained by this map
 * @param <V> the type of mapped values
 */
public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable {
    /**
     * Min capacity (other than zero) for a HashMap. Must be a power of two
     * greater than 1 (and less than 1 << 30).
     */
    private static final int MINIMUM_CAPACITY = 4;

    /**
     * Max capacity for a HashMap. Must be a power of two >= MINIMUM_CAPACITY.
     */
    private static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * An empty table shared by all zero-capacity maps (typically from default
     * constructor). It is never written to, and replaced on first put. Its size
     * is set to half the minimum, so that the first resize will create a
     * minimum-sized table.
     */
    private static final Entry[] EMPTY_TABLE
            = new HashMapEntry[MINIMUM_CAPACITY >>> 1];

    /**
     * The default load factor. Note that this implementation ignores the
     * load factor, but cannot do away with it entirely because it's
     * mentioned in the API.
     *
     *
Note that this constant has no impact on the behavior of the program,
     * but it is emitted as part of the serialized form. The load factor of
     * .75 is hardwired into the program, which uses cheap shifts in place of
     * expensive division.
     */
    static final float DEFAULT_LOAD_FACTOR = .75F;

    /**
     * The hash table. If this hash map contains a mapping for null, it is
     * not represented this hash table.
     */
    transient HashMapEntry<K, V>[] table;

    /**
     * The entry representing the null key, or null if there's no such mapping.
     */
    transient HashMapEntry<K, V> entryForNullKey;

    /**
     * The number of mappings in this hash map.
     */
    transient int size;

    /**
     * Incremented by "structural modifications" to allow (best effort)
     * detection of concurrent modification.
     */
    transient int modCount;

    /**
     * The table is rehashed when its size exceeds this threshold.
     * The value of this field is generally .75 * capacity, except when
     * the capacity is zero, as described in the EMPTY_TABLE declaration
     * above.
     */
    private transient int threshold;

    // Views - lazily initialized
    private transient Set<K> keySet;
    private transient Set<Entry<K, V>> entrySet;
    private transient Collection<V> values;

    /**
     * Constructs a new empty {@code HashMap} instance.
     */
    @SuppressWarnings("unchecked")
    public HashMap() {
        table = (HashMapEntry<K, V>[]) EMPTY_TABLE;
        threshold = -1; // Forces first put invocation to replace EMPTY_TABLE
    }

    /**
     * Constructs a new {@code HashMap} instance with the specified capacity.
     *
     * @param capacity
     *            the initial capacity of this hash map.
     * @throws IllegalArgumentException
     *                when the capacity is less than zero.
     */
    public HashMap(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("Capacity: " + capacity);
        }

        if (capacity == 0) {
            @SuppressWarnings("unchecked")
            HashMapEntry<K, V>[] tab = (HashMapEntry<K, V>[]) EMPTY_TABLE;
            table = tab;
            threshold = -1; // Forces first put() to replace EMPTY_TABLE
            return;
        }

        if (capacity < MINIMUM_CAPACITY) {
            capacity = MINIMUM_CAPACITY;
        } else if (capacity > MAXIMUM_CAPACITY) {
            capacity = MAXIMUM_CAPACITY;
        } else {
            capacity = Collections.roundUpToPowerOfTwo(capacity);
        }
        makeTable(capacity);
    }

    /**
     * Constructs a new {@code HashMap} instance with the specified capacity and
     * load factor.
     *
     * @param capacity
     *            the initial capacity of this hash map.
     * @param loadFactor
     *            the initial load factor.
     * @throws IllegalArgumentException
     *                when the capacity is less than zero or the load factor is
     *                less or equal to zero or NaN.
     */
    public HashMap(int capacity, float loadFactor) {
        this(capacity);

        if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
            throw new IllegalArgumentException("Load factor: " + loadFactor);
        }

        /*
         * Note that this implementation ignores loadFactor; it always uses
         * a load factor of 3/4. This simplifies the code and generally
         * improves performance.
         */
    }

    /**
     * Constructs a new {@code HashMap} instance containing the mappings from
     * the specified map.
     *
     * @param map
     *            the mappings to add.
     */
    public HashMap(Map<? extends K, ? extends V> map) {
        this(capacityForInitSize(map.size()));
        constructorPutAll(map);
    }

    /**
     * Inserts all of the elements of map into this HashMap in a manner
     * suitable for use by constructors and pseudo-constructors (i.e., clone,
     * readObject). Also used by LinkedHashMap.
     */
    final void constructorPutAll(Map<? extends K, ? extends V> map) {
        if (table == EMPTY_TABLE) {
            doubleCapacity(); // Don't do unchecked puts to a shared table.
        }
        for (Entry<? extends K, ? extends V> e : map.entrySet()) {
            constructorPut(e.getKey(), e.getValue());
        }
    }

    /**
     * Returns an appropriate capacity for the specified initial size. Does
     * not round the result up to a power of two; the caller must do this!
     * The returned value will be between 0 and MAXIMUM_CAPACITY (inclusive).
     */
    static int capacityForInitSize(int size) {
        int result = (size >> 1) + size; // Multiply by 3/2 to allow for growth

        // boolean expr is equivalent to result >= 0 && result<MAXIMUM_CAPACITY
        return (result & ~(MAXIMUM_CAPACITY-1))==0 ? result : MAXIMUM_CAPACITY;
    }

    /**
     * Returns a shallow copy of this map.
     *
     * @return a shallow copy of this map.
     */
    @SuppressWarnings("unchecked")
    @Override public Object clone() {
        /*
         * This could be made more efficient. It unnecessarily hashes all of
         * the elements in the map.
         */
        HashMap<K, V> result;
        try {
            result = (HashMap<K, V>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError(e);
        }

        // Restore clone to empty state, retaining our capacity and threshold
        result.makeTable(table.length);
        result.entryForNullKey = null;
        result.size = 0;
        result.keySet = null;
        result.entrySet = null;
        result.values = null;

        result.init(); // Give subclass a chance to initialize itself
        result.constructorPutAll(this); // Calls method overridden in subclass!!
        return result;
    }

    /**
     * This method is called from the pseudo-constructors (clone and readObject)
     * prior to invoking constructorPut/constructorPutAll, which invoke the
     * overridden constructorNewEntry method. Normally it is a VERY bad idea to
     * invoke an overridden method from a pseudo-constructor (Effective Java
     * Item 17). In this case it is unavoidable, and the init method provides a
     * workaround.
     */
    void init() { }

    /**
     * Returns whether this map is empty.
     *
     * @return {@code true} if this map has no elements, {@code false}
     *         otherwise.
     * @see #size()
     */
    @Override public boolean isEmpty() {
        return size == 0;
    }

    /**
     * Returns the number of elements in this map.
     *
     * @return the number of elements in this map.
     */
    @Override public int size() {
        return size;
    }

    /**
     * Returns the value of the mapping with the specified key.
     *
     * @param key
     *            the key.
     * @return the value of the mapping with the specified key, or {@code null}
     *         if no mapping for the specified key is found.
     */
    public V get(Object key) {
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            return e == null ? null : e.value;
        }

        // Doug Lea's supplemental secondaryHash function (inlined).
        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
        int hash = key.hashCode();
        hash ^= (hash >>> 20) ^ (hash >>> 12);
        hash ^= (hash >>> 7) ^ (hash >>> 4);

        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
                return e.value;
            }
        }
        return null;
    }

    /**
     * Returns whether this map contains the specified key.
     *
     * @param key
     *            the key to search for.
     * @return {@code true} if this map contains the specified key,
     *         {@code false} otherwise.
     */
    @Override public boolean containsKey(Object key) {
        if (key == null) {
            return entryForNullKey != null;
        }

        // Doug Lea's supplemental secondaryHash function (inlined).
        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
        int hash = key.hashCode();
        hash ^= (hash >>> 20) ^ (hash >>> 12);
        hash ^= (hash >>> 7) ^ (hash >>> 4);

        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
                return true;
            }
        }
        return false;
    }

    // Doug Lea's supplemental secondaryHash function (non-inlined).
    // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
    static int secondaryHash(Object key) {
        int hash = key.hashCode();
        hash ^= (hash >>> 20) ^ (hash >>> 12);
        hash ^= (hash >>> 7) ^ (hash >>> 4);
        return hash;
    }

    /**
     * Returns whether this map contains the specified value.
     *
     * @param value
     *            the value to search for.
     * @return {@code true} if this map contains the specified value,
     *         {@code false} otherwise.
     */
    @Override public boolean containsValue(Object value) {
        HashMapEntry[] tab = table;
        int len = tab.length;
        if (value == null) {
            for (int i = 0; i < len; i++) {
                for (HashMapEntry e = tab[i]; e != null; e = e.next) {
                    if (e.value == null) {
                        return true;
                    }
                }
            }
            return entryForNullKey != null && entryForNullKey.value == null;
        }

        // value is non-null
        for (int i = 0; i < len; i++) {
            for (HashMapEntry e = tab[i]; e != null; e = e.next) {
                if (value.equals(e.value)) {
                    return true;
                }
            }
        }
        return entryForNullKey != null && value.equals(entryForNullKey.value);
    }

    /**
     * Maps the specified key to the specified value.
     *
     * @param key
     *            the key.
     * @param value
     *            the value.
     * @return the value of any previous mapping with the specified key or
     *         {@code null} if there was no such mapping.
     */
    @Override public V put(K key, V value) {
        if (key == null) {
            return putValueForNullKey(value);
        }

        int hash = secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                preModify(e);
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

        // No entry for (non-null) key is present; create one
        modCount++;
        if (size++ > threshold) {
            tab = doubleCapacity();
            index = hash & (tab.length - 1);
        }
        addNewEntry(key, value, hash, index);
        return null;
    }

    private V putValueForNullKey(V value) {
        HashMapEntry<K, V> entry = entryForNullKey;
        if (entry == null) {
            addNewEntryForNullKey(value);
            size++;
            modCount++;
            return null;
        } else {
            preModify(entry);
            V oldValue = entry.value;
            entry.value = value;
            return oldValue;
        }
    }

    /**
     * Give LinkedHashMap a chance to take action when we modify an existing
     * entry.
     *
     * @param e the entry we're about to modify.
     */
    void preModify(HashMapEntry<K, V> e) { }

    /**
     * This method is just like put, except that it doesn't do things that
     * are inappropriate or unnecessary for constructors and pseudo-constructors
     * (i.e., clone, readObject). In particular, this method does not check to
     * ensure that capacity is sufficient, and does not increment modCount.
     */
    private void constructorPut(K key, V value) {
        if (key == null) {
            HashMapEntry<K, V> entry = entryForNullKey;
            if (entry == null) {
                entryForNullKey = constructorNewEntry(null, value, 0, null);
                size++;
            } else {
                entry.value = value;
            }
            return;
        }

        int hash = secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        HashMapEntry<K, V> first = tab[index];
        for (HashMapEntry<K, V> e = first; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                e.value = value;
                return;
            }
        }

        // No entry for (non-null) key is present; create one
        tab[index] = constructorNewEntry(key, value, hash, first);
        size++;
    }

    /**
     * Creates a new entry for the given key, value, hash, and index and
     * inserts it into the hash table. This method is called by put
     * (and indirectly, putAll), and overridden by LinkedHashMap. The hash
     * must incorporate the secondary hash function.
     */
    void addNewEntry(K key, V value, int hash, int index) {
        table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
    }

    /**
     * Creates a new entry for the null key, and the given value and
     * inserts it into the hash table. This method is called by put
     * (and indirectly, putAll), and overridden by LinkedHashMap.
     */
    void addNewEntryForNullKey(V value) {
        entryForNullKey = new HashMapEntry<K, V>(null, value, 0, null);
    }

    /**
     * Like newEntry, but does not perform any activity that would be
     * unnecessary or inappropriate for constructors. In this class, the
     * two methods behave identically; in LinkedHashMap, they differ.
     */
    HashMapEntry<K, V> constructorNewEntry(
            K key, V value, int hash, HashMapEntry<K, V> first) {
        return new HashMapEntry<K, V>(key, value, hash, first);
    }

    /**
     * Copies all the mappings in the specified map to this map. These mappings
     * will replace all mappings that this map had for any of the keys currently
     * in the given map.
     *
     * @param map
     *            the map to copy mappings from.
     */
    @Override public void putAll(Map<? extends K, ? extends V> map) {
        ensureCapacity(map.size());
        super.putAll(map);
    }

    /**
     * Ensures that the hash table has sufficient capacity to store the
     * specified number of mappings, with room to grow. If not, it increases the
     * capacity as appropriate. Like doubleCapacity, this method moves existing
     * entries to new buckets as appropriate. Unlike doubleCapacity, this method
     * can grow the table by factors of 2^n for n > 1. Hopefully, a single call
     * to this method will be faster than multiple calls to doubleCapacity.
     *
     *
This method is called only by putAll.
     */
    private void ensureCapacity(int numMappings) {
        int newCapacity = Collections.roundUpToPowerOfTwo(capacityForInitSize(numMappings));
        HashMapEntry<K, V>[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (newCapacity <= oldCapacity) {
            return;
        }
        if (newCapacity == oldCapacity * 2) {
            doubleCapacity();
            return;
        }

        // We're growing by at least 4x, rehash in the obvious way
        HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
        if (size != 0) {
            int newMask = newCapacity - 1;
            for (int i = 0; i < oldCapacity; i++) {
                for (HashMapEntry<K, V> e = oldTable[i]; e != null;) {
                    HashMapEntry<K, V> oldNext = e.next;
                    int newIndex = e.hash & newMask;
                    HashMapEntry<K, V> newNext = newTable[newIndex];
                    newTable[newIndex] = e;
                    e.next = newNext;
                    e = oldNext;
                }
            }
        }
    }

    /**
     * Allocate a table of the given capacity and set the threshold accordingly.
     * @param newCapacity must be a power of two
     */
    private HashMapEntry<K, V>[] makeTable(int newCapacity) {
        @SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable
                = (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];
        table = newTable;
        threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
        return newTable;
    }

    /**
     * Doubles the capacity of the hash table. Existing entries are placed in
     * the correct bucket on the enlarged table. If the current capacity is,
     * MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which
     * will be new unless we were already at MAXIMUM_CAPACITY.
     */
    private HashMapEntry<K, V>[] doubleCapacity() {
        HashMapEntry<K, V>[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            return oldTable;
        }
        int newCapacity = oldCapacity * 2;
        HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
        if (size == 0) {
            return newTable;
        }

        for (int j = 0; j < oldCapacity; j++) {
            /*
             * Rehash the bucket using the minimum number of field writes.
             * This is the most subtle and delicate code in the class.
             */
            HashMapEntry<K, V> e = oldTable[j];
            if (e == null) {
                continue;
            }
            int highBit = e.hash & oldCapacity;
            HashMapEntry<K, V> broken = null;
            newTable[j | highBit] = e;
            for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
                int nextHighBit = n.hash & oldCapacity;
                if (nextHighBit != highBit) {
                    if (broken == null)
                        newTable[j | nextHighBit] = n;
                    else
                        broken.next = n;
                    broken = e;
                    highBit = nextHighBit;
                }
            }
            if (broken != null)
                broken.next = null;
        }
        return newTable;
    }

    /**
     * Removes the mapping with the specified key from this map.
     *
     * @param key
     *            the key of the mapping to remove.
     * @return the value of the removed mapping or {@code null} if no mapping
     *         for the specified key was found.
     */
    @Override public V remove(Object key) {
        if (key == null) {
            return removeNullKey();
        }
        int hash = secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index], prev = null;
                e != null; prev = e, e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                if (prev == null) {
                    tab[index] = e.next;
                } else {
                    prev.next = e.next;
                }
                modCount++;
                size--;
                postRemove(e);
                return e.value;
            }
        }
        return null;
    }

    private V removeNullKey() {
        HashMapEntry<K, V> e = entryForNullKey;
        if (e == null) {
            return null;
        }
        entryForNullKey = null;
        modCount++;
        size--;
        postRemove(e);
        return e.value;
    }

    /**
     * Subclass overrides this method to unlink entry.
     */
    void postRemove(HashMapEntry<K, V> e) { }

    /**
     * Removes all mappings from this hash map, leaving it empty.
     *
     * @see #isEmpty
     * @see #size
     */
    @Override public void clear() {
        if (size != 0) {
            Arrays.fill(table, null);
            entryForNullKey = null;
            modCount++;
            size = 0;
        }
    }

    /**
     * Returns a set of the keys contained in this map. The set is backed by
     * this map so changes to one are reflected by the other. The set does not
     * support adding.
     *
     * @return a set of the keys.
     */
    @Override public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null) ? ks : (keySet = new KeySet());
    }

    /**
     * Returns a collection of the values contained in this map. The collection
     * is backed by this map so changes to one are reflected by the other. The
     * collection supports remove, removeAll, retainAll and clear operations,
     * and it does not support add or addAll operations.
     *

     * This method returns a collection which is the subclass of
     * AbstractCollection. The iterator method of this subclass returns a
     * "wrapper object" over the iterator of map's entrySet(). The {@code size}
     * method wraps the map's size method and the {@code contains} method wraps
     * the map's containsValue method.
     *

     *

     * The collection is created when this method is called for the first time
     * and returned in response to all subsequent calls. This method may return
     * different collections when multiple concurrent calls occur, since no
     * synchronization is performed.
     *

     *
     * @return a collection of the values contained in this map.
     */
    @Override public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null) ? vs : (values = new Values());
    }

    /**
     * Returns a set containing all of the mappings in this map. Each mapping is
     * an instance of {@link Map.Entry}. As the set is backed by this map,
     * changes in one will be reflected in the other.
     *
     * @return a set of the mappings.
     */
    public Set<Entry<K, V>> entrySet() {
        Set<Entry<K, V>> es = entrySet;
        return (es != null) ? es : (entrySet = new EntrySet());
    }

    static class HashMapEntry<K, V> implements Entry<K, V> {
        final K key;
        V value;
        final int hash;
        HashMapEntry<K, V> next;

        HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
            this.key = key;
            this.value = value;
            this.hash = hash;
            this.next = next;
        }

        public final K getKey() {
            return key;
        }

        public final V getValue() {
            return value;
        }

        public final V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        @Override public final boolean equals(Object o) {
            if (!(o instanceof Entry)) {
                return false;
            }
            Entry<?, ?> e = (Entry<?, ?>) o;
            return Objects.equal(e.getKey(), key)
                    && Objects.equal(e.getValue(), value);
        }

        @Override public final int hashCode() {
            return (key == null ? 0 : key.hashCode()) ^
                    (value == null ? 0 : value.hashCode());
        }

        @Override public final String toString() {
            return key + "=" + value;
        }
    }

    private abstract class HashIterator {
        int nextIndex;
        HashMapEntry<K, V> nextEntry = entryForNullKey;
        HashMapEntry<K, V> lastEntryReturned;
        int expectedModCount = modCount;

        HashIterator() {
            if (nextEntry == null) {
                HashMapEntry<K, V>[] tab = table;
                HashMapEntry<K, V> next = null;
                while (next == null && nextIndex < tab.length) {
                    next = tab[nextIndex++];
                }
                nextEntry = next;
            }
        }

        public boolean hasNext() {
            return nextEntry != null;
        }

        HashMapEntry<K, V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (nextEntry == null)
                throw new NoSuchElementException();

            HashMapEntry<K, V> entryToReturn = nextEntry;
            HashMapEntry<K, V>[] tab = table;
            HashMapEntry<K, V> next = entryToReturn.next;
            while (next == null && nextIndex < tab.length) {
                next = tab[nextIndex++];
            }
            nextEntry = next;
            return lastEntryReturned = entryToReturn;
        }

        public void remove() {
            if (lastEntryReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            HashMap.this.remove(lastEntryReturned.key);
            lastEntryReturned = null;
            expectedModCount = modCount;
        }
    }

    private final class KeyIterator extends HashIterator
            implements Iterator<K> {
        public K next() { return nextEntry().key; }
    }

    private final class ValueIterator extends HashIterator
            implements Iterator<V> {
        public V next() { return nextEntry().value; }
    }

    private final class EntryIterator extends HashIterator
            implements Iterator<Entry<K, V>> {
        public Entry<K, V> next() { return nextEntry(); }
    }

    /**
     * Returns true if this map contains the specified mapping.
     */
    private boolean containsMapping(Object key, Object value) {
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            return e != null && Objects.equal(value, e.value);
        }

        int hash = secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                return Objects.equal(value, e.value);
            }
        }
        return false; // No entry for key
    }

    /**
     * Removes the mapping from key to value and returns true if this mapping
     * exists; otherwise, returns does nothing and returns false.
     */
    private boolean removeMapping(Object key, Object value) {
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            if (e == null || !Objects.equal(value, e.value)) {
                return false;
            }
            entryForNullKey = null;
            modCount++;
            size--;
            postRemove(e);
            return true;
        }

        int hash = secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index], prev = null;
                e != null; prev = e, e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                if (!Objects.equal(value, e.value)) {
                    return false;  // Map has wrong value for key
                }
                if (prev == null) {
                    tab[index] = e.next;
                } else {
                    prev.next = e.next;
                }
                modCount++;
                size--;
                postRemove(e);
                return true;
            }
        }
        return false; // No entry for key
    }

    // Subclass (LinkedHashMap) overrides these for correct iteration order
    Iterator<K> newKeyIterator() { return new KeyIterator();   }
    Iterator<V> newValueIterator() { return new ValueIterator(); }
    Iterator<Entry<K, V>> newEntryIterator() { return new EntryIterator(); }

    private final class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
            return newKeyIterator();
        }
        public int size() {
            return size;
        }
        public boolean isEmpty() {
            return size == 0;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            int oldSize = size;
            HashMap.this.remove(o);
            return size != oldSize;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }

    private final class Values extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return newValueIterator();
        }
        public int size() {
            return size;
        }
        public boolean isEmpty() {
            return size == 0;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            HashMap.this.clear();
        }
    }

    private final class EntrySet extends AbstractSet<Entry<K, V>> {
        public Iterator<Entry<K, V>> iterator() {
            return newEntryIterator();
        }
        public boolean contains(Object o) {
            if (!(o instanceof Entry))
                return false;
            Entry<?, ?> e = (Entry<?, ?>) o;
            return containsMapping(e.getKey(), e.getValue());
        }
        public boolean remove(Object o) {
            if (!(o instanceof Entry))
                return false;
            Entry<?, ?> e = (Entry<?, ?>)o;
            return removeMapping(e.getKey(), e.getValue());
        }
        public int size() {
            return size;
        }
        public boolean isEmpty() {
            return size == 0;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }

    private static final long serialVersionUID = 362498820763181265L;

    private static final ObjectStreamField[] serialPersistentFields = {
        new ObjectStreamField("loadFactor", float.class)
    };

    private void writeObject(ObjectOutputStream stream) throws IOException {
        // Emulate loadFactor field for other implementations to read
        ObjectOutputStream.PutField fields = stream.putFields();
        fields.put("loadFactor", DEFAULT_LOAD_FACTOR);
        stream.writeFields();

        stream.writeInt(table.length); // Capacity
        stream.writeInt(size);
        for (Entry<K, V> e : entrySet()) {
            stream.writeObject(e.getKey());
            stream.writeObject(e.getValue());
        }
    }

    private void readObject(ObjectInputStream stream) throws IOException,
            ClassNotFoundException {
        stream.defaultReadObject();
        int capacity = stream.readInt();
        if (capacity < 0) {
            throw new InvalidObjectException("Capacity: " + capacity);
        }
        if (capacity < MINIMUM_CAPACITY) {
            capacity = MINIMUM_CAPACITY;
        } else if (capacity > MAXIMUM_CAPACITY) {
            capacity = MAXIMUM_CAPACITY;
        } else {
            capacity = Collections.roundUpToPowerOfTwo(capacity);
        }
        makeTable(capacity);

        int size = stream.readInt();
        if (size < 0) {
            throw new InvalidObjectException("Size: " + size);
        }

        init(); // Give subclass (LinkedHashMap) a chance to initialize itself
        for (int i = 0; i < size; i++) {
            @SuppressWarnings("unchecked") K key = (K) stream.readObject();
            @SuppressWarnings("unchecked") V val = (V) stream.readObject();
            constructorPut(key, val);
        }
    }
}


text:
#import "ProfessionalViewController.h"
#import "DataController.h"

@interface ProfessionalViewController ()

@end

@implementation ProfessionalViewController

- (void)viewDidLoad
{
  [super viewDidLoad];

  self.title = @"Professional";
}

- (void)refreshData
{
  for (NSDictionary * d in sharedDC.professionalBackgrounds)
  {
    MenuCellData * dat = [[MenuCellData alloc] initWithDictionary:d];
    [self addData:dat];
  }
}

- (void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

@end

redpajama_set_name: RedPajamaGithub


text:
package com.fsck.k9.mailstore.migrations;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;

class MigrationTo44 {
    public static void addMessagesThreadingColumns(SQLiteDatabase db) {
        try {
            db.execSQL("ALTER TABLE messages ADD thread_root INTEGER");
            db.execSQL("ALTER TABLE messages ADD thread_parent INTEGER");
            db.execSQL("ALTER TABLE messages ADD normalized_subject_hash INTEGER");
            db.execSQL("ALTER TABLE messages ADD empty INTEGER");
        } catch (SQLiteException e) {
            if (!e.getMessage().startsWith("duplicate column name:")) {
                throw e;
            }
        }
    }
}


text:
// RouteQueueEntry.jsp, etc

function submitQueueId(methodToCall, queueId)
{
    document.forms[0].elements['methodToCall'].value = methodToCall;
    document.forms[0].elements['messageId'].value = queueId;
    document.forms[0].submit();
}

function executeMessageFetcher()
{
	if (confirm('This will execute the Message Fetcher which will grab all messages in the queue with this machine\'s application id and ip address and queue them up to be processed again.  Are you sure you want to do this?')) {
	    document.forms[0].elements['methodToCall'].value = 'executeMessageFetcher';
   		document.forms[0].submit();
   	}
}

function refreshServiceRegistry()
{
	document.forms[0].elements['methodToCall'].value = 'refreshServiceRegistry';
   	document.forms[0].submit();
}

function deleteLocalhostEntries()
{
	document.forms[0].elements['methodToCall'].value = 'deleteLocalhostEntries';
   	document.forms[0].submit();
}


text:
- https://github.com/appium/ruby_lib/tree/master/docs - The Ruby lib has extensive documentation. This is the place
to look in terms of finding out what helper methods are available.

- https://code.google.com/p/selenium/wiki/RubyBindings - The full API of the selenium ruby bindings is available.
Under the hood the ruby bindings for appium use the selenium ruby bindings.

- https://code.google.com/p/selenium/wiki/PageObjects - The page object pattern is explained in great detail.

- http://rake.rubyforge.org/ - The Rake homepage contains an overview of the tool.


text:
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace DecodePeekLogs.Properties {

    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

        public static Settings Default {
            get {
                return defaultInstance;
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool fileHasBeenRead {
            get {
                return ((bool)(this["fileHasBeenRead"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("d:\\controllerlogs")]
        public string PeekDatPath {
            get {
                return ((string)(this["PeekDatPath"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("csv_files_e")]
        public string PeekCSVPAth {
            get {
                return ((string)(this["PeekCSVPAth"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("d:\\spmtools\\gzip.exe")]
        public string gzipExePath {
            get {
                return ((string)(this["gzipExePath"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("d:\\spmtools\\cuLogDecode.exe")]
        public string decoderExePAth {
            get {
                return ((string)(this["decoderExePAth"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("5")]
        public int MaxThreads {
            get {
                return ((int)(this["MaxThreads"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("True")]
        public bool WriteToConsole {
            get {
                return ((bool)(this["WriteToConsole"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool DeleteFiles {
            get {
                return ((bool)(this["DeleteFiles"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("d:\\spmtools")]
        public string ToolsDirectory {
            get {
                return ((string)(this["ToolsDirectory"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=MOE;Initial Catalog=moe;User ID=spm;Password=CHANGEME")]
        public string SPM {
            get {
                return ((string)(this["SPM"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("2010-01-01")]
        public global::System.DateTime EarliestAcceptableDate {
            get {
                return ((global::System.DateTime)(this["EarliestAcceptableDate"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool ForceNonParallel {
            get {
                return ((bool)(this["ForceNonParallel"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("Controller_Event_Log")]
        public string DestinationTableName {
            get {
                return ((string)(this["DestinationTableName"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("5000")]
        public int BulkCopyBatchSize {
            get {
                return ((int)(this["BulkCopyBatchSize"]));
            }
        }

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("30")]
        public int BulkCopyTimeOut {
            get {
                return ((int)(this["BulkCopyTimeOut"]));
            }
        }
    }
}


text:
package org.wildfly.extras.creaper.commands.security;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.File;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.wildfly.extras.creaper.core.CommandFailedException;
import org.wildfly.extras.creaper.core.ManagementClient;
import org.wildfly.extras.creaper.core.offline.OfflineManagementClient;
import org.wildfly.extras.creaper.core.offline.OfflineOptions;

import static org.junit.Assert.fail;
import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical;

public class AddMappingModuleOfflineTest {

    private static final String TEST_SECURITY_DOMAIN_NAME = "creaperSecDomain";

    private static final String SUBSYSTEM_ORIGINAL = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\"/>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_WITH_ONE_MAPPING_MODULE = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"PropertiesRoles\" code=\"PropertiesRoles\" "
            + "type=\"role\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_WITH_ONE_MAPPING_MODULE_WITHOUT_NAME = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module code=\"PropertiesRoles\" type=\"role\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_WITH_TWO_MAPPING_MODULES = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"PropertiesRoles\" code=\"PropertiesRoles\" "
            + "type=\"role\"/>\n"
            + "                        <mapping-module name=\"CreaperModule\" code=\"PropertiesRoles\" "
            + "type=\"role\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"CreaperModule\" code=\"PropertiesRoles\" "
            + "type=\"role\"/>\n"
            + "                        <mapping-module code=\"PropertiesRoles\" type=\"role\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_REPLACED_EXPECTED = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"PropertiesRoles\" code=\"PropertiesRoles\" "
            + "type=\"attribute\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_FULL_EXPECTED = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"CreaperModule\" code=\"PropertiesRoles\" type=\"role\" "
            + "module=\"org.picketbox\">\n"
            + "                            <module-option name=\"rolesProperties\" value=\"roles.properties\"/>\n"
            + "                        </mapping-module>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    private static final String SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED_REPLACE_EXPECTED = ""
            + "<server xmlns=\"urn:jboss:domain:1.7\">\n"
            + "    <profile>\n"
            + "        <subsystem xmlns=\"urn:jboss:domain:security:1.2\">\n"
            + "            <security-domains>\n"
            + "                <security-domain name=\"creaperSecDomain\">\n"
            + "                    <mapping>\n"
            + "                        <mapping-module name=\"CreaperModule\" code=\"PropertiesRoles\" "
            + "type=\"role\"/>\n"
            + "                        <mapping-module name=\"PropertiesRoles\" code=\"PropertiesRoles\" "
            + "type=\"attribute\"/>\n"
            + "                    </mapping>\n"
            + "                </security-domain>\n"
            + "            </security-domains>\n"
            + "        </subsystem>\n"
            + "    </profile>\n"
            + "</server>";

    @Rule
    public final TemporaryFolder tmp = new TemporaryFolder();

    @Before
    public void setUp() {
        XMLUnit.setNormalizeWhitespace(true);
    }

    @Test
    public void addSimple() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_ORIGINAL, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("role")
                .build();

        assertXmlIdentical(SUBSYSTEM_ORIGINAL, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, Files.toString(cfg, Charsets.UTF_8));
    }

    @Test
    public void addSecondSimple() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles", "CreaperModule")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("role")
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_WITH_TWO_MAPPING_MODULES, Files.toString(cfg, Charsets.UTF_8));
    }

    @Test(expected = CommandFailedException.class)
    public void existing() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);

        fail("Login module already exists in configuration, exception should be thrown");
    }

    @Test
    public void overrideExisting() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .replaceExisting()
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_REPLACED_EXPECTED, Files.toString(cfg, Charsets.UTF_8));

    }

    @Test(expected = CommandFailedException.class)
    public void existingWithoutName() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_ONE_MAPPING_MODULE_WITHOUT_NAME, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE_WITHOUT_NAME, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);

        fail("Login module already exists in configuration, exception should be thrown");

    }

    @Test
    public void overrideExistingWithoutName() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_ONE_MAPPING_MODULE_WITHOUT_NAME, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .replaceExisting()
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_ONE_MAPPING_MODULE_WITHOUT_NAME, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_REPLACED_EXPECTED, Files.toString(cfg, Charsets.UTF_8));
    }

    @Test(expected = CommandFailedException.class)
    public void existingWithoutNameTwoLoginModules() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);

        fail("Login module already exists in configuration, exception should be thrown");

    }

    @Test
    public void overrideExistingWithoutNameTwoLoginModules() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("attribute")
                .replaceExisting()
                .build();

        assertXmlIdentical(SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_WITH_TWO_MAPPING_MODULES_UNNAMED_REPLACE_EXPECTED, Files.toString(cfg,
                Charsets.UTF_8));
    }

    @Test
    public void addFullLoginModule() throws Exception {
        File cfg = tmp.newFile("xmlTransform.xml");
        Files.write(SUBSYSTEM_ORIGINAL, cfg, Charsets.UTF_8);

        OfflineManagementClient client = ManagementClient.offline(
                OfflineOptions.standalone().configurationFile(cfg).build());

        AddMappingModule addMappingModule = new AddMappingModule.Builder("PropertiesRoles", "CreaperModule")
                .securityDomainName(TEST_SECURITY_DOMAIN_NAME)
                .type("role")
                .module("org.picketbox")
                .addModuleOption("rolesProperties", "roles.properties")
                .build();

        assertXmlIdentical(SUBSYSTEM_ORIGINAL, Files.toString(cfg, Charsets.UTF_8));
        client.apply(addMappingModule);
        assertXmlIdentical(SUBSYSTEM_FULL_EXPECTED, Files.toString(cfg, Charsets.UTF_8));
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace RelatedData.Controllers
{
    public class Supplier
    {
        public Supplier()
        {
            this.Products = new List<Product>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public string Country { get; set; }

        // 'Navigation property' - association - collection of Product objects
        public ICollection<Product> Products { get; set; }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ProductCode { get; set; }
        public string UPC { get; set; }
        public double MSRP { get; set; }

        // 'Navigation property' - association - Supplier object
        public Supplier Supplier { get; set; }
    }

}


text:
class ImproveUsersIndexing < ActiveRecord::Migration[5.0]
  def change
    add_index :users, :updated_at
    add_index :users, :github_id
  end
end


text:
package org.cactoos.list;

import java.util.List;
import java.util.ListIterator;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.hamcrest.collection.IsEmptyCollection;
import org.hamcrest.core.IsEqual;
import org.junit.jupiter.api.Test;
import org.llorllale.cactoos.matchers.Assertion;
import org.llorllale.cactoos.matchers.HasValues;

/**
 * Test case for {@link ListEnvelope}.
 *
 * @since 0.32
 * @checkstyle JavadocMethodCheck (500 lines)
 * @checkstyle JavadocTypeCheck (500 lines)
 */
@SuppressWarnings({"PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals"})
final class ListEnvelopeTest {

    @Test
    void returnsListIteratorWithSupportedSet() {
        final ListEnvelope<String> list = new StringList("one", "two");
        final ListIterator<String> iterator = list.listIterator(1);
        iterator.next();
        iterator.set("zero");
        iterator.previous();
        MatcherAssert.assertThat(
            "iterator is not equal to expected",
            () -> iterator,
            Matchers.contains(
                "zero"
            )
        );
    }

    @Test
    void removeIsDelegated() {
        final ListEnvelope<String> list = new StringList("one");
        list.remove(0);
        new Assertion<>(
            "must be empty after removal of 0th element",
            list,
            new IsEmptyCollection<>()
        ).affirm();
    }

    @Test
    void indexOfIsDelegated() {
        final ListEnvelope<String> list = new StringList("one");
        new Assertion<>(
            "must return correct index of element",
            list.indexOf("one"),
            new IsEqual<>(0)
        ).affirm();
    }

    @Test
    void addAllIsDelegated() {
        final ListEnvelope<String> list = new StringList("one");
        list.addAll(0, new StringList("two"));
        new Assertion<>(
            "element must be added at 0th position",
            list,
            new IsEqual<>(new ListOf<>("two", "one"))
        ).affirm();
    }

    @Test
    void setIsDelegatedToTheOriginal() {
        final ListEnvelope<String> list = new StringList("one");
        list.set(0, "zero");
        new Assertion<>(
            "value must be changed",
            list,
            new HasValues<>("zero")
        ).affirm();
    }

    @Test
    void addIsDelegated() {
        final ListEnvelope<String> list = new StringList("one");
        list.add("two");
        new Assertion<>(
            "value must be added",
            list,
            new HasValues<>("one", "two")
        ).affirm();
    }

    void returnsSubListWithRemove() {
        final ListEnvelope<String> list = new StringList("one");
        list.subList(0, 1).remove(0);
        new Assertion<>(
            "must be empty after removal of 0th element via subList",
            list,
            new IsEmptyCollection<>()
        ).affirm();
    }

    @Test
    void returnsSubListWithSupportedSet() {
        final List<String> list = new StringList("one");
        list.subList(0, 1).set(0, "zero");
        new Assertion<>(
            "ListEnvelope().subList(...).set() must change the original list",
            list,
            new HasValues<>(
                "zero"
            )
        ).affirm();
    }

    @Test
    void addsAtGivenIndex() {
        final ListEnvelope<String> list = new StringList("one");
        list.add(0, "two");
        new Assertion<>(
            "must add value at given index",
            list,
            new HasValues<>("two")
        ).affirm();
    }

    @Test
    void getsAtGivenIndex() {
        final ListEnvelope<String> list = new StringList("one");
        new Assertion<>(
            "must get 0th value",
            list.get(0),
            new IsEqual<>("one")
        ).affirm();
    }

    @Test
    void getsLastIndexOfValue() {
        final ListEnvelope<String> list = new StringList("one");
        list.add(1, "one");
        new Assertion<>(
            "must return correct last index of element",
            list.lastIndexOf("one"),
            new IsEqual<>(1)
        ).affirm();
    }

    @Test
    void mustReturnPreviousIndex() {
        new Assertion<>(
            "List iterator must return previous index",
            new StringList("1").listIterator().previousIndex(),
            new IsEqual<>(-1)
        ).affirm();
    }

    @Test
    void mustReturnPreviousElement() {
        new Assertion<>(
            "List iterator must return previous element",
            new StringList("3", "7").listIterator(1).previous(),
            new IsEqual<>("3")
        ).affirm();
    }

    @Test
    void mustReturnNextIndex() {
        new Assertion<>(
            "List iterator must return next index",
            new StringList("1").listIterator().nextIndex(),
            new IsEqual<>(0)
        ).affirm();
    }

    @Test
    void mustReturnNextElement() {
        new Assertion<>(
            "List iterator must return next item",
            new  StringList("5", "11", "13").listIterator(1).next(),
            new IsEqual<>("11")
        ).affirm();
    }

    private static final class StringList extends ListEnvelope<String> {
        StringList(final String... elements) {
            super(new ListOf<>(elements));
        }
    }
}


text:
module Test.Framework.Providers.API where

import           Test.Hspec.Core.Spec

type TestName = String
type Test = SpecTree ()


text:
/*
 *
 *
 *   Module Name: SamFDlg
 *
 *   OS/2 Workplace Shell Access Manager
 *
 */

#include <string.h>
#include <stdlib.h>

#include "wpsamf.ih"
#include "wpsamf.ph"

extern HMODULE  hmod;

/**************************  ORDINARY CODE SECTION  ***************************
*****                                                                     *****
*****                  Any non-method code should go here.                *****
*****                                                                     *****
******************************************************************************/
#undef SOM_CurrentClass

MRESULT EXPENTRY CtxtDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
    {
    static PWINDOWDATA pWindowData;
    static WPSamFData  *somThis;

    switch (msg)
        {
        case WM_INITDLG:
            pWindowData =
                (PWINDOWDATA) _wpAllocMem ((WPSamF *) mp2, sizeof(*pWindowData), NULL);

            if (pWindowData)
                {
                pWindowData->somSelf = (WPSamF *) mp2;
                somThis = WPSamFGetData(pWindowData->somSelf);
                }
            else
                {
                DebugE (-1, "AdjustDlgProc: WM_INITDLG",
                          "Couldn't allocate window words");
                break;
                }

            WinSetWindowPtr (hwnd, QWL_USER, pWindowData);

            WinCheckButton (hwnd, DID_SORTENABLE,     (_ulFlag & SORTENABLE)     ? 1 : 0);
            WinCheckButton (hwnd, DID_ARRANGEENABLE,  (_ulFlag & ARRANGEENABLE)  ? 1 : 0);
            WinCheckButton (hwnd, DID_SHUTDOWNENABLE, (_ulFlag & SHUTDOWNENABLE) ? 1 : 0);
            WinCheckButton (hwnd, DID_LOCKUPENABLE,   (_ulFlag & LOCKUPENABLE)   ? 1 : 0);
            WinCheckButton (hwnd, DID_ORIGDESKENABLE, (_ulFlag & ORIGDESKENABLE) ? 1 : 0);

            return (MRESULT) FALSE;

        case WM_COMMAND:
            switch (COMMANDMSG(&msg)->cmd)
                {
                case DID_DEFAULT:
                   DebugE (-1, "AdjustDlgProc: WM_COMMAND", "DEFAULT");
                   break;

                case DID_HELP:
                   break;

                }
            return 0;

        case WM_CONTROL:
            switch (SHORT1FROMMP(mp1))
            {
                case DID_SORTENABLE:
                   if (WinSendDlgItemMsg(hwnd, DID_SORTENABLE, BM_QUERYCHECK, NULL, NULL))
                      _ulFlag |= SORTENABLE;

                   else
                      _ulFlag &= ~SORTENABLE;

                   _wpSaveDeferred(pWindowData->somSelf);
                   break;

                case DID_ARRANGEENABLE:
                   if (WinSendDlgItemMsg(hwnd, DID_ARRANGEENABLE, BM_QUERYCHECK, NULL, NULL))
                      _ulFlag |= ARRANGEENABLE;

                   else
                      _ulFlag &= ~ARRANGEENABLE;

                   _wpSaveDeferred(pWindowData->somSelf);
                   break;

                case DID_SHUTDOWNENABLE:
                   if (WinSendDlgItemMsg(hwnd, DID_SHUTDOWNENABLE, BM_QUERYCHECK, NULL, NULL))
                      _ulFlag |= SHUTDOWNENABLE;

                   else
                      _ulFlag &= ~SHUTDOWNENABLE;

                   _wpSaveDeferred(pWindowData->somSelf);
                   break;

                case DID_LOCKUPENABLE:
                   if (WinSendDlgItemMsg(hwnd, DID_LOCKUPENABLE, BM_QUERYCHECK, NULL, NULL))
                      _ulFlag |= LOCKUPENABLE;

                   else
                      _ulFlag &= ~LOCKUPENABLE;

                   _wpSaveDeferred(pWindowData->somSelf);
                   break;

                case DID_ORIGDESKENABLE:
                   if (WinSendDlgItemMsg(hwnd, DID_ORIGDESKENABLE, BM_QUERYCHECK, NULL, NULL))
                      _ulFlag |= ORIGDESKENABLE;

                   else
                      _ulFlag &= ~ORIGDESKENABLE;

                   _wpSaveDeferred(pWindowData->somSelf);
                   break;

            }

            return 0;

        }

    return WinDefDlgProc (hwnd, msg, mp1, mp2);
    }


text:
A module for exposing defined business logic via URLs, in web consumable
formats, and for providing access to consumers of these webservices via
token access.

These are NOT strictly speaking REST services, in that a single URL isn't
meant to be accessible via GET and POST; it is RPC over HTTP.

## Maintainer Contacts

*  Marcus Nyeholt <marcus@silverstripe.com.au>

## Versions

The master branch of this module is currently aiming for SilverStripe 3.1 compatibility

* [SilverStripe 3.0 compatible version](https://github.com/nyeholt/silverstripe-webservices/tree/2.0)
* [SilverStripe 2.4 compatible version](https://github.com/nyeholt/silverstripe-webservices/tree/ss24)

## Requirements

* SilverStripe 2.4+

## Installation

* Place this directory in the root of your SilverStripe installation.
* Run dev/build
* Creates your service class, which will be accessible by both controller
  code and directly via the web
* Access your service via the appropriate URL, eg

	http://yourUrl/jsonservice/DummyWeb/myMethod?param=stuff&SecurityID=security_id_here

* Use the response

## Documentation

The webservices module will automatically translate a url based request to a
system service from URL + parameters to a method and variables, then
automatically convert the response into a web accessible format (JSON and XML
supported, though XML is not yet complete). Part of its goal is to encourage
service oriented architectures in SilverStripe projects so that business logic
is encapsulated in a layer away from controllers (an all too common problem).

URLs are decomposed as follows

    (type)/(service)/(method)?(paramName)=(value)&token=(token)[&SecurityID=(securityID)]

* type: either jsonservice or webservice, indicates the desired output format
* service: the name of a service class (see below). It expects the service to
  end in the string 'Service' - in fact, that will be automatically appended to
  the name passed through here.
* method: the name of the method to call on the service
* paramName/value: key/value pairs representing parameters. The paramName MUST
  match the name of the parameter in the method declaration.
  * See the note below for information on how to pass DataObjects
* token | SecurityID: Each request must be verified; this is either through
  the use of a token parameter (which matches up with a user's API token) OR
  by passing the security ID for a user who has already logged in. The token
  can be found by looking on the user's details tab in the CMS

Included is an example service for creating events in a calendar using the
event_calendar module. You can create events for this using the following
curl statement

    curl -X POST -d "token={your token here}&parentCalendar={ID of calendar}&title=My new event&content=This is an event on a day here and now&startDate=2012-04-21" http://{your site url}/jsonservice/calendarweb/createEvent

### Passing DataObjects

In some cases you'll be wanting to pass data objects to your service method.
To allow that from URL parameters, you can instead pass an ID and Type parameter
which will be converted for use appropriately. For example, this method signature

	public function myMethod(DataObject $page) {

	}

can be accessed via

	jsonservice/Service/myMethod?pageID=1&pageType=Page

The module will take care of converting that to the relevant object type

### Allowing access to services and their methods

To be able to call methods on a service, the service has to be marked as being
accessible - this is done in one of two ways

* Implement the `WebServiceable` interface
* Implement the `webEnabledMethods` method, which returns an map of method names
  and the request type that they support (GET or POST only supported currently).
  Note that to perform user level access control, you should perform the checks
  in the method directly, OR wrap user checking logic around the array this
  method generates.

So, by default, it's not possible to arbitrarily call any service. Also, the
`webEnabledMethods` call does NOT use SilverStripe's hasMethod construct (as
it is not expected that a service carry the overhead of inheriting from
'Object') so at the moment this is not overrideable using extensions. There will
be ways to update this via extensions at a later date.

### Passing parameters via URL

The webservice controller supports passing parameter/value pairs via the URL.
For example, the following request will have the parameters extracted

/jsonservice/my/method/name/something/id/2

Will call My::method(), passing parameters of

* name = something
* id = 2

### File uploads

Files can be handled as either multipart uploads or by posting the raw file to
the webservice, typically in conjuction with the URL parameter referencing above.

To have the file accessible to your service method, you MUST have a method
parameter named "file" and a request type of POST; the raw post body of the
request will be placed in the "file" variable, and any parameters found on the
URL also passed through.

eg in your service

    public function method($file, $name) {

    }

sending a post such as

    curl -X POST -d @somefile.jpg http://site/jsonservice/my/method/name/myfile.jpg

will send the body of somefile.jpg in the $file variable, and $name == 'myfile.jpg'

### Sending POST body

Instead of passing parameters via the URL, you can send all method parameters
in a JSON object that is the body of a POST request. For example, the JSON data

```JSON
{
    "parentCalendar": "2",
    "title": "This is a calendar event"
}
```

will pass the two fields as the parameters to whichever method is named by the
URL. The important thing is that you MUST send the `Content-Type: application/json`
header.

### Tokens

Authentication tokens can be passed either in the URL as the _token_ GET
parameter, or by including the `X-Auth-Token` header in the request.

The module will automatically add a 'Token' field to user objects, and
generate a random token when a user account is created. This can be used
to access the API without being logged in first.

Otherwise, if the user is logged in, they can pass through the security token
as a parameter (appropriately named, by default SecurityID) with the request
which will grant the user access. This can be disabled by setting the
`allowPublicAccess` parameter for the WebserviceAuthenticator

    Injector:
      WebserviceAuthenticator:
        properties:
          allowPublicAccess: 0


text:
package dockershim

import (
	"fmt"
	"testing"

	dockertypes "github.com/docker/docker/api/types"
	"github.com/docker/docker/pkg/jsonmessage"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
	"k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker"
)

func TestRemoveImage(t *testing.T) {
	ds, fakeDocker, _ := newTestDockerService()
	id := "1111"
	fakeDocker.InjectImageInspects([]dockertypes.ImageInspect{{ID: id, RepoTags: []string{"foo"}}})
	ds.RemoveImage(getTestCTX(), &runtimeapi.RemoveImageRequest{Image: &runtimeapi.ImageSpec{Image: id}})
	fakeDocker.AssertCallDetails(libdocker.NewCalledDetail("inspect_image", nil),
		libdocker.NewCalledDetail("remove_image", []interface{}{id, dockertypes.ImageRemoveOptions{PruneChildren: true}}))
}

func TestRemoveImageWithMultipleTags(t *testing.T) {
	ds, fakeDocker, _ := newTestDockerService()
	id := "1111"
	fakeDocker.InjectImageInspects([]dockertypes.ImageInspect{{ID: id, RepoTags: []string{"foo", "bar"}}})
	ds.RemoveImage(getTestCTX(), &runtimeapi.RemoveImageRequest{Image: &runtimeapi.ImageSpec{Image: id}})
	fakeDocker.AssertCallDetails(libdocker.NewCalledDetail("inspect_image", nil),
		libdocker.NewCalledDetail("remove_image", []interface{}{"foo", dockertypes.ImageRemoveOptions{PruneChildren: true}}),
		libdocker.NewCalledDetail("remove_image", []interface{}{"bar", dockertypes.ImageRemoveOptions{PruneChildren: true}}))
}

func TestPullWithJSONError(t *testing.T) {
	ds, fakeDocker, _ := newTestDockerService()
	tests := map[string]struct {
		image         *runtimeapi.ImageSpec
		err           error
		expectedError string
	}{
		"Json error": {
			&runtimeapi.ImageSpec{Image: "ubuntu"},
			&jsonmessage.JSONError{Code: 50, Message: "Json error"},
			"Json error",
		},
		"Bad gateway": {
			&runtimeapi.ImageSpec{Image: "ubuntu"},
			&jsonmessage.JSONError{Code: 502, Message: "<!doctype html>\n\n    \n  \n    \n
Oops, there was an error!
\n
We have been contacted of this error, feel free to check out status.docker.com\n           to see if there is a bigger issue.
\n\n    \n"},
			"RegistryUnavailable",
		},
	}
	for key, test := range tests {
		fakeDocker.InjectError("pull", test.err)
		_, err := ds.PullImage(getTestCTX(), &runtimeapi.PullImageRequest{Image: test.image, Auth: &runtimeapi.AuthConfig{}})
		require.Error(t, err, fmt.Sprintf("TestCase [%s]", key))
		assert.Contains(t, err.Error(), test.expectedError)
	}
}


text:
package main

import (
	"fmt"
	"io"
	"os"

	"github.com/gorilla/websocket"
	"github.com/mattn/go-colorable"
)

func (c *consoleCmd) getStdout() io.WriteCloser {
	// Defined in exec_windows.go
	return &WrappedWriteCloser{os.Stdout, colorable.NewColorableStdout()}
}

func (c *consoleCmd) getTERM() (string, bool) {
	return "dumb", true
}

func (c *consoleCmd) controlSocketHandler(control *websocket.Conn) {
	// TODO: figure out what the equivalent of signal.SIGWINCH is on
	// windows and use that; for now if you resize your terminal it just
	// won't work quite correctly.
	err := c.sendTermSize(control)
	if err != nil {
		fmt.Printf("error setting term size %s\n", err)
	}
}


text:
package consul

import (
	"fmt"
	"io"
	"net"
	"os"
	"time"

	"github.com/hashicorp/consul/agent/consul/structs"
	"github.com/hashicorp/consul/tlsutil"
	"github.com/hashicorp/consul/types"
	"github.com/hashicorp/memberlist"
	"github.com/hashicorp/raft"
	"github.com/hashicorp/serf/serf"
)

const (
	DefaultDC          = "dc1"
	DefaultRPCPort     = 8300
	DefaultLANSerfPort = 8301
	DefaultWANSerfPort = 8302

	// DefaultRaftMultiplier is used as a baseline Raft configuration that
	// will be reliable on a very basic server. See docs/guides/performance.html
	// for information on how this value was obtained.
	DefaultRaftMultiplier uint = 5

	// MaxRaftMultiplier is a fairly arbitrary upper bound that limits the
	// amount of performance detuning that's possible.
	MaxRaftMultiplier uint = 10
)

var (
	DefaultRPCAddr = &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: DefaultRPCPort}

	// ProtocolVersionMap is the mapping of Consul protocol versions
	// to Serf protocol versions. We mask the Serf protocols using
	// our own protocol version.
	protocolVersionMap map[uint8]uint8
)

func init() {
	protocolVersionMap = map[uint8]uint8{
		1: 4,
		2: 4,
		3: 4,
	}
}

// Config is used to configure the server
type Config struct {
	// Bootstrap mode is used to bring up the first Consul server.
	// It is required so that it can elect a leader without any
	// other nodes being present
	Bootstrap bool

	// BootstrapExpect mode is used to automatically bring up a collection of
	// Consul servers. This can be used to automatically bring up a collection
	// of nodes.
	BootstrapExpect int

	// Datacenter is the datacenter this Consul server represents
	Datacenter string

	// DataDir is the directory to store our state in
	DataDir string

	// DevMode is used to enable a development server mode.
	DevMode bool

	// NodeID is a unique identifier for this node across space and time.
	NodeID types.NodeID

	// Node name is the name we use to advertise. Defaults to hostname.
	NodeName string

	// Domain is the DNS domain for the records. Defaults to "consul."
	Domain string

	// RaftConfig is the configuration used for Raft in the local DC
	RaftConfig *raft.Config

	// (Enterprise-only) NonVoter is used to prevent this server from being added
	// as a voting member of the Raft cluster.
	NonVoter bool

	// RPCAddr is the RPC address used by Consul. This should be reachable
	// by the WAN and LAN
	RPCAddr *net.TCPAddr

	// RPCAdvertise is the address that is advertised to other nodes for
	// the RPC endpoint. This can differ from the RPC address, if for example
	// the RPCAddr is unspecified "0.0.0.0:8300", but this address must be
	// reachable
	RPCAdvertise *net.TCPAddr

	// RPCSrcAddr is the source address for outgoing RPC connections.
	RPCSrcAddr *net.TCPAddr

	// SerfLANConfig is the configuration for the intra-dc serf
	SerfLANConfig *serf.Config

	// SerfWANConfig is the configuration for the cross-dc serf
	SerfWANConfig *serf.Config

	// SerfFloodInterval controls how often we attempt to flood local Serf
	// Consul servers into the global areas (WAN and user-defined areas in
	// Consul Enterprise).
	SerfFloodInterval time.Duration

	// ReconcileInterval controls how often we reconcile the strongly
	// consistent store with the Serf info. This is used to handle nodes
	// that are force removed, as well as intermittent unavailability during
	// leader election.
	ReconcileInterval time.Duration

	// LogOutput is the location to write logs to. If this is not set,
	// logs will go to stderr.
	LogOutput io.Writer

	// ProtocolVersion is the protocol version to speak. This must be between
	// ProtocolVersionMin and ProtocolVersionMax.
	ProtocolVersion uint8

	// VerifyIncoming is used to verify the authenticity of incoming connections.
	// This means that TCP requests are forbidden, only allowing for TLS. TLS connections
	// must match a provided certificate authority. This can be used to force client auth.
	VerifyIncoming bool

	// VerifyOutgoing is used to force verification of the authenticity of outgoing connections.
	// This means that TLS requests are used, and TCP requests are not made. TLS connections
	// must match a provided certificate authority.
	VerifyOutgoing bool

	// UseTLS is used to enable TLS for outgoing connections to other TLS-capable Consul
	// servers. This doesn't imply any verification, it only enables TLS if possible.
	UseTLS bool

	// VerifyServerHostname is used to enable hostname verification of servers. This
	// ensures that the certificate presented is valid for server.<datacenter>.<domain>.
	// This prevents a compromised client from being restarted as a server, and then
	// intercepting request traffic as well as being added as a raft peer. This should be
	// enabled by default with VerifyOutgoing, but for legacy reasons we cannot break
	// existing clients.
	VerifyServerHostname bool

	// CAFile is a path to a certificate authority file. This is used with VerifyIncoming
	// or VerifyOutgoing to verify the TLS connection.
	CAFile string

	// CAPath is a path to a directory of certificate authority files. This is used with
	// VerifyIncoming or VerifyOutgoing to verify the TLS connection.
	CAPath string

	// CertFile is used to provide a TLS certificate that is used for serving TLS connections.
	// Must be provided to serve TLS connections.
	CertFile string

	// KeyFile is used to provide a TLS key that is used for serving TLS connections.
	// Must be provided to serve TLS connections.
	KeyFile string

	// ServerName is used with the TLS certificate to ensure the name we
	// provide matches the certificate
	ServerName string

	// TLSMinVersion is used to set the minimum TLS version used for TLS connections.
	TLSMinVersion string

	// TLSCipherSuites is used to specify the list of supported ciphersuites.
	TLSCipherSuites []uint16

	// TLSPreferServerCipherSuites specifies whether to prefer the server's ciphersuite
	// over the client ciphersuites.
	TLSPreferServerCipherSuites bool

	// RejoinAfterLeave controls our interaction with Serf.
	// When set to false (default), a leave causes a Consul to not rejoin
	// the cluster until an explicit join is received. If this is set to
	// true, we ignore the leave, and rejoin the cluster on start.
	RejoinAfterLeave bool

	// Build is a string that is gossiped around, and can be used to help
	// operators track which versions are actively deployed
	Build string

	// ACLToken is the default token to use when making a request.
	// If not provided, the anonymous token is used. This enables
	// backwards compatibility as well.
	ACLToken string

	// ACLAgentToken is the default token used to make requests for the agent
	// itself, such as for registering itself with the catalog. If not
	// configured, the ACLToken will be used.
	ACLAgentToken string

	// ACLMasterToken is used to bootstrap the ACL system. It should be specified
	// on the servers in the ACLDatacenter. When the leader comes online, it ensures
	// that the Master token is available. This provides the initial token.
	ACLMasterToken string

	// ACLDatacenter provides the authoritative datacenter for ACL
	// tokens. If not provided, ACL verification is disabled.
	ACLDatacenter string

	// ACLTTL controls the time-to-live of cached ACL policies.
	// It can be set to zero to disable caching, but this adds
	// a substantial cost.
	ACLTTL time.Duration

	// ACLDefaultPolicy is used to control the ACL interaction when
	// there is no defined policy. This can be "allow" which means
	// ACLs are used to black-list, or "deny" which means ACLs are
	// white-lists.
	ACLDefaultPolicy string

	// ACLDownPolicy controls the behavior of ACLs if the ACLDatacenter
	// cannot be contacted. It can be either "deny" to deny all requests,
	// or "extend-cache" which ignores the ACLCacheInterval and uses
	// cached policies. If a policy is not in the cache, it acts like deny.
	// "allow" can be used to allow all requests. This is not recommended.
	ACLDownPolicy string

	// ACLReplicationToken is used to fetch ACLs from the ACLDatacenter in
	// order to replicate them locally. Setting this to a non-empty value
	// also enables replication. Replication is only available in datacenters
	// other than the ACLDatacenter.
	ACLReplicationToken string

	// ACLReplicationInterval is the interval at which replication passes
	// will occur. Queries to the ACLDatacenter may block, so replication
	// can happen less often than this, but the interval forms the upper
	// limit to how fast we will go if there was constant ACL churn on the
	// remote end.
	ACLReplicationInterval time.Duration

	// ACLReplicationApplyLimit is the max number of replication-related
	// apply operations that we allow during a one second period. This is
	// used to limit the amount of Raft bandwidth used for replication.
	ACLReplicationApplyLimit int

	// ACLEnforceVersion8 is used to gate a set of ACL policy features that
	// are opt-in prior to Consul 0.8 and opt-out in Consul 0.8 and later.
	ACLEnforceVersion8 bool

	// TombstoneTTL is used to control how long KV tombstones are retained.
	// This provides a window of time where the X-Consul-Index is monotonic.
	// Outside this window, the index may not be monotonic. This is a result
	// of a few trade offs:
	// 1) The index is defined by the data view and not globally. This is a
	// performance optimization that prevents any write from incrementing the
	// index for all data views.
	// 2) Tombstones are not kept indefinitely, since otherwise storage required
	// is also monotonic. This prevents deletes from reducing the disk space
	// used.
	// In theory, neither of these are intrinsic limitations, however for the
	// purposes of building a practical system, they are reasonable trade offs.
	//
	// It is also possible to set this to an incredibly long time, thereby
	// simulating infinite retention. This is not recommended however.
	//
	TombstoneTTL time.Duration

	// TombstoneTTLGranularity is used to control how granular the timers are
	// for the Tombstone GC. This is used to batch the GC of many keys together
	// to reduce overhead. It is unlikely a user would ever need to tune this.
	TombstoneTTLGranularity time.Duration

	// Minimum Session TTL
	SessionTTLMin time.Duration

	// ServerUp callback can be used to trigger a notification that
	// a Consul server is now up and known about.
	ServerUp func()

	// UserEventHandler callback can be used to handle incoming
	// user events. This function should not block.
	UserEventHandler func(serf.UserEvent)

	// CoordinateUpdatePeriod controls how long a server batches coordinate
	// updates before applying them in a Raft transaction. A larger period
	// leads to fewer Raft transactions, but also the stored coordinates
	// being more stale.
	CoordinateUpdatePeriod time.Duration

	// CoordinateUpdateBatchSize controls the maximum number of updates a
	// server batches before applying them in a Raft transaction.
	CoordinateUpdateBatchSize int

	// CoordinateUpdateMaxBatches controls the maximum number of batches we
	// are willing to apply in one period. After this limit we will issue a
	// warning and discard the remaining updates.
	CoordinateUpdateMaxBatches int

	// RPCHoldTimeout is how long an RPC can be "held" before it is errored.
	// This is used to paper over a loss of leadership by instead holding RPCs,
	// so that the caller experiences a slow response rather than an error.
	// This period is meant to be long enough for a leader election to take
	// place, and a small jitter is applied to avoid a thundering herd.
	RPCHoldTimeout time.Duration

	// AutopilotConfig is used to apply the initial autopilot config when
	// bootstrapping.
	AutopilotConfig *structs.AutopilotConfig

	// ServerHealthInterval is the frequency with which the health of the
	// servers in the cluster will be updated.
	ServerHealthInterval time.Duration

	// AutopilotInterval is the frequency with which the leader will perform
	// autopilot tasks, such as promoting eligible non-voters and removing
	// dead servers.
	AutopilotInterval time.Duration
}

// CheckProtocolVersion validates the protocol version.
func (c *Config) CheckProtocolVersion() error {
	if c.ProtocolVersion < ProtocolVersionMin {
		return fmt.Errorf("Protocol version '%d' too low. Must be in range: [%d, %d]", c.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax)
	}
	if c.ProtocolVersion > ProtocolVersionMax {
		return fmt.Errorf("Protocol version '%d' too high. Must be in range: [%d, %d]", c.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax)
	}
	return nil
}

// CheckACL validates the ACL configuration.
func (c *Config) CheckACL() error {
	switch c.ACLDefaultPolicy {
	case "allow":
	case "deny":
	default:
		return fmt.Errorf("Unsupported default ACL policy: %s", c.ACLDefaultPolicy)
	}
	switch c.ACLDownPolicy {
	case "allow":
	case "deny":
	case "extend-cache":
	default:
		return fmt.Errorf("Unsupported down ACL policy: %s", c.ACLDownPolicy)
	}
	return nil
}

// DefaultConfig returns a sane default configuration.
func DefaultConfig() *Config {
	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	conf := &Config{
		Build:                    "0.8.0",
		Datacenter:               DefaultDC,
		NodeName:                 hostname,
		RPCAddr:                  DefaultRPCAddr,
		RaftConfig:               raft.DefaultConfig(),
		SerfLANConfig:            serf.DefaultConfig(),
		SerfWANConfig:            serf.DefaultConfig(),
		SerfFloodInterval:        60 * time.Second,
		ReconcileInterval:        60 * time.Second,
		ProtocolVersion:          ProtocolVersion2Compatible,
		ACLTTL:                   30 * time.Second,
		ACLDefaultPolicy:         "allow",
		ACLDownPolicy:            "extend-cache",
		ACLReplicationInterval:   30 * time.Second,
		ACLReplicationApplyLimit: 100, // ops / sec
		TombstoneTTL:             15 * time.Minute,
		TombstoneTTLGranularity:  30 * time.Second,
		SessionTTLMin:            10 * time.Second,

		// These are tuned to provide a total throughput of 128 updates
		// per second. If you update these, you should update the client-
		// side SyncCoordinateRateTarget parameter accordingly.
		CoordinateUpdatePeriod:     5 * time.Second,
		CoordinateUpdateBatchSize:  128,
		CoordinateUpdateMaxBatches: 5,

		// This holds RPCs during leader elections. For the default Raft
		// config the election timeout is 5 seconds, so we set this a
		// bit longer to try to cover that period. This should be more
		// than enough when running in the high performance mode.
		RPCHoldTimeout: 7 * time.Second,

		TLSMinVersion: "tls10",

		AutopilotConfig: &structs.AutopilotConfig{
			CleanupDeadServers:      true,
			LastContactThreshold:    200 * time.Millisecond,
			MaxTrailingLogs:         250,
			ServerStabilizationTime: 10 * time.Second,
		},
		ServerHealthInterval: 2 * time.Second,
		AutopilotInterval:    10 * time.Second,
	}

	// Increase our reap interval to 3 days instead of 24h.
	conf.SerfLANConfig.ReconnectTimeout = 3 * 24 * time.Hour
	conf.SerfWANConfig.ReconnectTimeout = 3 * 24 * time.Hour

	// WAN Serf should use the WAN timing, since we are using it
	// to communicate between DC's
	conf.SerfWANConfig.MemberlistConfig = memberlist.DefaultWANConfig()

	// Ensure we don't have port conflicts
	conf.SerfLANConfig.MemberlistConfig.BindPort = DefaultLANSerfPort
	conf.SerfWANConfig.MemberlistConfig.BindPort = DefaultWANSerfPort

	// TODO: default to 3 in Consul 0.9
	// Use a transitional version of the raft protocol to interoperate with
	// versions 1 and 3
	conf.RaftConfig.ProtocolVersion = 2
	conf.ScaleRaft(DefaultRaftMultiplier)

	// Disable shutdown on removal
	conf.RaftConfig.ShutdownOnRemove = false

	// Check every 5 seconds to see if there are enough new entries for a snapshot
	conf.RaftConfig.SnapshotInterval = 5 * time.Second

	return conf
}

// ScaleRaft sets the config to have Raft timing parameters scaled by the given
// performance multiplier. This is done in an idempotent way so it's not tricky
// to call this when composing configurations and potentially calling this
// multiple times on the same structure.
func (c *Config) ScaleRaft(raftMultRaw uint) {
	raftMult := time.Duration(raftMultRaw)

	def := raft.DefaultConfig()
	c.RaftConfig.HeartbeatTimeout = raftMult * def.HeartbeatTimeout
	c.RaftConfig.ElectionTimeout = raftMult * def.ElectionTimeout
	c.RaftConfig.LeaderLeaseTimeout = raftMult * def.LeaderLeaseTimeout
}

// tlsConfig maps this config into a tlsutil config.
func (c *Config) tlsConfig() *tlsutil.Config {
	tlsConf := &tlsutil.Config{
		VerifyIncoming:           c.VerifyIncoming,
		VerifyOutgoing:           c.VerifyOutgoing,
		VerifyServerHostname:     c.VerifyServerHostname,
		UseTLS:                   c.UseTLS,
		CAFile:                   c.CAFile,
		CAPath:                   c.CAPath,
		CertFile:                 c.CertFile,
		KeyFile:                  c.KeyFile,
		NodeName:                 c.NodeName,
		ServerName:               c.ServerName,
		Domain:                   c.Domain,
		TLSMinVersion:            c.TLSMinVersion,
		PreferServerCipherSuites: c.TLSPreferServerCipherSuites,
	}
	return tlsConf
}

// GetTokenForAgent returns the token the agent should use for its own internal
// operations, such as registering itself with the catalog.
func (c *Config) GetTokenForAgent() string {
	if c.ACLAgentToken != "" {
		return c.ACLAgentToken
	}
	if c.ACLToken != "" {
		return c.ACLToken
	}
	return ""
}