diff --git a/src/ooxml/java/org/apache/poi/util/java7_util/AbstractMap7.java b/src/ooxml/java/org/apache/poi/util/java7_util/AbstractMap7.java
new file mode 100644
index 0000000000..6e65da7f23
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/java7_util/AbstractMap7.java
@@ -0,0 +1,828 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.apache.poi.util.java7_util;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This class provides a skeletal implementation of the Map
+ * interface, to minimize the effort required to implement this interface.
+ *
+ *
To implement an unmodifiable map, the programmer needs only to extend this
+ * class and provide an implementation for the entrySet method, which
+ * returns a set-view of the map's mappings. Typically, the returned set
+ * will, in turn, be implemented atop AbstractSet. This set should
+ * not support the add or remove methods, and its iterator
+ * should not support the remove method.
+ *
+ *
To implement a modifiable map, the programmer must additionally override
+ * this class's put method (which otherwise throws an
+ * UnsupportedOperationException), and the iterator returned by
+ * entrySet().iterator() must additionally implement its
+ * remove method.
+ *
+ *
The programmer should generally provide a void (no argument) and map
+ * constructor, as per the recommendation in the Map interface
+ * specification.
+ *
+ *
The documentation for each non-abstract method in this class describes its
+ * implementation in detail. Each of these methods may be overridden if the
+ * map being implemented admits a more efficient implementation.
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @param the type of keys maintained by this map
+ * @param the type of mapped values
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Map
+ * @see Collection
+ * @since 1.2
+ */
+
+public abstract class AbstractMap7 implements Map {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected AbstractMap7() {
+ }
+
+ // Query Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation returns entrySet().size().
+ */
+ public int size() {
+ return entrySet().size();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation returns size() == 0.
+ */
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() searching
+ * for an entry with the specified value. If such an entry is found,
+ * true is returned. If the iteration terminates without
+ * finding such an entry, false is returned. Note that this
+ * implementation requires linear time in the size of the map.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public boolean containsValue(Object value) {
+ Iterator> i = entrySet().iterator();
+ if (value==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getValue()==null)
+ return true;
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (value.equals(e.getValue()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation iterates over entrySet() searching
+ * for an entry with the specified key. If such an entry is found,
+ * true is returned. If the iteration terminates without
+ * finding such an entry, false is returned. Note that this
+ * implementation requires linear time in the size of the map; many
+ * implementations will override this method.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public boolean containsKey(Object key) {
+ Iterator> i = entrySet().iterator();
+ if (key==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ return true;
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (key.equals(e.getKey()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation iterates over entrySet() searching
+ * for an entry with the specified key. If such an entry is found,
+ * the entry's value is returned. If the iteration terminates without
+ * finding such an entry, null is returned. Note that this
+ * implementation requires linear time in the size of the map; many
+ * implementations will override this method.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public V get(Object key) {
+ Iterator> i = entrySet().iterator();
+ if (key==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ return e.getValue();
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (key.equals(e.getKey()))
+ return e.getValue();
+ }
+ }
+ return null;
+ }
+
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation always throws an
+ * UnsupportedOperationException.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() searching for an
+ * entry with the specified key. If such an entry is found, its value is
+ * obtained with its getValue operation, the entry is removed
+ * from the collection (and the backing map) with the iterator's
+ * remove operation, and the saved value is returned. If the
+ * iteration terminates without finding such an entry, null is
+ * returned. Note that this implementation requires linear time in the
+ * size of the map; many implementations will override this method.
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if the entrySet
+ * iterator does not support the remove method and this map
+ * contains a mapping for the specified key.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public V remove(Object key) {
+ Iterator> i = entrySet().iterator();
+ Entry correctEntry = null;
+ if (key==null) {
+ while (correctEntry==null && i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ correctEntry = e;
+ }
+ } else {
+ while (correctEntry==null && i.hasNext()) {
+ Entry e = i.next();
+ if (key.equals(e.getKey()))
+ correctEntry = e;
+ }
+ }
+
+ V oldValue = null;
+ if (correctEntry !=null) {
+ oldValue = correctEntry.getValue();
+ i.remove();
+ }
+ return oldValue;
+ }
+
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation iterates over the specified map's
+ * entrySet() collection, and calls this map's put
+ * operation once for each entry returned by the iteration.
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if this map does not support
+ * the put operation and the specified map is nonempty.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public void putAll(Map extends K, ? extends V> m) {
+ for (Map.Entry extends K, ? extends V> e : m.entrySet())
+ put(e.getKey(), e.getValue());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation calls entrySet().clear().
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if the entrySet
+ * does not support the clear operation.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ */
+ public void clear() {
+ entrySet().clear();
+ }
+
+
+ // Views
+
+ /**
+ * Each of these fields are initialized to contain an instance of the
+ * appropriate view the first time this view is requested. The views are
+ * stateless, so there's no reason to create more than one of each.
+ */
+ transient volatile Set keySet = null;
+ transient volatile Collection values = null;
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation returns a set that subclasses {@link AbstractSet}.
+ * The subclass's iterator method returns a "wrapper object" over this
+ * map's entrySet() iterator. The size method
+ * delegates to this map's size method and the
+ * contains method delegates to this map's
+ * containsKey method.
+ *
+ *
The set is created the first time this method is called,
+ * and returned in response to all subsequent calls. No synchronization
+ * is performed, so there is a slight chance that multiple calls to this
+ * method will not all return the same set.
+ */
+ public Set keySet() {
+ if (keySet == null) {
+ keySet = new AbstractSet() {
+ public Iterator iterator() {
+ return new Iterator() {
+ private Iterator> i = entrySet().iterator();
+
+ public boolean hasNext() {
+ return i.hasNext();
+ }
+
+ public K next() {
+ return i.next().getKey();
+ }
+
+ public void remove() {
+ i.remove();
+ }
+ };
+ }
+
+ public int size() {
+ return AbstractMap7.this.size();
+ }
+
+ public boolean isEmpty() {
+ return AbstractMap7.this.isEmpty();
+ }
+
+ public void clear() {
+ AbstractMap7.this.clear();
+ }
+
+ public boolean contains(Object k) {
+ return AbstractMap7.this.containsKey(k);
+ }
+ };
+ }
+ return keySet;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation returns a collection that subclasses {@link
+ * AbstractCollection}. The subclass's iterator method returns a
+ * "wrapper object" over this map's entrySet() iterator.
+ * The size method delegates to this map's size
+ * method and the contains method delegates to this map's
+ * containsValue method.
+ *
+ *
The collection is created the first time this method is called, and
+ * returned in response to all subsequent calls. No synchronization is
+ * performed, so there is a slight chance that multiple calls to this
+ * method will not all return the same collection.
+ */
+ public Collection values() {
+ if (values == null) {
+ values = new AbstractCollection() {
+ public Iterator iterator() {
+ return new Iterator() {
+ private Iterator> i = entrySet().iterator();
+
+ public boolean hasNext() {
+ return i.hasNext();
+ }
+
+ public V next() {
+ return i.next().getValue();
+ }
+
+ public void remove() {
+ i.remove();
+ }
+ };
+ }
+
+ public int size() {
+ return AbstractMap7.this.size();
+ }
+
+ public boolean isEmpty() {
+ return AbstractMap7.this.isEmpty();
+ }
+
+ public void clear() {
+ AbstractMap7.this.clear();
+ }
+
+ public boolean contains(Object v) {
+ return AbstractMap7.this.containsValue(v);
+ }
+ };
+ }
+ return values;
+ }
+
+ public abstract Set> entrySet();
+
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this map for equality. Returns
+ * true if the given object is also a map and the two maps
+ * represent the same mappings. More formally, two maps m1 and
+ * m2 represent the same mappings if
+ * m1.entrySet().equals(m2.entrySet()). This ensures that the
+ * equals method works properly across different implementations
+ * of the Map interface.
+ *
+ * This implementation first checks if the specified object is this map;
+ * if so it returns true. Then, it checks if the specified
+ * object is a map whose size is identical to the size of this map; if
+ * not, it returns false. If so, it iterates over this map's
+ * entrySet collection, and checks that the specified map
+ * contains each mapping that this map contains. If the specified map
+ * fails to contain such a mapping, false is returned. If the
+ * iteration completes, true is returned.
+ *
+ * @param o object to be compared for equality with this map
+ * @return true if the specified object is equal to this map
+ */
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+
+ if (!(o instanceof Map))
+ return false;
+ Map m = (Map) o;
+ if (m.size() != size())
+ return false;
+
+ try {
+ Iterator> i = entrySet().iterator();
+ while (i.hasNext()) {
+ Entry e = i.next();
+ K key = e.getKey();
+ V value = e.getValue();
+ if (value == null) {
+ if (!(m.get(key)==null && m.containsKey(key)))
+ return false;
+ } else {
+ if (!value.equals(m.get(key)))
+ return false;
+ }
+ }
+ } catch (ClassCastException unused) {
+ return false;
+ } catch (NullPointerException unused) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the hash code value for this map. The hash code of a map is
+ * defined to be the sum of the hash codes of each entry in the map's
+ * entrySet() view. This ensures that m1.equals(m2)
+ * implies that m1.hashCode()==m2.hashCode() for any two maps
+ * m1 and m2, as required by the general contract of
+ * {@link Object#hashCode}.
+ *
+ * This implementation iterates over entrySet(), calling
+ * {@link Map.Entry#hashCode hashCode()} on each element (entry) in the
+ * set, and adding up the results.
+ *
+ * @return the hash code value for this map
+ * @see Map.Entry#hashCode()
+ * @see Object#equals(Object)
+ * @see Set#equals(Object)
+ */
+ public int hashCode() {
+ int h = 0;
+ Iterator> i = entrySet().iterator();
+ while (i.hasNext())
+ h += i.next().hashCode();
+ return h;
+ }
+
+ /**
+ * Returns a string representation of this map. The string representation
+ * consists of a list of key-value mappings in the order returned by the
+ * map's entrySet view's iterator, enclosed in braces
+ * ("{}"). Adjacent mappings are separated by the characters
+ * ", " (comma and space). Each key-value mapping is rendered as
+ * the key followed by an equals sign ("=") followed by the
+ * associated value. Keys and values are converted to strings as by
+ * {@link String#valueOf(Object)}.
+ *
+ * @return a string representation of this map
+ */
+ public String toString() {
+ Iterator> i = entrySet().iterator();
+ if (! i.hasNext())
+ return "{}";
+
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ for (;;) {
+ Entry e = i.next();
+ K key = e.getKey();
+ V value = e.getValue();
+ sb.append(key == this ? "(this Map)" : key);
+ sb.append('=');
+ sb.append(value == this ? "(this Map)" : value);
+ if (! i.hasNext())
+ return sb.append('}').toString();
+ sb.append(',').append(' ');
+ }
+ }
+
+ /**
+ * Returns a shallow copy of this AbstractMap7 instance: the keys
+ * and values themselves are not cloned.
+ *
+ * @return a shallow copy of this map
+ */
+ protected Object clone() throws CloneNotSupportedException {
+ AbstractMap7 result = (AbstractMap7)super.clone();
+ result.keySet = null;
+ result.values = null;
+ return result;
+ }
+
+ /**
+ * Utility method for SimpleEntry and SimpleImmutableEntry.
+ * Test for equality, checking for nulls.
+ */
+ private static boolean eq(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+
+ // Implementation Note: SimpleEntry and SimpleImmutableEntry
+ // are distinct unrelated classes, even though they share
+ // some code. Since you can't add or subtract final-ness
+ // of a field in a subclass, they can't share representations,
+ // and the amount of duplicated code is too small to warrant
+ // exposing a common abstract class.
+
+
+ /**
+ * An Entry maintaining a key and a value. The value may be
+ * changed using the setValue method. This class
+ * facilitates the process of building custom map
+ * implementations. For example, it may be convenient to return
+ * arrays of SimpleEntry instances in method
+ * Map.entrySet().toArray.
+ *
+ * @since 1.6
+ */
+ public static class SimpleEntry
+ implements Entry, java.io.Serializable
+ {
+ private static final long serialVersionUID = -8499721149061103585L;
+
+ private final K key;
+ private V value;
+
+ /**
+ * Creates an entry representing a mapping from the specified
+ * key to the specified value.
+ *
+ * @param key the key represented by this entry
+ * @param value the value represented by this entry
+ */
+ public SimpleEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ /**
+ * Creates an entry representing the same mapping as the
+ * specified entry.
+ *
+ * @param entry the entry to copy
+ */
+ public SimpleEntry(Entry extends K, ? extends V> entry) {
+ this.key = entry.getKey();
+ this.value = entry.getValue();
+ }
+
+ /**
+ * Returns the key corresponding to this entry.
+ *
+ * @return the key corresponding to this entry
+ */
+ public K getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the value corresponding to this entry.
+ *
+ * @return the value corresponding to this entry
+ */
+ public V getValue() {
+ return value;
+ }
+
+ /**
+ * Replaces the value corresponding to this entry with the specified
+ * value.
+ *
+ * @param value new value to be stored in this entry
+ * @return the old value corresponding to the entry
+ */
+ public V setValue(V value) {
+ V oldValue = this.value;
+ this.value = value;
+ return oldValue;
+ }
+
+ /**
+ * Compares the specified object with this entry for equality.
+ * Returns {@code true} if the given object is also a map entry and
+ * the two entries represent the same mapping. More formally, two
+ * entries {@code e1} and {@code e2} represent the same mapping
+ * if
+ * (e1.getKey()==null ?
+ * e2.getKey()==null :
+ * e1.getKey().equals(e2.getKey()))
+ * &&
+ * (e1.getValue()==null ?
+ * e2.getValue()==null :
+ * e1.getValue().equals(e2.getValue()))
+ * This ensures that the {@code equals} method works properly across
+ * different implementations of the {@code Map.Entry} interface.
+ *
+ * @param o object to be compared for equality with this map entry
+ * @return {@code true} if the specified object is equal to this map
+ * entry
+ * @see #hashCode
+ */
+ public boolean equals(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry)o;
+ return eq(key, e.getKey()) && eq(value, e.getValue());
+ }
+
+ /**
+ * Returns the hash code value for this map entry. The hash code
+ * of a map entry {@code e} is defined to be:
+ * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
+ * (e.getValue()==null ? 0 : e.getValue().hashCode())
+ * This ensures that {@code e1.equals(e2)} implies that
+ * {@code e1.hashCode()==e2.hashCode()} for any two Entries
+ * {@code e1} and {@code e2}, as required by the general
+ * contract of {@link Object#hashCode}.
+ *
+ * @return the hash code value for this map entry
+ * @see #equals
+ */
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode()) ^
+ (value == null ? 0 : value.hashCode());
+ }
+
+ /**
+ * Returns a String representation of this map entry. This
+ * implementation returns the string representation of this
+ * entry's key followed by the equals character ("=")
+ * followed by the string representation of this entry's value.
+ *
+ * @return a String representation of this map entry
+ */
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ }
+
+ /**
+ * An Entry maintaining an immutable key and value. This class
+ * does not support method setValue. This class may be
+ * convenient in methods that return thread-safe snapshots of
+ * key-value mappings.
+ *
+ * @since 1.6
+ */
+ public static class SimpleImmutableEntry
+ implements Entry, java.io.Serializable
+ {
+ private static final long serialVersionUID = 7138329143949025153L;
+
+ private final K key;
+ private final V value;
+
+ /**
+ * Creates an entry representing a mapping from the specified
+ * key to the specified value.
+ *
+ * @param key the key represented by this entry
+ * @param value the value represented by this entry
+ */
+ public SimpleImmutableEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ /**
+ * Creates an entry representing the same mapping as the
+ * specified entry.
+ *
+ * @param entry the entry to copy
+ */
+ public SimpleImmutableEntry(Entry extends K, ? extends V> entry) {
+ this.key = entry.getKey();
+ this.value = entry.getValue();
+ }
+
+ /**
+ * Returns the key corresponding to this entry.
+ *
+ * @return the key corresponding to this entry
+ */
+ public K getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the value corresponding to this entry.
+ *
+ * @return the value corresponding to this entry
+ */
+ public V getValue() {
+ return value;
+ }
+
+ /**
+ * Replaces the value corresponding to this entry with the specified
+ * value (optional operation). This implementation simply throws
+ * UnsupportedOperationException, as this class implements
+ * an immutable map entry.
+ *
+ * @param value new value to be stored in this entry
+ * @return (Does not return)
+ * @throws UnsupportedOperationException always
+ */
+ public V setValue(V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Compares the specified object with this entry for equality.
+ * Returns {@code true} if the given object is also a map entry and
+ * the two entries represent the same mapping. More formally, two
+ * entries {@code e1} and {@code e2} represent the same mapping
+ * if
+ * (e1.getKey()==null ?
+ * e2.getKey()==null :
+ * e1.getKey().equals(e2.getKey()))
+ * &&
+ * (e1.getValue()==null ?
+ * e2.getValue()==null :
+ * e1.getValue().equals(e2.getValue()))
+ * This ensures that the {@code equals} method works properly across
+ * different implementations of the {@code Map.Entry} interface.
+ *
+ * @param o object to be compared for equality with this map entry
+ * @return {@code true} if the specified object is equal to this map
+ * entry
+ * @see #hashCode
+ */
+ public boolean equals(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry)o;
+ return eq(key, e.getKey()) && eq(value, e.getValue());
+ }
+
+ /**
+ * Returns the hash code value for this map entry. The hash code
+ * of a map entry {@code e} is defined to be:
+ * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
+ * (e.getValue()==null ? 0 : e.getValue().hashCode())
+ * This ensures that {@code e1.equals(e2)} implies that
+ * {@code e1.hashCode()==e2.hashCode()} for any two Entries
+ * {@code e1} and {@code e2}, as required by the general
+ * contract of {@link Object#hashCode}.
+ *
+ * @return the hash code value for this map entry
+ * @see #equals
+ */
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode()) ^
+ (value == null ? 0 : value.hashCode());
+ }
+
+ /**
+ * Returns a String representation of this map entry. This
+ * implementation returns the string representation of this
+ * entry's key followed by the equals character ("=")
+ * followed by the string representation of this entry's value.
+ *
+ * @return a String representation of this map entry
+ */
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/util/java7_util/AbstractSet7.java b/src/ooxml/java/org/apache/poi/util/java7_util/AbstractSet7.java
new file mode 100644
index 0000000000..bb4fe00119
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/java7_util/AbstractSet7.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.apache.poi.util.java7_util;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * This class provides a skeletal implementation of the Set
+ * interface to minimize the effort required to implement this
+ * interface.
+ *
+ * The process of implementing a set by extending this class is identical
+ * to that of implementing a Collection by extending AbstractCollection,
+ * except that all of the methods and constructors in subclasses of this
+ * class must obey the additional constraints imposed by the Set
+ * interface (for instance, the add method must not permit addition of
+ * multiple instances of an object to a set).
+ *
+ * Note that this class does not override any of the implementations from
+ * the AbstractCollection class. It merely adds implementations
+ * for equals and hashCode.
+ *
+ * This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @param the type of elements maintained by this set
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Collection
+ * @see AbstractCollection
+ * @see Set
+ * @since 1.2
+ */
+
+public abstract class AbstractSet7 extends AbstractCollection implements Set {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected AbstractSet7() {
+ }
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this set for equality. Returns
+ * true if the given object is also a set, the two sets have
+ * the same size, and every member of the given set is contained in
+ * this set. This ensures that the equals method works
+ * properly across different implementations of the Set
+ * interface.
+ *
+ * This implementation first checks if the specified object is this
+ * set; if so it returns true. Then, it checks if the
+ * specified object is a set whose size is identical to the size of
+ * this set; if not, it returns false. If so, it returns
+ * containsAll((Collection) o).
+ *
+ * @param o object to be compared for equality with this set
+ * @return true if the specified object is equal to this set
+ */
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+
+ if (!(o instanceof Set))
+ return false;
+ Collection c = (Collection) o;
+ if (c.size() != size())
+ return false;
+ try {
+ return containsAll(c);
+ } catch (ClassCastException unused) {
+ return false;
+ } catch (NullPointerException unused) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the hash code value for this set. The hash code of a set is
+ * defined to be the sum of the hash codes of the elements in the set,
+ * where the hash code of a null element is defined to be zero.
+ * This ensures that s1.equals(s2) implies that
+ * s1.hashCode()==s2.hashCode() for any two sets s1
+ * and s2, as required by the general contract of
+ * {@link Object#hashCode}.
+ *
+ *
This implementation iterates over the set, calling the
+ * hashCode method on each element in the set, and adding up
+ * the results.
+ *
+ * @return the hash code value for this set
+ * @see Object#equals(Object)
+ * @see Set#equals(Object)
+ */
+ public int hashCode() {
+ int h = 0;
+ Iterator i = iterator();
+ while (i.hasNext()) {
+ E obj = i.next();
+ if (obj != null)
+ h += obj.hashCode();
+ }
+ return h;
+ }
+
+ /**
+ * Removes from this set all of its elements that are contained in the
+ * specified collection (optional operation). If the specified
+ * collection is also a set, this operation effectively modifies this
+ * set so that its value is the asymmetric set difference of
+ * the two sets.
+ *
+ * This implementation determines which is the smaller of this set
+ * and the specified collection, by invoking the size
+ * method on each. If this set has fewer elements, then the
+ * implementation iterates over this set, checking each element
+ * returned by the iterator in turn to see if it is contained in
+ * the specified collection. If it is so contained, it is removed
+ * from this set with the iterator's remove method. If
+ * the specified collection has fewer elements, then the
+ * implementation iterates over the specified collection, removing
+ * from this set each element returned by the iterator, using this
+ * set's remove method.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException if the iterator returned by the
+ * iterator method does not implement the remove method.
+ *
+ * @param c collection containing elements to be removed from this set
+ * @return true if this set changed as a result of the call
+ * @throws UnsupportedOperationException if the removeAll operation
+ * is not supported by this set
+ * @throws ClassCastException if the class of an element of this set
+ * is incompatible with the specified collection
+ * (optional)
+ * @throws NullPointerException if this set contains a null element and the
+ * specified collection does not permit null elements
+ * (optional),
+ * or if the specified collection is null
+ * @see #remove(Object)
+ * @see #contains(Object)
+ */
+ public boolean removeAll(Collection> c) {
+ boolean modified = false;
+
+ if (size() > c.size()) {
+ for (Iterator> i = c.iterator(); i.hasNext(); )
+ modified |= remove(i.next());
+ } else {
+ for (Iterator> i = iterator(); i.hasNext(); ) {
+ if (c.contains(i.next())) {
+ i.remove();
+ modified = true;
+ }
+ }
+ }
+ return modified;
+ }
+
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/util/java7_util/NavigableMap7.java b/src/ooxml/java/org/apache/poi/util/java7_util/NavigableMap7.java
new file mode 100644
index 0000000000..45150d5b71
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/java7_util/NavigableMap7.java
@@ -0,0 +1,429 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Josh Bloch with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package org.apache.poi.util.java7_util;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+
+/**
+ * A {@link SortedMap} extended with navigation methods returning the
+ * closest matches for given search targets. Methods
+ * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry},
+ * and {@code higherEntry} return {@code Map.Entry} objects
+ * associated with keys respectively less than, less than or equal,
+ * greater than or equal, and greater than a given key, returning
+ * {@code null} if there is no such key. Similarly, methods
+ * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and
+ * {@code higherKey} return only the associated keys. All of these
+ * methods are designed for locating, not traversing entries.
+ *
+ *
A {@code NavigableMap7} may be accessed and traversed in either
+ * ascending or descending key order. The {@code descendingMap}
+ * method returns a view of the map with the senses of all relational
+ * and directional methods inverted. The performance of ascending
+ * operations and views is likely to be faster than that of descending
+ * ones. Methods {@code subMap}, {@code headMap},
+ * and {@code tailMap} differ from the like-named {@code
+ * SortedMap} methods in accepting additional arguments describing
+ * whether lower and upper bounds are inclusive versus exclusive.
+ * Submaps of any {@code NavigableMap7} must implement the {@code
+ * NavigableMap7} interface.
+ *
+ *
This interface additionally defines methods {@code firstEntry},
+ * {@code pollFirstEntry}, {@code lastEntry}, and
+ * {@code pollLastEntry} that return and/or remove the least and
+ * greatest mappings, if any exist, else returning {@code null}.
+ *
+ *
Implementations of entry-returning methods are expected to
+ * return {@code Map.Entry} pairs representing snapshots of mappings
+ * at the time they were produced, and thus generally do not
+ * support the optional {@code Entry.setValue} method. Note however
+ * that it is possible to change mappings in the associated map using
+ * method {@code put}.
+ *
+ *
Methods
+ * {@link #subMap(Object, Object) subMap(K, K)},
+ * {@link #headMap(Object) headMap(K)}, and
+ * {@link #tailMap(Object) tailMap(K)}
+ * are specified to return {@code SortedMap} to allow existing
+ * implementations of {@code SortedMap} to be compatibly retrofitted to
+ * implement {@code NavigableMap7}, but extensions and implementations
+ * of this interface are encouraged to override these methods to return
+ * {@code NavigableMap7}. Similarly,
+ * {@link #keySet()} can be overriden to return {@code NavigableSet}.
+ *
+ *
This interface is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Doug Lea
+ * @author Josh Bloch
+ * @param the type of keys maintained by this map
+ * @param the type of mapped values
+ * @since 1.6
+ */
+public interface NavigableMap7 extends SortedMap {
+ /**
+ * Returns a key-value mapping associated with the greatest key
+ * strictly less than the given key, or {@code null} if there is
+ * no such key.
+ *
+ * @param key the key
+ * @return an entry with the greatest key less than {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ Map.Entry lowerEntry(K key);
+
+ /**
+ * Returns the greatest key strictly less than the given key, or
+ * {@code null} if there is no such key.
+ *
+ * @param key the key
+ * @return the greatest key less than {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ K lowerKey(K key);
+
+ /**
+ * Returns a key-value mapping associated with the greatest key
+ * less than or equal to the given key, or {@code null} if there
+ * is no such key.
+ *
+ * @param key the key
+ * @return an entry with the greatest key less than or equal to
+ * {@code key}, or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ Map.Entry floorEntry(K key);
+
+ /**
+ * Returns the greatest key less than or equal to the given key,
+ * or {@code null} if there is no such key.
+ *
+ * @param key the key
+ * @return the greatest key less than or equal to {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ K floorKey(K key);
+
+ /**
+ * Returns a key-value mapping associated with the least key
+ * greater than or equal to the given key, or {@code null} if
+ * there is no such key.
+ *
+ * @param key the key
+ * @return an entry with the least key greater than or equal to
+ * {@code key}, or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ Map.Entry ceilingEntry(K key);
+
+ /**
+ * Returns the least key greater than or equal to the given key,
+ * or {@code null} if there is no such key.
+ *
+ * @param key the key
+ * @return the least key greater than or equal to {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ K ceilingKey(K key);
+
+ /**
+ * Returns a key-value mapping associated with the least key
+ * strictly greater than the given key, or {@code null} if there
+ * is no such key.
+ *
+ * @param key the key
+ * @return an entry with the least key greater than {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ Map.Entry higherEntry(K key);
+
+ /**
+ * Returns the least key strictly greater than the given key, or
+ * {@code null} if there is no such key.
+ *
+ * @param key the key
+ * @return the least key greater than {@code key},
+ * or {@code null} if there is no such key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map does not permit null keys
+ */
+ K higherKey(K key);
+
+ /**
+ * Returns a key-value mapping associated with the least
+ * key in this map, or {@code null} if the map is empty.
+ *
+ * @return an entry with the least key,
+ * or {@code null} if this map is empty
+ */
+ Map.Entry firstEntry();
+
+ /**
+ * Returns a key-value mapping associated with the greatest
+ * key in this map, or {@code null} if the map is empty.
+ *
+ * @return an entry with the greatest key,
+ * or {@code null} if this map is empty
+ */
+ Map.Entry lastEntry();
+
+ /**
+ * Removes and returns a key-value mapping associated with
+ * the least key in this map, or {@code null} if the map is empty.
+ *
+ * @return the removed first entry of this map,
+ * or {@code null} if this map is empty
+ */
+ Map.Entry pollFirstEntry();
+
+ /**
+ * Removes and returns a key-value mapping associated with
+ * the greatest key in this map, or {@code null} if the map is empty.
+ *
+ * @return the removed last entry of this map,
+ * or {@code null} if this map is empty
+ */
+ Map.Entry pollLastEntry();
+
+ /**
+ * Returns a reverse order view of the mappings contained in this map.
+ * The descending map is backed by this map, so changes to the map are
+ * reflected in the descending map, and vice-versa. If either map is
+ * modified while an iteration over a collection view of either map
+ * is in progress (except through the iterator's own {@code remove}
+ * operation), the results of the iteration are undefined.
+ *
+ * The returned map has an ordering equivalent to
+ * {@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator()).
+ * The expression {@code m.descendingMap().descendingMap()} returns a
+ * view of {@code m} essentially equivalent to {@code m}.
+ *
+ * @return a reverse order view of this map
+ */
+ NavigableMap7 descendingMap();
+
+ /**
+ * Returns a {@link NavigableSet} view of the keys contained in this map.
+ * The set's iterator returns the keys in ascending order.
+ * The set is backed by the map, so changes to the map are reflected in
+ * the set, and vice-versa. If the map is modified while an iteration
+ * over the set is in progress (except through the iterator's own {@code
+ * remove} operation), the results of the iteration are undefined. The
+ * set supports element removal, which removes the corresponding mapping
+ * from the map, via the {@code Iterator.remove}, {@code Set.remove},
+ * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
+ * It does not support the {@code add} or {@code addAll} operations.
+ *
+ * @return a navigable set view of the keys in this map
+ */
+ NavigableSet7 navigableKeySet();
+
+ /**
+ * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
+ * The set's iterator returns the keys in descending order.
+ * The set is backed by the map, so changes to the map are reflected in
+ * the set, and vice-versa. If the map is modified while an iteration
+ * over the set is in progress (except through the iterator's own {@code
+ * remove} operation), the results of the iteration are undefined. The
+ * set supports element removal, which removes the corresponding mapping
+ * from the map, via the {@code Iterator.remove}, {@code Set.remove},
+ * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
+ * It does not support the {@code add} or {@code addAll} operations.
+ *
+ * @return a reverse order navigable set view of the keys in this map
+ */
+ NavigableSet7 descendingKeySet();
+
+ /**
+ * Returns a view of the portion of this map whose keys range from
+ * {@code fromKey} to {@code toKey}. If {@code fromKey} and
+ * {@code toKey} are equal, the returned map is empty unless
+ * {@code fromInclusive} and {@code toInclusive} are both true. The
+ * returned map is backed by this map, so changes in the returned map are
+ * reflected in this map, and vice-versa. The returned map supports all
+ * optional map operations that this map supports.
+ *
+ * The returned map will throw an {@code IllegalArgumentException}
+ * on an attempt to insert a key outside of its range, or to construct a
+ * submap either of whose endpoints lie outside its range.
+ *
+ * @param fromKey low endpoint of the keys in the returned map
+ * @param fromInclusive {@code true} if the low endpoint
+ * is to be included in the returned view
+ * @param toKey high endpoint of the keys in the returned map
+ * @param toInclusive {@code true} if the high endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this map whose keys range from
+ * {@code fromKey} to {@code toKey}
+ * @throws ClassCastException if {@code fromKey} and {@code toKey}
+ * cannot be compared to one another using this map's comparator
+ * (or, if the map has no comparator, using natural ordering).
+ * Implementations may, but are not required to, throw this
+ * exception if {@code fromKey} or {@code toKey}
+ * cannot be compared to keys currently in the map.
+ * @throws NullPointerException if {@code fromKey} or {@code toKey}
+ * is null and this map does not permit null keys
+ * @throws IllegalArgumentException if {@code fromKey} is greater than
+ * {@code toKey}; or if this map itself has a restricted
+ * range, and {@code fromKey} or {@code toKey} lies
+ * outside the bounds of the range
+ */
+ NavigableMap7 subMap(K fromKey, boolean fromInclusive,
+ K toKey, boolean toInclusive);
+
+ /**
+ * Returns a view of the portion of this map whose keys are less than (or
+ * equal to, if {@code inclusive} is true) {@code toKey}. The returned
+ * map is backed by this map, so changes in the returned map are reflected
+ * in this map, and vice-versa. The returned map supports all optional
+ * map operations that this map supports.
+ *
+ * The returned map will throw an {@code IllegalArgumentException}
+ * on an attempt to insert a key outside its range.
+ *
+ * @param toKey high endpoint of the keys in the returned map
+ * @param inclusive {@code true} if the high endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this map whose keys are less than
+ * (or equal to, if {@code inclusive} is true) {@code toKey}
+ * @throws ClassCastException if {@code toKey} is not compatible
+ * with this map's comparator (or, if the map has no comparator,
+ * if {@code toKey} does not implement {@link Comparable}).
+ * Implementations may, but are not required to, throw this
+ * exception if {@code toKey} cannot be compared to keys
+ * currently in the map.
+ * @throws NullPointerException if {@code toKey} is null
+ * and this map does not permit null keys
+ * @throws IllegalArgumentException if this map itself has a
+ * restricted range, and {@code toKey} lies outside the
+ * bounds of the range
+ */
+ NavigableMap7 headMap(K toKey, boolean inclusive);
+
+ /**
+ * Returns a view of the portion of this map whose keys are greater than (or
+ * equal to, if {@code inclusive} is true) {@code fromKey}. The returned
+ * map is backed by this map, so changes in the returned map are reflected
+ * in this map, and vice-versa. The returned map supports all optional
+ * map operations that this map supports.
+ *
+ * The returned map will throw an {@code IllegalArgumentException}
+ * on an attempt to insert a key outside its range.
+ *
+ * @param fromKey low endpoint of the keys in the returned map
+ * @param inclusive {@code true} if the low endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this map whose keys are greater than
+ * (or equal to, if {@code inclusive} is true) {@code fromKey}
+ * @throws ClassCastException if {@code fromKey} is not compatible
+ * with this map's comparator (or, if the map has no comparator,
+ * if {@code fromKey} does not implement {@link Comparable}).
+ * Implementations may, but are not required to, throw this
+ * exception if {@code fromKey} cannot be compared to keys
+ * currently in the map.
+ * @throws NullPointerException if {@code fromKey} is null
+ * and this map does not permit null keys
+ * @throws IllegalArgumentException if this map itself has a
+ * restricted range, and {@code fromKey} lies outside the
+ * bounds of the range
+ */
+ NavigableMap7 tailMap(K fromKey, boolean inclusive);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code subMap(fromKey, true, toKey, false)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ SortedMap subMap(K fromKey, K toKey);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code headMap(toKey, false)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ SortedMap headMap(K toKey);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code tailMap(fromKey, true)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ SortedMap tailMap(K fromKey);
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/util/java7_util/NavigableSet7.java b/src/ooxml/java/org/apache/poi/util/java7_util/NavigableSet7.java
new file mode 100644
index 0000000000..bc515e7274
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/java7_util/NavigableSet7.java
@@ -0,0 +1,324 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Josh Bloch with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package org.apache.poi.util.java7_util;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.SortedSet;
+
+/**
+ * A {@link SortedSet} extended with navigation methods reporting
+ * closest matches for given search targets. Methods {@code lower},
+ * {@code floor}, {@code ceiling}, and {@code higher} return elements
+ * respectively less than, less than or equal, greater than or equal,
+ * and greater than a given element, returning {@code null} if there
+ * is no such element. A {@code NavigableSet7} may be accessed and
+ * traversed in either ascending or descending order. The {@code
+ * descendingSet} method returns a view of the set with the senses of
+ * all relational and directional methods inverted. The performance of
+ * ascending operations and views is likely to be faster than that of
+ * descending ones. This interface additionally defines methods
+ * {@code pollFirst} and {@code pollLast} that return and remove the
+ * lowest and highest element, if one exists, else returning {@code
+ * null}. Methods {@code subSet}, {@code headSet},
+ * and {@code tailSet} differ from the like-named {@code
+ * SortedSet} methods in accepting additional arguments describing
+ * whether lower and upper bounds are inclusive versus exclusive.
+ * Subsets of any {@code NavigableSet7} must implement the {@code
+ * NavigableSet7} interface.
+ *
+ * The return values of navigation methods may be ambiguous in
+ * implementations that permit {@code null} elements. However, even
+ * in this case the result can be disambiguated by checking
+ * {@code contains(null)}. To avoid such issues, implementations of
+ * this interface are encouraged to not permit insertion of
+ * {@code null} elements. (Note that sorted sets of {@link
+ * Comparable} elements intrinsically do not permit {@code null}.)
+ *
+ *
Methods
+ * {@link #subSet(Object, Object) subSet(E, E)},
+ * {@link #headSet(Object) headSet(E)}, and
+ * {@link #tailSet(Object) tailSet(E)}
+ * are specified to return {@code SortedSet} to allow existing
+ * implementations of {@code SortedSet} to be compatibly retrofitted to
+ * implement {@code NavigableSet7}, but extensions and implementations
+ * of this interface are encouraged to override these methods to return
+ * {@code NavigableSet7}.
+ *
+ *
This interface is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Doug Lea
+ * @author Josh Bloch
+ * @param the type of elements maintained by this set
+ * @since 1.6
+ */
+public interface NavigableSet7 extends SortedSet {
+ /**
+ * Returns the greatest element in this set strictly less than the
+ * given element, or {@code null} if there is no such element.
+ *
+ * @param e the value to match
+ * @return the greatest element less than {@code e},
+ * or {@code null} if there is no such element
+ * @throws ClassCastException if the specified element cannot be
+ * compared with the elements currently in the set
+ * @throws NullPointerException if the specified element is null
+ * and this set does not permit null elements
+ */
+ E lower(E e);
+
+ /**
+ * Returns the greatest element in this set less than or equal to
+ * the given element, or {@code null} if there is no such element.
+ *
+ * @param e the value to match
+ * @return the greatest element less than or equal to {@code e},
+ * or {@code null} if there is no such element
+ * @throws ClassCastException if the specified element cannot be
+ * compared with the elements currently in the set
+ * @throws NullPointerException if the specified element is null
+ * and this set does not permit null elements
+ */
+ E floor(E e);
+
+ /**
+ * Returns the least element in this set greater than or equal to
+ * the given element, or {@code null} if there is no such element.
+ *
+ * @param e the value to match
+ * @return the least element greater than or equal to {@code e},
+ * or {@code null} if there is no such element
+ * @throws ClassCastException if the specified element cannot be
+ * compared with the elements currently in the set
+ * @throws NullPointerException if the specified element is null
+ * and this set does not permit null elements
+ */
+ E ceiling(E e);
+
+ /**
+ * Returns the least element in this set strictly greater than the
+ * given element, or {@code null} if there is no such element.
+ *
+ * @param e the value to match
+ * @return the least element greater than {@code e},
+ * or {@code null} if there is no such element
+ * @throws ClassCastException if the specified element cannot be
+ * compared with the elements currently in the set
+ * @throws NullPointerException if the specified element is null
+ * and this set does not permit null elements
+ */
+ E higher(E e);
+
+ /**
+ * Retrieves and removes the first (lowest) element,
+ * or returns {@code null} if this set is empty.
+ *
+ * @return the first element, or {@code null} if this set is empty
+ */
+ E pollFirst();
+
+ /**
+ * Retrieves and removes the last (highest) element,
+ * or returns {@code null} if this set is empty.
+ *
+ * @return the last element, or {@code null} if this set is empty
+ */
+ E pollLast();
+
+ /**
+ * Returns an iterator over the elements in this set, in ascending order.
+ *
+ * @return an iterator over the elements in this set, in ascending order
+ */
+ Iterator iterator();
+
+ /**
+ * Returns a reverse order view of the elements contained in this set.
+ * The descending set is backed by this set, so changes to the set are
+ * reflected in the descending set, and vice-versa. If either set is
+ * modified while an iteration over either set is in progress (except
+ * through the iterator's own {@code remove} operation), the results of
+ * the iteration are undefined.
+ *
+ * The returned set has an ordering equivalent to
+ * {@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator()).
+ * The expression {@code s.descendingSet().descendingSet()} returns a
+ * view of {@code s} essentially equivalent to {@code s}.
+ *
+ * @return a reverse order view of this set
+ */
+ NavigableSet7 descendingSet();
+
+ /**
+ * Returns an iterator over the elements in this set, in descending order.
+ * Equivalent in effect to {@code descendingSet().iterator()}.
+ *
+ * @return an iterator over the elements in this set, in descending order
+ */
+ Iterator descendingIterator();
+
+ /**
+ * Returns a view of the portion of this set whose elements range from
+ * {@code fromElement} to {@code toElement}. If {@code fromElement} and
+ * {@code toElement} are equal, the returned set is empty unless {@code
+ * fromInclusive} and {@code toInclusive} are both true. The returned set
+ * is backed by this set, so changes in the returned set are reflected in
+ * this set, and vice-versa. The returned set supports all optional set
+ * operations that this set supports.
+ *
+ * The returned set will throw an {@code IllegalArgumentException}
+ * on an attempt to insert an element outside its range.
+ *
+ * @param fromElement low endpoint of the returned set
+ * @param fromInclusive {@code true} if the low endpoint
+ * is to be included in the returned view
+ * @param toElement high endpoint of the returned set
+ * @param toInclusive {@code true} if the high endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this set whose elements range from
+ * {@code fromElement}, inclusive, to {@code toElement}, exclusive
+ * @throws ClassCastException if {@code fromElement} and
+ * {@code toElement} cannot be compared to one another using this
+ * set's comparator (or, if the set has no comparator, using
+ * natural ordering). Implementations may, but are not required
+ * to, throw this exception if {@code fromElement} or
+ * {@code toElement} cannot be compared to elements currently in
+ * the set.
+ * @throws NullPointerException if {@code fromElement} or
+ * {@code toElement} is null and this set does
+ * not permit null elements
+ * @throws IllegalArgumentException if {@code fromElement} is
+ * greater than {@code toElement}; or if this set itself
+ * has a restricted range, and {@code fromElement} or
+ * {@code toElement} lies outside the bounds of the range.
+ */
+ NavigableSet7 subSet(E fromElement, boolean fromInclusive,
+ E toElement, boolean toInclusive);
+
+ /**
+ * Returns a view of the portion of this set whose elements are less than
+ * (or equal to, if {@code inclusive} is true) {@code toElement}. The
+ * returned set is backed by this set, so changes in the returned set are
+ * reflected in this set, and vice-versa. The returned set supports all
+ * optional set operations that this set supports.
+ *
+ * The returned set will throw an {@code IllegalArgumentException}
+ * on an attempt to insert an element outside its range.
+ *
+ * @param toElement high endpoint of the returned set
+ * @param inclusive {@code true} if the high endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this set whose elements are less than
+ * (or equal to, if {@code inclusive} is true) {@code toElement}
+ * @throws ClassCastException if {@code toElement} is not compatible
+ * with this set's comparator (or, if the set has no comparator,
+ * if {@code toElement} does not implement {@link Comparable}).
+ * Implementations may, but are not required to, throw this
+ * exception if {@code toElement} cannot be compared to elements
+ * currently in the set.
+ * @throws NullPointerException if {@code toElement} is null and
+ * this set does not permit null elements
+ * @throws IllegalArgumentException if this set itself has a
+ * restricted range, and {@code toElement} lies outside the
+ * bounds of the range
+ */
+ NavigableSet7 headSet(E toElement, boolean inclusive);
+
+ /**
+ * Returns a view of the portion of this set whose elements are greater
+ * than (or equal to, if {@code inclusive} is true) {@code fromElement}.
+ * The returned set is backed by this set, so changes in the returned set
+ * are reflected in this set, and vice-versa. The returned set supports
+ * all optional set operations that this set supports.
+ *
+ * The returned set will throw an {@code IllegalArgumentException}
+ * on an attempt to insert an element outside its range.
+ *
+ * @param fromElement low endpoint of the returned set
+ * @param inclusive {@code true} if the low endpoint
+ * is to be included in the returned view
+ * @return a view of the portion of this set whose elements are greater
+ * than or equal to {@code fromElement}
+ * @throws ClassCastException if {@code fromElement} is not compatible
+ * with this set's comparator (or, if the set has no comparator,
+ * if {@code fromElement} does not implement {@link Comparable}).
+ * Implementations may, but are not required to, throw this
+ * exception if {@code fromElement} cannot be compared to elements
+ * currently in the set.
+ * @throws NullPointerException if {@code fromElement} is null
+ * and this set does not permit null elements
+ * @throws IllegalArgumentException if this set itself has a
+ * restricted range, and {@code fromElement} lies outside the
+ * bounds of the range
+ */
+ NavigableSet7 tailSet(E fromElement, boolean inclusive);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code subSet(fromElement, true, toElement, false)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ SortedSet subSet(E fromElement, E toElement);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code headSet(toElement, false)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+na */
+ SortedSet headSet(E toElement);
+
+ /**
+ * {@inheritDoc}
+ *
+ * Equivalent to {@code tailSet(fromElement, true)}.
+ *
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ SortedSet tailSet(E fromElement);
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/util/java7_util/TreeMap7.java b/src/ooxml/java/org/apache/poi/util/java7_util/TreeMap7.java
new file mode 100644
index 0000000000..591d8fb6d5
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/java7_util/TreeMap7.java
@@ -0,0 +1,2458 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.apache.poi.util.java7_util;
+
+import java.io.IOException;
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+/**
+ * A Red-Black tree based {@link NavigableMap7} implementation.
+ * The map is sorted according to the {@linkplain Comparable natural
+ * ordering} of its keys, or by a {@link Comparator} provided at map
+ * creation time, depending on which constructor is used.
+ *
+ * This implementation provides guaranteed log(n) time cost for the
+ * {@code containsKey}, {@code get}, {@code put} and {@code remove}
+ * operations. Algorithms are adaptations of those in Cormen, Leiserson, and
+ * Rivest's Introduction to Algorithms.
+ *
+ *
Note that the ordering maintained by a tree map, like any sorted map, and
+ * whether or not an explicit comparator is provided, must be consistent
+ * with {@code equals} if this sorted map is to correctly implement the
+ * {@code Map} interface. (See {@code Comparable} or {@code Comparator} for a
+ * precise definition of consistent with equals.) This is so because
+ * the {@code Map} interface is defined in terms of the {@code equals}
+ * operation, but a sorted map performs all key comparisons using its {@code
+ * compareTo} (or {@code compare}) method, so two keys that are deemed equal by
+ * this method are, from the standpoint of the sorted map, equal. The behavior
+ * of a sorted map is well-defined even if its ordering is
+ * inconsistent with {@code equals}; it just fails to obey the general contract
+ * of the {@code Map} interface.
+ *
+ *
Note that this implementation is not synchronized.
+ * If multiple threads access a map concurrently, and at least one of the
+ * threads modifies the map structurally, it must be synchronized
+ * externally. (A structural modification is any operation that adds or
+ * deletes one or more mappings; merely changing the value associated
+ * with an existing key is not a structural modification.) This is
+ * typically accomplished by synchronizing on some object that naturally
+ * encapsulates the map.
+ * If no such object exists, the map should be "wrapped" using the
+ * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap}
+ * method. This is best done at creation time, to prevent accidental
+ * unsynchronized access to the map:
+ * SortedMap m = Collections.synchronizedSortedMap(new TreeMap7(...));
+ *
+ * The iterators returned by the {@code iterator} method of the collections
+ * returned by all of this class's "collection view methods" are
+ * fail-fast: if the map is structurally modified at any time after
+ * the iterator is created, in any way except through the iterator's own
+ * {@code remove} method, the iterator will throw a {@link
+ * ConcurrentModificationException}. Thus, in the face of concurrent
+ * modification, the iterator fails quickly and cleanly, rather than risking
+ * arbitrary, non-deterministic behavior at an undetermined time in the future.
+ *
+ *
Note that the fail-fast behavior of an iterator cannot be guaranteed
+ * as it is, generally speaking, impossible to make any hard guarantees in the
+ * presence of unsynchronized concurrent modification. Fail-fast iterators
+ * throw {@code ConcurrentModificationException} on a best-effort basis.
+ * Therefore, it would be wrong to write a program that depended on this
+ * exception for its correctness: the fail-fast behavior of iterators
+ * should be used only to detect bugs.
+ *
+ *
All {@code Map.Entry} pairs returned by methods in this class
+ * and its views represent snapshots of mappings at the time they were
+ * produced. They do not support the {@code Entry.setValue}
+ * method. (Note however that it is possible to change mappings in the
+ * associated map using {@code put}.)
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @param the type of keys maintained by this map
+ * @param the type of mapped values
+ *
+ * @author Josh Bloch and Doug Lea
+ * @see Map
+ * @see HashMap
+ * @see Hashtable
+ * @see Comparable
+ * @see Comparator
+ * @see Collection
+ * @since 1.2
+ */
+
+public class TreeMap7
+ extends AbstractMap7
+ implements NavigableMap7, Cloneable, java.io.Serializable
+{
+ /**
+ * The comparator used to maintain order in this tree map, or
+ * null if it uses the natural ordering of its keys.
+ *
+ * @serial
+ */
+ private final Comparator super K> comparator;
+
+ private transient Entry root = null;
+
+ /**
+ * The number of entries in the tree
+ */
+ private transient int size = 0;
+
+ /**
+ * The number of structural modifications to the tree.
+ */
+ private transient int modCount = 0;
+
+ /**
+ * Constructs a new, empty tree map, using the natural ordering of its
+ * keys. All keys inserted into the map must implement the {@link
+ * Comparable} interface. Furthermore, all such keys must be
+ * mutually comparable: {@code k1.compareTo(k2)} must not throw
+ * a {@code ClassCastException} for any keys {@code k1} and
+ * {@code k2} in the map. If the user attempts to put a key into the
+ * map that violates this constraint (for example, the user attempts to
+ * put a string key into a map whose keys are integers), the
+ * {@code put(Object key, Object value)} call will throw a
+ * {@code ClassCastException}.
+ */
+ public TreeMap7() {
+ comparator = null;
+ }
+
+ /**
+ * Constructs a new, empty tree map, ordered according to the given
+ * comparator. All keys inserted into the map must be mutually
+ * comparable by the given comparator: {@code comparator.compare(k1,
+ * k2)} must not throw a {@code ClassCastException} for any keys
+ * {@code k1} and {@code k2} in the map. If the user attempts to put
+ * a key into the map that violates this constraint, the {@code put(Object
+ * key, Object value)} call will throw a
+ * {@code ClassCastException}.
+ *
+ * @param comparator the comparator that will be used to order this map.
+ * If {@code null}, the {@linkplain Comparable natural
+ * ordering} of the keys will be used.
+ */
+ public TreeMap7(Comparator super K> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Constructs a new tree map containing the same mappings as the given
+ * map, ordered according to the natural ordering of its keys.
+ * All keys inserted into the new map must implement the {@link
+ * Comparable} interface. Furthermore, all such keys must be
+ * mutually comparable: {@code k1.compareTo(k2)} must not throw
+ * a {@code ClassCastException} for any keys {@code k1} and
+ * {@code k2} in the map. This method runs in n*log(n) time.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws ClassCastException if the keys in m are not {@link Comparable},
+ * or are not mutually comparable
+ * @throws NullPointerException if the specified map is null
+ */
+ public TreeMap7(Map extends K, ? extends V> m) {
+ comparator = null;
+ putAll(m);
+ }
+
+ /**
+ * Constructs a new tree map containing the same mappings and
+ * using the same ordering as the specified sorted map. This
+ * method runs in linear time.
+ *
+ * @param m the sorted map whose mappings are to be placed in this map,
+ * and whose comparator is to be used to sort this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public TreeMap7(SortedMap m) {
+ comparator = m.comparator();
+ try {
+ buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
+ } catch (java.io.IOException cannotHappen) {
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+ }
+
+
+ // Query Operations
+
+ /**
+ * Returns the number of key-value mappings in this map.
+ *
+ * @return the number of key-value mappings in this map
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns {@code true} if this map contains a mapping for the specified
+ * key.
+ *
+ * @param key key whose presence in this map is to be tested
+ * @return {@code true} if this map contains a mapping for the
+ * specified key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ */
+ public boolean containsKey(Object key) {
+ return getEntry(key) != null;
+ }
+
+ /**
+ * Returns {@code true} if this map maps one or more keys to the
+ * specified value. More formally, returns {@code true} if and only if
+ * this map contains at least one mapping to a value {@code v} such
+ * that {@code (value==null ? v==null : value.equals(v))}. This
+ * operation will probably require time linear in the map size for
+ * most implementations.
+ *
+ * @param value value whose presence in this map is to be tested
+ * @return {@code true} if a mapping to {@code value} exists;
+ * {@code false} otherwise
+ * @since 1.2
+ */
+ public boolean containsValue(Object value) {
+ for (Entry e = getFirstEntry(); e != null; e = successor(e))
+ if (valEquals(value, e.value))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped,
+ * or {@code null} if this map contains no mapping for the key.
+ *
+ * More formally, if this map contains a mapping from a key
+ * {@code k} to a value {@code v} such that {@code key} compares
+ * equal to {@code k} according to the map's ordering, then this
+ * method returns {@code v}; otherwise it returns {@code null}.
+ * (There can be at most one such mapping.)
+ *
+ *
A return value of {@code null} does not necessarily
+ * indicate that the map contains no mapping for the key; it's also
+ * possible that the map explicitly maps the key to {@code null}.
+ * The {@link #containsKey containsKey} operation may be used to
+ * distinguish these two cases.
+ *
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ */
+ public V get(Object key) {
+ Entry p = getEntry(key);
+ return (p==null ? null : p.value);
+ }
+
+ public Comparator super K> comparator() {
+ return comparator;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public K firstKey() {
+ return key(getFirstEntry());
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public K lastKey() {
+ return key(getLastEntry());
+ }
+
+ /**
+ * Copies all of the mappings from the specified map to this map.
+ * These mappings replace any mappings that this map had for any
+ * of the keys currently in the specified map.
+ *
+ * @param map mappings to be stored in this map
+ * @throws ClassCastException if the class of a key or value in
+ * the specified map prevents it from being stored in this map
+ * @throws NullPointerException if the specified map is null or
+ * the specified map contains a null key and this map does not
+ * permit null keys
+ */
+ public void putAll(Map extends K, ? extends V> map) {
+ int mapSize = map.size();
+ if (size==0 && mapSize!=0 && map instanceof SortedMap) {
+ Comparator c = ((SortedMap)map).comparator();
+ if (c == comparator || (c != null && c.equals(comparator))) {
+ ++modCount;
+ try {
+ buildFromSorted(mapSize, map.entrySet().iterator(),
+ null, null);
+ } catch (java.io.IOException cannotHappen) {
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+ return;
+ }
+ }
+ super.putAll(map);
+ }
+
+ /**
+ * Returns this map's entry for the given key, or {@code null} if the map
+ * does not contain an entry for the key.
+ *
+ * @return this map's entry for the given key, or {@code null} if the map
+ * does not contain an entry for the key
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ */
+ final Entry getEntry(Object key) {
+ // Offload comparator-based version for sake of performance
+ if (comparator != null)
+ return getEntryUsingComparator(key);
+ if (key == null)
+ throw new NullPointerException();
+ Comparable super K> k = (Comparable super K>) key;
+ Entry p = root;
+ while (p != null) {
+ int cmp = k.compareTo(p.key);
+ if (cmp < 0)
+ p = p.left;
+ else if (cmp > 0)
+ p = p.right;
+ else
+ return p;
+ }
+ return null;
+ }
+
+ /**
+ * Version of getEntry using comparator. Split off from getEntry
+ * for performance. (This is not worth doing for most methods,
+ * that are less dependent on comparator performance, but is
+ * worthwhile here.)
+ */
+ final Entry getEntryUsingComparator(Object key) {
+ K k = (K) key;
+ Comparator super K> cpr = comparator;
+ if (cpr != null) {
+ Entry p = root;
+ while (p != null) {
+ int cmp = cpr.compare(k, p.key);
+ if (cmp < 0)
+ p = p.left;
+ else if (cmp > 0)
+ p = p.right;
+ else
+ return p;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the entry corresponding to the specified key; if no such entry
+ * exists, returns the entry for the least key greater than the specified
+ * key; if no such entry exists (i.e., the greatest key in the Tree is less
+ * than the specified key), returns {@code null}.
+ */
+ final Entry getCeilingEntry(K key) {
+ Entry p = root;
+ while (p != null) {
+ int cmp = compare(key, p.key);
+ if (cmp < 0) {
+ if (p.left != null)
+ p = p.left;
+ else
+ return p;
+ } else if (cmp > 0) {
+ if (p.right != null) {
+ p = p.right;
+ } else {
+ Entry parent = p.parent;
+ Entry ch = p;
+ while (parent != null && ch == parent.right) {
+ ch = parent;
+ parent = parent.parent;
+ }
+ return parent;
+ }
+ } else
+ return p;
+ }
+ return null;
+ }
+
+ /**
+ * Gets the entry corresponding to the specified key; if no such entry
+ * exists, returns the entry for the greatest key less than the specified
+ * key; if no such entry exists, returns {@code null}.
+ */
+ final Entry getFloorEntry(K key) {
+ Entry p = root;
+ while (p != null) {
+ int cmp = compare(key, p.key);
+ if (cmp > 0) {
+ if (p.right != null)
+ p = p.right;
+ else
+ return p;
+ } else if (cmp < 0) {
+ if (p.left != null) {
+ p = p.left;
+ } else {
+ Entry parent = p.parent;
+ Entry ch = p;
+ while (parent != null && ch == parent.left) {
+ ch = parent;
+ parent = parent.parent;
+ }
+ return parent;
+ }
+ } else
+ return p;
+
+ }
+ return null;
+ }
+
+ /**
+ * Gets the entry for the least key greater than the specified
+ * key; if no such entry exists, returns the entry for the least
+ * key greater than the specified key; if no such entry exists
+ * returns {@code null}.
+ */
+ final Entry getHigherEntry(K key) {
+ Entry p = root;
+ while (p != null) {
+ int cmp = compare(key, p.key);
+ if (cmp < 0) {
+ if (p.left != null)
+ p = p.left;
+ else
+ return p;
+ } else {
+ if (p.right != null) {
+ p = p.right;
+ } else {
+ Entry parent = p.parent;
+ Entry ch = p;
+ while (parent != null && ch == parent.right) {
+ ch = parent;
+ parent = parent.parent;
+ }
+ return parent;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the entry for the greatest key less than the specified key; if
+ * no such entry exists (i.e., the least key in the Tree is greater than
+ * the specified key), returns {@code null}.
+ */
+ final Entry getLowerEntry(K key) {
+ Entry p = root;
+ while (p != null) {
+ int cmp = compare(key, p.key);
+ if (cmp > 0) {
+ if (p.right != null)
+ p = p.right;
+ else
+ return p;
+ } else {
+ if (p.left != null) {
+ p = p.left;
+ } else {
+ Entry parent = p.parent;
+ Entry ch = p;
+ while (parent != null && ch == parent.left) {
+ ch = parent;
+ parent = parent.parent;
+ }
+ return parent;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Associates the specified value with the specified key in this map.
+ * If the map previously contained a mapping for the key, the old
+ * value is replaced.
+ *
+ * @param key key with which the specified value is to be associated
+ * @param value value to be associated with the specified key
+ *
+ * @return the previous value associated with {@code key}, or
+ * {@code null} if there was no mapping for {@code key}.
+ * (A {@code null} return can also indicate that the map
+ * previously associated {@code null} with {@code key}.)
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ */
+ public V put(K key, V value) {
+ Entry t = root;
+ if (t == null) {
+ compare(key, key); // type (and possibly null) check
+
+ root = new Entry(key, value, null);
+ size = 1;
+ modCount++;
+ return null;
+ }
+ int cmp;
+ Entry parent;
+ // split comparator and comparable paths
+ Comparator super K> cpr = comparator;
+ if (cpr != null) {
+ do {
+ parent = t;
+ cmp = cpr.compare(key, t.key);
+ if (cmp < 0)
+ t = t.left;
+ else if (cmp > 0)
+ t = t.right;
+ else
+ return t.setValue(value);
+ } while (t != null);
+ }
+ else {
+ if (key == null)
+ throw new NullPointerException();
+ Comparable super K> k = (Comparable super K>) key;
+ do {
+ parent = t;
+ cmp = k.compareTo(t.key);
+ if (cmp < 0)
+ t = t.left;
+ else if (cmp > 0)
+ t = t.right;
+ else
+ return t.setValue(value);
+ } while (t != null);
+ }
+ Entry e = new Entry(key, value, parent);
+ if (cmp < 0)
+ parent.left = e;
+ else
+ parent.right = e;
+ fixAfterInsertion(e);
+ size++;
+ modCount++;
+ return null;
+ }
+
+ /**
+ * Removes the mapping for this key from this TreeMap7 if present.
+ *
+ * @param key key for which mapping should be removed
+ * @return the previous value associated with {@code key}, or
+ * {@code null} if there was no mapping for {@code key}.
+ * (A {@code null} return can also indicate that the map
+ * previously associated {@code null} with {@code key}.)
+ * @throws ClassCastException if the specified key cannot be compared
+ * with the keys currently in the map
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ */
+ public V remove(Object key) {
+ Entry p = getEntry(key);
+ if (p == null)
+ return null;
+
+ V oldValue = p.value;
+ deleteEntry(p);
+ return oldValue;
+ }
+
+ /**
+ * Removes all of the mappings from this map.
+ * The map will be empty after this call returns.
+ */
+ public void clear() {
+ modCount++;
+ size = 0;
+ root = null;
+ }
+
+ /**
+ * Returns a shallow copy of this {@code TreeMap7} instance. (The keys and
+ * values themselves are not cloned.)
+ *
+ * @return a shallow copy of this map
+ */
+ public Object clone() {
+ TreeMap7 clone = null;
+ try {
+ clone = (TreeMap7) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new InternalError();
+ }
+
+ // Put clone into "virgin" state (except for comparator)
+ clone.root = null;
+ clone.size = 0;
+ clone.modCount = 0;
+ clone.entrySet = null;
+ clone.navigableKeySet = null;
+ clone.descendingMap = null;
+
+ // Initialize clone with our mappings
+ try {
+ clone.buildFromSorted(size, entrySet().iterator(), null, null);
+ } catch (java.io.IOException cannotHappen) {
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+
+ return clone;
+ }
+
+ // NavigableMap7 API methods
+
+ /**
+ * @since 1.6
+ */
+ public Map.Entry firstEntry() {
+ return exportEntry(getFirstEntry());
+ }
+
+ /**
+ * @since 1.6
+ */
+ public Map.Entry lastEntry() {
+ return exportEntry(getLastEntry());
+ }
+
+ /**
+ * @since 1.6
+ */
+ public Map.Entry pollFirstEntry() {
+ Entry p = getFirstEntry();
+ Map.Entry result = exportEntry(p);
+ if (p != null)
+ deleteEntry(p);
+ return result;
+ }
+
+ /**
+ * @since 1.6
+ */
+ public Map.Entry pollLastEntry() {
+ Entry p = getLastEntry();
+ Map.Entry result = exportEntry(p);
+ if (p != null)
+ deleteEntry(p);
+ return result;
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public Map.Entry lowerEntry(K key) {
+ return exportEntry(getLowerEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public K lowerKey(K key) {
+ return keyOrNull(getLowerEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public Map.Entry floorEntry(K key) {
+ return exportEntry(getFloorEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public K floorKey(K key) {
+ return keyOrNull(getFloorEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public Map.Entry ceilingEntry(K key) {
+ return exportEntry(getCeilingEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public K ceilingKey(K key) {
+ return keyOrNull(getCeilingEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public Map.Entry higherEntry(K key) {
+ return exportEntry(getHigherEntry(key));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @since 1.6
+ */
+ public K higherKey(K key) {
+ return keyOrNull(getHigherEntry(key));
+ }
+
+ // Views
+
+ /**
+ * Fields initialized to contain an instance of the entry set view
+ * the first time this view is requested. Views are stateless, so
+ * there's no reason to create more than one.
+ */
+ private transient EntrySet entrySet = null;
+ private transient KeySet navigableKeySet = null;
+ private transient NavigableMap7 descendingMap = null;
+
+ /**
+ * Returns a {@link Set} view of the keys contained in this map.
+ * The set's iterator returns the keys in ascending order.
+ * The set is backed by the map, so changes to the map are
+ * reflected in the set, and vice-versa. If the map is modified
+ * while an iteration over the set is in progress (except through
+ * the iterator's own {@code remove} operation), the results of
+ * the iteration are undefined. The set supports element removal,
+ * which removes the corresponding mapping from the map, via the
+ * {@code Iterator.remove}, {@code Set.remove},
+ * {@code removeAll}, {@code retainAll}, and {@code clear}
+ * operations. It does not support the {@code add} or {@code addAll}
+ * operations.
+ */
+ public Set keySet() {
+ return navigableKeySet();
+ }
+
+ /**
+ * @since 1.6
+ */
+ public NavigableSet7 navigableKeySet() {
+ KeySet nks = navigableKeySet;
+ return (nks != null) ? nks : (navigableKeySet = new KeySet(this));
+ }
+
+ /**
+ * @since 1.6
+ */
+ public NavigableSet7 descendingKeySet() {
+ return descendingMap().navigableKeySet();
+ }
+
+ /**
+ * Returns a {@link Collection} view of the values contained in this map.
+ * The collection's iterator returns the values in ascending order
+ * of the corresponding keys.
+ * The collection is backed by the map, so changes to the map are
+ * reflected in the collection, and vice-versa. If the map is
+ * modified while an iteration over the collection is in progress
+ * (except through the iterator's own {@code remove} operation),
+ * the results of the iteration are undefined. The collection
+ * supports element removal, which removes the corresponding
+ * mapping from the map, via the {@code Iterator.remove},
+ * {@code Collection.remove}, {@code removeAll},
+ * {@code retainAll} and {@code clear} operations. It does not
+ * support the {@code add} or {@code addAll} operations.
+ */
+ public Collection values() {
+ Collection vs = values;
+ return (vs != null) ? vs : (values = new Values());
+ }
+
+ /**
+ * Returns a {@link Set} view of the mappings contained in this map.
+ * The set's iterator returns the entries in ascending key order.
+ * The set is backed by the map, so changes to the map are
+ * reflected in the set, and vice-versa. If the map is modified
+ * while an iteration over the set is in progress (except through
+ * the iterator's own {@code remove} operation, or through the
+ * {@code setValue} operation on a map entry returned by the
+ * iterator) the results of the iteration are undefined. The set
+ * supports element removal, which removes the corresponding
+ * mapping from the map, via the {@code Iterator.remove},
+ * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
+ * {@code clear} operations. It does not support the
+ * {@code add} or {@code addAll} operations.
+ */
+ public Set> entrySet() {
+ EntrySet es = entrySet;
+ return (es != null) ? es : (entrySet = new EntrySet());
+ }
+
+ /**
+ * @since 1.6
+ */
+ public NavigableMap7 descendingMap() {
+ NavigableMap7 km = descendingMap;
+ return (km != null) ? km :
+ (descendingMap = new DescendingSubMap(this,
+ true, null, true,
+ true, null, true));
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code fromKey} or {@code toKey} is
+ * null and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @since 1.6
+ */
+ public NavigableMap7 subMap(K fromKey, boolean fromInclusive,
+ K toKey, boolean toInclusive) {
+ return new AscendingSubMap(this,
+ false, fromKey, fromInclusive,
+ false, toKey, toInclusive);
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code toKey} is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @since 1.6
+ */
+ public NavigableMap7 headMap(K toKey, boolean inclusive) {
+ return new AscendingSubMap(this,
+ true, null, true,
+ false, toKey, inclusive);
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code fromKey} is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @since 1.6
+ */
+ public NavigableMap7 tailMap(K fromKey, boolean inclusive) {
+ return new AscendingSubMap(this,
+ false, fromKey, inclusive,
+ true, null, true);
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code fromKey} or {@code toKey} is
+ * null and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public SortedMap subMap(K fromKey, K toKey) {
+ return subMap(fromKey, true, toKey, false);
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code toKey} is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public SortedMap headMap(K toKey) {
+ return headMap(toKey, false);
+ }
+
+ /**
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException if {@code fromKey} is null
+ * and this map uses natural ordering, or its comparator
+ * does not permit null keys
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public SortedMap tailMap(K fromKey) {
+ return tailMap(fromKey, true);
+ }
+
+ // View class support
+
+ class Values extends AbstractCollection {
+ public Iterator iterator() {
+ return new ValueIterator(getFirstEntry());
+ }
+
+ public int size() {
+ return TreeMap7.this.size();
+ }
+
+ public boolean contains(Object o) {
+ return TreeMap7.this.containsValue(o);
+ }
+
+ public boolean remove(Object o) {
+ for (Entry e = getFirstEntry(); e != null; e = successor(e)) {
+ if (valEquals(e.getValue(), o)) {
+ deleteEntry(e);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void clear() {
+ TreeMap7.this.clear();
+ }
+ }
+
+ class EntrySet extends AbstractSet> {
+ public Iterator> iterator() {
+ return new EntryIterator(getFirstEntry());
+ }
+
+ public boolean contains(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry entry = (Map.Entry) o;
+ V value = entry.getValue();
+ Entry p = getEntry(entry.getKey());
+ return p != null && valEquals(p.getValue(), value);
+ }
+
+ public boolean remove(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry entry = (Map.Entry) o;
+ V value = entry.getValue();
+ Entry p = getEntry(entry.getKey());
+ if (p != null && valEquals(p.getValue(), value)) {
+ deleteEntry(p);
+ return true;
+ }
+ return false;
+ }
+
+ public int size() {
+ return TreeMap7.this.size();
+ }
+
+ public void clear() {
+ TreeMap7.this.clear();
+ }
+ }
+
+ /*
+ * Unlike Values and EntrySet, the KeySet class is static,
+ * delegating to a NavigableMap7 to allow use by SubMaps, which
+ * outweighs the ugliness of needing type-tests for the following
+ * Iterator methods that are defined appropriately in main versus
+ * submap classes.
+ */
+
+ Iterator keyIterator() {
+ return new KeyIterator(getFirstEntry());
+ }
+
+ Iterator descendingKeyIterator() {
+ return new DescendingKeyIterator(getLastEntry());
+ }
+
+ static final class KeySet extends AbstractSet implements NavigableSet7 {
+ private final NavigableMap7 m;
+ KeySet(NavigableMap7 map) { m = map; }
+
+ public Iterator iterator() {
+ if (m instanceof TreeMap7)
+ return ((TreeMap7)m).keyIterator();
+ else
+ return (Iterator)(((TreeMap7.NavigableSubMap)m).keyIterator());
+ }
+
+ public Iterator descendingIterator() {
+ if (m instanceof TreeMap7)
+ return ((TreeMap7)m).descendingKeyIterator();
+ else
+ return (Iterator)(((TreeMap7.NavigableSubMap)m).descendingKeyIterator());
+ }
+
+ public int size() { return m.size(); }
+ public boolean isEmpty() { return m.isEmpty(); }
+ public boolean contains(Object o) { return m.containsKey(o); }
+ public void clear() { m.clear(); }
+ public E lower(E e) { return m.lowerKey(e); }
+ public E floor(E e) { return m.floorKey(e); }
+ public E ceiling(E e) { return m.ceilingKey(e); }
+ public E higher(E e) { return m.higherKey(e); }
+ public E first() { return m.firstKey(); }
+ public E last() { return m.lastKey(); }
+ public Comparator super E> comparator() { return m.comparator(); }
+ public E pollFirst() {
+ Map.Entry e = m.pollFirstEntry();
+ return (e == null) ? null : e.getKey();
+ }
+ public E pollLast() {
+ Map.Entry e = m.pollLastEntry();
+ return (e == null) ? null : e.getKey();
+ }
+ public boolean remove(Object o) {
+ int oldSize = size();
+ m.remove(o);
+ return size() != oldSize;
+ }
+ public NavigableSet7 subSet(E fromElement, boolean fromInclusive,
+ E toElement, boolean toInclusive) {
+ return new KeySet(m.subMap(fromElement, fromInclusive,
+ toElement, toInclusive));
+ }
+ public NavigableSet7 headSet(E toElement, boolean inclusive) {
+ return new KeySet(m.headMap(toElement, inclusive));
+ }
+ public NavigableSet7 tailSet(E fromElement, boolean inclusive) {
+ return new KeySet(m.tailMap(fromElement, inclusive));
+ }
+ public SortedSet subSet(E fromElement, E toElement) {
+ return subSet(fromElement, true, toElement, false);
+ }
+ public SortedSet headSet(E toElement) {
+ return headSet(toElement, false);
+ }
+ public SortedSet tailSet(E fromElement) {
+ return tailSet(fromElement, true);
+ }
+ public NavigableSet7 descendingSet() {
+ return new KeySet(m.descendingMap());
+ }
+ }
+
+ /**
+ * Base class for TreeMap7 Iterators
+ */
+ abstract class PrivateEntryIterator implements Iterator {
+ Entry next;
+ Entry lastReturned;
+ int expectedModCount;
+
+ PrivateEntryIterator(Entry first) {
+ expectedModCount = modCount;
+ lastReturned = null;
+ next = first;
+ }
+
+ public final boolean hasNext() {
+ return next != null;
+ }
+
+ final Entry nextEntry() {
+ Entry e = next;
+ if (e == null)
+ throw new NoSuchElementException();
+ if (modCount != expectedModCount)
+ throw new ConcurrentModificationException();
+ next = successor(e);
+ lastReturned = e;
+ return e;
+ }
+
+ final Entry prevEntry() {
+ Entry e = next;
+ if (e == null)
+ throw new NoSuchElementException();
+ if (modCount != expectedModCount)
+ throw new ConcurrentModificationException();
+ next = predecessor(e);
+ lastReturned = e;
+ return e;
+ }
+
+ public void remove() {
+ if (lastReturned == null)
+ throw new IllegalStateException();
+ if (modCount != expectedModCount)
+ throw new ConcurrentModificationException();
+ // deleted entries are replaced by their successors
+ if (lastReturned.left != null && lastReturned.right != null)
+ next = lastReturned;
+ deleteEntry(lastReturned);
+ expectedModCount = modCount;
+ lastReturned = null;
+ }
+ }
+
+ final class EntryIterator extends PrivateEntryIterator> {
+ EntryIterator(Entry first) {
+ super(first);
+ }
+ public Map.Entry next() {
+ return nextEntry();
+ }
+ }
+
+ final class ValueIterator extends PrivateEntryIterator {
+ ValueIterator(Entry first) {
+ super(first);
+ }
+ public V next() {
+ return nextEntry().value;
+ }
+ }
+
+ final class KeyIterator extends PrivateEntryIterator {
+ KeyIterator(Entry first) {
+ super(first);
+ }
+ public K next() {
+ return nextEntry().key;
+ }
+ }
+
+ final class DescendingKeyIterator extends PrivateEntryIterator {
+ DescendingKeyIterator(Entry first) {
+ super(first);
+ }
+ public K next() {
+ return prevEntry().key;
+ }
+ }
+
+ // Little utilities
+
+ /**
+ * Compares two keys using the correct comparison method for this TreeMap7.
+ */
+ final int compare(Object k1, Object k2) {
+ return comparator==null ? ((Comparable super K>)k1).compareTo((K)k2)
+ : comparator.compare((K)k1, (K)k2);
+ }
+
+ /**
+ * Test two values for equality. Differs from o1.equals(o2) only in
+ * that it copes with {@code null} o1 properly.
+ */
+ static final boolean valEquals(Object o1, Object o2) {
+ return (o1==null ? o2==null : o1.equals(o2));
+ }
+
+ /**
+ * Return SimpleImmutableEntry for entry, or null if null
+ */
+ static Map.Entry exportEntry(TreeMap7.Entry e) {
+ return (e == null) ? null :
+ new AbstractMap7.SimpleImmutableEntry(e);
+ }
+
+ /**
+ * Return key for entry, or null if null
+ */
+ static K keyOrNull(TreeMap7.Entry e) {
+ return (e == null) ? null : e.key;
+ }
+
+ /**
+ * Returns the key corresponding to the specified Entry.
+ * @throws NoSuchElementException if the Entry is null
+ */
+ static K key(Entry e) {
+ if (e==null)
+ throw new NoSuchElementException();
+ return e.key;
+ }
+
+
+ // SubMaps
+
+ /**
+ * Dummy value serving as unmatchable fence key for unbounded
+ * SubMapIterators
+ */
+ private static final Object UNBOUNDED = new Object();
+
+ /**
+ * @serial include
+ */
+ abstract static class NavigableSubMap extends AbstractMap7
+ implements NavigableMap7, java.io.Serializable {
+ /**
+ * The backing map.
+ */
+ final TreeMap7 m;
+
+ /**
+ * Endpoints are represented as triples (fromStart, lo,
+ * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
+ * true, then the low (absolute) bound is the start of the
+ * backing map, and the other values are ignored. Otherwise,
+ * if loInclusive is true, lo is the inclusive bound, else lo
+ * is the exclusive bound. Similarly for the upper bound.
+ */
+ final K lo, hi;
+ final boolean fromStart, toEnd;
+ final boolean loInclusive, hiInclusive;
+
+ NavigableSubMap(TreeMap7 m,
+ boolean fromStart, K lo, boolean loInclusive,
+ boolean toEnd, K hi, boolean hiInclusive) {
+ if (!fromStart && !toEnd) {
+ if (m.compare(lo, hi) > 0)
+ throw new IllegalArgumentException("fromKey > toKey");
+ } else {
+ if (!fromStart) // type check
+ m.compare(lo, lo);
+ if (!toEnd)
+ m.compare(hi, hi);
+ }
+
+ this.m = m;
+ this.fromStart = fromStart;
+ this.lo = lo;
+ this.loInclusive = loInclusive;
+ this.toEnd = toEnd;
+ this.hi = hi;
+ this.hiInclusive = hiInclusive;
+ }
+
+ // internal utilities
+
+ final boolean tooLow(Object key) {
+ if (!fromStart) {
+ int c = m.compare(key, lo);
+ if (c < 0 || (c == 0 && !loInclusive))
+ return true;
+ }
+ return false;
+ }
+
+ final boolean tooHigh(Object key) {
+ if (!toEnd) {
+ int c = m.compare(key, hi);
+ if (c > 0 || (c == 0 && !hiInclusive))
+ return true;
+ }
+ return false;
+ }
+
+ final boolean inRange(Object key) {
+ return !tooLow(key) && !tooHigh(key);
+ }
+
+ final boolean inClosedRange(Object key) {
+ return (fromStart || m.compare(key, lo) >= 0)
+ && (toEnd || m.compare(hi, key) >= 0);
+ }
+
+ final boolean inRange(Object key, boolean inclusive) {
+ return inclusive ? inRange(key) : inClosedRange(key);
+ }
+
+ /*
+ * Absolute versions of relation operations.
+ * Subclasses map to these using like-named "sub"
+ * versions that invert senses for descending maps
+ */
+
+ final TreeMap7.Entry absLowest() {
+ TreeMap7.Entry e =
+ (fromStart ? m.getFirstEntry() :
+ (loInclusive ? m.getCeilingEntry(lo) :
+ m.getHigherEntry(lo)));
+ return (e == null || tooHigh(e.key)) ? null : e;
+ }
+
+ final TreeMap7.Entry absHighest() {
+ TreeMap7.Entry e =
+ (toEnd ? m.getLastEntry() :
+ (hiInclusive ? m.getFloorEntry(hi) :
+ m.getLowerEntry(hi)));
+ return (e == null || tooLow(e.key)) ? null : e;
+ }
+
+ final TreeMap7.Entry absCeiling(K key) {
+ if (tooLow(key))
+ return absLowest();
+ TreeMap7.Entry e = m.getCeilingEntry(key);
+ return (e == null || tooHigh(e.key)) ? null : e;
+ }
+
+ final TreeMap7.Entry absHigher(K key) {
+ if (tooLow(key))
+ return absLowest();
+ TreeMap7.Entry e = m.getHigherEntry(key);
+ return (e == null || tooHigh(e.key)) ? null : e;
+ }
+
+ final TreeMap7.Entry absFloor(K key) {
+ if (tooHigh(key))
+ return absHighest();
+ TreeMap7.Entry