summaryrefslogtreecommitdiffstats
path: root/guava/src/com/google/common/base
diff options
context:
space:
mode:
Diffstat (limited to 'guava/src/com/google/common/base')
-rw-r--r--guava/src/com/google/common/base/Absent.java87
-rw-r--r--guava/src/com/google/common/base/AbstractIterator.java84
-rw-r--r--guava/src/com/google/common/base/Ascii.java487
-rw-r--r--guava/src/com/google/common/base/CaseFormat.java164
-rw-r--r--guava/src/com/google/common/base/CharMatcher.java1271
-rw-r--r--guava/src/com/google/common/base/Charsets.java83
-rw-r--r--guava/src/com/google/common/base/Defaults.java60
-rw-r--r--guava/src/com/google/common/base/Enums.java128
-rw-r--r--guava/src/com/google/common/base/Equivalence.java358
-rw-r--r--guava/src/com/google/common/base/Equivalences.java65
-rw-r--r--guava/src/com/google/common/base/FinalizablePhantomReference.java44
-rw-r--r--guava/src/com/google/common/base/FinalizableReference.java33
-rw-r--r--guava/src/com/google/common/base/FinalizableReferenceQueue.java299
-rw-r--r--guava/src/com/google/common/base/FinalizableSoftReference.java42
-rw-r--r--guava/src/com/google/common/base/FinalizableWeakReference.java42
-rw-r--r--guava/src/com/google/common/base/Function.java63
-rw-r--r--guava/src/com/google/common/base/FunctionalEquivalence.java77
-rw-r--r--guava/src/com/google/common/base/Functions.java356
-rw-r--r--guava/src/com/google/common/base/Joiner.java562
-rw-r--r--guava/src/com/google/common/base/MediumCharMatcher.java133
-rw-r--r--guava/src/com/google/common/base/Objects.java440
-rw-r--r--guava/src/com/google/common/base/Optional.java245
-rw-r--r--guava/src/com/google/common/base/PairwiseEquivalence.java80
-rw-r--r--guava/src/com/google/common/base/Platform.java55
-rw-r--r--guava/src/com/google/common/base/Preconditions.java449
-rw-r--r--guava/src/com/google/common/base/Predicate.java63
-rw-r--r--guava/src/com/google/common/base/Predicates.java626
-rw-r--r--guava/src/com/google/common/base/Present.java92
-rw-r--r--guava/src/com/google/common/base/SmallCharMatcher.java128
-rw-r--r--guava/src/com/google/common/base/Splitter.java571
-rw-r--r--guava/src/com/google/common/base/Stopwatch.java226
-rw-r--r--guava/src/com/google/common/base/Strings.java238
-rw-r--r--guava/src/com/google/common/base/Supplier.java38
-rw-r--r--guava/src/com/google/common/base/Suppliers.java293
-rw-r--r--guava/src/com/google/common/base/Throwables.java220
-rw-r--r--guava/src/com/google/common/base/Ticker.java63
-rw-r--r--guava/src/com/google/common/base/internal/Finalizer.java205
-rw-r--r--guava/src/com/google/common/base/package-info.java66
38 files changed, 8536 insertions, 0 deletions
diff --git a/guava/src/com/google/common/base/Absent.java b/guava/src/com/google/common/base/Absent.java
new file mode 100644
index 0000000..852fa20
--- /dev/null
+++ b/guava/src/com/google/common/base/Absent.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * Implementation of an {@link Optional} not containing a reference.
+ */
+@GwtCompatible
+final class Absent extends Optional<Object> {
+ static final Absent INSTANCE = new Absent();
+
+ @Override public boolean isPresent() {
+ return false;
+ }
+
+ @Override public Object get() {
+ throw new IllegalStateException("value is absent");
+ }
+
+ @Override public Object or(Object defaultValue) {
+ return checkNotNull(defaultValue, "use orNull() instead of or(null)");
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ @Override public Optional<Object> or(Optional<?> secondChoice) {
+ return (Optional) checkNotNull(secondChoice);
+ }
+
+ @Override public Object or(Supplier<?> supplier) {
+ return checkNotNull(supplier.get(),
+ "use orNull() instead of a Supplier that returns null");
+ }
+
+ @Override @Nullable public Object orNull() {
+ return null;
+ }
+
+ @Override public Set<Object> asSet() {
+ return Collections.emptySet();
+ }
+
+ @Override public <V> Optional<V> transform(Function<Object, V> function) {
+ checkNotNull(function);
+ return Optional.absent();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return object == this;
+ }
+
+ @Override public int hashCode() {
+ return 0x598df91c;
+ }
+
+ @Override public String toString() {
+ return "Optional.absent()";
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava/src/com/google/common/base/AbstractIterator.java b/guava/src/com/google/common/base/AbstractIterator.java
new file mode 100644
index 0000000..d171af2
--- /dev/null
+++ b/guava/src/com/google/common/base/AbstractIterator.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Note this class is a copy of
+ * {@link com.google.common.collect.AbstractIterator} (for dependency reasons).
+ */
+@GwtCompatible
+abstract class AbstractIterator<T> implements Iterator<T> {
+ private State state = State.NOT_READY;
+
+ protected AbstractIterator() {}
+
+ private enum State {
+ READY, NOT_READY, DONE, FAILED,
+ }
+
+ private T next;
+
+ protected abstract T computeNext();
+
+ protected final T endOfData() {
+ state = State.DONE;
+ return null;
+ }
+
+ @Override
+ public final boolean hasNext() {
+ checkState(state != State.FAILED);
+ switch (state) {
+ case DONE:
+ return false;
+ case READY:
+ return true;
+ default:
+ }
+ return tryToComputeNext();
+ }
+
+ private boolean tryToComputeNext() {
+ state = State.FAILED; // temporary pessimism
+ next = computeNext();
+ if (state != State.DONE) {
+ state = State.READY;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public final T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ state = State.NOT_READY;
+ return next;
+ }
+
+ @Override public final void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/guava/src/com/google/common/base/Ascii.java b/guava/src/com/google/common/base/Ascii.java
new file mode 100644
index 0000000..792856d
--- /dev/null
+++ b/guava/src/com/google/common/base/Ascii.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * Static methods pertaining to ASCII characters (those in the range of values
+ * {@code 0x00} through {@code 0x7F}), and to strings containing such
+ * characters.
+ *
+ * <p>ASCII utilities also exist in other classes of this package:
+ * <ul>
+ * <!-- TODO(kevinb): how can we make this not produce a warning when building gwt javadoc? -->
+ * <li>{@link Charsets#US_ASCII} specifies the {@code Charset} of ASCII characters.
+ * <li>{@link CharMatcher#ASCII} matches ASCII characters and provides text processing methods
+ * which operate only on the ASCII characters of a string.
+ * </ul>
+ *
+ * @author Craig Berry
+ * @author Gregory Kick
+ * @since 7.0
+ */
+@GwtCompatible
+public final class Ascii {
+
+ private Ascii() {}
+
+ /* The ASCII control characters, per RFC 20. */
+ /**
+ * Null ('\0'): The all-zeros character which may serve to accomplish
+ * time fill and media fill. Normally used as a C string terminator.
+ * <p>Although RFC 20 names this as "Null", note that it is distinct
+ * from the C/C++ "NULL" pointer.
+ *
+ * @since 8.0
+ */
+ public static final byte NUL = 0;
+
+ /**
+ * Start of Heading: A communication control character used at
+ * the beginning of a sequence of characters which constitute a
+ * machine-sensible address or routing information. Such a sequence is
+ * referred to as the "heading." An STX character has the effect of
+ * terminating a heading.
+ *
+ * @since 8.0
+ */
+ public static final byte SOH = 1;
+
+ /**
+ * Start of Text: A communication control character which
+ * precedes a sequence of characters that is to be treated as an entity
+ * and entirely transmitted through to the ultimate destination. Such a
+ * sequence is referred to as "text." STX may be used to terminate a
+ * sequence of characters started by SOH.
+ *
+ * @since 8.0
+ */
+ public static final byte STX = 2;
+
+ /**
+ * End of Text: A communication control character used to
+ * terminate a sequence of characters started with STX and transmitted
+ * as an entity.
+ *
+ * @since 8.0
+ */
+ public static final byte ETX = 3;
+
+ /**
+ * End of Transmission: A communication control character used
+ * to indicate the conclusion of a transmission, which may have
+ * contained one or more texts and any associated headings.
+ *
+ * @since 8.0
+ */
+ public static final byte EOT = 4;
+
+ /**
+ * Enquiry: A communication control character used in data
+ * communication systems as a request for a response from a remote
+ * station. It may be used as a "Who Are You" (WRU) to obtain
+ * identification, or may be used to obtain station status, or both.
+ *
+ * @since 8.0
+ */
+ public static final byte ENQ = 5;
+
+ /**
+ * Acknowledge: A communication control character transmitted
+ * by a receiver as an affirmative response to a sender.
+ *
+ * @since 8.0
+ */
+ public static final byte ACK = 6;
+
+ /**
+ * Bell ('\a'): A character for use when there is a need to call for
+ * human attention. It may control alarm or attention devices.
+ *
+ * @since 8.0
+ */
+ public static final byte BEL = 7;
+
+ /**
+ * Backspace ('\b'): A format effector which controls the movement of
+ * the printing position one printing space backward on the same
+ * printing line. (Applicable also to display devices.)
+ *
+ * @since 8.0
+ */
+ public static final byte BS = 8;
+
+ /**
+ * Horizontal Tabulation ('\t'): A format effector which controls the
+ * movement of the printing position to the next in a series of
+ * predetermined positions along the printing line. (Applicable also to
+ * display devices and the skip function on punched cards.)
+ *
+ * @since 8.0
+ */
+ public static final byte HT = 9;
+
+ /**
+ * Line Feed ('\n'): A format effector which controls the movement of
+ * the printing position to the next printing line. (Applicable also to
+ * display devices.) Where appropriate, this character may have the
+ * meaning "New Line" (NL), a format effector which controls the
+ * movement of the printing point to the first printing position on the
+ * next printing line. Use of this convention requires agreement
+ * between sender and recipient of data.
+ *
+ * @since 8.0
+ */
+ public static final byte LF = 10;
+
+ /**
+ * Alternate name for {@link #LF}. ({@code LF} is preferred.)
+ *
+ * @since 8.0
+ */
+ public static final byte NL = 10;
+
+ /**
+ * Vertical Tabulation ('\v'): A format effector which controls the
+ * movement of the printing position to the next in a series of
+ * predetermined printing lines. (Applicable also to display devices.)
+ *
+ * @since 8.0
+ */
+ public static final byte VT = 11;
+
+ /**
+ * Form Feed ('\f'): A format effector which controls the movement of
+ * the printing position to the first pre-determined printing line on
+ * the next form or page. (Applicable also to display devices.)
+ *
+ * @since 8.0
+ */
+ public static final byte FF = 12;
+
+ /**
+ * Carriage Return ('\r'): A format effector which controls the
+ * movement of the printing position to the first printing position on
+ * the same printing line. (Applicable also to display devices.)
+ *
+ * @since 8.0
+ */
+ public static final byte CR = 13;
+
+ /**
+ * Shift Out: A control character indicating that the code
+ * combinations which follow shall be interpreted as outside of the
+ * character set of the standard code table until a Shift In character
+ * is reached.
+ *
+ * @since 8.0
+ */
+ public static final byte SO = 14;
+
+ /**
+ * Shift In: A control character indicating that the code
+ * combinations which follow shall be interpreted according to the
+ * standard code table.
+ *
+ * @since 8.0
+ */
+ public static final byte SI = 15;
+
+ /**
+ * Data Link Escape: A communication control character which
+ * will change the meaning of a limited number of contiguously following
+ * characters. It is used exclusively to provide supplementary controls
+ * in data communication networks.
+ *
+ * @since 8.0
+ */
+ public static final byte DLE = 16;
+
+ /**
+ * Device Control 1. Characters for the control
+ * of ancillary devices associated with data processing or
+ * telecommunication systems, more especially switching devices "on" or
+ * "off." (If a single "stop" control is required to interrupt or turn
+ * off ancillary devices, DC4 is the preferred assignment.)
+ *
+ * @since 8.0
+ */
+ public static final byte DC1 = 17; // aka XON
+
+ /**
+ * Transmission On: Although originally defined as DC1, this ASCII
+ * control character is now better known as the XON code used for software
+ * flow control in serial communications. The main use is restarting
+ * the transmission after the communication has been stopped by the XOFF
+ * control code.
+ *
+ * @since 8.0
+ */
+ public static final byte XON = 17; // aka DC1
+
+ /**
+ * Device Control 2. Characters for the control
+ * of ancillary devices associated with data processing or
+ * telecommunication systems, more especially switching devices "on" or
+ * "off." (If a single "stop" control is required to interrupt or turn
+ * off ancillary devices, DC4 is the preferred assignment.)
+ *
+ * @since 8.0
+ */
+ public static final byte DC2 = 18;
+
+ /**
+ * Device Control 3. Characters for the control
+ * of ancillary devices associated with data processing or
+ * telecommunication systems, more especially switching devices "on" or
+ * "off." (If a single "stop" control is required to interrupt or turn
+ * off ancillary devices, DC4 is the preferred assignment.)
+ *
+ * @since 8.0
+ */
+ public static final byte DC3 = 19; // aka XOFF
+
+ /**
+ * Transmission off. See {@link #XON} for explanation.
+ *
+ * @since 8.0
+ */
+ public static final byte XOFF = 19; // aka DC3
+
+ /**
+ * Device Control 4. Characters for the control
+ * of ancillary devices associated with data processing or
+ * telecommunication systems, more especially switching devices "on" or
+ * "off." (If a single "stop" control is required to interrupt or turn
+ * off ancillary devices, DC4 is the preferred assignment.)
+ *
+ * @since 8.0
+ */
+ public static final byte DC4 = 20;
+
+ /**
+ * Negative Acknowledge: A communication control character
+ * transmitted by a receiver as a negative response to the sender.
+ *
+ * @since 8.0
+ */
+ public static final byte NAK = 21;
+
+ /**
+ * Synchronous Idle: A communication control character used by
+ * a synchronous transmission system in the absence of any other
+ * character to provide a signal from which synchronism may be achieved
+ * or retained.
+ *
+ * @since 8.0
+ */
+ public static final byte SYN = 22;
+
+ /**
+ * End of Transmission Block: A communication control character
+ * used to indicate the end of a block of data for communication
+ * purposes. ETB is used for blocking data where the block structure is
+ * not necessarily related to the processing format.
+ *
+ * @since 8.0
+ */
+ public static final byte ETB = 23;
+
+ /**
+ * Cancel: A control character used to indicate that the data
+ * with which it is sent is in error or is to be disregarded.
+ *
+ * @since 8.0
+ */
+ public static final byte CAN = 24;
+
+ /**
+ * End of Medium: A control character associated with the sent
+ * data which may be used to identify the physical end of the medium, or
+ * the end of the used, or wanted, portion of information recorded on a
+ * medium. (The position of this character does not necessarily
+ * correspond to the physical end of the medium.)
+ *
+ * @since 8.0
+ */
+ public static final byte EM = 25;
+
+ /**
+ * Substitute: A character that may be substituted for a
+ * character which is determined to be invalid or in error.
+ *
+ * @since 8.0
+ */
+ public static final byte SUB = 26;
+
+ /**
+ * Escape: A control character intended to provide code
+ * extension (supplementary characters) in general information
+ * interchange. The Escape character itself is a prefix affecting the
+ * interpretation of a limited number of contiguously following
+ * characters.
+ *
+ * @since 8.0
+ */
+ public static final byte ESC = 27;
+
+ /**
+ * File Separator: These four information separators may be
+ * used within data in optional fashion, except that their hierarchical
+ * relationship shall be: FS is the most inclusive, then GS, then RS,
+ * and US is least inclusive. (The content and length of a File, Group,
+ * Record, or Unit are not specified.)
+ *
+ * @since 8.0
+ */
+ public static final byte FS = 28;
+
+ /**
+ * Group Separator: These four information separators may be
+ * used within data in optional fashion, except that their hierarchical
+ * relationship shall be: FS is the most inclusive, then GS, then RS,
+ * and US is least inclusive. (The content and length of a File, Group,
+ * Record, or Unit are not specified.)
+ *
+ * @since 8.0
+ */
+ public static final byte GS = 29;
+
+ /**
+ * Record Separator: These four information separators may be
+ * used within data in optional fashion, except that their hierarchical
+ * relationship shall be: FS is the most inclusive, then GS, then RS,
+ * and US is least inclusive. (The content and length of a File, Group,
+ * Record, or Unit are not specified.)
+ *
+ * @since 8.0
+ */
+ public static final byte RS = 30;
+
+ /**
+ * Unit Separator: These four information separators may be
+ * used within data in optional fashion, except that their hierarchical
+ * relationship shall be: FS is the most inclusive, then GS, then RS,
+ * and US is least inclusive. (The content and length of a File, Group,
+ * Record, or Unit are not specified.)
+ *
+ * @since 8.0
+ */
+ public static final byte US = 31;
+
+ /**
+ * Space: A normally non-printing graphic character used to
+ * separate words. It is also a format effector which controls the
+ * movement of the printing position, one printing position forward.
+ * (Applicable also to display devices.)
+ *
+ * @since 8.0
+ */
+ public static final byte SP = 32;
+
+ /**
+ * Alternate name for {@link #SP}.
+ *
+ * @since 8.0
+ */
+ public static final byte SPACE = 32;
+
+ /**
+ * Delete: This character is used primarily to "erase" or
+ * "obliterate" erroneous or unwanted characters in perforated tape.
+ *
+ * @since 8.0
+ */
+ public static final byte DEL = 127;
+
+ /**
+ * The minimum value of an ASCII character.
+ *
+ * @since 9.0 (was type {@code int} before 12.0)
+ */
+ public static final char MIN = 0;
+
+ /**
+ * The maximum value of an ASCII character.
+ *
+ * @since 9.0 (was type {@code int} before 12.0)
+ */
+ public static final char MAX = 127;
+
+ /**
+ * Returns a copy of the input string in which all {@linkplain #isUpperCase(char) uppercase ASCII
+ * characters} have been converted to lowercase. All other characters are copied without
+ * modification.
+ */
+ public static String toLowerCase(String string) {
+ int length = string.length();
+ StringBuilder builder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ builder.append(toLowerCase(string.charAt(i)));
+ }
+ return builder.toString();
+ }
+
+ /**
+ * If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character} returns the
+ * lowercase equivalent. Otherwise returns the argument.
+ */
+ public static char toLowerCase(char c) {
+ return isUpperCase(c) ? (char) (c ^ 0x20) : c;
+ }
+
+ /**
+ * Returns a copy of the input string in which all {@linkplain #isLowerCase(char) lowercase ASCII
+ * characters} have been converted to uppercase. All other characters are copied without
+ * modification.
+ */
+ public static String toUpperCase(String string) {
+ int length = string.length();
+ StringBuilder builder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ builder.append(toUpperCase(string.charAt(i)));
+ }
+ return builder.toString();
+ }
+
+ /**
+ * If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character} returns the
+ * uppercase equivalent. Otherwise returns the argument.
+ */
+ public static char toUpperCase(char c) {
+ return isLowerCase(c) ? (char) (c & 0x5f) : c;
+ }
+
+ /**
+ * Indicates whether {@code c} is one of the twenty-six lowercase ASCII alphabetic characters
+ * between {@code 'a'} and {@code 'z'} inclusive. All others (including non-ASCII characters)
+ * return {@code false}.
+ */
+ public static boolean isLowerCase(char c) {
+ return (c >= 'a') && (c <= 'z');
+ }
+
+ /**
+ * Indicates whether {@code c} is one of the twenty-six uppercase ASCII alphabetic characters
+ * between {@code 'A'} and {@code 'Z'} inclusive. All others (including non-ASCII characters)
+ * return {@code false}.
+ */
+ public static boolean isUpperCase(char c) {
+ return (c >= 'A') && (c <= 'Z');
+ }
+}
diff --git a/guava/src/com/google/common/base/CaseFormat.java b/guava/src/com/google/common/base/CaseFormat.java
new file mode 100644
index 0000000..8ef7c5c
--- /dev/null
+++ b/guava/src/com/google/common/base/CaseFormat.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2006 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * Utility class for converting between various ASCII case formats.
+ *
+ * @author Mike Bostock
+ * @since 1.0
+ */
+@GwtCompatible
+public enum CaseFormat {
+ /**
+ * Hyphenated variable naming convention, e.g., "lower-hyphen".
+ */
+ LOWER_HYPHEN(CharMatcher.is('-'), "-"),
+
+ /**
+ * C++ variable naming convention, e.g., "lower_underscore".
+ */
+ LOWER_UNDERSCORE(CharMatcher.is('_'), "_"),
+
+ /**
+ * Java variable naming convention, e.g., "lowerCamel".
+ */
+ LOWER_CAMEL(CharMatcher.inRange('A', 'Z'), ""),
+
+ /**
+ * Java and C++ class naming convention, e.g., "UpperCamel".
+ */
+ UPPER_CAMEL(CharMatcher.inRange('A', 'Z'), ""),
+
+ /**
+ * Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE".
+ */
+ UPPER_UNDERSCORE(CharMatcher.is('_'), "_");
+
+ private final CharMatcher wordBoundary;
+ private final String wordSeparator;
+
+ CaseFormat(CharMatcher wordBoundary, String wordSeparator) {
+ this.wordBoundary = wordBoundary;
+ this.wordSeparator = wordSeparator;
+ }
+
+ /**
+ * Converts the specified {@code String s} from this format to the specified {@code format}. A
+ * "best effort" approach is taken; if {@code s} does not conform to the assumed format, then the
+ * behavior of this method is undefined but we make a reasonable effort at converting anyway.
+ */
+ public String to(CaseFormat format, String s) {
+ if (format == null) {
+ throw new NullPointerException();
+ }
+ if (s == null) {
+ throw new NullPointerException();
+ }
+
+ if (format == this) {
+ return s;
+ }
+
+ /* optimize cases where no camel conversion is required */
+ switch (this) {
+ case LOWER_HYPHEN:
+ switch (format) {
+ case LOWER_UNDERSCORE:
+ return s.replace('-', '_');
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(s.replace('-', '_'));
+ }
+ break;
+ case LOWER_UNDERSCORE:
+ switch (format) {
+ case LOWER_HYPHEN:
+ return s.replace('_', '-');
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(s);
+ }
+ break;
+ case UPPER_UNDERSCORE:
+ switch (format) {
+ case LOWER_HYPHEN:
+ return Ascii.toLowerCase(s.replace('_', '-'));
+ case LOWER_UNDERSCORE:
+ return Ascii.toLowerCase(s);
+ }
+ break;
+ }
+
+ // otherwise, deal with camel conversion
+ StringBuilder out = null;
+ int i = 0;
+ int j = -1;
+ while ((j = wordBoundary.indexIn(s, ++j)) != -1) {
+ if (i == 0) {
+ // include some extra space for separators
+ out = new StringBuilder(s.length() + 4 * wordSeparator.length());
+ out.append(format.normalizeFirstWord(s.substring(i, j)));
+ } else {
+ out.append(format.normalizeWord(s.substring(i, j)));
+ }
+ out.append(format.wordSeparator);
+ i = j + wordSeparator.length();
+ }
+ if (i == 0) {
+ return format.normalizeFirstWord(s);
+ }
+ out.append(format.normalizeWord(s.substring(i)));
+ return out.toString();
+ }
+
+ private String normalizeFirstWord(String word) {
+ switch (this) {
+ case LOWER_CAMEL:
+ return Ascii.toLowerCase(word);
+ default:
+ return normalizeWord(word);
+ }
+ }
+
+ private String normalizeWord(String word) {
+ switch (this) {
+ case LOWER_HYPHEN:
+ return Ascii.toLowerCase(word);
+ case LOWER_UNDERSCORE:
+ return Ascii.toLowerCase(word);
+ case LOWER_CAMEL:
+ return firstCharOnlyToUpper(word);
+ case UPPER_CAMEL:
+ return firstCharOnlyToUpper(word);
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(word);
+ }
+ throw new RuntimeException("unknown case: " + this);
+ }
+
+ private static String firstCharOnlyToUpper(String word) {
+ int length = word.length();
+ if (length == 0) {
+ return word;
+ }
+ return new StringBuilder(length)
+ .append(Ascii.toUpperCase(word.charAt(0)))
+ .append(Ascii.toLowerCase(word.substring(1)))
+ .toString();
+ }
+}
diff --git a/guava/src/com/google/common/base/CharMatcher.java b/guava/src/com/google/common/base/CharMatcher.java
new file mode 100644
index 0000000..64a70b7
--- /dev/null
+++ b/guava/src/com/google/common/base/CharMatcher.java
@@ -0,0 +1,1271 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Arrays;
+import javax.annotation.CheckReturnValue;
+
+/**
+ * Determines a true or false value for any Java {@code char} value, just as {@link Predicate} does
+ * for any {@link Object}. Also offers basic text processing methods based on this function.
+ * Implementations are strongly encouraged to be side-effect-free and immutable.
+ *
+ * <p>Throughout the documentation of this class, the phrase "matching character" is used to mean
+ * "any character {@code c} for which {@code this.matches(c)} returns {@code true}".
+ *
+ * <p><b>Note:</b> This class deals only with {@code char} values; it does not understand
+ * supplementary Unicode code points in the range {@code 0x10000} to {@code 0x10FFFF}. Such logical
+ * characters are encoded into a {@code String} using surrogate pairs, and a {@code CharMatcher}
+ * treats these just as two separate characters.
+ *
+ * <p>Example usages: <pre>
+ * String trimmed = {@link #WHITESPACE WHITESPACE}.{@link #trimFrom trimFrom}(userInput);
+ * if ({@link #ASCII ASCII}.{@link #matchesAllOf matchesAllOf}(s)) { ... }</pre>
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#CharMatcher">
+ * {@code CharMatcher}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 1.0
+ */
+@Beta // Possibly change from chars to code points; decide constants vs. methods
+@GwtCompatible
+public abstract class CharMatcher implements Predicate<Character> {
+ // Constants
+ /**
+ * Determines whether a character is a breaking whitespace (that is, a whitespace which can be
+ * interpreted as a break between words for formatting purposes). See {@link #WHITESPACE} for a
+ * discussion of that term.
+ *
+ * @since 2.0
+ */
+ public static final CharMatcher BREAKING_WHITESPACE =
+ anyOf("\t\n\013\f\r \u0085\u1680\u2028\u2029\u205f\u3000")
+ .or(inRange('\u2000', '\u2006'))
+ .or(inRange('\u2008', '\u200a'))
+ .withToString("CharMatcher.BREAKING_WHITESPACE")
+ .precomputed();
+
+ /**
+ * Determines whether a character is ASCII, meaning that its code point is less than 128.
+ */
+ public static final CharMatcher ASCII = inRange('\0', '\u007f', "CharMatcher.ASCII");
+
+ /**
+ * Determines whether a character is a digit according to
+ * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D">Unicode</a>.
+ */
+ public static final CharMatcher DIGIT;
+
+ static {
+ CharMatcher digit = inRange('0', '9');
+ String zeroes =
+ "\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6\u0c66"
+ + "\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946"
+ + "\u19d0\u1b50\u1bb0\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
+ for (char base : zeroes.toCharArray()) {
+ digit = digit.or(inRange(base, (char) (base + 9)));
+ }
+ DIGIT = digit.withToString("CharMatcher.DIGIT").precomputed();
+ }
+
+ /**
+ * Determines whether a character is a digit according to {@link Character#isDigit(char) Java's
+ * definition}. If you only care to match ASCII digits, you can use {@code inRange('0', '9')}.
+ */
+ public static final CharMatcher JAVA_DIGIT = new CharMatcher("CharMatcher.JAVA_DIGIT") {
+ @Override public boolean matches(char c) {
+ return Character.isDigit(c);
+ }
+ };
+
+ /**
+ * Determines whether a character is a letter according to {@link Character#isLetter(char) Java's
+ * definition}. If you only care to match letters of the Latin alphabet, you can use {@code
+ * inRange('a', 'z').or(inRange('A', 'Z'))}.
+ */
+ public static final CharMatcher JAVA_LETTER = new CharMatcher("CharMatcher.JAVA_LETTER") {
+ @Override public boolean matches(char c) {
+ return Character.isLetter(c);
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+
+ /**
+ * Determines whether a character is a letter or digit according to {@link
+ * Character#isLetterOrDigit(char) Java's definition}.
+ */
+ public static final CharMatcher JAVA_LETTER_OR_DIGIT =
+ new CharMatcher("CharMatcher.JAVA_LETTER_OR_DIGIT") {
+ @Override public boolean matches(char c) {
+ return Character.isLetterOrDigit(c);
+ }
+ };
+
+ /**
+ * Determines whether a character is upper case according to {@link Character#isUpperCase(char)
+ * Java's definition}.
+ */
+ public static final CharMatcher JAVA_UPPER_CASE =
+ new CharMatcher("CharMatcher.JAVA_UPPER_CASE") {
+ @Override public boolean matches(char c) {
+ return Character.isUpperCase(c);
+ }
+ };
+
+ /**
+ * Determines whether a character is lower case according to {@link Character#isLowerCase(char)
+ * Java's definition}.
+ */
+ public static final CharMatcher JAVA_LOWER_CASE =
+ new CharMatcher("CharMatcher.JAVA_LOWER_CASE") {
+ @Override public boolean matches(char c) {
+ return Character.isLowerCase(c);
+ }
+ };
+
+ /**
+ * Determines whether a character is an ISO control character as specified by {@link
+ * Character#isISOControl(char)}.
+ */
+ public static final CharMatcher JAVA_ISO_CONTROL =
+ inRange('\u0000', '\u001f')
+ .or(inRange('\u007f', '\u009f'))
+ .withToString("CharMatcher.JAVA_ISO_CONTROL");
+
+ /**
+ * Determines whether a character is invisible; that is, if its Unicode category is any of
+ * SPACE_SEPARATOR, LINE_SEPARATOR, PARAGRAPH_SEPARATOR, CONTROL, FORMAT, SURROGATE, and
+ * PRIVATE_USE according to ICU4J.
+ */
+ public static final CharMatcher INVISIBLE = inRange('\u0000', '\u0020')
+ .or(inRange('\u007f', '\u00a0'))
+ .or(is('\u00ad'))
+ .or(inRange('\u0600', '\u0604'))
+ .or(anyOf("\u06dd\u070f\u1680\u180e"))
+ .or(inRange('\u2000', '\u200f'))
+ .or(inRange('\u2028', '\u202f'))
+ .or(inRange('\u205f', '\u2064'))
+ .or(inRange('\u206a', '\u206f'))
+ .or(is('\u3000'))
+ .or(inRange('\ud800', '\uf8ff'))
+ .or(anyOf("\ufeff\ufff9\ufffa\ufffb"))
+ .withToString("CharMatcher.INVISIBLE")
+ .precomputed();
+
+ /**
+ * Determines whether a character is single-width (not double-width). When in doubt, this matcher
+ * errs on the side of returning {@code false} (that is, it tends to assume a character is
+ * double-width).
+ *
+ * <p><b>Note:</b> as the reference file evolves, we will modify this constant to keep it up to
+ * date.
+ */
+ public static final CharMatcher SINGLE_WIDTH = inRange('\u0000', '\u04f9')
+ .or(is('\u05be'))
+ .or(inRange('\u05d0', '\u05ea'))
+ .or(is('\u05f3'))
+ .or(is('\u05f4'))
+ .or(inRange('\u0600', '\u06ff'))
+ .or(inRange('\u0750', '\u077f'))
+ .or(inRange('\u0e00', '\u0e7f'))
+ .or(inRange('\u1e00', '\u20af'))
+ .or(inRange('\u2100', '\u213a'))
+ .or(inRange('\ufb50', '\ufdff'))
+ .or(inRange('\ufe70', '\ufeff'))
+ .or(inRange('\uff61', '\uffdc'))
+ .withToString("CharMatcher.SINGLE_WIDTH")
+ .precomputed();
+
+ /** Matches any character. */
+ public static final CharMatcher ANY =
+ new CharMatcher("CharMatcher.ANY") {
+ @Override public boolean matches(char c) {
+ return true;
+ }
+
+ @Override public int indexIn(CharSequence sequence) {
+ return (sequence.length() == 0) ? -1 : 0;
+ }
+
+ @Override public int indexIn(CharSequence sequence, int start) {
+ int length = sequence.length();
+ Preconditions.checkPositionIndex(start, length);
+ return (start == length) ? -1 : start;
+ }
+
+ @Override public int lastIndexIn(CharSequence sequence) {
+ return sequence.length() - 1;
+ }
+
+ @Override public boolean matchesAllOf(CharSequence sequence) {
+ checkNotNull(sequence);
+ return true;
+ }
+
+ @Override public boolean matchesNoneOf(CharSequence sequence) {
+ return sequence.length() == 0;
+ }
+
+ @Override public String removeFrom(CharSequence sequence) {
+ checkNotNull(sequence);
+ return "";
+ }
+
+ @Override public String replaceFrom(CharSequence sequence, char replacement) {
+ char[] array = new char[sequence.length()];
+ Arrays.fill(array, replacement);
+ return new String(array);
+ }
+
+ @Override public String replaceFrom(CharSequence sequence, CharSequence replacement) {
+ StringBuilder retval = new StringBuilder(sequence.length() * replacement.length());
+ for (int i = 0; i < sequence.length(); i++) {
+ retval.append(replacement);
+ }
+ return retval.toString();
+ }
+
+ @Override public String collapseFrom(CharSequence sequence, char replacement) {
+ return (sequence.length() == 0) ? "" : String.valueOf(replacement);
+ }
+
+ @Override public String trimFrom(CharSequence sequence) {
+ checkNotNull(sequence);
+ return "";
+ }
+
+ @Override public int countIn(CharSequence sequence) {
+ return sequence.length();
+ }
+
+ @Override public CharMatcher and(CharMatcher other) {
+ return checkNotNull(other);
+ }
+
+ @Override public CharMatcher or(CharMatcher other) {
+ checkNotNull(other);
+ return this;
+ }
+
+ @Override public CharMatcher negate() {
+ return NONE;
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+
+ /** Matches no characters. */
+ public static final CharMatcher NONE =
+ new CharMatcher("CharMatcher.NONE") {
+ @Override public boolean matches(char c) {
+ return false;
+ }
+
+ @Override public int indexIn(CharSequence sequence) {
+ checkNotNull(sequence);
+ return -1;
+ }
+
+ @Override public int indexIn(CharSequence sequence, int start) {
+ int length = sequence.length();
+ Preconditions.checkPositionIndex(start, length);
+ return -1;
+ }
+
+ @Override public int lastIndexIn(CharSequence sequence) {
+ checkNotNull(sequence);
+ return -1;
+ }
+
+ @Override public boolean matchesAllOf(CharSequence sequence) {
+ return sequence.length() == 0;
+ }
+
+ @Override public boolean matchesNoneOf(CharSequence sequence) {
+ checkNotNull(sequence);
+ return true;
+ }
+
+ @Override public String removeFrom(CharSequence sequence) {
+ return sequence.toString();
+ }
+
+ @Override public String replaceFrom(CharSequence sequence, char replacement) {
+ return sequence.toString();
+ }
+
+ @Override public String replaceFrom(CharSequence sequence, CharSequence replacement) {
+ checkNotNull(replacement);
+ return sequence.toString();
+ }
+
+ @Override public String collapseFrom(CharSequence sequence, char replacement) {
+ return sequence.toString();
+ }
+
+ @Override public String trimFrom(CharSequence sequence) {
+ return sequence.toString();
+ }
+
+ @Override public int countIn(CharSequence sequence) {
+ checkNotNull(sequence);
+ return 0;
+ }
+
+ @Override public CharMatcher and(CharMatcher other) {
+ checkNotNull(other);
+ return this;
+ }
+
+ @Override public CharMatcher or(CharMatcher other) {
+ return checkNotNull(other);
+ }
+
+ @Override public CharMatcher negate() {
+ return ANY;
+ }
+
+ @Override void setBits(LookupTable table) {}
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+
+ // Static factories
+
+ /**
+ * Returns a {@code char} matcher that matches only one specified character.
+ */
+ public static CharMatcher is(final char match) {
+ String description = new StringBuilder("CharMatcher.is(")
+ .append(Integer.toHexString(match))
+ .append(")")
+ .toString();
+ return new CharMatcher(description) {
+ @Override public boolean matches(char c) {
+ return c == match;
+ }
+
+ @Override public String replaceFrom(CharSequence sequence, char replacement) {
+ return sequence.toString().replace(match, replacement);
+ }
+
+ @Override public CharMatcher and(CharMatcher other) {
+ return other.matches(match) ? this : NONE;
+ }
+
+ @Override public CharMatcher or(CharMatcher other) {
+ return other.matches(match) ? other : super.or(other);
+ }
+
+ @Override public CharMatcher negate() {
+ return isNot(match);
+ }
+
+ @Override void setBits(LookupTable table) {
+ table.set(match);
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+ }
+
+ /**
+ * Returns a {@code char} matcher that matches any character except the one specified.
+ *
+ * <p>To negate another {@code CharMatcher}, use {@link #negate()}.
+ */
+ public static CharMatcher isNot(final char match) {
+ String description = new StringBuilder("CharMatcher.isNot(")
+ .append(Integer.toHexString(match))
+ .append(")")
+ .toString();
+ return new CharMatcher(description) {
+ @Override public boolean matches(char c) {
+ return c != match;
+ }
+
+ @Override public CharMatcher and(CharMatcher other) {
+ return other.matches(match) ? super.and(other) : other;
+ }
+
+ @Override public CharMatcher or(CharMatcher other) {
+ return other.matches(match) ? ANY : this;
+ }
+
+ @Override public CharMatcher negate() {
+ return is(match);
+ }
+ };
+ }
+
+ /**
+ * Returns a {@code char} matcher that matches any character present in the given character
+ * sequence.
+ */
+ public static CharMatcher anyOf(final CharSequence sequence) {
+ switch (sequence.length()) {
+ case 0:
+ return NONE;
+ case 1:
+ return is(sequence.charAt(0));
+ case 2:
+ final char match1 = sequence.charAt(0);
+ final char match2 = sequence.charAt(1);
+ return new CharMatcher(
+ new StringBuilder("CharMatcher.anyOf(\"").append(sequence).append("\")").toString()) {
+ @Override public boolean matches(char c) {
+ return c == match1 || c == match2;
+ }
+
+ @Override void setBits(LookupTable table) {
+ table.set(match1);
+ table.set(match2);
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+ }
+ final char[] chars = sequence.toString().toCharArray();
+ Arrays.sort(chars);
+
+ return new CharMatcher(new StringBuilder("CharMatcher.anyOf(\"").append(chars)
+ .append("\")").toString()) {
+ @Override public boolean matches(char c) {
+ return Arrays.binarySearch(chars, c) >= 0;
+ }
+ };
+ }
+
+ /**
+ * Returns a {@code char} matcher that matches any character not present in the given character
+ * sequence.
+ */
+ public static CharMatcher noneOf(CharSequence sequence) {
+ return anyOf(sequence).negate();
+ }
+
+ /**
+ * Returns a {@code char} matcher that matches any character in a given range (both endpoints are
+ * inclusive). For example, to match any lowercase letter of the English alphabet, use {@code
+ * CharMatcher.inRange('a', 'z')}.
+ *
+ * @throws IllegalArgumentException if {@code endInclusive < startInclusive}
+ */
+ public static CharMatcher inRange(final char startInclusive, final char endInclusive) {
+ checkArgument(endInclusive >= startInclusive);
+ String description = new StringBuilder("CharMatcher.inRange(")
+ .append(Integer.toHexString(startInclusive))
+ .append(", ")
+ .append(Integer.toHexString(endInclusive))
+ .append(")")
+ .toString();
+ return inRange(startInclusive, endInclusive, description);
+ }
+
+ static CharMatcher inRange(final char startInclusive, final char endInclusive,
+ String description) {
+ return new CharMatcher(description) {
+ @Override public boolean matches(char c) {
+ return startInclusive <= c && c <= endInclusive;
+ }
+
+ @Override void setBits(LookupTable table) {
+ char c = startInclusive;
+ while (true) {
+ table.set(c);
+ if (c++ == endInclusive) {
+ break;
+ }
+ }
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+ }
+
+ /**
+ * Returns a matcher with identical behavior to the given {@link Character}-based predicate, but
+ * which operates on primitive {@code char} instances instead.
+ */
+ public static CharMatcher forPredicate(final Predicate<? super Character> predicate) {
+ checkNotNull(predicate);
+ if (predicate instanceof CharMatcher) {
+ return (CharMatcher) predicate;
+ }
+ String description = new StringBuilder("CharMatcher.forPredicate(")
+ .append(predicate)
+ .append(')')
+ .toString();
+ return new CharMatcher(description) {
+ @Override public boolean matches(char c) {
+ return predicate.apply(c);
+ }
+
+ @Override public boolean apply(Character character) {
+ return predicate.apply(checkNotNull(character));
+ }
+ };
+ }
+
+ // State
+ final String description;
+
+ // Constructors
+
+ /**
+ * Sets the {@code toString()} from the given description.
+ */
+ CharMatcher(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Constructor for use by subclasses. When subclassing, you may want to override
+ * {@code toString()} to provide a useful description.
+ */
+ protected CharMatcher() {
+ description = "UnknownCharMatcher";
+ }
+
+ // Abstract methods
+
+ /** Determines a true or false value for the given character. */
+ public abstract boolean matches(char c);
+
+ // Non-static factories
+
+ /**
+ * Returns a matcher that matches any character not matched by this matcher.
+ */
+ public CharMatcher negate() {
+ final CharMatcher original = this;
+ return new CharMatcher(original + ".negate()") {
+ @Override public boolean matches(char c) {
+ return !original.matches(c);
+ }
+
+ @Override public boolean matchesAllOf(CharSequence sequence) {
+ return original.matchesNoneOf(sequence);
+ }
+
+ @Override public boolean matchesNoneOf(CharSequence sequence) {
+ return original.matchesAllOf(sequence);
+ }
+
+ @Override public int countIn(CharSequence sequence) {
+ return sequence.length() - original.countIn(sequence);
+ }
+
+ @Override public CharMatcher negate() {
+ return original;
+ }
+ };
+ }
+
+ /**
+ * Returns a matcher that matches any character matched by both this matcher and {@code other}.
+ */
+ public CharMatcher and(CharMatcher other) {
+ return new And(this, checkNotNull(other));
+ }
+
+ private static class And extends CharMatcher {
+ final CharMatcher first;
+ final CharMatcher second;
+
+ And(CharMatcher a, CharMatcher b) {
+ this(a, b, "CharMatcher.and(" + a + ", " + b + ")");
+ }
+
+ And(CharMatcher a, CharMatcher b, String description) {
+ super(description);
+ first = checkNotNull(a);
+ second = checkNotNull(b);
+ }
+
+ @Override
+ public CharMatcher and(CharMatcher other) {
+ return new And(this, other);
+ }
+
+ @Override
+ public boolean matches(char c) {
+ return first.matches(c) && second.matches(c);
+ }
+
+ @Override
+ CharMatcher withToString(String description) {
+ return new And(first, second, description);
+ }
+ }
+
+ /**
+ * Returns a matcher that matches any character matched by either this matcher or {@code other}.
+ */
+ public CharMatcher or(CharMatcher other) {
+ return new Or(this, checkNotNull(other));
+ }
+
+ private static class Or extends CharMatcher {
+ final CharMatcher first;
+ final CharMatcher second;
+
+ Or(CharMatcher a, CharMatcher b, String description) {
+ super(description);
+ first = checkNotNull(a);
+ second = checkNotNull(b);
+ }
+
+ Or(CharMatcher a, CharMatcher b) {
+ this(a, b, "CharMatcher.or(" + a + ", " + b + ")");
+ }
+
+ @Override
+ public CharMatcher or(CharMatcher other) {
+ return new Or(this, checkNotNull(other));
+ }
+
+ @Override
+ public boolean matches(char c) {
+ return first.matches(c) || second.matches(c);
+ }
+
+ @Override
+ CharMatcher withToString(String description) {
+ return new Or(first, second, description);
+ }
+ }
+
+ /**
+ * Returns a {@code char} matcher functionally equivalent to this one, but which may be faster to
+ * query than the original; your mileage may vary. Precomputation takes time and is likely to be
+ * worthwhile only if the precomputed matcher is queried many thousands of times.
+ *
+ * <p>This method has no effect (returns {@code this}) when called in GWT: it's unclear whether a
+ * precomputed matcher is faster, but it certainly consumes more memory, which doesn't seem like a
+ * worthwhile tradeoff in a browser.
+ */
+ public CharMatcher precomputed() {
+ return Platform.precomputeCharMatcher(this);
+ }
+
+ /**
+ * Construct an array of all possible chars in the slowest way possible.
+ */
+ char[] slowGetChars() {
+ char[] allChars = new char[65536];
+ int size = 0;
+ for (int c = Character.MIN_VALUE; c <= Character.MAX_VALUE; c++) {
+ if (matches((char) c)) {
+ allChars[size++] = (char) c;
+ }
+ }
+ char[] retValue = new char[size];
+ System.arraycopy(allChars, 0, retValue, 0, size);
+ return retValue;
+ }
+
+ /**
+ * This is the actual implementation of {@link #precomputed}, but we bounce calls through a method
+ * on {@link Platform} so that we can have different behavior in GWT.
+ *
+ * <p>If the number of matched characters is small enough, we try to build a small hash
+ * table to contain all of the characters. Otherwise, we record the characters in eight-kilobyte
+ * bit array. In many situations this produces a matcher which is faster to query
+ * than the original.
+ */
+ CharMatcher precomputedInternal() {
+ final char[] chars = slowGetChars();
+ int totalCharacters = chars.length;
+ if (totalCharacters == 0) {
+ return NONE;
+ } else if (totalCharacters == 1) {
+ return is(chars[0]);
+ } else if (totalCharacters < SmallCharMatcher.MAX_SIZE) {
+ return SmallCharMatcher.from(chars, toString());
+ } else if (totalCharacters < MediumCharMatcher.MAX_SIZE) {
+ return MediumCharMatcher.from(chars, toString());
+ }
+ // Otherwise, make the full lookup table.
+ final LookupTable table = new LookupTable();
+ setBits(table);
+ final CharMatcher outer = this;
+
+ return new CharMatcher(outer.toString()) {
+ @Override public boolean matches(char c) {
+ return table.get(c);
+ }
+
+ // TODO(kevinb): make methods like negate() smart?
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+ }
+
+ /**
+ * Subclasses should provide a new CharMatcher with the same characteristics as {@code this},
+ * but with their {@code toString} method overridden with the new description.
+ *
+ * <p>This is unsupported by default.
+ */
+ CharMatcher withToString(String description) {
+ throw new UnsupportedOperationException();
+
+ }
+
+ /**
+ * For use by implementors; sets the bit corresponding to each character ('\0' to '{@literal
+ * \}uFFFF') that matches this matcher in the given bit array, leaving all other bits untouched.
+ *
+ * <p>The default implementation loops over every possible character value, invoking {@link
+ * #matches} for each one.
+ */
+ void setBits(LookupTable table) {
+ char c = Character.MIN_VALUE;
+ while (true) {
+ if (matches(c)) {
+ table.set(c);
+ }
+ if (c++ == Character.MAX_VALUE) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * A bit array with one bit per {@code char} value, used by {@link CharMatcher#precomputed}.
+ *
+ * <p>TODO(kevinb): possibly share a common BitArray class with BloomFilter and others... a
+ * simpler java.util.BitSet.
+ */
+ private static final class LookupTable {
+ int[] data = new int[2048];
+
+ void set(char index) {
+ data[index >> 5] |= (1 << index);
+ }
+
+ boolean get(char index) {
+ return (data[index >> 5] & (1 << index)) != 0;
+ }
+ }
+
+ // Text processing routines
+
+ /**
+ * Returns {@code true} if a character sequence contains at least one matching character.
+ * Equivalent to {@code !matchesNoneOf(sequence)}.
+ *
+ * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
+ * character, until this returns {@code true} or the end is reached.
+ *
+ * @param sequence the character sequence to examine, possibly empty
+ * @return {@code true} if this matcher matches at least one character in the sequence
+ * @since 8.0
+ */
+ public boolean matchesAnyOf(CharSequence sequence) {
+ return !matchesNoneOf(sequence);
+ }
+
+ /**
+ * Returns {@code true} if a character sequence contains only matching characters.
+ *
+ * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
+ * character, until this returns {@code false} or the end is reached.
+ *
+ * @param sequence the character sequence to examine, possibly empty
+ * @return {@code true} if this matcher matches every character in the sequence, including when
+ * the sequence is empty
+ */
+ public boolean matchesAllOf(CharSequence sequence) {
+ for (int i = sequence.length() - 1; i >= 0; i--) {
+ if (!matches(sequence.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if a character sequence contains no matching characters. Equivalent to
+ * {@code !matchesAnyOf(sequence)}.
+ *
+ * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
+ * character, until this returns {@code false} or the end is reached.
+ *
+ * @param sequence the character sequence to examine, possibly empty
+ * @return {@code true} if this matcher matches every character in the sequence, including when
+ * the sequence is empty
+ */
+ public boolean matchesNoneOf(CharSequence sequence) {
+ return indexIn(sequence) == -1;
+ }
+
+ /**
+ * Returns the index of the first matching character in a character sequence, or {@code -1} if no
+ * matching character is present.
+ *
+ * <p>The default implementation iterates over the sequence in forward order calling {@link
+ * #matches} for each character.
+ *
+ * @param sequence the character sequence to examine from the beginning
+ * @return an index, or {@code -1} if no character matches
+ */
+ public int indexIn(CharSequence sequence) {
+ int length = sequence.length();
+ for (int i = 0; i < length; i++) {
+ if (matches(sequence.charAt(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index of the first matching character in a character sequence, starting from a
+ * given position, or {@code -1} if no character matches after that position.
+ *
+ * <p>The default implementation iterates over the sequence in forward order, beginning at {@code
+ * start}, calling {@link #matches} for each character.
+ *
+ * @param sequence the character sequence to examine
+ * @param start the first index to examine; must be nonnegative and no greater than {@code
+ * sequence.length()}
+ * @return the index of the first matching character, guaranteed to be no less than {@code start},
+ * or {@code -1} if no character matches
+ * @throws IndexOutOfBoundsException if start is negative or greater than {@code
+ * sequence.length()}
+ */
+ public int indexIn(CharSequence sequence, int start) {
+ int length = sequence.length();
+ Preconditions.checkPositionIndex(start, length);
+ for (int i = start; i < length; i++) {
+ if (matches(sequence.charAt(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index of the last matching character in a character sequence, or {@code -1} if no
+ * matching character is present.
+ *
+ * <p>The default implementation iterates over the sequence in reverse order calling {@link
+ * #matches} for each character.
+ *
+ * @param sequence the character sequence to examine from the end
+ * @return an index, or {@code -1} if no character matches
+ */
+ public int lastIndexIn(CharSequence sequence) {
+ for (int i = sequence.length() - 1; i >= 0; i--) {
+ if (matches(sequence.charAt(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the number of matching characters found in a character sequence.
+ */
+ public int countIn(CharSequence sequence) {
+ int count = 0;
+ for (int i = 0; i < sequence.length(); i++) {
+ if (matches(sequence.charAt(i))) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Returns a string containing all non-matching characters of a character sequence, in order. For
+ * example: <pre> {@code
+ *
+ * CharMatcher.is('a').removeFrom("bazaar")}</pre>
+ *
+ * ... returns {@code "bzr"}.
+ */
+ @CheckReturnValue
+ public String removeFrom(CharSequence sequence) {
+ String string = sequence.toString();
+ int pos = indexIn(string);
+ if (pos == -1) {
+ return string;
+ }
+
+ char[] chars = string.toCharArray();
+ int spread = 1;
+
+ // This unusual loop comes from extensive benchmarking
+ OUT: while (true) {
+ pos++;
+ while (true) {
+ if (pos == chars.length) {
+ break OUT;
+ }
+ if (matches(chars[pos])) {
+ break;
+ }
+ chars[pos - spread] = chars[pos];
+ pos++;
+ }
+ spread++;
+ }
+ return new String(chars, 0, pos - spread);
+ }
+
+ /**
+ * Returns a string containing all matching characters of a character sequence, in order. For
+ * example: <pre> {@code
+ *
+ * CharMatcher.is('a').retainFrom("bazaar")}</pre>
+ *
+ * ... returns {@code "aaa"}.
+ */
+ @CheckReturnValue
+ public String retainFrom(CharSequence sequence) {
+ return negate().removeFrom(sequence);
+ }
+
+ /**
+ * Returns a string copy of the input character sequence, with each character that matches this
+ * matcher replaced by a given replacement character. For example: <pre> {@code
+ *
+ * CharMatcher.is('a').replaceFrom("radar", 'o')}</pre>
+ *
+ * ... returns {@code "rodor"}.
+ *
+ * <p>The default implementation uses {@link #indexIn(CharSequence)} to find the first matching
+ * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each
+ * character.
+ *
+ * @param sequence the character sequence to replace matching characters in
+ * @param replacement the character to append to the result string in place of each matching
+ * character in {@code sequence}
+ * @return the new string
+ */
+ @CheckReturnValue
+ public String replaceFrom(CharSequence sequence, char replacement) {
+ String string = sequence.toString();
+ int pos = indexIn(string);
+ if (pos == -1) {
+ return string;
+ }
+ char[] chars = string.toCharArray();
+ chars[pos] = replacement;
+ for (int i = pos + 1; i < chars.length; i++) {
+ if (matches(chars[i])) {
+ chars[i] = replacement;
+ }
+ }
+ return new String(chars);
+ }
+
+ /**
+ * Returns a string copy of the input character sequence, with each character that matches this
+ * matcher replaced by a given replacement sequence. For example: <pre> {@code
+ *
+ * CharMatcher.is('a').replaceFrom("yaha", "oo")}</pre>
+ *
+ * ... returns {@code "yoohoo"}.
+ *
+ * <p><b>Note:</b> If the replacement is a fixed string with only one character, you are better
+ * off calling {@link #replaceFrom(CharSequence, char)} directly.
+ *
+ * @param sequence the character sequence to replace matching characters in
+ * @param replacement the characters to append to the result string in place of each matching
+ * character in {@code sequence}
+ * @return the new string
+ */
+ @CheckReturnValue
+ public String replaceFrom(CharSequence sequence, CharSequence replacement) {
+ int replacementLen = replacement.length();
+ if (replacementLen == 0) {
+ return removeFrom(sequence);
+ }
+ if (replacementLen == 1) {
+ return replaceFrom(sequence, replacement.charAt(0));
+ }
+
+ String string = sequence.toString();
+ int pos = indexIn(string);
+ if (pos == -1) {
+ return string;
+ }
+
+ int len = string.length();
+ StringBuilder buf = new StringBuilder((len * 3 / 2) + 16);
+
+ int oldpos = 0;
+ do {
+ buf.append(string, oldpos, pos);
+ buf.append(replacement);
+ oldpos = pos + 1;
+ pos = indexIn(string, oldpos);
+ } while (pos != -1);
+
+ buf.append(string, oldpos, len);
+ return buf.toString();
+ }
+
+ /**
+ * Returns a substring of the input character sequence that omits all characters this matcher
+ * matches from the beginning and from the end of the string. For example: <pre> {@code
+ *
+ * CharMatcher.anyOf("ab").trimFrom("abacatbab")}</pre>
+ *
+ * ... returns {@code "cat"}.
+ *
+ * <p>Note that: <pre> {@code
+ *
+ * CharMatcher.inRange('\0', ' ').trimFrom(str)}</pre>
+ *
+ * ... is equivalent to {@link String#trim()}.
+ */
+ @CheckReturnValue
+ public String trimFrom(CharSequence sequence) {
+ int len = sequence.length();
+ int first;
+ int last;
+
+ for (first = 0; first < len; first++) {
+ if (!matches(sequence.charAt(first))) {
+ break;
+ }
+ }
+ for (last = len - 1; last > first; last--) {
+ if (!matches(sequence.charAt(last))) {
+ break;
+ }
+ }
+
+ return sequence.subSequence(first, last + 1).toString();
+ }
+
+ /**
+ * Returns a substring of the input character sequence that omits all characters this matcher
+ * matches from the beginning of the string. For example: <pre> {@code
+ *
+ * CharMatcher.anyOf("ab").trimLeadingFrom("abacatbab")}</pre>
+ *
+ * ... returns {@code "catbab"}.
+ */
+ @CheckReturnValue
+ public String trimLeadingFrom(CharSequence sequence) {
+ int len = sequence.length();
+ int first;
+
+ for (first = 0; first < len; first++) {
+ if (!matches(sequence.charAt(first))) {
+ break;
+ }
+ }
+
+ return sequence.subSequence(first, len).toString();
+ }
+
+ /**
+ * Returns a substring of the input character sequence that omits all characters this matcher
+ * matches from the end of the string. For example: <pre> {@code
+ *
+ * CharMatcher.anyOf("ab").trimTrailingFrom("abacatbab")}</pre>
+ *
+ * ... returns {@code "abacat"}.
+ */
+ @CheckReturnValue
+ public String trimTrailingFrom(CharSequence sequence) {
+ int len = sequence.length();
+ int last;
+
+ for (last = len - 1; last >= 0; last--) {
+ if (!matches(sequence.charAt(last))) {
+ break;
+ }
+ }
+
+ return sequence.subSequence(0, last + 1).toString();
+ }
+
+ /**
+ * Returns a string copy of the input character sequence, with each group of consecutive
+ * characters that match this matcher replaced by a single replacement character. For example:
+ * <pre> {@code
+ *
+ * CharMatcher.anyOf("eko").collapseFrom("bookkeeper", '-')}</pre>
+ *
+ * ... returns {@code "b-p-r"}.
+ *
+ * <p>The default implementation uses {@link #indexIn(CharSequence)} to find the first matching
+ * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each
+ * character.
+ *
+ * @param sequence the character sequence to replace matching groups of characters in
+ * @param replacement the character to append to the result string in place of each group of
+ * matching characters in {@code sequence}
+ * @return the new string
+ */
+ @CheckReturnValue
+ public String collapseFrom(CharSequence sequence, char replacement) {
+ int first = indexIn(sequence);
+ if (first == -1) {
+ return sequence.toString();
+ }
+
+ // TODO(kevinb): see if this implementation can be made faster
+ StringBuilder builder = new StringBuilder(sequence.length())
+ .append(sequence.subSequence(0, first))
+ .append(replacement);
+ boolean in = true;
+ for (int i = first + 1; i < sequence.length(); i++) {
+ char c = sequence.charAt(i);
+ if (matches(c)) {
+ if (!in) {
+ builder.append(replacement);
+ in = true;
+ }
+ } else {
+ builder.append(c);
+ in = false;
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Collapses groups of matching characters exactly as {@link #collapseFrom} does, except that
+ * groups of matching characters at the start or end of the sequence are removed without
+ * replacement.
+ */
+ @CheckReturnValue
+ public String trimAndCollapseFrom(CharSequence sequence, char replacement) {
+ int first = negate().indexIn(sequence);
+ if (first == -1) {
+ return ""; // everything matches. nothing's left.
+ }
+ StringBuilder builder = new StringBuilder(sequence.length());
+ boolean inMatchingGroup = false;
+ for (int i = first; i < sequence.length(); i++) {
+ char c = sequence.charAt(i);
+ if (matches(c)) {
+ inMatchingGroup = true;
+ } else {
+ if (inMatchingGroup) {
+ builder.append(replacement);
+ inMatchingGroup = false;
+ }
+ builder.append(c);
+ }
+ }
+ return builder.toString();
+ }
+
+ // Predicate interface
+
+ /**
+ * Returns {@code true} if this matcher matches the given character.
+ *
+ * @throws NullPointerException if {@code character} is null
+ */
+ @Override public boolean apply(Character character) {
+ return matches(character);
+ }
+
+ /**
+ * Returns a string representation of this {@code CharMatcher}, such as
+ * {@code CharMatcher.or(WHITESPACE, JAVA_DIGIT)}.
+ */
+ @Override
+ public String toString() {
+ return description;
+ }
+
+ /**
+ * Determines whether a character is whitespace according to the latest Unicode standard, as
+ * illustrated
+ * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bwhitespace%7D">here</a>.
+ * This is not the same definition used by other Java APIs. (See a
+ * <a href="http://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ">comparison of several
+ * definitions of "whitespace"</a>.)
+ *
+ * <p><b>Note:</b> as the Unicode definition evolves, we will modify this constant to keep it up
+ * to date.
+ */
+ public static final CharMatcher WHITESPACE = new CharMatcher("CharMatcher.WHITESPACE") {
+ /**
+ * A special-case CharMatcher for Unicode whitespace characters that is extremely
+ * efficient both in space required and in time to check for matches.
+ *
+ * Implementation details.
+ * It turns out that all current (early 2012) Unicode characters are unique modulo 79:
+ * so we can construct a lookup table of exactly 79 entries, and just check the character code
+ * mod 79, and see if that character is in the table.
+ *
+ * There is a 1 at the beginning of the table so that the null character is not listed
+ * as whitespace.
+ *
+ * Other things we tried that did not prove to be beneficial, mostly due to speed concerns:
+ *
+ * * Binary search into the sorted list of characters, i.e., what
+ * CharMatcher.anyOf() does</li>
+ * * Perfect hash function into a table of size 26 (using an offset table and a special
+ * Jenkins hash function)</li>
+ * * Perfect-ish hash function that required two lookups into a single table of size 26.</li>
+ * * Using a power-of-2 sized hash table (size 64) with linear probing.</li>
+ *
+ * --Christopher Swenson, February 2012.
+ */
+
+ // Mod-79 lookup table.
+ private final char[] table = {1, 0, 160, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 0,
+ 8232, 8233, 0, 0, 0, 0, 0, 8239, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199,
+ 8200, 8201, 8202, 0, 0, 0, 0, 0, 8287, 5760, 0, 0, 6158, 0, 0, 0};
+
+ @Override public boolean matches(char c) {
+ return table[c % 79] == c;
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
+}
diff --git a/guava/src/com/google/common/base/Charsets.java b/guava/src/com/google/common/base/Charsets.java
new file mode 100644
index 0000000..79c9128
--- /dev/null
+++ b/guava/src/com/google/common/base/Charsets.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.nio.charset.Charset;
+
+/**
+ * Contains constant definitions for the six standard {@link Charset} instances, which are
+ * guaranteed to be supported by all Java platform implementations.
+ *
+ * <p>Assuming you're free to choose, note that <b>{@link #UTF_8} is widely preferred</b>.
+ *
+ * <p>See the Guava User Guide article on <a
+ * href="http://code.google.com/p/guava-libraries/wiki/StringsExplained#Charsets">
+ * {@code Charsets}</a>.
+ *
+ * @author Mike Bostock
+ * @since 1.0
+ */
+@GwtCompatible(emulated = true)
+public final class Charsets {
+ private Charsets() {}
+
+ /**
+ * US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US).
+ */
+ @GwtIncompatible("Non-UTF-8 Charset")
+ public static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+ /**
+ * ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1).
+ */
+ @GwtIncompatible("Non-UTF-8 Charset")
+ public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+
+ /**
+ * UTF-8: eight-bit UCS Transformation Format.
+ */
+ public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ /**
+ * UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order.
+ */
+ @GwtIncompatible("Non-UTF-8 Charset")
+ public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+
+ /**
+ * UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order.
+ */
+ @GwtIncompatible("Non-UTF-8 Charset")
+ public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+
+ /**
+ * UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order
+ * mark.
+ */
+ @GwtIncompatible("Non-UTF-8 Charset")
+ public static final Charset UTF_16 = Charset.forName("UTF-16");
+
+ /*
+ * Please do not add new Charset references to this class, unless those character encodings are
+ * part of the set required to be supported by all Java platform implementations! Any Charsets
+ * initialized here may cause unexpected delays when this class is loaded. See the Charset
+ * Javadocs for the list of built-in character encodings.
+ */
+}
diff --git a/guava/src/com/google/common/base/Defaults.java b/guava/src/com/google/common/base/Defaults.java
new file mode 100644
index 0000000..b3e8555
--- /dev/null
+++ b/guava/src/com/google/common/base/Defaults.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class provides default values for all Java types, as defined by the JLS.
+ *
+ * @author Ben Yu
+ * @since 1.0
+ */
+public final class Defaults {
+ private Defaults() {}
+
+ private static final Map<Class<?>, Object> DEFAULTS;
+
+ static {
+ Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();
+ put(map, boolean.class, false);
+ put(map, char.class, '\0');
+ put(map, byte.class, (byte) 0);
+ put(map, short.class, (short) 0);
+ put(map, int.class, 0);
+ put(map, long.class, 0L);
+ put(map, float.class, 0f);
+ put(map, double.class, 0d);
+ DEFAULTS = Collections.unmodifiableMap(map);
+ }
+
+ private static <T> void put(Map<Class<?>, Object> map, Class<T> type, T value) {
+ map.put(type, value);
+ }
+
+ /**
+ * Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code
+ * false} for {@code boolean} and {@code '\0'} for {@code char}. For non-primitive types and
+ * {@code void}, null is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T defaultValue(Class<T> type) {
+ return (T) DEFAULTS.get(type);
+ }
+}
diff --git a/guava/src/com/google/common/base/Enums.java b/guava/src/com/google/common/base/Enums.java
new file mode 100644
index 0000000..6105410
--- /dev/null
+++ b/guava/src/com/google/common/base/Enums.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+
+import javax.annotation.Nullable;
+
+/**
+ * Utility methods for working with {@link Enum} instances.
+ *
+ * @author Steve McKay
+ *
+ * @since 9.0
+ */
+@GwtCompatible(emulated = true)
+@Beta
+public final class Enums {
+
+ private Enums() {}
+
+ /**
+ * Returns the {@link Field} in which {@code enumValue} is defined.
+ * For example, to get the {@code Description} annotation on the {@code GOLF}
+ * constant of enum {@code Sport}, use
+ * {@code Enums.getField(Sport.GOLF).getAnnotation(Description.class)}.
+ *
+ * @since 12.0
+ */
+ @GwtIncompatible("reflection")
+ public static Field getField(Enum<?> enumValue) {
+ Class<?> clazz = enumValue.getDeclaringClass();
+ try {
+ return clazz.getDeclaredField(enumValue.name());
+ } catch (NoSuchFieldException impossible) {
+ throw new AssertionError(impossible);
+ }
+ }
+
+ /**
+ * Returns a {@link Function} that maps an {@link Enum} name to the associated
+ * {@code Enum} constant. The {@code Function} will return {@code null} if the
+ * {@code Enum} constant does not exist.
+ *
+ * @param enumClass the {@link Class} of the {@code Enum} declaring the
+ * constant values.
+ */
+ public static <T extends Enum<T>> Function<String, T> valueOfFunction(Class<T> enumClass) {
+ return new ValueOfFunction<T>(enumClass);
+ }
+
+ /**
+ * A {@link Function} that maps an {@link Enum} name to the associated
+ * constant, or {@code null} if the constant does not exist.
+ */
+ private static final class ValueOfFunction<T extends Enum<T>>
+ implements Function<String, T>, Serializable {
+
+ private final Class<T> enumClass;
+
+ private ValueOfFunction(Class<T> enumClass) {
+ this.enumClass = checkNotNull(enumClass);
+ }
+
+ @Override
+ public T apply(String value) {
+ try {
+ return Enum.valueOf(enumClass, value);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ return obj instanceof ValueOfFunction &&
+ enumClass.equals(((ValueOfFunction) obj).enumClass);
+ }
+
+ @Override public int hashCode() {
+ return enumClass.hashCode();
+ }
+
+ @Override public String toString() {
+ return "Enums.valueOf(" + enumClass + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns an optional enum constant for the given type, using {@link Enum#valueOf}. If the
+ * constant does not exist, {@link Optional#absent} is returned. A common use case is for parsing
+ * user input or falling back to a default enum constant. For example,
+ * {@code Enums.getIfPresent(Country.class, countryInput).or(Country.DEFAULT);}
+ *
+ * @since 12.0
+ */
+ public static <T extends Enum<T>> Optional<T> getIfPresent(Class<T> enumClass, String value) {
+ checkNotNull(enumClass);
+ checkNotNull(value);
+ try {
+ return Optional.of(Enum.valueOf(enumClass, value));
+ } catch (IllegalArgumentException iae) {
+ return Optional.absent();
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Equivalence.java b/guava/src/com/google/common/base/Equivalence.java
new file mode 100644
index 0000000..d039283
--- /dev/null
+++ b/guava/src/com/google/common/base/Equivalence.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+
+import javax.annotation.Nullable;
+
+/**
+ * A strategy for determining whether two instances are considered equivalent. Examples of
+ * equivalences are the {@link Equivalences#identity() identity equivalence} and {@link
+ * Equivalences#equals equals equivalence}.
+ *
+ * @author Bob Lee
+ * @author Ben Yu
+ * @author Gregory Kick
+ * @since 10.0 (<a href="http://code.google.com/p/guava-libraries/wiki/Compatibility"
+ * >mostly source-compatible</a> since 4.0)
+ */
+@GwtCompatible
+public abstract class Equivalence<T> {
+ /**
+ * Constructor for use by subclasses.
+ */
+ protected Equivalence() {}
+
+ /**
+ * Returns {@code true} if the given objects are considered equivalent.
+ *
+ * <p>The {@code equivalent} method implements an equivalence relation on object references:
+ *
+ * <ul>
+ * <li>It is <i>reflexive</i>: for any reference {@code x}, including null, {@code
+ * equivalent(x, x)} returns {@code true}.
+ * <li>It is <i>symmetric</i>: for any references {@code x} and {@code y}, {@code
+ * equivalent(x, y) == equivalent(y, x)}.
+ * <li>It is <i>transitive</i>: for any references {@code x}, {@code y}, and {@code z}, if
+ * {@code equivalent(x, y)} returns {@code true} and {@code equivalent(y, z)} returns {@code
+ * true}, then {@code equivalent(x, z)} returns {@code true}.
+ * <li>It is <i>consistent</i>: for any references {@code x} and {@code y}, multiple invocations
+ * of {@code equivalent(x, y)} consistently return {@code true} or consistently return {@code
+ * false} (provided that neither {@code x} nor {@code y} is modified).
+ * </ul>
+ */
+ public final boolean equivalent(@Nullable T a, @Nullable T b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ return doEquivalent(a, b);
+ }
+
+ /**
+ * Returns {@code true} if {@code a} and {@code b} are considered equivalent.
+ *
+ * <p>Called by {@link #equivalent}. {@code a} and {@code b} are not the same
+ * object and are not nulls.
+ *
+ * @since 10.0 (previously, subclasses would override equivalent())
+ */
+ protected abstract boolean doEquivalent(T a, T b);
+
+ /**
+ * Returns a hash code for {@code t}.
+ *
+ * <p>The {@code hash} has the following properties:
+ * <ul>
+ * <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of
+ * {@code hash(x}} consistently return the same value provided {@code x} remains unchanged
+ * according to the definition of the equivalence. The hash need not remain consistent from
+ * one execution of an application to another execution of the same application.
+ * <li>It is <i>distributable accross equivalence</i>: for any references {@code x} and {@code y},
+ * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i> necessary
+ * that the hash be distributable accorss <i>inequivalence</i>. If {@code equivalence(x, y)}
+ * is false, {@code hash(x) == hash(y)} may still be true.
+ * <li>{@code hash(null)} is {@code 0}.
+ * </ul>
+ */
+ public final int hash(@Nullable T t) {
+ if (t == null) {
+ return 0;
+ }
+ return doHash(t);
+ }
+
+ /**
+ * Returns a hash code for non-null object {@code t}.
+ *
+ * <p>Called by {@link #hash}.
+ *
+ * @since 10.0 (previously, subclasses would override hash())
+ */
+ protected abstract int doHash(T t);
+
+ /**
+ * Returns a new equivalence relation for {@code F} which evaluates equivalence by first applying
+ * {@code function} to the argument, then evaluating using {@code this}. That is, for any pair of
+ * non-null objects {@code x} and {@code y}, {@code
+ * equivalence.onResultOf(function).equivalent(a, b)} is true if and only if {@code
+ * equivalence.equivalent(function.apply(a), function.apply(b))} is true.
+ *
+ * <p>For example: <pre> {@code
+ *
+ * Equivalence<Person> SAME_AGE = Equivalences.equals().onResultOf(GET_PERSON_AGE);
+ * }</pre>
+ *
+ * <p>{@code function} will never be invoked with a null value.
+ *
+ * <p>Note that {@code function} must be consistent according to {@code this} equivalence
+ * relation. That is, invoking {@link Function#apply} multiple times for a given value must return
+ * equivalent results.
+ * For example, {@code Equivalences.identity().onResultOf(Functions.toStringFunction())} is broken
+ * because it's not guaranteed that {@link Object#toString}) always returns the same string
+ * instance.
+ *
+ * @since 10.0
+ */
+ public final <F> Equivalence<F> onResultOf(Function<F, ? extends T> function) {
+ return new FunctionalEquivalence<F, T>(function, this);
+ }
+
+ /**
+ * Returns a wrapper of {@code reference} that implements
+ * {@link Wrapper#equals(Object) Object.equals()} such that
+ * {@code wrap(this, a).equals(wrap(this, b))} if and only if {@code this.equivalent(a, b)}.
+ *
+ * @since 10.0
+ */
+ public final <S extends T> Wrapper<S> wrap(@Nullable S reference) {
+ return new Wrapper<S>(this, reference);
+ }
+
+ /**
+ * Wraps an object so that {@link #equals(Object)} and {@link #hashCode()} delegate to an
+ * {@link Equivalence}.
+ *
+ * <p>For example, given an {@link Equivalence} for {@link String strings} named {@code equiv}
+ * that tests equivalence using their lengths:
+ *
+ * <pre> {@code
+ * equiv.wrap("a").equals(equiv.wrap("b")) // true
+ * equiv.wrap("a").equals(equiv.wrap("hello")) // false
+ * }</pre>
+ *
+ * <p>Note in particular that an equivalence wrapper is never equal to the object it wraps.
+ *
+ * <pre> {@code
+ * equiv.wrap(obj).equals(obj) // always false
+ * }</pre>
+ *
+ * @since 10.0
+ */
+ public static final class Wrapper<T> implements Serializable {
+ private final Equivalence<? super T> equivalence;
+ @Nullable private final T reference;
+
+ private Wrapper(Equivalence<? super T> equivalence, @Nullable T reference) {
+ this.equivalence = checkNotNull(equivalence);
+ this.reference = reference;
+ }
+
+ /** Returns the (possibly null) reference wrapped by this instance. */
+ @Nullable public T get() {
+ return reference;
+ }
+
+ /**
+ * Returns {@code true} if {@link Equivalence#equivalent(Object, Object)} applied to the wrapped
+ * references is {@code true} and both wrappers use the {@link Object#equals(Object) same}
+ * equivalence.
+ */
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj == this) {
+ return true;
+ } else if (obj instanceof Wrapper) {
+ Wrapper<?> that = (Wrapper<?>) obj;
+ /*
+ * We cast to Equivalence<Object> here because we can't check the type of the reference held
+ * by the other wrapper. But, by checking that the Equivalences are equal, we know that
+ * whatever type it is, it is assignable to the type handled by this wrapper's equivalence.
+ */
+ @SuppressWarnings("unchecked")
+ Equivalence<Object> equivalence = (Equivalence<Object>) this.equivalence;
+ return equivalence.equals(that.equivalence)
+ && equivalence.equivalent(this.reference, that.reference);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the result of {@link Equivalence#hash(Object)} applied to the the wrapped reference.
+ */
+ @Override public int hashCode() {
+ return equivalence.hash(reference);
+ }
+
+ /**
+ * Returns a string representation for this equivalence wrapper. The form of this string
+ * representation is not specified.
+ */
+ @Override public String toString() {
+ return equivalence + ".wrap(" + reference + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns an equivalence over iterables based on the equivalence of their elements. More
+ * specifically, two iterables are considered equivalent if they both contain the same number of
+ * elements, and each pair of corresponding elements is equivalent according to
+ * {@code this}. Null iterables are equivalent to one another.
+ *
+ * <p>Note that this method performs a similar function for equivalences as {@link
+ * com.google.common.collect.Ordering#lexicographical} does for orderings.
+ *
+ * @since 10.0
+ */
+ @GwtCompatible(serializable = true)
+ public final <S extends T> Equivalence<Iterable<S>> pairwise() {
+ // Ideally, the returned equivalence would support Iterable<? extends T>. However,
+ // the need for this is so rare that it's not worth making callers deal with the ugly wildcard.
+ return new PairwiseEquivalence<S>(this);
+ }
+
+ /**
+ * Returns a predicate that evaluates to true if and only if the input is
+ * equivalent to {@code target} according to this equivalence relation.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public final Predicate<T> equivalentTo(@Nullable T target) {
+ return new EquivalentToPredicate<T>(this, target);
+ }
+
+ private static final class EquivalentToPredicate<T> implements Predicate<T>, Serializable {
+
+ private final Equivalence<T> equivalence;
+ @Nullable private final T target;
+
+ EquivalentToPredicate(Equivalence<T> equivalence, @Nullable T target) {
+ this.equivalence = checkNotNull(equivalence);
+ this.target = target;
+ }
+
+ @Override public boolean apply(@Nullable T input) {
+ return equivalence.equivalent(input, target);
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof EquivalentToPredicate) {
+ EquivalentToPredicate<?> that = (EquivalentToPredicate<?>) obj;
+ return equivalence.equals(that.equivalence)
+ && Objects.equal(target, that.target);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hashCode(equivalence, target);
+ }
+
+ @Override public String toString() {
+ return equivalence + ".equivalentTo(" + target + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
+ * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
+ * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns
+ * {@code 0} if passed a null value.
+ *
+ * @since 13.0
+ * @since 8.0 (in Equivalences with null-friendly behavior)
+ * @since 4.0 (in Equivalences)
+ */
+ public static Equivalence<Object> equals() {
+ return Equals.INSTANCE;
+ }
+
+ /**
+ * Returns an equivalence that uses {@code ==} to compare values and {@link
+ * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent}
+ * returns {@code true} if {@code a == b}, including in the case that a and b are both null.
+ *
+ * @since 13.0
+ * @since 4.0 (in Equivalences)
+ */
+ public static Equivalence<Object> identity() {
+ return Identity.INSTANCE;
+ }
+
+ static final class Equals extends Equivalence<Object>
+ implements Serializable {
+
+ static final Equals INSTANCE = new Equals();
+
+ @Override protected boolean doEquivalent(Object a, Object b) {
+ return a.equals(b);
+ }
+ @Override public int doHash(Object o) {
+ return o.hashCode();
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+ private static final long serialVersionUID = 1;
+ }
+
+ static final class Identity extends Equivalence<Object>
+ implements Serializable {
+
+ static final Identity INSTANCE = new Identity();
+
+ @Override protected boolean doEquivalent(Object a, Object b) {
+ return false;
+ }
+
+ @Override protected int doHash(Object o) {
+ return System.identityHashCode(o);
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+ private static final long serialVersionUID = 1;
+ }
+}
diff --git a/guava/src/com/google/common/base/Equivalences.java b/guava/src/com/google/common/base/Equivalences.java
new file mode 100644
index 0000000..23f947c
--- /dev/null
+++ b/guava/src/com/google/common/base/Equivalences.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * Contains static factory methods for creating {@code Equivalence} instances.
+ *
+ * <p>All methods return serializable instances.
+ *
+ * @author Bob Lee
+ * @author Kurt Alfred Kluever
+ * @author Gregory Kick
+ * @since 4.0
+ */
+@Beta
+@GwtCompatible
+public final class Equivalences {
+ private Equivalences() {}
+
+ /**
+ * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
+ * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
+ * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns
+ * {@code 0} if passed a null value.
+ *
+ * @since 8.0 (present null-friendly behavior)
+ * @since 4.0 (otherwise)
+ * @deprecated This method has been moved to {@link Equivalence#equals}. This method is scheduled
+ * to be removed in Guava release 14.0.
+ */
+ @Deprecated
+ public static Equivalence<Object> equals() {
+ return Equivalence.Equals.INSTANCE;
+ }
+
+ /**
+ * Returns an equivalence that uses {@code ==} to compare values and {@link
+ * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent}
+ * returns {@code true} if {@code a == b}, including in the case that a and b are both null.
+ *
+ * @deprecated This method has been moved to {@link Equivalence#identity}. This method is schedule
+ * to be removed in Guava release 14.0.
+ */
+ @Deprecated
+ public static Equivalence<Object> identity() {
+ return Equivalence.Identity.INSTANCE;
+ }
+}
diff --git a/guava/src/com/google/common/base/FinalizablePhantomReference.java b/guava/src/com/google/common/base/FinalizablePhantomReference.java
new file mode 100644
index 0000000..c694bc9
--- /dev/null
+++ b/guava/src/com/google/common/base/FinalizablePhantomReference.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+
+/**
+ * Phantom reference with a {@code finalizeReferent()} method which a background thread invokes
+ * after the garbage collector reclaims the referent. This is a simpler alternative to using a
+ * {@link ReferenceQueue}.
+ *
+ * <p>Unlike a normal phantom reference, this reference will be cleared automatically.
+ *
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ */
+public abstract class FinalizablePhantomReference<T> extends PhantomReference<T>
+ implements FinalizableReference {
+ /**
+ * Constructs a new finalizable phantom reference.
+ *
+ * @param referent to phantom reference
+ * @param queue that should finalize the referent
+ */
+ protected FinalizablePhantomReference(T referent, FinalizableReferenceQueue queue) {
+ super(referent, queue.queue);
+ queue.cleanUp();
+ }
+}
diff --git a/guava/src/com/google/common/base/FinalizableReference.java b/guava/src/com/google/common/base/FinalizableReference.java
new file mode 100644
index 0000000..ab2dec3
--- /dev/null
+++ b/guava/src/com/google/common/base/FinalizableReference.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+/**
+ * Implemented by references that have code to run after garbage collection of their referents.
+ *
+ * @see FinalizableReferenceQueue
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ */
+public interface FinalizableReference {
+ /**
+ * Invoked on a background thread after the referent has been garbage collected unless security
+ * restrictions prevented starting a background thread, in which case this method is invoked when
+ * new references are created.
+ */
+ void finalizeReferent();
+}
diff --git a/guava/src/com/google/common/base/FinalizableReferenceQueue.java b/guava/src/com/google/common/base/FinalizableReferenceQueue.java
new file mode 100644
index 0000000..aaa5f76
--- /dev/null
+++ b/guava/src/com/google/common/base/FinalizableReferenceQueue.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A reference queue with an associated background thread that dequeues references and invokes
+ * {@link FinalizableReference#finalizeReferent()} on them.
+ *
+ * <p>Keep a strong reference to this object until all of the associated referents have been
+ * finalized. If this object is garbage collected earlier, the backing thread will not invoke {@code
+ * finalizeReferent()} on the remaining references.
+ *
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ */
+public class FinalizableReferenceQueue {
+ /*
+ * The Finalizer thread keeps a phantom reference to this object. When the client (for example, a
+ * map built by MapMaker) no longer has a strong reference to this object, the garbage collector
+ * will reclaim it and enqueue the phantom reference. The enqueued reference will trigger the
+ * Finalizer to stop.
+ *
+ * If this library is loaded in the system class loader, FinalizableReferenceQueue can load
+ * Finalizer directly with no problems.
+ *
+ * If this library is loaded in an application class loader, it's important that Finalizer not
+ * have a strong reference back to the class loader. Otherwise, you could have a graph like this:
+ *
+ * Finalizer Thread runs instance of -> Finalizer.class loaded by -> Application class loader
+ * which loaded -> ReferenceMap.class which has a static -> FinalizableReferenceQueue instance
+ *
+ * Even if no other references to classes from the application class loader remain, the Finalizer
+ * thread keeps an indirect strong reference to the queue in ReferenceMap, which keeps the
+ * Finalizer running, and as a result, the application class loader can never be reclaimed.
+ *
+ * This means that dynamically loaded web applications and OSGi bundles can't be unloaded.
+ *
+ * If the library is loaded in an application class loader, we try to break the cycle by loading
+ * Finalizer in its own independent class loader:
+ *
+ * System class loader -> Application class loader -> ReferenceMap -> FinalizableReferenceQueue
+ * -> etc. -> Decoupled class loader -> Finalizer
+ *
+ * Now, Finalizer no longer keeps an indirect strong reference to the static
+ * FinalizableReferenceQueue field in ReferenceMap. The application class loader can be reclaimed
+ * at which point the Finalizer thread will stop and its decoupled class loader can also be
+ * reclaimed.
+ *
+ * If any of this fails along the way, we fall back to loading Finalizer directly in the
+ * application class loader.
+ */
+
+ private static final Logger logger = Logger.getLogger(FinalizableReferenceQueue.class.getName());
+
+ private static final String FINALIZER_CLASS_NAME = "com.google.common.base.internal.Finalizer";
+
+ /** Reference to Finalizer.startFinalizer(). */
+ private static final Method startFinalizer;
+ static {
+ Class<?> finalizer = loadFinalizer(
+ new SystemLoader(), new DecoupledLoader(), new DirectLoader());
+ startFinalizer = getStartFinalizer(finalizer);
+ }
+
+ /**
+ * The actual reference queue that our background thread will poll.
+ */
+ final ReferenceQueue<Object> queue;
+
+ /**
+ * Whether or not the background thread started successfully.
+ */
+ final boolean threadStarted;
+
+ /**
+ * Constructs a new queue.
+ */
+ @SuppressWarnings("unchecked")
+ public FinalizableReferenceQueue() {
+ // We could start the finalizer lazily, but I'd rather it blow up early.
+ ReferenceQueue<Object> queue;
+ boolean threadStarted = false;
+ try {
+ queue = (ReferenceQueue<Object>)
+ startFinalizer.invoke(null, FinalizableReference.class, this);
+ threadStarted = true;
+ } catch (IllegalAccessException impossible) {
+ throw new AssertionError(impossible); // startFinalizer() is public
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "Failed to start reference finalizer thread."
+ + " Reference cleanup will only occur when new references are created.", t);
+ queue = new ReferenceQueue<Object>();
+ }
+
+ this.queue = queue;
+ this.threadStarted = threadStarted;
+ }
+
+ /**
+ * Repeatedly dequeues references from the queue and invokes {@link
+ * FinalizableReference#finalizeReferent()} on them until the queue is empty. This method is a
+ * no-op if the background thread was created successfully.
+ */
+ void cleanUp() {
+ if (threadStarted) {
+ return;
+ }
+
+ Reference<?> reference;
+ while ((reference = queue.poll()) != null) {
+ /*
+ * This is for the benefit of phantom references. Weak and soft references will have already
+ * been cleared by this point.
+ */
+ reference.clear();
+ try {
+ ((FinalizableReference) reference).finalizeReferent();
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
+ }
+ }
+ }
+
+ /**
+ * Iterates through the given loaders until it finds one that can load Finalizer.
+ *
+ * @return Finalizer.class
+ */
+ private static Class<?> loadFinalizer(FinalizerLoader... loaders) {
+ for (FinalizerLoader loader : loaders) {
+ Class<?> finalizer = loader.loadFinalizer();
+ if (finalizer != null) {
+ return finalizer;
+ }
+ }
+
+ throw new AssertionError();
+ }
+
+ /**
+ * Loads Finalizer.class.
+ */
+ interface FinalizerLoader {
+
+ /**
+ * Returns Finalizer.class or null if this loader shouldn't or can't load it.
+ *
+ * @throws SecurityException if we don't have the appropriate privileges
+ */
+ Class<?> loadFinalizer();
+ }
+
+ /**
+ * Tries to load Finalizer from the system class loader. If Finalizer is in the system class path,
+ * we needn't create a separate loader.
+ */
+ static class SystemLoader implements FinalizerLoader {
+ // This is used by the ClassLoader-leak test in FinalizableReferenceQueueTest to disable
+ // finding Finalizer on the system class path even if it is there.
+ @VisibleForTesting
+ static boolean disabled;
+
+ @Override
+ public Class<?> loadFinalizer() {
+ if (disabled) {
+ return null;
+ }
+ ClassLoader systemLoader;
+ try {
+ systemLoader = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException e) {
+ logger.info("Not allowed to access system class loader.");
+ return null;
+ }
+ if (systemLoader != null) {
+ try {
+ return systemLoader.loadClass(FINALIZER_CLASS_NAME);
+ } catch (ClassNotFoundException e) {
+ // Ignore. Finalizer is simply in a child class loader.
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Try to load Finalizer in its own class loader. If Finalizer's thread had a direct reference to
+ * our class loader (which could be that of a dynamically loaded web application or OSGi bundle),
+ * it would prevent our class loader from getting garbage collected.
+ */
+ static class DecoupledLoader implements FinalizerLoader {
+ private static final String LOADING_ERROR = "Could not load Finalizer in its own class loader."
+ + "Loading Finalizer in the current class loader instead. As a result, you will not be able"
+ + "to garbage collect this class loader. To support reclaiming this class loader, either"
+ + "resolve the underlying issue, or move Google Collections to your system class path.";
+
+ @Override
+ public Class<?> loadFinalizer() {
+ try {
+ /*
+ * We use URLClassLoader because it's the only concrete class loader implementation in the
+ * JDK. If we used our own ClassLoader subclass, Finalizer would indirectly reference this
+ * class loader:
+ *
+ * Finalizer.class -> CustomClassLoader -> CustomClassLoader.class -> This class loader
+ *
+ * System class loader will (and must) be the parent.
+ */
+ ClassLoader finalizerLoader = newLoader(getBaseUrl());
+ return finalizerLoader.loadClass(FINALIZER_CLASS_NAME);
+ } catch (Exception e) {
+ logger.log(Level.WARNING, LOADING_ERROR, e);
+ return null;
+ }
+ }
+
+ /**
+ * Gets URL for base of path containing Finalizer.class.
+ */
+ URL getBaseUrl() throws IOException {
+ // Find URL pointing to Finalizer.class file.
+ String finalizerPath = FINALIZER_CLASS_NAME.replace('.', '/') + ".class";
+ URL finalizerUrl = getClass().getClassLoader().getResource(finalizerPath);
+ if (finalizerUrl == null) {
+ throw new FileNotFoundException(finalizerPath);
+ }
+
+ // Find URL pointing to base of class path.
+ String urlString = finalizerUrl.toString();
+ if (!urlString.endsWith(finalizerPath)) {
+ throw new IOException("Unsupported path style: " + urlString);
+ }
+ urlString = urlString.substring(0, urlString.length() - finalizerPath.length());
+ return new URL(finalizerUrl, urlString);
+ }
+
+ /** Creates a class loader with the given base URL as its classpath. */
+ URLClassLoader newLoader(URL base) {
+ // We use the bootstrap class loader as the parent because Finalizer by design uses
+ // only standard Java classes. That also means that FinalizableReferenceQueueTest
+ // doesn't pick up the wrong version of the Finalizer class.
+ return new URLClassLoader(new URL[] {base}, null);
+ }
+ }
+
+ /**
+ * Loads Finalizer directly using the current class loader. We won't be able to garbage collect
+ * this class loader, but at least the world doesn't end.
+ */
+ static class DirectLoader implements FinalizerLoader {
+ @Override
+ public Class<?> loadFinalizer() {
+ try {
+ return Class.forName(FINALIZER_CLASS_NAME);
+ } catch (ClassNotFoundException e) {
+ throw new AssertionError(e);
+ }
+ }
+ }
+
+ /**
+ * Looks up Finalizer.startFinalizer().
+ */
+ static Method getStartFinalizer(Class<?> finalizer) {
+ try {
+ return finalizer.getMethod("startFinalizer", Class.class, Object.class);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/FinalizableSoftReference.java b/guava/src/com/google/common/base/FinalizableSoftReference.java
new file mode 100644
index 0000000..88607f4
--- /dev/null
+++ b/guava/src/com/google/common/base/FinalizableSoftReference.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+
+/**
+ * Soft reference with a {@code finalizeReferent()} method which a background thread invokes after
+ * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link
+ * ReferenceQueue}.
+ *
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ */
+public abstract class FinalizableSoftReference<T> extends SoftReference<T>
+ implements FinalizableReference {
+ /**
+ * Constructs a new finalizable soft reference.
+ *
+ * @param referent to softly reference
+ * @param queue that should finalize the referent
+ */
+ protected FinalizableSoftReference(T referent, FinalizableReferenceQueue queue) {
+ super(referent, queue.queue);
+ queue.cleanUp();
+ }
+}
diff --git a/guava/src/com/google/common/base/FinalizableWeakReference.java b/guava/src/com/google/common/base/FinalizableWeakReference.java
new file mode 100644
index 0000000..b14d023
--- /dev/null
+++ b/guava/src/com/google/common/base/FinalizableWeakReference.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+/**
+ * Weak reference with a {@code finalizeReferent()} method which a background thread invokes after
+ * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link
+ * ReferenceQueue}.
+ *
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ */
+public abstract class FinalizableWeakReference<T> extends WeakReference<T>
+ implements FinalizableReference {
+ /**
+ * Constructs a new finalizable weak reference.
+ *
+ * @param referent to weakly reference
+ * @param queue that should finalize the referent
+ */
+ protected FinalizableWeakReference(T referent, FinalizableReferenceQueue queue) {
+ super(referent, queue.queue);
+ queue.cleanUp();
+ }
+}
diff --git a/guava/src/com/google/common/base/Function.java b/guava/src/com/google/common/base/Function.java
new file mode 100644
index 0000000..9c29264
--- /dev/null
+++ b/guava/src/com/google/common/base/Function.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * Determines an output value based on an input value.
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
+ * Function}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public interface Function<F, T> {
+ /**
+ * Returns the result of applying this function to {@code input}. This method is <i>generally
+ * expected</i>, but not absolutely required, to have the following properties:
+ *
+ * <ul>
+ * <li>Its execution does not cause any observable side effects.
+ * <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
+ * Objects.equal}{@code (a, b)} implies that {@code Objects.equal(function.apply(a),
+ * function.apply(b))}.
+ * </ul>
+ *
+ * @throws NullPointerException if {@code input} is null and this function does not accept null
+ * arguments
+ */
+ @Nullable T apply(@Nullable F input);
+
+ /**
+ * Indicates whether another object is equal to this function.
+ *
+ * <p>Most implementations will have no reason to override the behavior of {@link Object#equals}.
+ * However, an implementation may also choose to return {@code true} whenever {@code object} is a
+ * {@link Function} that it considers <i>interchangeable</i> with this one. "Interchangeable"
+ * <i>typically</i> means that {@code Objects.equal(this.apply(f), that.apply(f))} is true for all
+ * {@code f} of type {@code F}. Note that a {@code false} result from this method does not imply
+ * that the functions are known <i>not</i> to be interchangeable.
+ */
+ @Override
+ boolean equals(@Nullable Object object);
+}
diff --git a/guava/src/com/google/common/base/FunctionalEquivalence.java b/guava/src/com/google/common/base/FunctionalEquivalence.java
new file mode 100644
index 0000000..a5e9c13
--- /dev/null
+++ b/guava/src/com/google/common/base/FunctionalEquivalence.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+
+import javax.annotation.Nullable;
+
+/**
+ * Equivalence applied on functional result.
+ *
+ * @author Bob Lee
+ * @since 10.0
+ */
+@Beta
+@GwtCompatible
+final class FunctionalEquivalence<F, T> extends Equivalence<F>
+ implements Serializable {
+
+ private static final long serialVersionUID = 0;
+
+ private final Function<F, ? extends T> function;
+ private final Equivalence<T> resultEquivalence;
+
+ FunctionalEquivalence(
+ Function<F, ? extends T> function, Equivalence<T> resultEquivalence) {
+ this.function = checkNotNull(function);
+ this.resultEquivalence = checkNotNull(resultEquivalence);
+ }
+
+ @Override protected boolean doEquivalent(F a, F b) {
+ return resultEquivalence.equivalent(function.apply(a), function.apply(b));
+ }
+
+ @Override protected int doHash(F a) {
+ return resultEquivalence.hash(function.apply(a));
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof FunctionalEquivalence) {
+ FunctionalEquivalence<?, ?> that = (FunctionalEquivalence<?, ?>) obj;
+ return function.equals(that.function)
+ && resultEquivalence.equals(that.resultEquivalence);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hashCode(function, resultEquivalence);
+ }
+
+ @Override public String toString() {
+ return resultEquivalence + ".onResultOf(" + function + ")";
+ }
+}
diff --git a/guava/src/com/google/common/base/Functions.java b/guava/src/com/google/common/base/Functions.java
new file mode 100644
index 0000000..65fc2c6
--- /dev/null
+++ b/guava/src/com/google/common/base/Functions.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+/**
+ * Static utility methods pertaining to {@code Function} instances.
+ *
+ * <p>All methods return serializable functions as long as they're given serializable parameters.
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
+ * Function}</a>.
+ *
+ * @author Mike Bostock
+ * @author Jared Levy
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public final class Functions {
+ private Functions() {}
+
+ /**
+ * Returns a function that calls {@code toString()} on its argument. The function does not accept
+ * nulls; it will throw a {@link NullPointerException} when applied to {@code null}.
+ *
+ * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
+ * documented at {@link Function#apply}). For example, this function yields different results for
+ * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
+ */
+ public static Function<Object, String> toStringFunction() {
+ return ToStringFunction.INSTANCE;
+ }
+
+ // enum singleton pattern
+ private enum ToStringFunction implements Function<Object, String> {
+ INSTANCE;
+
+ @Override
+ public String apply(Object o) {
+ checkNotNull(o); // eager for GWT.
+ return o.toString();
+ }
+
+ @Override public String toString() {
+ return "toString";
+ }
+ }
+
+ /**
+ * Returns the identity function.
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Function<E, E> identity() {
+ return (Function<E, E>) IdentityFunction.INSTANCE;
+ }
+
+ // enum singleton pattern
+ private enum IdentityFunction implements Function<Object, Object> {
+ INSTANCE;
+
+ @Override
+ public Object apply(Object o) {
+ return o;
+ }
+
+ @Override public String toString() {
+ return "identity";
+ }
+ }
+
+ /**
+ * Returns a function which performs a map lookup. The returned function throws an {@link
+ * IllegalArgumentException} if given a key that does not exist in the map.
+ */
+ public static <K, V> Function<K, V> forMap(Map<K, V> map) {
+ return new FunctionForMapNoDefault<K, V>(map);
+ }
+
+ private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
+ final Map<K, V> map;
+
+ FunctionForMapNoDefault(Map<K, V> map) {
+ this.map = checkNotNull(map);
+ }
+
+ @Override
+ public V apply(K key) {
+ V result = map.get(key);
+ checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
+ return result;
+ }
+
+ @Override public boolean equals(@Nullable Object o) {
+ if (o instanceof FunctionForMapNoDefault) {
+ FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
+ return map.equals(that.map);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return "forMap(" + map + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a function which performs a map lookup with a default value. The function created by
+ * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
+ * set.
+ *
+ * @param map source map that determines the function behavior
+ * @param defaultValue the value to return for inputs that aren't map keys
+ * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
+ * defaultValue} otherwise
+ */
+ public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
+ return new ForMapWithDefault<K, V>(map, defaultValue);
+ }
+
+ private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
+ final Map<K, ? extends V> map;
+ final V defaultValue;
+
+ ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
+ this.map = checkNotNull(map);
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public V apply(K key) {
+ V result = map.get(key);
+ return (result != null || map.containsKey(key)) ? result : defaultValue;
+ }
+
+ @Override public boolean equals(@Nullable Object o) {
+ if (o instanceof ForMapWithDefault) {
+ ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
+ return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hashCode(map, defaultValue);
+ }
+
+ @Override public String toString() {
+ return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
+ * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
+ *
+ * @param g the second function to apply
+ * @param f the first function to apply
+ * @return the composition of {@code f} and {@code g}
+ * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
+ */
+ public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
+ return new FunctionComposition<A, B, C>(g, f);
+ }
+
+ private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
+ private final Function<B, C> g;
+ private final Function<A, ? extends B> f;
+
+ public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
+ this.g = checkNotNull(g);
+ this.f = checkNotNull(f);
+ }
+
+ @Override
+ public C apply(A a) {
+ return g.apply(f.apply(a));
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof FunctionComposition) {
+ FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
+ return f.equals(that.f) && g.equals(that.g);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return f.hashCode() ^ g.hashCode();
+ }
+
+ @Override public String toString() {
+ return g.toString() + "(" + f.toString() + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a function that returns the same boolean output as the given predicate for all inputs.
+ *
+ * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
+ * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
+ */
+ public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
+ return new PredicateFunction<T>(predicate);
+ }
+
+ /** @see Functions#forPredicate */
+ private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
+ private final Predicate<T> predicate;
+
+ private PredicateFunction(Predicate<T> predicate) {
+ this.predicate = checkNotNull(predicate);
+ }
+
+ @Override
+ public Boolean apply(T t) {
+ return predicate.apply(t);
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof PredicateFunction) {
+ PredicateFunction<?> that = (PredicateFunction<?>) obj;
+ return predicate.equals(that.predicate);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return predicate.hashCode();
+ }
+
+ @Override public String toString() {
+ return "forPredicate(" + predicate + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a function that returns {@code value} for any input.
+ *
+ * @param value the constant value for the function to return
+ * @return a function that always returns {@code value}
+ */
+ public static <E> Function<Object, E> constant(@Nullable E value) {
+ return new ConstantFunction<E>(value);
+ }
+
+ private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
+ private final E value;
+
+ public ConstantFunction(@Nullable E value) {
+ this.value = value;
+ }
+
+ @Override
+ public E apply(@Nullable Object from) {
+ return value;
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof ConstantFunction) {
+ ConstantFunction<?> that = (ConstantFunction<?>) obj;
+ return Objects.equal(value, that.value);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return (value == null) ? 0 : value.hashCode();
+ }
+
+ @Override public String toString() {
+ return "constant(" + value + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code
+ * supplier}, regardless of its input.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
+ return new SupplierFunction<T>(supplier);
+ }
+
+ /** @see Functions#forSupplier*/
+ private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
+
+ private final Supplier<T> supplier;
+
+ private SupplierFunction(Supplier<T> supplier) {
+ this.supplier = checkNotNull(supplier);
+ }
+
+ @Override public T apply(@Nullable Object input) {
+ return supplier.get();
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof SupplierFunction) {
+ SupplierFunction<?> that = (SupplierFunction<?>) obj;
+ return this.supplier.equals(that.supplier);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return supplier.hashCode();
+ }
+
+ @Override public String toString() {
+ return "forSupplier(" + supplier + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
diff --git a/guava/src/com/google/common/base/Joiner.java b/guava/src/com/google/common/base/Joiner.java
new file mode 100644
index 0000000..9391550
--- /dev/null
+++ b/guava/src/com/google/common/base/Joiner.java
@@ -0,0 +1,562 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.IOException;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.CheckReturnValue;
+import javax.annotation.Nullable;
+
+/**
+ * An object which joins pieces of text (specified as an array, {@link Iterable}, varargs or even a
+ * {@link Map}) with a separator. It either appends the results to an {@link Appendable} or returns
+ * them as a {@link String}. Example: <pre> {@code
+ *
+ * Joiner joiner = Joiner.on("; ").skipNulls();
+ * . . .
+ * return joiner.join("Harry", null, "Ron", "Hermione");}</pre>
+ *
+ * This returns the string {@code "Harry; Ron; Hermione"}. Note that all input elements are
+ * converted to strings using {@link Object#toString()} before being appended.
+ *
+ * <p>If neither {@link #skipNulls()} nor {@link #useForNull(String)} is specified, the joining
+ * methods will throw {@link NullPointerException} if any given element is null.
+ *
+ * <p><b>Warning: joiner instances are always immutable</b>; a configuration method such as {@code
+ * useForNull} has no effect on the instance it is invoked on! You must store and use the new joiner
+ * instance returned by the method. This makes joiners thread-safe, and safe to store as {@code
+ * static final} constants. <pre> {@code
+ *
+ * // Bad! Do not do this!
+ * Joiner joiner = Joiner.on(',');
+ * joiner.skipNulls(); // does nothing!
+ * return joiner.join("wrong", null, "wrong");}</pre>
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#Joiner">{@code Joiner}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public class Joiner {
+ /**
+ * Returns a joiner which automatically places {@code separator} between consecutive elements.
+ */
+ public static Joiner on(String separator) {
+ return new Joiner(separator);
+ }
+
+ /**
+ * Returns a joiner which automatically places {@code separator} between consecutive elements.
+ */
+ public static Joiner on(char separator) {
+ return new Joiner(String.valueOf(separator));
+ }
+
+ private final String separator;
+
+ private Joiner(String separator) {
+ this.separator = checkNotNull(separator);
+ }
+
+ private Joiner(Joiner prototype) {
+ this.separator = prototype.separator;
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #appendTo(Appendable, Iterator)} by casting {@code parts} to
+ * {@code Iterator<?>}, or better yet, by implementing only {@code Iterator} and not
+ * {@code Iterable}. <b>This method is scheduled for deletion in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ final <A extends Appendable, I extends Object & Iterable<?> & Iterator<?>> A
+ appendTo(A appendable, I parts) throws IOException {
+ return appendTo(appendable, (Iterator<?>) parts);
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code appendable}.
+ */
+ public <A extends Appendable> A appendTo(A appendable, Iterable<?> parts) throws IOException {
+ return appendTo(appendable, parts.iterator());
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code appendable}.
+ *
+ * @since 11.0
+ */
+ public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
+ checkNotNull(appendable);
+ if (parts.hasNext()) {
+ appendable.append(toString(parts.next()));
+ while (parts.hasNext()) {
+ appendable.append(separator);
+ appendable.append(toString(parts.next()));
+ }
+ }
+ return appendable;
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code appendable}.
+ */
+ public final <A extends Appendable> A appendTo(A appendable, Object[] parts) throws IOException {
+ return appendTo(appendable, Arrays.asList(parts));
+ }
+
+ /**
+ * Appends to {@code appendable} the string representation of each of the remaining arguments.
+ */
+ public final <A extends Appendable> A appendTo(
+ A appendable, @Nullable Object first, @Nullable Object second, Object... rest)
+ throws IOException {
+ return appendTo(appendable, iterable(first, second, rest));
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #appendTo(StringBuilder, Iterator)} by casting {@code parts} to
+ * {@code Iterator<?>}, or better yet, by implementing only {@code Iterator} and not
+ * {@code Iterable}. <b>This method is scheduled for deletion in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ final <I extends Object & Iterable<?> & Iterator<?>> StringBuilder
+ appendTo(StringBuilder builder, I parts) {
+ return appendTo(builder, (Iterator<?>) parts);
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
+ * Iterable)}, except that it does not throw {@link IOException}.
+ */
+ public final StringBuilder appendTo(StringBuilder builder, Iterable<?> parts) {
+ return appendTo(builder, parts.iterator());
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
+ * Iterable)}, except that it does not throw {@link IOException}.
+ *
+ * @since 11.0
+ */
+ public final StringBuilder appendTo(StringBuilder builder, Iterator<?> parts) {
+ try {
+ appendTo((Appendable) builder, parts);
+ } catch (IOException impossible) {
+ throw new AssertionError(impossible);
+ }
+ return builder;
+ }
+
+ /**
+ * Appends the string representation of each of {@code parts}, using the previously configured
+ * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable,
+ * Iterable)}, except that it does not throw {@link IOException}.
+ */
+ public final StringBuilder appendTo(StringBuilder builder, Object[] parts) {
+ return appendTo(builder, Arrays.asList(parts));
+ }
+
+ /**
+ * Appends to {@code builder} the string representation of each of the remaining arguments.
+ * Identical to {@link #appendTo(Appendable, Object, Object, Object...)}, except that it does not
+ * throw {@link IOException}.
+ */
+ public final StringBuilder appendTo(
+ StringBuilder builder, @Nullable Object first, @Nullable Object second, Object... rest) {
+ return appendTo(builder, iterable(first, second, rest));
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #join(Iterator)} by casting {@code parts} to
+ * {@code Iterator<?>}, or better yet, by implementing only {@code Iterator} and not
+ * {@code Iterable}. <b>This method is scheduled for deletion in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ final <I extends Object & Iterable<?> & Iterator<?>> String join(I parts) {
+ return join((Iterator<?>) parts);
+ }
+
+ /**
+ * Returns a string containing the string representation of each of {@code parts}, using the
+ * previously configured separator between each.
+ */
+ public final String join(Iterable<?> parts) {
+ return join(parts.iterator());
+ }
+
+ /**
+ * Returns a string containing the string representation of each of {@code parts}, using the
+ * previously configured separator between each.
+ *
+ * @since 11.0
+ */
+ public final String join(Iterator<?> parts) {
+ return appendTo(new StringBuilder(), parts).toString();
+ }
+
+ /**
+ * Returns a string containing the string representation of each of {@code parts}, using the
+ * previously configured separator between each.
+ */
+ public final String join(Object[] parts) {
+ return join(Arrays.asList(parts));
+ }
+
+ /**
+ * Returns a string containing the string representation of each argument, using the previously
+ * configured separator between each.
+ */
+ public final String join(@Nullable Object first, @Nullable Object second, Object... rest) {
+ return join(iterable(first, second, rest));
+ }
+
+ /**
+ * Returns a joiner with the same behavior as this one, except automatically substituting {@code
+ * nullText} for any provided null elements.
+ */
+ @CheckReturnValue
+ public Joiner useForNull(final String nullText) {
+ checkNotNull(nullText);
+ return new Joiner(this) {
+ @Override CharSequence toString(Object part) {
+ return (part == null) ? nullText : Joiner.this.toString(part);
+ }
+
+ @Override public Joiner useForNull(String nullText) {
+ checkNotNull(nullText); // weird: just to satisfy NullPointerTester.
+ throw new UnsupportedOperationException("already specified useForNull");
+ }
+
+ @Override public Joiner skipNulls() {
+ throw new UnsupportedOperationException("already specified useForNull");
+ }
+ };
+ }
+
+ /**
+ * Returns a joiner with the same behavior as this joiner, except automatically skipping over any
+ * provided null elements.
+ */
+ @CheckReturnValue
+ public Joiner skipNulls() {
+ return new Joiner(this) {
+ @Override public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts)
+ throws IOException {
+ checkNotNull(appendable, "appendable");
+ checkNotNull(parts, "parts");
+ while (parts.hasNext()) {
+ Object part = parts.next();
+ if (part != null) {
+ appendable.append(Joiner.this.toString(part));
+ break;
+ }
+ }
+ while (parts.hasNext()) {
+ Object part = parts.next();
+ if (part != null) {
+ appendable.append(separator);
+ appendable.append(Joiner.this.toString(part));
+ }
+ }
+ return appendable;
+ }
+
+ @Override public Joiner useForNull(String nullText) {
+ checkNotNull(nullText); // weird: just to satisfy NullPointerTester.
+ throw new UnsupportedOperationException("already specified skipNulls");
+ }
+
+ @Override public MapJoiner withKeyValueSeparator(String kvs) {
+ checkNotNull(kvs); // weird: just to satisfy NullPointerTester.
+ throw new UnsupportedOperationException("can't use .skipNulls() with maps");
+ }
+ };
+ }
+
+ /**
+ * Returns a {@code MapJoiner} using the given key-value separator, and the same configuration as
+ * this {@code Joiner} otherwise.
+ */
+ @CheckReturnValue
+ public MapJoiner withKeyValueSeparator(String keyValueSeparator) {
+ return new MapJoiner(this, keyValueSeparator);
+ }
+
+ /**
+ * An object that joins map entries in the same manner as {@code Joiner} joins iterables and
+ * arrays. Like {@code Joiner}, it is thread-safe and immutable.
+ *
+ * <p>In addition to operating on {@code Map} instances, {@code MapJoiner} can operate on {@code
+ * Multimap} entries in two distinct modes:
+ *
+ * <ul>
+ * <li>To output a separate entry for each key-value pair, pass {@code multimap.entries()} to a
+ * {@code MapJoiner} method that accepts entries as input, and receive output of the form
+ * {@code key1=A&key1=B&key2=C}.
+ * <li>To output a single entry for each key, pass {@code multimap.asMap()} to a {@code MapJoiner}
+ * method that accepts a map as input, and receive output of the form {@code
+ * key1=[A, B]&key2=C}.
+ * </ul>
+ *
+ * @since 2.0 (imported from Google Collections Library)
+ */
+ public final static class MapJoiner {
+ private final Joiner joiner;
+ private final String keyValueSeparator;
+
+ private MapJoiner(Joiner joiner, String keyValueSeparator) {
+ this.joiner = joiner; // only "this" is ever passed, so don't checkNotNull
+ this.keyValueSeparator = checkNotNull(keyValueSeparator);
+ }
+
+ /**
+ * Appends the string representation of each entry of {@code map}, using the previously
+ * configured separator and key-value separator, to {@code appendable}.
+ */
+ public <A extends Appendable> A appendTo(A appendable, Map<?, ?> map) throws IOException {
+ return appendTo(appendable, map.entrySet());
+ }
+
+ /**
+ * Appends the string representation of each entry of {@code map}, using the previously
+ * configured separator and key-value separator, to {@code builder}. Identical to {@link
+ * #appendTo(Appendable, Map)}, except that it does not throw {@link IOException}.
+ */
+ public StringBuilder appendTo(StringBuilder builder, Map<?, ?> map) {
+ return appendTo(builder, map.entrySet());
+ }
+
+ /**
+ * Returns a string containing the string representation of each entry of {@code map}, using the
+ * previously configured separator and key-value separator.
+ */
+ public String join(Map<?, ?> map) {
+ return join(map.entrySet());
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #appendTo(Appendable, Iterator)} by casting {@code entries} to
+ * {@code Iterator<? extends Entry<?, ?>>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled for deletion
+ * in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ <A extends Appendable,
+ I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
+ A appendTo(A appendable, I entries) throws IOException {
+ Iterator<? extends Entry<?, ?>> iterator = entries;
+ return appendTo(appendable, iterator);
+ }
+
+ /**
+ * Appends the string representation of each entry in {@code entries}, using the previously
+ * configured separator and key-value separator, to {@code appendable}.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public <A extends Appendable> A appendTo(A appendable, Iterable<? extends Entry<?, ?>> entries)
+ throws IOException {
+ return appendTo(appendable, entries.iterator());
+ }
+
+ /**
+ * Appends the string representation of each entry in {@code entries}, using the previously
+ * configured separator and key-value separator, to {@code appendable}.
+ *
+ * @since 11.0
+ */
+ @Beta
+ public <A extends Appendable> A appendTo(A appendable, Iterator<? extends Entry<?, ?>> parts)
+ throws IOException {
+ checkNotNull(appendable);
+ if (parts.hasNext()) {
+ Entry<?, ?> entry = parts.next();
+ appendable.append(joiner.toString(entry.getKey()));
+ appendable.append(keyValueSeparator);
+ appendable.append(joiner.toString(entry.getValue()));
+ while (parts.hasNext()) {
+ appendable.append(joiner.separator);
+ Entry<?, ?> e = parts.next();
+ appendable.append(joiner.toString(e.getKey()));
+ appendable.append(keyValueSeparator);
+ appendable.append(joiner.toString(e.getValue()));
+ }
+ }
+ return appendable;
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #appendTo(StringBuilder, Iterator)} by casting {@code entries} to
+ * {@code Iterator<? extends Entry<?, ?>>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled for deletion
+ * in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
+ StringBuilder appendTo(StringBuilder builder, I entries) throws IOException {
+ Iterator<? extends Entry<?, ?>> iterator = entries;
+ return appendTo(builder, iterator);
+ }
+
+ /**
+ * Appends the string representation of each entry in {@code entries}, using the previously
+ * configured separator and key-value separator, to {@code builder}. Identical to {@link
+ * #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public StringBuilder appendTo(StringBuilder builder, Iterable<? extends Entry<?, ?>> entries) {
+ return appendTo(builder, entries.iterator());
+ }
+
+ /**
+ * Appends the string representation of each entry in {@code entries}, using the previously
+ * configured separator and key-value separator, to {@code builder}. Identical to {@link
+ * #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}.
+ *
+ * @since 11.0
+ */
+ @Beta
+ public StringBuilder appendTo(StringBuilder builder, Iterator<? extends Entry<?, ?>> entries) {
+ try {
+ appendTo((Appendable) builder, entries);
+ } catch (IOException impossible) {
+ throw new AssertionError(impossible);
+ }
+ return builder;
+ }
+
+ /**
+ * <b>Deprecated.</b>
+ *
+ * @since 11.0
+ * @deprecated use {@link #join(Iterator)} by casting {@code entries} to
+ * {@code Iterator<? extends Entry<?, ?>>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled for deletion
+ * in June 2013.</b>
+ */
+ @Beta
+ @Deprecated
+ public
+ <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
+ String join(I entries) throws IOException {
+ Iterator<? extends Entry<?, ?>> iterator = entries;
+ return join(iterator);
+ }
+
+ /**
+ * Returns a string containing the string representation of each entry in {@code entries}, using
+ * the previously configured separator and key-value separator.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public String join(Iterable<? extends Entry<?, ?>> entries) {
+ return join(entries.iterator());
+ }
+
+ /**
+ * Returns a string containing the string representation of each entry in {@code entries}, using
+ * the previously configured separator and key-value separator.
+ *
+ * @since 11.0
+ */
+ @Beta
+ public String join(Iterator<? extends Entry<?, ?>> entries) {
+ return appendTo(new StringBuilder(), entries).toString();
+ }
+
+ /**
+ * Returns a map joiner with the same behavior as this one, except automatically substituting
+ * {@code nullText} for any provided null keys or values.
+ */
+ @CheckReturnValue
+ public MapJoiner useForNull(String nullText) {
+ return new MapJoiner(joiner.useForNull(nullText), keyValueSeparator);
+ }
+ }
+
+ CharSequence toString(Object part) {
+ checkNotNull(part); // checkNotNull for GWT (do not optimize).
+ return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
+ }
+
+ private static Iterable<Object> iterable(
+ final Object first, final Object second, final Object[] rest) {
+ checkNotNull(rest);
+ return new AbstractList<Object>() {
+ @Override public int size() {
+ return rest.length + 2;
+ }
+
+ @Override public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ default:
+ return rest[index - 2];
+ }
+ }
+ };
+ }
+}
diff --git a/guava/src/com/google/common/base/MediumCharMatcher.java b/guava/src/com/google/common/base/MediumCharMatcher.java
new file mode 100644
index 0000000..f55ad5d
--- /dev/null
+++ b/guava/src/com/google/common/base/MediumCharMatcher.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * An immutable version of CharMatcher for medium-sized sets of characters that uses a hash table
+ * with linear probing to check for matches.
+ *
+ * @author Christopher Swenson
+ */
+@GwtCompatible
+final class MediumCharMatcher extends CharMatcher {
+ static final int MAX_SIZE = 1023;
+ private final char[] table;
+ private final boolean containsZero;
+ private final long filter;
+
+ private MediumCharMatcher(char[] table, long filter, boolean containsZero,
+ String description) {
+ super(description);
+ this.table = table;
+ this.filter = filter;
+ this.containsZero = containsZero;
+ }
+
+ private boolean checkFilter(int c) {
+ return 1 == (1 & (filter >> c));
+ }
+
+ // This is all essentially copied from ImmutableSet, but we have to duplicate because
+ // of dependencies.
+
+ // Represents how tightly we can pack things, as a maximum.
+ private static final double DESIRED_LOAD_FACTOR = 0.5;
+
+ /**
+ * Returns an array size suitable for the backing array of a hash table that
+ * uses open addressing with linear probing in its implementation. The
+ * returned size is the smallest power of two that can hold setSize elements
+ * with the desired load factor.
+ */
+ @VisibleForTesting static int chooseTableSize(int setSize) {
+ if (setSize == 1) {
+ return 2;
+ }
+ // Correct the size for open addressing to match desired load factor.
+ // Round up to the next highest power of 2.
+ int tableSize = Integer.highestOneBit(setSize - 1) << 1;
+ while (tableSize * DESIRED_LOAD_FACTOR < setSize) {
+ tableSize <<= 1;
+ }
+ return tableSize;
+ }
+
+ // This method is thread-safe, since if any two threads execute it simultaneously, all
+ // that will happen is that they compute the same data structure twice, but nothing will ever
+ // be incorrect.
+ @Override
+ public CharMatcher precomputed() {
+ return this;
+ }
+
+ static CharMatcher from(char[] chars, String description) {
+ // Compute the filter.
+ long filter = 0;
+ int size = chars.length;
+ boolean containsZero = (chars[0] == 0);
+ // Compute the filter.
+ for (char c : chars) {
+ filter |= 1L << c;
+ }
+ // Compute the hash table.
+ char[] table = new char[chooseTableSize(size)];
+ int mask = table.length - 1;
+ for (char c : chars) {
+ int index = c & mask;
+ while (true) {
+ // Check for empty.
+ if (table[index] == 0) {
+ table[index] = c;
+ break;
+ }
+ // Linear probing.
+ index = (index + 1) & mask;
+ }
+ }
+ return new MediumCharMatcher(table, filter, containsZero, description);
+ }
+
+ @Override
+ public boolean matches(char c) {
+ if (c == 0) {
+ return containsZero;
+ }
+ if (!checkFilter(c)) {
+ return false;
+ }
+ int mask = table.length - 1;
+ int startingIndex = c & mask;
+ int index = startingIndex;
+ do {
+ // Check for empty.
+ if (table[index] == 0) {
+ return false;
+ // Check for match.
+ } else if (table[index] == c) {
+ return true;
+ } else {
+ // Linear probing.
+ index = (index + 1) & mask;
+ }
+ // Check to see if we wrapped around the whole table.
+ } while (index != startingIndex);
+ return false;
+ }
+}
diff --git a/guava/src/com/google/common/base/Objects.java b/guava/src/com/google/common/base/Objects.java
new file mode 100644
index 0000000..e1c79a3
--- /dev/null
+++ b/guava/src/com/google/common/base/Objects.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Helper functions that can operate on any {@code Object}.
+ *
+ * <p>See the Guava User Guide on <a
+ * href="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing
+ * {@code Object} methods with {@code Objects}</a>.
+ *
+ * @author Laurence Gonsalves
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public final class Objects {
+ private Objects() {}
+
+ /**
+ * Determines whether two possibly-null objects are equal. Returns:
+ *
+ * <ul>
+ * <li>{@code true} if {@code a} and {@code b} are both null.
+ * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
+ * equal according to {@link Object#equals(Object)}.
+ * <li>{@code false} in all other situations.
+ * </ul>
+ *
+ * <p>This assumes that any non-null objects passed to this function conform
+ * to the {@code equals()} contract.
+ */
+ public static boolean equal(@Nullable Object a, @Nullable Object b) {
+ return a == b || (a != null && a.equals(b));
+ }
+
+ /**
+ * Generates a hash code for multiple values. The hash code is generated by
+ * calling {@link Arrays#hashCode(Object[])}.
+ *
+ * <p>This is useful for implementing {@link Object#hashCode()}. For example,
+ * in an object that has three properties, {@code x}, {@code y}, and
+ * {@code z}, one could write:
+ * <pre>
+ * public int hashCode() {
+ * return Objects.hashCode(getX(), getY(), getZ());
+ * }</pre>
+ *
+ * <b>Warning</b>: When a single object is supplied, the returned hash code
+ * does not equal the hash code of that object.
+ */
+ public static int hashCode(@Nullable Object... objects) {
+ return Arrays.hashCode(objects);
+ }
+
+ /**
+ * Creates an instance of {@link ToStringHelper}.
+ *
+ * <p>This is helpful for implementing {@link Object#toString()}.
+ * Specification by example: <pre> {@code
+ * // Returns "ClassName{}"
+ * Objects.toStringHelper(this)
+ * .toString();
+ *
+ * // Returns "ClassName{x=1}"
+ * Objects.toStringHelper(this)
+ * .add("x", 1)
+ * .toString();
+ *
+ * // Returns "MyObject{x=1}"
+ * Objects.toStringHelper("MyObject")
+ * .add("x", 1)
+ * .toString();
+ *
+ * // Returns "ClassName{x=1, y=foo}"
+ * Objects.toStringHelper(this)
+ * .add("x", 1)
+ * .add("y", "foo")
+ * .toString();
+ * }}
+ *
+ * // Returns "ClassName{x=1}"
+ * Objects.toStringHelper(this)
+ * .omitNullValues()
+ * .add("x", 1)
+ * .add("y", null)
+ * .toString();
+ * }}</pre>
+ *
+ * <p>Note that in GWT, class names are often obfuscated.
+ *
+ * @param self the object to generate the string for (typically {@code this}),
+ * used only for its class name
+ * @since 2.0
+ */
+ public static ToStringHelper toStringHelper(Object self) {
+ return new ToStringHelper(simpleName(self.getClass()));
+ }
+
+ /**
+ * Creates an instance of {@link ToStringHelper} in the same manner as
+ * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
+ * instead of using an instance's {@link Object#getClass()}.
+ *
+ * <p>Note that in GWT, class names are often obfuscated.
+ *
+ * @param clazz the {@link Class} of the instance
+ * @since 7.0 (source-compatible since 2.0)
+ */
+ public static ToStringHelper toStringHelper(Class<?> clazz) {
+ return new ToStringHelper(simpleName(clazz));
+ }
+
+ /**
+ * Creates an instance of {@link ToStringHelper} in the same manner as
+ * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
+ * of using an instance's {@link Object#getClass()}.
+ *
+ * @param className the name of the instance type
+ * @since 7.0 (source-compatible since 2.0)
+ */
+ public static ToStringHelper toStringHelper(String className) {
+ return new ToStringHelper(className);
+ }
+
+ /**
+ * {@link Class#getSimpleName()} is not GWT compatible yet, so we
+ * provide our own implementation.
+ */
+ private static String simpleName(Class<?> clazz) {
+ String name = clazz.getName();
+
+ // the nth anonymous class has a class name ending in "Outer$n"
+ // and local inner classes have names ending in "Outer.$1Inner"
+ name = name.replaceAll("\\$[0-9]+", "\\$");
+
+ // we want the name of the inner class all by its lonesome
+ int start = name.lastIndexOf('$');
+
+ // if this isn't an inner class, just find the start of the
+ // top level class name.
+ if (start == -1) {
+ start = name.lastIndexOf('.');
+ }
+ return name.substring(start + 1);
+ }
+
+ /**
+ * Returns the first of two given parameters that is not {@code null}, if
+ * either is, or otherwise throws a {@link NullPointerException}.
+ *
+ * <p><b>Note:</b> if {@code first} is represented as an {@code Optional<T>},
+ * this can be accomplished with {@code first.or(second)}. That approach also
+ * allows for lazy evaluation of the fallback instance, using
+ * {@code first.or(Supplier)}.
+ *
+ * @return {@code first} if {@code first} is not {@code null}, or
+ * {@code second} if {@code first} is {@code null} and {@code second} is
+ * not {@code null}
+ * @throws NullPointerException if both {@code first} and {@code second} were
+ * {@code null}
+ * @since 3.0
+ */
+ public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
+ return first != null ? first : checkNotNull(second);
+ }
+
+ /**
+ * Support class for {@link Objects#toStringHelper}.
+ *
+ * @author Jason Lee
+ * @since 2.0
+ */
+ public static final class ToStringHelper {
+ private final String className;
+ private final List<ValueHolder> valueHolders =
+ new LinkedList<ValueHolder>();
+ private boolean omitNullValues = false;
+
+ /**
+ * Use {@link Objects#toStringHelper(Object)} to create an instance.
+ */
+ private ToStringHelper(String className) {
+ this.className = checkNotNull(className);
+ }
+
+ /**
+ * When called, the formatted output returned by {@link #toString()} will
+ * ignore {@code null} values.
+ *
+ * @since 12.0
+ */
+ @Beta
+ public ToStringHelper omitNullValues() {
+ omitNullValues = true;
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format. If {@code value} is {@code null}, the string {@code "null"}
+ * is used, unless {@link #omitNullValues()} is called, in which case this
+ * name/value pair will not be added.
+ */
+ public ToStringHelper add(String name, @Nullable Object value) {
+ checkNotNull(name);
+ addHolder(value).builder.append(name).append('=').append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, boolean value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, char value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, double value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, float value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, int value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ /**
+ * Adds a name/value pair to the formatted output in {@code name=value}
+ * format.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper add(String name, long value) {
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ private StringBuilder checkNameAndAppend(String name) {
+ checkNotNull(name);
+ return addHolder().builder.append(name).append('=');
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
+ * and give value a readable name.
+ */
+ public ToStringHelper addValue(@Nullable Object value) {
+ addHolder(value).builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(boolean value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, char)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(char value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, double)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(double value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, float)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(float value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, int)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(int value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Adds an unnamed value to the formatted output.
+ *
+ * <p>It is strongly encouraged to use {@link #add(String, long)} instead
+ * and give value a readable name.
+ *
+ * @since 11.0 (source-compatible since 2.0)
+ */
+ public ToStringHelper addValue(long value) {
+ addHolder().builder.append(value);
+ return this;
+ }
+
+ /**
+ * Returns a string in the format specified by {@link
+ * Objects#toStringHelper(Object)}.
+ */
+ @Override public String toString() {
+ // create a copy to keep it consistent in case value changes
+ boolean omitNullValuesSnapshot = omitNullValues;
+ boolean needsSeparator = false;
+ StringBuilder builder = new StringBuilder(32).append(className)
+ .append('{');
+ for (ValueHolder valueHolder : valueHolders) {
+ if (!omitNullValuesSnapshot || !valueHolder.isNull) {
+ if (needsSeparator) {
+ builder.append(", ");
+ } else {
+ needsSeparator = true;
+ }
+ // must explicitly cast it, otherwise GWT tests might fail because
+ // it tries to access StringBuilder.append(StringBuilder), which is
+ // a private method
+ // TODO(user): change once 5904010 is fixed
+ CharSequence sequence = valueHolder.builder;
+ builder.append(sequence);
+ }
+ }
+ return builder.append('}').toString();
+ }
+
+ private ValueHolder addHolder() {
+ ValueHolder valueHolder = new ValueHolder();
+ valueHolders.add(valueHolder);
+ return valueHolder;
+ }
+
+ private ValueHolder addHolder(@Nullable Object value) {
+ ValueHolder valueHolder = addHolder();
+ valueHolder.isNull = (value == null);
+ return valueHolder;
+ }
+
+ private static final class ValueHolder {
+ final StringBuilder builder = new StringBuilder();
+ boolean isNull;
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Optional.java b/guava/src/com/google/common/base/Optional.java
new file mode 100644
index 0000000..8cd7cda
--- /dev/null
+++ b/guava/src/com/google/common/base/Optional.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * An immutable object that may contain a non-null reference to another object. Each
+ * instance of this type either contains a non-null reference, or contains nothing (in
+ * which case we say that the reference is "absent"); it is never said to "contain {@code
+ * null}".
+ *
+ * <p>A non-null {@code Optional<T>} reference can be used as a replacement for a nullable
+ * {@code T} reference. It allows you to represent "a {@code T} that must be present" and
+ * a "a {@code T} that might be absent" as two distinct types in your program, which can
+ * aid clarity.
+ *
+ * <p>Some uses of this class include
+ *
+ * <ul>
+ * <li>As a method return type, as an alternative to returning {@code null} to indicate
+ * that no value was available
+ * <li>To distinguish between "unknown" (for example, not present in a map) and "known to
+ * have no value" (present in the map, with value {@code Optional.absent()})
+ * <li>To wrap nullable references for storage in a collection that does not support
+ * {@code null} (though there are
+ * <a href="http://code.google.com/p/guava-libraries/wiki/LivingWithNullHostileCollections">
+ * several other approaches to this</a> that should be considered first)
+ * </ul>
+ *
+ * <p>A common alternative to using this class is to find or create a suitable
+ * <a href="http://en.wikipedia.org/wiki/Null_Object_pattern">null object</a> for the
+ * type in question.
+ *
+ * <p>This class is not intended as a direct analogue of any existing "option" or "maybe"
+ * construct from other programming environments, though it may bear some similarities.
+ *
+ * <p>See the Guava User Guide article on <a
+ * href="http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional">
+ * using {@code Optional}</a>.
+ *
+ * @param <T> the type of instance that can be contained. {@code Optional} is naturally
+ * covariant on this type, so it is safe to cast an {@code Optional<T>} to {@code
+ * Optional<S>} for any supertype {@code S} of {@code T}.
+ * @author Kurt Alfred Kluever
+ * @author Kevin Bourrillion
+ * @since 10.0
+ */
+@GwtCompatible(serializable = true)
+public abstract class Optional<T> implements Serializable {
+ /**
+ * Returns an {@code Optional} instance with no contained reference.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Optional<T> absent() {
+ return (Optional<T>) Absent.INSTANCE;
+ }
+
+ /**
+ * Returns an {@code Optional} instance containing the given non-null reference.
+ */
+ public static <T> Optional<T> of(T reference) {
+ return new Present<T>(checkNotNull(reference));
+ }
+
+ /**
+ * If {@code nullableReference} is non-null, returns an {@code Optional} instance containing that
+ * reference; otherwise returns {@link Optional#absent}.
+ */
+ public static <T> Optional<T> fromNullable(@Nullable T nullableReference) {
+ return (nullableReference == null)
+ ? Optional.<T>absent()
+ : new Present<T>(nullableReference);
+ }
+
+ Optional() {}
+
+ /**
+ * Returns {@code true} if this holder contains a (non-null) instance.
+ */
+ public abstract boolean isPresent();
+
+ /**
+ * Returns the contained instance, which must be present. If the instance might be
+ * absent, use {@link #or(Object)} or {@link #orNull} instead.
+ *
+ * @throws IllegalStateException if the instance is absent ({@link #isPresent} returns
+ * {@code false})
+ */
+ public abstract T get();
+
+ /**
+ * Returns the contained instance if it is present; {@code defaultValue} otherwise. If
+ * no default value should be required because the instance is known to be present, use
+ * {@link #get()} instead. For a default value of {@code null}, use {@link #orNull}.
+ *
+ * <p>Note about generics: The signature {@code public T or(T defaultValue)} is overly
+ * restrictive. However, the ideal signature, {@code public <S super T> S or(S)}, is not legal
+ * Java. As a result, some sensible operations involving subtypes are compile errors:
+ * <pre> {@code
+ *
+ * Optional<Integer> optionalInt = getSomeOptionalInt();
+ * Number value = optionalInt.or(0.5); // error
+ *
+ * FluentIterable<? extends Number> numbers = getSomeNumbers();
+ * Optional<? extends Number> first = numbers.first();
+ * Number value = first.or(0.5); // error}</pre>
+ *
+ * As a workaround, it is always safe to cast an {@code Optional<? extends T>} to {@code
+ * Optional<T>}. Casting either of the above example {@code Optional} instances to {@code
+ * Optional<Number>} (where {@code Number} is the desired output type) solves the problem:
+ * <pre> {@code
+ *
+ * Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
+ * Number value = optionalInt.or(0.5); // fine
+ *
+ * FluentIterable<? extends Number> numbers = getSomeNumbers();
+ * Optional<Number> first = (Optional) numbers.first();
+ * Number value = first.or(0.5); // fine}</pre>
+ */
+ public abstract T or(T defaultValue);
+
+ /**
+ * Returns this {@code Optional} if it has a value present; {@code secondChoice}
+ * otherwise.
+ */
+ @Beta
+ public abstract Optional<T> or(Optional<? extends T> secondChoice);
+
+ /**
+ * Returns the contained instance if it is present; {@code supplier.get()} otherwise. If the
+ * supplier returns {@code null}, a {@link NullPointerException} is thrown.
+ *
+ * @throws NullPointerException if the supplier returns {@code null}
+ */
+ @Beta
+ public abstract T or(Supplier<? extends T> supplier);
+
+ /**
+ * Returns the contained instance if it is present; {@code null} otherwise. If the
+ * instance is known to be present, use {@link #get()} instead.
+ */
+ @Nullable
+ public abstract T orNull();
+
+ /**
+ * Returns an immutable singleton {@link Set} whose only element is the contained instance
+ * if it is present; an empty immutable {@link Set} otherwise.
+ *
+ * @since 11.0
+ */
+ public abstract Set<T> asSet();
+
+ /**
+ * If the instance is present, it is transformed with the given {@link Function}; otherwise,
+ * {@link Optional#absent} is returned. If the function returns {@code null}, a
+ * {@link NullPointerException} is thrown.
+ *
+ * @throws NullPointerException if the function returns {@code null}
+ *
+ * @since 12.0
+ */
+ @Beta
+ public abstract <V> Optional<V> transform(Function<? super T, V> function);
+
+ /**
+ * Returns {@code true} if {@code object} is an {@code Optional} instance, and either
+ * the contained references are {@linkplain Object#equals equal} to each other or both
+ * are absent. Note that {@code Optional} instances of differing parameterized types can
+ * be equal.
+ */
+ @Override
+ public abstract boolean equals(@Nullable Object object);
+
+ /**
+ * Returns a hash code for this instance.
+ */
+ @Override
+ public abstract int hashCode();
+
+ /**
+ * Returns a string representation for this instance. The form of this string
+ * representation is unspecified.
+ */
+ @Override
+ public abstract String toString();
+
+ /**
+ * Returns the value of each present instance from the supplied {@code optionals}, in order,
+ * skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are
+ * evaluated lazily.
+ *
+ * @since 11.0 (generics widened in 13.0)
+ */
+ @Beta
+ public static <T> Iterable<T> presentInstances(
+ final Iterable<? extends Optional<? extends T>> optionals) {
+ checkNotNull(optionals);
+ return new Iterable<T>() {
+ @Override
+ public Iterator<T> iterator() {
+ return new AbstractIterator<T>() {
+ private final Iterator<? extends Optional<? extends T>> iterator =
+ checkNotNull(optionals.iterator());
+
+ @Override
+ protected T computeNext() {
+ while (iterator.hasNext()) {
+ Optional<? extends T> optional = iterator.next();
+ if (optional.isPresent()) {
+ return optional.get();
+ }
+ }
+ return endOfData();
+ }
+ };
+ };
+ };
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava/src/com/google/common/base/PairwiseEquivalence.java b/guava/src/com/google/common/base/PairwiseEquivalence.java
new file mode 100644
index 0000000..23ab539
--- /dev/null
+++ b/guava/src/com/google/common/base/PairwiseEquivalence.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import javax.annotation.Nullable;
+
+@GwtCompatible(serializable = true)
+final class PairwiseEquivalence<T> extends Equivalence<Iterable<T>>
+ implements Serializable {
+
+ final Equivalence<? super T> elementEquivalence;
+
+ PairwiseEquivalence(Equivalence<? super T> elementEquivalence) {
+ this.elementEquivalence = Preconditions.checkNotNull(elementEquivalence);
+ }
+
+ @Override
+ protected boolean doEquivalent(Iterable<T> iterableA, Iterable<T> iterableB) {
+ Iterator<T> iteratorA = iterableA.iterator();
+ Iterator<T> iteratorB = iterableB.iterator();
+
+ while (iteratorA.hasNext() && iteratorB.hasNext()) {
+ if (!elementEquivalence.equivalent(iteratorA.next(), iteratorB.next())) {
+ return false;
+ }
+ }
+
+ return !iteratorA.hasNext() && !iteratorB.hasNext();
+ }
+
+ @Override
+ protected int doHash(Iterable<T> iterable) {
+ int hash = 78721;
+ for (T element : iterable) {
+ hash = hash * 24943 + elementEquivalence.hash(element);
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ if (object instanceof PairwiseEquivalence) {
+ PairwiseEquivalence<?> that = (PairwiseEquivalence<?>) object;
+ return this.elementEquivalence.equals(that.elementEquivalence);
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return elementEquivalence.hashCode() ^ 0x46a3eb07;
+ }
+
+ @Override
+ public String toString() {
+ return elementEquivalence + ".pairwise()";
+ }
+
+ private static final long serialVersionUID = 1;
+}
diff --git a/guava/src/com/google/common/base/Platform.java b/guava/src/com/google/common/base/Platform.java
new file mode 100644
index 0000000..dcbe06c
--- /dev/null
+++ b/guava/src/com/google/common/base/Platform.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * Methods factored out so that they can be emulated differently in GWT.
+ *
+ * @author Jesse Wilson
+ */
+@GwtCompatible(emulated = true)
+final class Platform {
+ private Platform() {}
+
+ /** Returns a thread-local 1024-char array. */
+ static char[] charBufferFromThreadLocal() {
+ return DEST_TL.get();
+ }
+
+ /** Calls {@link System#nanoTime()}. */
+ static long systemNanoTime() {
+ return System.nanoTime();
+ }
+
+ /**
+ * A thread-local destination buffer to keep us from creating new buffers.
+ * The starting size is 1024 characters. If we grow past this we don't
+ * put it back in the threadlocal, we just keep going and grow as needed.
+ */
+ private static final ThreadLocal<char[]> DEST_TL = new ThreadLocal<char[]>() {
+ @Override
+ protected char[] initialValue() {
+ return new char[1024];
+ }
+ };
+
+ static CharMatcher precomputeCharMatcher(CharMatcher matcher) {
+ return matcher.precomputedInternal();
+ }
+}
diff --git a/guava/src/com/google/common/base/Preconditions.java b/guava/src/com/google/common/base/Preconditions.java
new file mode 100644
index 0000000..802a309
--- /dev/null
+++ b/guava/src/com/google/common/base/Preconditions.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+/**
+ * Simple static methods to be called at the start of your own methods to verify
+ * correct arguments and state. This allows constructs such as
+ * <pre>
+ * if (count <= 0) {
+ * throw new IllegalArgumentException("must be positive: " + count);
+ * }</pre>
+ *
+ * to be replaced with the more compact
+ * <pre>
+ * checkArgument(count > 0, "must be positive: %s", count);</pre>
+ *
+ * Note that the sense of the expression is inverted; with {@code Preconditions}
+ * you declare what you expect to be <i>true</i>, just as you do with an
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html">
+ * {@code assert}</a> or a JUnit {@code assertTrue} call.
+ *
+ * <p><b>Warning:</b> only the {@code "%s"} specifier is recognized as a
+ * placeholder in these messages, not the full range of {@link
+ * String#format(String, Object[])} specifiers.
+ *
+ * <p>Take care not to confuse precondition checking with other similar types
+ * of checks! Precondition exceptions -- including those provided here, but also
+ * {@link IndexOutOfBoundsException}, {@link NoSuchElementException}, {@link
+ * UnsupportedOperationException} and others -- are used to signal that the
+ * <i>calling method</i> has made an error. This tells the caller that it should
+ * not have invoked the method when it did, with the arguments it did, or
+ * perhaps ever. Postcondition or other invariant failures should not throw
+ * these types of exceptions.
+ *
+ * <p>See the Guava User Guide on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/PreconditionsExplained">
+ * using {@code Preconditions}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public final class Preconditions {
+ private Preconditions() {}
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(boolean expression) {
+ if (!expression) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(
+ boolean expression, @Nullable Object errorMessage) {
+ if (!expression) {
+ throw new IllegalArgumentException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @throws IllegalArgumentException if {@code expression} is false
+ * @throws NullPointerException if the check fails and either {@code
+ * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+ * this happen)
+ */
+ public static void checkArgument(boolean expression,
+ @Nullable String errorMessageTemplate,
+ @Nullable Object... errorMessageArgs) {
+ if (!expression) {
+ throw new IllegalArgumentException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(boolean expression) {
+ if (!expression) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(
+ boolean expression, @Nullable Object errorMessage) {
+ if (!expression) {
+ throw new IllegalStateException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @throws IllegalStateException if {@code expression} is false
+ * @throws NullPointerException if the check fails and either {@code
+ * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+ * this happen)
+ */
+ public static void checkState(boolean expression,
+ @Nullable String errorMessageTemplate,
+ @Nullable Object... errorMessageArgs) {
+ if (!expression) {
+ throw new IllegalStateException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference) {
+ if (reference == null) {
+ throw new NullPointerException();
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
+ if (reference == null) {
+ throw new NullPointerException(String.valueOf(errorMessage));
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference,
+ @Nullable String errorMessageTemplate,
+ @Nullable Object... errorMessageArgs) {
+ if (reference == null) {
+ // If either of these parameters is null, the right thing happens anyway
+ throw new NullPointerException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ return reference;
+ }
+
+ /*
+ * All recent hotspots (as of 2009) *really* like to have the natural code
+ *
+ * if (guardExpression) {
+ * throw new BadException(messageExpression);
+ * }
+ *
+ * refactored so that messageExpression is moved to a separate
+ * String-returning method.
+ *
+ * if (guardExpression) {
+ * throw new BadException(badMsg(...));
+ * }
+ *
+ * The alternative natural refactorings into void or Exception-returning
+ * methods are much slower. This is a big deal - we're talking factors of
+ * 2-8 in microbenchmarks, not just 10-20%. (This is a hotspot optimizer
+ * bug, which should be fixed, but that's a separate, big project).
+ *
+ * The coding pattern above is heavily used in java.util, e.g. in ArrayList.
+ * There is a RangeCheckMicroBenchmark in the JDK that was used to test this.
+ *
+ * But the methods in this class want to throw different exceptions,
+ * depending on the args, so it appears that this pattern is not directly
+ * applicable. But we can use the ridiculous, devious trick of throwing an
+ * exception in the middle of the construction of another exception.
+ * Hotspot is fine with that.
+ */
+
+ /**
+ * Ensures that {@code index} specifies a valid <i>element</i> in an array,
+ * list or string of size {@code size}. An element index may range from zero,
+ * inclusive, to {@code size}, exclusive.
+ *
+ * @param index a user-supplied index identifying an element of an array, list
+ * or string
+ * @param size the size of that array, list or string
+ * @return the value of {@code index}
+ * @throws IndexOutOfBoundsException if {@code index} is negative or is not
+ * less than {@code size}
+ * @throws IllegalArgumentException if {@code size} is negative
+ */
+ public static int checkElementIndex(int index, int size) {
+ return checkElementIndex(index, size, "index");
+ }
+
+ /**
+ * Ensures that {@code index} specifies a valid <i>element</i> in an array,
+ * list or string of size {@code size}. An element index may range from zero,
+ * inclusive, to {@code size}, exclusive.
+ *
+ * @param index a user-supplied index identifying an element of an array, list
+ * or string
+ * @param size the size of that array, list or string
+ * @param desc the text to use to describe this index in an error message
+ * @return the value of {@code index}
+ * @throws IndexOutOfBoundsException if {@code index} is negative or is not
+ * less than {@code size}
+ * @throws IllegalArgumentException if {@code size} is negative
+ */
+ public static int checkElementIndex(
+ int index, int size, @Nullable String desc) {
+ // Carefully optimized for execution by hotspot (explanatory comment above)
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
+ }
+ return index;
+ }
+
+ private static String badElementIndex(int index, int size, String desc) {
+ if (index < 0) {
+ return format("%s (%s) must not be negative", desc, index);
+ } else if (size < 0) {
+ throw new IllegalArgumentException("negative size: " + size);
+ } else { // index >= size
+ return format("%s (%s) must be less than size (%s)", desc, index, size);
+ }
+ }
+
+ /**
+ * Ensures that {@code index} specifies a valid <i>position</i> in an array,
+ * list or string of size {@code size}. A position index may range from zero
+ * to {@code size}, inclusive.
+ *
+ * @param index a user-supplied index identifying a position in an array, list
+ * or string
+ * @param size the size of that array, list or string
+ * @return the value of {@code index}
+ * @throws IndexOutOfBoundsException if {@code index} is negative or is
+ * greater than {@code size}
+ * @throws IllegalArgumentException if {@code size} is negative
+ */
+ public static int checkPositionIndex(int index, int size) {
+ return checkPositionIndex(index, size, "index");
+ }
+
+ /**
+ * Ensures that {@code index} specifies a valid <i>position</i> in an array,
+ * list or string of size {@code size}. A position index may range from zero
+ * to {@code size}, inclusive.
+ *
+ * @param index a user-supplied index identifying a position in an array, list
+ * or string
+ * @param size the size of that array, list or string
+ * @param desc the text to use to describe this index in an error message
+ * @return the value of {@code index}
+ * @throws IndexOutOfBoundsException if {@code index} is negative or is
+ * greater than {@code size}
+ * @throws IllegalArgumentException if {@code size} is negative
+ */
+ public static int checkPositionIndex(
+ int index, int size, @Nullable String desc) {
+ // Carefully optimized for execution by hotspot (explanatory comment above)
+ if (index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
+ }
+ return index;
+ }
+
+ private static String badPositionIndex(int index, int size, String desc) {
+ if (index < 0) {
+ return format("%s (%s) must not be negative", desc, index);
+ } else if (size < 0) {
+ throw new IllegalArgumentException("negative size: " + size);
+ } else { // index > size
+ return format("%s (%s) must not be greater than size (%s)",
+ desc, index, size);
+ }
+ }
+
+ /**
+ * Ensures that {@code start} and {@code end} specify a valid <i>positions</i>
+ * in an array, list or string of size {@code size}, and are in order. A
+ * position index may range from zero to {@code size}, inclusive.
+ *
+ * @param start a user-supplied index identifying a starting position in an
+ * array, list or string
+ * @param end a user-supplied index identifying a ending position in an array,
+ * list or string
+ * @param size the size of that array, list or string
+ * @throws IndexOutOfBoundsException if either index is negative or is
+ * greater than {@code size}, or if {@code end} is less than {@code start}
+ * @throws IllegalArgumentException if {@code size} is negative
+ */
+ public static void checkPositionIndexes(int start, int end, int size) {
+ // Carefully optimized for execution by hotspot (explanatory comment above)
+ if (start < 0 || end < start || end > size) {
+ throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
+ }
+ }
+
+ private static String badPositionIndexes(int start, int end, int size) {
+ if (start < 0 || start > size) {
+ return badPositionIndex(start, size, "start index");
+ }
+ if (end < 0 || end > size) {
+ return badPositionIndex(end, size, "end index");
+ }
+ // end < start
+ return format("end index (%s) must not be less than start index (%s)",
+ end, start);
+ }
+
+ /**
+ * Substitutes each {@code %s} in {@code template} with an argument. These
+ * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
+ * If there are more arguments than placeholders, the unmatched arguments will
+ * be appended to the end of the formatted message in square braces.
+ *
+ * @param template a non-null string containing 0 or more {@code %s}
+ * placeholders.
+ * @param args the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}. Arguments can be null.
+ */
+ @VisibleForTesting static String format(String template,
+ @Nullable Object... args) {
+ template = String.valueOf(template); // null -> "null"
+
+ // start substituting the arguments into the '%s' placeholders
+ StringBuilder builder = new StringBuilder(
+ template.length() + 16 * args.length);
+ int templateStart = 0;
+ int i = 0;
+ while (i < args.length) {
+ int placeholderStart = template.indexOf("%s", templateStart);
+ if (placeholderStart == -1) {
+ break;
+ }
+ builder.append(template.substring(templateStart, placeholderStart));
+ builder.append(args[i++]);
+ templateStart = placeholderStart + 2;
+ }
+ builder.append(template.substring(templateStart));
+
+ // if we run out of placeholders, append the extra args in square braces
+ if (i < args.length) {
+ builder.append(" [");
+ builder.append(args[i++]);
+ while (i < args.length) {
+ builder.append(", ");
+ builder.append(args[i++]);
+ }
+ builder.append(']');
+ }
+
+ return builder.toString();
+ }
+}
diff --git a/guava/src/com/google/common/base/Predicate.java b/guava/src/com/google/common/base/Predicate.java
new file mode 100644
index 0000000..89a8c36
--- /dev/null
+++ b/guava/src/com/google/common/base/Predicate.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * Determines a true or false value for a given input.
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
+ * Predicate}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public interface Predicate<T> {
+ /**
+ * Returns the result of applying this predicate to {@code input}. This method is <i>generally
+ * expected</i>, but not absolutely required, to have the following properties:
+ *
+ * <ul>
+ * <li>Its execution does not cause any observable side effects.
+ * <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
+ * Objects.equal}{@code (a, b)} implies that {@code predicate.apply(a) ==
+ * predicate.apply(b))}.
+ * </ul>
+ *
+ * @throws NullPointerException if {@code input} is null and this predicate does not accept null
+ * arguments
+ */
+ boolean apply(@Nullable T input);
+
+ /**
+ * Indicates whether another object is equal to this predicate.
+ *
+ * <p>Most implementations will have no reason to override the behavior of {@link Object#equals}.
+ * However, an implementation may also choose to return {@code true} whenever {@code object} is a
+ * {@link Predicate} that it considers <i>interchangeable</i> with this one. "Interchangeable"
+ * <i>typically</i> means that {@code this.apply(t) == that.apply(t)} for all {@code t} of type
+ * {@code T}). Note that a {@code false} result from this method does not imply that the
+ * predicates are known <i>not</i> to be interchangeable.
+ */
+ @Override
+ boolean equals(@Nullable Object object);
+}
diff --git a/guava/src/com/google/common/base/Predicates.java b/guava/src/com/google/common/base/Predicates.java
new file mode 100644
index 0000000..5c42c55
--- /dev/null
+++ b/guava/src/com/google/common/base/Predicates.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
+
+/**
+ * Static utility methods pertaining to {@code Predicate} instances.
+ *
+ * <p>All methods returns serializable predicates as long as they're given
+ * serializable parameters.
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the
+ * use of {@code Predicate}</a>.
+ *
+ * @author Kevin Bourrillion
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible(emulated = true)
+public final class Predicates {
+ private Predicates() {}
+
+ // TODO(kevinb): considering having these implement a VisitablePredicate
+ // interface which specifies an accept(PredicateVisitor) method.
+
+ /**
+ * Returns a predicate that always evaluates to {@code true}.
+ */
+ @GwtCompatible(serializable = true)
+ public static <T> Predicate<T> alwaysTrue() {
+ return ObjectPredicate.ALWAYS_TRUE.withNarrowedType();
+ }
+
+ /**
+ * Returns a predicate that always evaluates to {@code false}.
+ */
+ @GwtCompatible(serializable = true)
+ public static <T> Predicate<T> alwaysFalse() {
+ return ObjectPredicate.ALWAYS_FALSE.withNarrowedType();
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is null.
+ */
+ @GwtCompatible(serializable = true)
+ public static <T> Predicate<T> isNull() {
+ return ObjectPredicate.IS_NULL.withNarrowedType();
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is not null.
+ */
+ @GwtCompatible(serializable = true)
+ public static <T> Predicate<T> notNull() {
+ return ObjectPredicate.NOT_NULL.withNarrowedType();
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the given predicate
+ * evaluates to {@code false}.
+ */
+ public static <T> Predicate<T> not(Predicate<T> predicate) {
+ return new NotPredicate<T>(predicate);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if each of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found. It defensively copies the iterable passed in, so future
+ * changes to it won't alter the behavior of this predicate. If {@code
+ * components} is empty, the returned predicate will always evaluate to {@code
+ * true}.
+ */
+ public static <T> Predicate<T> and(
+ Iterable<? extends Predicate<? super T>> components) {
+ return new AndPredicate<T>(defensiveCopy(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if each of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found. It defensively copies the array passed in, so future
+ * changes to it won't alter the behavior of this predicate. If {@code
+ * components} is empty, the returned predicate will always evaluate to {@code
+ * true}.
+ */
+ public static <T> Predicate<T> and(Predicate<? super T>... components) {
+ return new AndPredicate<T>(defensiveCopy(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both of its
+ * components evaluate to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found.
+ */
+ public static <T> Predicate<T> and(Predicate<? super T> first,
+ Predicate<? super T> second) {
+ return new AndPredicate<T>(Predicates.<T>asList(
+ checkNotNull(first), checkNotNull(second)));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if any one of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a
+ * true predicate is found. It defensively copies the iterable passed in, so
+ * future changes to it won't alter the behavior of this predicate. If {@code
+ * components} is empty, the returned predicate will always evaluate to {@code
+ * false}.
+ */
+ public static <T> Predicate<T> or(
+ Iterable<? extends Predicate<? super T>> components) {
+ return new OrPredicate<T>(defensiveCopy(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if any one of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a
+ * true predicate is found. It defensively copies the array passed in, so
+ * future changes to it won't alter the behavior of this predicate. If {@code
+ * components} is empty, the returned predicate will always evaluate to {@code
+ * false}.
+ */
+ public static <T> Predicate<T> or(Predicate<? super T>... components) {
+ return new OrPredicate<T>(defensiveCopy(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if either of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a
+ * true predicate is found.
+ */
+ public static <T> Predicate<T> or(
+ Predicate<? super T> first, Predicate<? super T> second) {
+ return new OrPredicate<T>(Predicates.<T>asList(
+ checkNotNull(first), checkNotNull(second)));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object being
+ * tested {@code equals()} the given target or both are null.
+ */
+ public static <T> Predicate<T> equalTo(@Nullable T target) {
+ return (target == null)
+ ? Predicates.<T>isNull()
+ : new IsEqualToPredicate<T>(target);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object being
+ * tested is an instance of the given class. If the object being tested
+ * is {@code null} this predicate evaluates to {@code false}.
+ *
+ * <p>If you want to filter an {@code Iterable} to narrow its type, consider
+ * using {@link com.google.common.collect.Iterables#filter(Iterable, Class)}
+ * in preference.
+ *
+ * <p><b>Warning:</b> contrary to the typical assumptions about predicates (as
+ * documented at {@link Predicate#apply}), the returned predicate may not be
+ * <i>consistent with equals</i>. For example, {@code
+ * instanceOf(ArrayList.class)} will yield different results for the two equal
+ * instances {@code Lists.newArrayList(1)} and {@code Arrays.asList(1)}.
+ */
+ @GwtIncompatible("Class.isInstance")
+ public static Predicate<Object> instanceOf(Class<?> clazz) {
+ return new InstanceOfPredicate(clazz);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the class being
+ * tested is assignable from the given class. The returned predicate
+ * does not allow null inputs.
+ *
+ * @since 10.0
+ */
+ @GwtIncompatible("Class.isAssignableFrom")
+ @Beta
+ public static Predicate<Class<?>> assignableFrom(Class<?> clazz) {
+ return new AssignableFromPredicate(clazz);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is a member of the given collection. It does not defensively
+ * copy the collection passed in, so future changes to it will alter the
+ * behavior of the predicate.
+ *
+ * <p>This method can technically accept any {@code Collection<?>}, but using
+ * a typed collection helps prevent bugs. This approach doesn't block any
+ * potential users since it is always possible to use {@code
+ * Predicates.<Object>in()}.
+ *
+ * @param target the collection that may contain the function input
+ */
+ public static <T> Predicate<T> in(Collection<? extends T> target) {
+ return new InPredicate<T>(target);
+ }
+
+ /**
+ * Returns the composition of a function and a predicate. For every {@code x},
+ * the generated predicate returns {@code predicate(function(x))}.
+ *
+ * @return the composition of the provided function and predicate
+ */
+ public static <A, B> Predicate<A> compose(
+ Predicate<B> predicate, Function<A, ? extends B> function) {
+ return new CompositionPredicate<A, B>(predicate, function);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the
+ * {@code CharSequence} being tested contains any match for the given
+ * regular expression pattern. The test used is equivalent to
+ * {@code Pattern.compile(pattern).matcher(arg).find()}
+ *
+ * @throws java.util.regex.PatternSyntaxException if the pattern is invalid
+ * @since 3.0
+ */
+ @GwtIncompatible(value = "java.util.regex.Pattern")
+ public static Predicate<CharSequence> containsPattern(String pattern) {
+ return new ContainsPatternPredicate(pattern);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the
+ * {@code CharSequence} being tested contains any match for the given
+ * regular expression pattern. The test used is equivalent to
+ * {@code pattern.matcher(arg).find()}
+ *
+ * @since 3.0
+ */
+ @GwtIncompatible(value = "java.util.regex.Pattern")
+ public static Predicate<CharSequence> contains(Pattern pattern) {
+ return new ContainsPatternPredicate(pattern);
+ }
+
+ // End public API, begin private implementation classes.
+
+ // Package private for GWT serialization.
+ enum ObjectPredicate implements Predicate<Object> {
+ ALWAYS_TRUE {
+ @Override public boolean apply(@Nullable Object o) {
+ return true;
+ }
+ },
+ ALWAYS_FALSE {
+ @Override public boolean apply(@Nullable Object o) {
+ return false;
+ }
+ },
+ IS_NULL {
+ @Override public boolean apply(@Nullable Object o) {
+ return o == null;
+ }
+ },
+ NOT_NULL {
+ @Override public boolean apply(@Nullable Object o) {
+ return o != null;
+ }
+ };
+
+ @SuppressWarnings("unchecked") // these Object predicates work for any T
+ <T> Predicate<T> withNarrowedType() {
+ return (Predicate<T>) this;
+ }
+ }
+
+ /** @see Predicates#not(Predicate) */
+ private static class NotPredicate<T> implements Predicate<T>, Serializable {
+ final Predicate<T> predicate;
+
+ NotPredicate(Predicate<T> predicate) {
+ this.predicate = checkNotNull(predicate);
+ }
+ @Override
+ public boolean apply(T t) {
+ return !predicate.apply(t);
+ }
+ @Override public int hashCode() {
+ return ~predicate.hashCode();
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof NotPredicate) {
+ NotPredicate<?> that = (NotPredicate<?>) obj;
+ return predicate.equals(that.predicate);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "Not(" + predicate.toString() + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private static final Joiner COMMA_JOINER = Joiner.on(",");
+
+ /** @see Predicates#and(Iterable) */
+ private static class AndPredicate<T> implements Predicate<T>, Serializable {
+ private final List<? extends Predicate<? super T>> components;
+
+ private AndPredicate(List<? extends Predicate<? super T>> components) {
+ this.components = components;
+ }
+ @Override
+ public boolean apply(T t) {
+ // Avoid using the Iterator to avoid generating garbage (issue 820).
+ for (int i = 0; i < components.size(); i++) {
+ if (!components.get(i).apply(t)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ @Override public int hashCode() {
+ // add a random number to avoid collisions with OrPredicate
+ return components.hashCode() + 0x12472c2c;
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof AndPredicate) {
+ AndPredicate<?> that = (AndPredicate<?>) obj;
+ return components.equals(that.components);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "And(" + COMMA_JOINER.join(components) + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#or(Iterable) */
+ private static class OrPredicate<T> implements Predicate<T>, Serializable {
+ private final List<? extends Predicate<? super T>> components;
+
+ private OrPredicate(List<? extends Predicate<? super T>> components) {
+ this.components = components;
+ }
+ @Override
+ public boolean apply(T t) {
+ // Avoid using the Iterator to avoid generating garbage (issue 820).
+ for (int i = 0; i < components.size(); i++) {
+ if (components.get(i).apply(t)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ // add a random number to avoid collisions with AndPredicate
+ return components.hashCode() + 0x053c91cf;
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof OrPredicate) {
+ OrPredicate<?> that = (OrPredicate<?>) obj;
+ return components.equals(that.components);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "Or(" + COMMA_JOINER.join(components) + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#equalTo(Object) */
+ private static class IsEqualToPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final T target;
+
+ private IsEqualToPredicate(T target) {
+ this.target = target;
+ }
+ @Override
+ public boolean apply(T t) {
+ return target.equals(t);
+ }
+ @Override public int hashCode() {
+ return target.hashCode();
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof IsEqualToPredicate) {
+ IsEqualToPredicate<?> that = (IsEqualToPredicate<?>) obj;
+ return target.equals(that.target);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "IsEqualTo(" + target + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#instanceOf(Class) */
+ @GwtIncompatible("Class.isInstance")
+ private static class InstanceOfPredicate
+ implements Predicate<Object>, Serializable {
+ private final Class<?> clazz;
+
+ private InstanceOfPredicate(Class<?> clazz) {
+ this.clazz = checkNotNull(clazz);
+ }
+ @Override
+ public boolean apply(@Nullable Object o) {
+ return clazz.isInstance(o);
+ }
+ @Override public int hashCode() {
+ return clazz.hashCode();
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof InstanceOfPredicate) {
+ InstanceOfPredicate that = (InstanceOfPredicate) obj;
+ return clazz == that.clazz;
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "IsInstanceOf(" + clazz.getName() + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#assignableFrom(Class) */
+ @GwtIncompatible("Class.isAssignableFrom")
+ private static class AssignableFromPredicate
+ implements Predicate<Class<?>>, Serializable {
+ private final Class<?> clazz;
+
+ private AssignableFromPredicate(Class<?> clazz) {
+ this.clazz = checkNotNull(clazz);
+ }
+ @Override
+ public boolean apply(Class<?> input) {
+ return clazz.isAssignableFrom(input);
+ }
+ @Override public int hashCode() {
+ return clazz.hashCode();
+ }
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof AssignableFromPredicate) {
+ AssignableFromPredicate that = (AssignableFromPredicate) obj;
+ return clazz == that.clazz;
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "IsAssignableFrom(" + clazz.getName() + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#in(Collection) */
+ private static class InPredicate<T> implements Predicate<T>, Serializable {
+ private final Collection<?> target;
+
+ private InPredicate(Collection<?> target) {
+ this.target = checkNotNull(target);
+ }
+
+ @Override
+ public boolean apply(T t) {
+ try {
+ return target.contains(t);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof InPredicate) {
+ InPredicate<?> that = (InPredicate<?>) obj;
+ return target.equals(that.target);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return target.hashCode();
+ }
+
+ @Override public String toString() {
+ return "In(" + target + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#compose(Predicate, Function) */
+ private static class CompositionPredicate<A, B>
+ implements Predicate<A>, Serializable {
+ final Predicate<B> p;
+ final Function<A, ? extends B> f;
+
+ private CompositionPredicate(Predicate<B> p, Function<A, ? extends B> f) {
+ this.p = checkNotNull(p);
+ this.f = checkNotNull(f);
+ }
+
+ @Override
+ public boolean apply(A a) {
+ return p.apply(f.apply(a));
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof CompositionPredicate) {
+ CompositionPredicate<?, ?> that = (CompositionPredicate<?, ?>) obj;
+ return f.equals(that.f) && p.equals(that.p);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return f.hashCode() ^ p.hashCode();
+ }
+
+ @Override public String toString() {
+ return p.toString() + "(" + f.toString() + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * @see Predicates#contains(Pattern)
+ * @see Predicates#containsPattern(String)
+ */
+ @GwtIncompatible("Only used by other GWT-incompatible code.")
+ private static class ContainsPatternPredicate
+ implements Predicate<CharSequence>, Serializable {
+ final Pattern pattern;
+
+ ContainsPatternPredicate(Pattern pattern) {
+ this.pattern = checkNotNull(pattern);
+ }
+
+ ContainsPatternPredicate(String patternStr) {
+ this(Pattern.compile(patternStr));
+ }
+
+ @Override
+ public boolean apply(CharSequence t) {
+ return pattern.matcher(t).find();
+ }
+
+ @Override public int hashCode() {
+ // Pattern uses Object.hashCode, so we have to reach
+ // inside to build a hashCode consistent with equals.
+
+ return Objects.hashCode(pattern.pattern(), pattern.flags());
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof ContainsPatternPredicate) {
+ ContainsPatternPredicate that = (ContainsPatternPredicate) obj;
+
+ // Pattern uses Object (identity) equality, so we have to reach
+ // inside to compare individual fields.
+ return Objects.equal(pattern.pattern(), that.pattern.pattern())
+ && Objects.equal(pattern.flags(), that.pattern.flags());
+ }
+ return false;
+ }
+
+ @Override public String toString() {
+ return Objects.toStringHelper(this)
+ .add("pattern", pattern)
+ .add("pattern.flags", Integer.toHexString(pattern.flags()))
+ .toString();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> List<Predicate<? super T>> asList(
+ Predicate<? super T> first, Predicate<? super T> second) {
+ return Arrays.<Predicate<? super T>>asList(first, second);
+ }
+
+ private static <T> List<T> defensiveCopy(T... array) {
+ return defensiveCopy(Arrays.asList(array));
+ }
+
+ static <T> List<T> defensiveCopy(Iterable<T> iterable) {
+ ArrayList<T> list = new ArrayList<T>();
+ for (T element : iterable) {
+ list.add(checkNotNull(element));
+ }
+ return list;
+ }
+}
diff --git a/guava/src/com/google/common/base/Present.java b/guava/src/com/google/common/base/Present.java
new file mode 100644
index 0000000..aa1ddc5
--- /dev/null
+++ b/guava/src/com/google/common/base/Present.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * Implementation of an {@link Optional} containing a reference.
+ */
+@GwtCompatible
+final class Present<T> extends Optional<T> {
+ private final T reference;
+
+ Present(T reference) {
+ this.reference = reference;
+ }
+
+ @Override public boolean isPresent() {
+ return true;
+ }
+
+ @Override public T get() {
+ return reference;
+ }
+
+ @Override public T or(T defaultValue) {
+ checkNotNull(defaultValue, "use orNull() instead of or(null)");
+ return reference;
+ }
+
+ @Override public Optional<T> or(Optional<? extends T> secondChoice) {
+ checkNotNull(secondChoice);
+ return this;
+ }
+
+ @Override public T or(Supplier<? extends T> supplier) {
+ checkNotNull(supplier);
+ return reference;
+ }
+
+ @Override public T orNull() {
+ return reference;
+ }
+
+ @Override public Set<T> asSet() {
+ return Collections.singleton(reference);
+ }
+
+ @Override public <V> Optional<V> transform(Function<? super T, V> function) {
+ return new Present<V>(checkNotNull(function.apply(reference),
+ "Transformation function cannot return null."));
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Present) {
+ Present<?> other = (Present<?>) object;
+ return reference.equals(other.reference);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return 0x598df91c + reference.hashCode();
+ }
+
+ @Override public String toString() {
+ return "Optional.of(" + reference + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava/src/com/google/common/base/SmallCharMatcher.java b/guava/src/com/google/common/base/SmallCharMatcher.java
new file mode 100644
index 0000000..b62a488
--- /dev/null
+++ b/guava/src/com/google/common/base/SmallCharMatcher.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * An immutable small version of CharMatcher that uses an efficient hash table implementation, with
+ * non-power-of-2 sizing to try to use no reprobing, if possible.
+ *
+ * @author Christopher Swenson
+ */
+@GwtCompatible
+final class SmallCharMatcher extends CharMatcher {
+ static final int MAX_SIZE = 63;
+ static final int MAX_TABLE_SIZE = 128;
+ private final boolean reprobe;
+ private final char[] table;
+ private final boolean containsZero;
+ final long filter;
+
+ private SmallCharMatcher(char[] table, long filter, boolean containsZero,
+ boolean reprobe, String description) {
+ super(description);
+ this.table = table;
+ this.filter = filter;
+ this.containsZero = containsZero;
+ this.reprobe = reprobe;
+ }
+
+ private boolean checkFilter(int c) {
+ return 1 == (1 & (filter >> c));
+ }
+
+ @Override
+ public CharMatcher precomputed() {
+ return this;
+ }
+
+ @VisibleForTesting
+ static char[] buildTable(int modulus, char[] allChars, boolean reprobe) {
+ char[] table = new char[modulus];
+ for (int i = 0; i < allChars.length; i++) {
+ char c = allChars[i];
+ int index = c % modulus;
+ if (index < 0) {
+ index += modulus;
+ }
+ if ((table[index] != 0) && !reprobe) {
+ return null;
+ } else if (reprobe) {
+ while (table[index] != 0) {
+ index = (index + 1) % modulus;
+ }
+ }
+ table[index] = c;
+ }
+ return table;
+ }
+
+ static CharMatcher from(char[] chars, String description) {
+ long filter = 0;
+ int size = chars.length;
+ boolean containsZero = false;
+ boolean reprobe = false;
+ containsZero = chars[0] == 0;
+
+ // Compute the filter.
+ for (char c : chars) {
+ filter |= 1L << c;
+ }
+ char[] table = null;
+ for (int i = size; i < MAX_TABLE_SIZE; i++) {
+ table = buildTable(i, chars, false);
+ if (table != null) {
+ break;
+ }
+ }
+ // Compute the hash table.
+ if (table == null) {
+ table = buildTable(MAX_TABLE_SIZE, chars, true);
+ reprobe = true;
+ }
+ return new SmallCharMatcher(table, filter, containsZero, reprobe, description);
+ }
+
+ @Override
+ public boolean matches(char c) {
+ if (c == 0) {
+ return containsZero;
+ }
+ if (!checkFilter(c)) {
+ return false;
+ }
+ int index = c % table.length;
+ if (index < 0) {
+ index += table.length;
+ }
+ while (true) {
+ // Check for empty.
+ if (table[index] == 0) {
+ return false;
+ } else if (table[index] == c) {
+ return true;
+ } else if (reprobe) {
+ // Linear probing will terminate eventually.
+ index = (index + 1) % table.length;
+ } else {
+ return false;
+ }
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Splitter.java b/guava/src/com/google/common/base/Splitter.java
new file mode 100644
index 0000000..a1c236c
--- /dev/null
+++ b/guava/src/com/google/common/base/Splitter.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2009 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.CheckReturnValue;
+
+/**
+ * An object that divides strings (or other instances of {@code CharSequence})
+ * into substrings, by recognizing a <i>separator</i> (a.k.a. "delimiter")
+ * which can be expressed as a single character, literal string, regular
+ * expression, {@code CharMatcher}, or by using a fixed substring length. This
+ * class provides the complementary functionality to {@link Joiner}.
+ *
+ * <p>Here is the most basic example of {@code Splitter} usage: <pre> {@code
+ *
+ * Splitter.on(',').split("foo,bar")}</pre>
+ *
+ * This invocation returns an {@code Iterable<String>} containing {@code "foo"}
+ * and {@code "bar"}, in that order.
+ *
+ * <p>By default {@code Splitter}'s behavior is very simplistic: <pre> {@code
+ *
+ * Splitter.on(',').split("foo,,bar, quux")}</pre>
+ *
+ * This returns an iterable containing {@code ["foo", "", "bar", " quux"]}.
+ * Notice that the splitter does not assume that you want empty strings removed,
+ * or that you wish to trim whitespace. If you want features like these, simply
+ * ask for them: <pre> {@code
+ *
+ * private static final Splitter MY_SPLITTER = Splitter.on(',')
+ * .trimResults()
+ * .omitEmptyStrings();}</pre>
+ *
+ * Now {@code MY_SPLITTER.split("foo, ,bar, quux,")} returns an iterable
+ * containing just {@code ["foo", "bar", "quux"]}. Note that the order in which
+ * the configuration methods are called is never significant; for instance,
+ * trimming is always applied first before checking for an empty result,
+ * regardless of the order in which the {@link #trimResults()} and
+ * {@link #omitEmptyStrings()} methods were invoked.
+ *
+ * <p><b>Warning: splitter instances are always immutable</b>; a configuration
+ * method such as {@code omitEmptyStrings} has no effect on the instance it
+ * is invoked on! You must store and use the new splitter instance returned by
+ * the method. This makes splitters thread-safe, and safe to store as {@code
+ * static final} constants (as illustrated above). <pre> {@code
+ *
+ * // Bad! Do not do this!
+ * Splitter splitter = Splitter.on('/');
+ * splitter.trimResults(); // does nothing!
+ * return splitter.split("wrong / wrong / wrong");}</pre>
+ *
+ * The separator recognized by the splitter does not have to be a single
+ * literal character as in the examples above. See the methods {@link
+ * #on(String)}, {@link #on(Pattern)} and {@link #on(CharMatcher)} for examples
+ * of other ways to specify separators.
+ *
+ * <p><b>Note:</b> this class does not mimic any of the quirky behaviors of
+ * similar JDK methods; for instance, it does not silently discard trailing
+ * separators, as does {@link String#split(String)}, nor does it have a default
+ * behavior of using five particular whitespace characters as separators, like
+ * {@link java.util.StringTokenizer}.
+ *
+ * <p>See the Guava User Guide article on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#Splitter">
+ * {@code Splitter}</a>.
+ *
+ * @author Julien Silland
+ * @author Jesse Wilson
+ * @author Kevin Bourrillion
+ * @author Louis Wasserman
+ * @since 1.0
+ */
+@GwtCompatible(emulated = true)
+public final class Splitter {
+ private final CharMatcher trimmer;
+ private final boolean omitEmptyStrings;
+ private final Strategy strategy;
+ private final int limit;
+
+ private Splitter(Strategy strategy) {
+ this(strategy, false, CharMatcher.NONE, Integer.MAX_VALUE);
+ }
+
+ private Splitter(Strategy strategy, boolean omitEmptyStrings,
+ CharMatcher trimmer, int limit) {
+ this.strategy = strategy;
+ this.omitEmptyStrings = omitEmptyStrings;
+ this.trimmer = trimmer;
+ this.limit = limit;
+ }
+
+ /**
+ * Returns a splitter that uses the given single-character separator. For
+ * example, {@code Splitter.on(',').split("foo,,bar")} returns an iterable
+ * containing {@code ["foo", "", "bar"]}.
+ *
+ * @param separator the character to recognize as a separator
+ * @return a splitter, with default settings, that recognizes that separator
+ */
+ public static Splitter on(char separator) {
+ return on(CharMatcher.is(separator));
+ }
+
+ /**
+ * Returns a splitter that considers any single character matched by the
+ * given {@code CharMatcher} to be a separator. For example, {@code
+ * Splitter.on(CharMatcher.anyOf(";,")).split("foo,;bar,quux")} returns an
+ * iterable containing {@code ["foo", "", "bar", "quux"]}.
+ *
+ * @param separatorMatcher a {@link CharMatcher} that determines whether a
+ * character is a separator
+ * @return a splitter, with default settings, that uses this matcher
+ */
+ public static Splitter on(final CharMatcher separatorMatcher) {
+ checkNotNull(separatorMatcher);
+
+ return new Splitter(new Strategy() {
+ @Override public SplittingIterator iterator(
+ Splitter splitter, final CharSequence toSplit) {
+ return new SplittingIterator(splitter, toSplit) {
+ @Override int separatorStart(int start) {
+ return separatorMatcher.indexIn(toSplit, start);
+ }
+
+ @Override int separatorEnd(int separatorPosition) {
+ return separatorPosition + 1;
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * Returns a splitter that uses the given fixed string as a separator. For
+ * example, {@code Splitter.on(", ").split("foo, bar, baz,qux")} returns an
+ * iterable containing {@code ["foo", "bar", "baz,qux"]}.
+ *
+ * @param separator the literal, nonempty string to recognize as a separator
+ * @return a splitter, with default settings, that recognizes that separator
+ */
+ public static Splitter on(final String separator) {
+ checkArgument(separator.length() != 0,
+ "The separator may not be the empty string.");
+
+ return new Splitter(new Strategy() {
+ @Override public SplittingIterator iterator(
+ Splitter splitter, CharSequence toSplit) {
+ return new SplittingIterator(splitter, toSplit) {
+ @Override public int separatorStart(int start) {
+ int delimeterLength = separator.length();
+
+ positions:
+ for (int p = start, last = toSplit.length() - delimeterLength;
+ p <= last; p++) {
+ for (int i = 0; i < delimeterLength; i++) {
+ if (toSplit.charAt(i + p) != separator.charAt(i)) {
+ continue positions;
+ }
+ }
+ return p;
+ }
+ return -1;
+ }
+
+ @Override public int separatorEnd(int separatorPosition) {
+ return separatorPosition + separator.length();
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * Returns a splitter that considers any subsequence matching {@code
+ * pattern} to be a separator. For example, {@code
+ * Splitter.on(Pattern.compile("\r?\n")).split(entireFile)} splits a string
+ * into lines whether it uses DOS-style or UNIX-style line terminators.
+ *
+ * @param separatorPattern the pattern that determines whether a subsequence
+ * is a separator. This pattern may not match the empty string.
+ * @return a splitter, with default settings, that uses this pattern
+ * @throws IllegalArgumentException if {@code separatorPattern} matches the
+ * empty string
+ */
+ @GwtIncompatible("java.util.regex")
+ public static Splitter on(final Pattern separatorPattern) {
+ checkNotNull(separatorPattern);
+ checkArgument(!separatorPattern.matcher("").matches(),
+ "The pattern may not match the empty string: %s", separatorPattern);
+
+ return new Splitter(new Strategy() {
+ @Override public SplittingIterator iterator(
+ final Splitter splitter, CharSequence toSplit) {
+ final Matcher matcher = separatorPattern.matcher(toSplit);
+ return new SplittingIterator(splitter, toSplit) {
+ @Override public int separatorStart(int start) {
+ return matcher.find(start) ? matcher.start() : -1;
+ }
+
+ @Override public int separatorEnd(int separatorPosition) {
+ return matcher.end();
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * Returns a splitter that considers any subsequence matching a given
+ * pattern (regular expression) to be a separator. For example, {@code
+ * Splitter.onPattern("\r?\n").split(entireFile)} splits a string into lines
+ * whether it uses DOS-style or UNIX-style line terminators. This is
+ * equivalent to {@code Splitter.on(Pattern.compile(pattern))}.
+ *
+ * @param separatorPattern the pattern that determines whether a subsequence
+ * is a separator. This pattern may not match the empty string.
+ * @return a splitter, with default settings, that uses this pattern
+ * @throws java.util.regex.PatternSyntaxException if {@code separatorPattern}
+ * is a malformed expression
+ * @throws IllegalArgumentException if {@code separatorPattern} matches the
+ * empty string
+ */
+ @GwtIncompatible("java.util.regex")
+ public static Splitter onPattern(String separatorPattern) {
+ return on(Pattern.compile(separatorPattern));
+ }
+
+ /**
+ * Returns a splitter that divides strings into pieces of the given length.
+ * For example, {@code Splitter.fixedLength(2).split("abcde")} returns an
+ * iterable containing {@code ["ab", "cd", "e"]}. The last piece can be
+ * smaller than {@code length} but will never be empty.
+ *
+ * @param length the desired length of pieces after splitting
+ * @return a splitter, with default settings, that can split into fixed sized
+ * pieces
+ */
+ public static Splitter fixedLength(final int length) {
+ checkArgument(length > 0, "The length may not be less than 1");
+
+ return new Splitter(new Strategy() {
+ @Override public SplittingIterator iterator(
+ final Splitter splitter, CharSequence toSplit) {
+ return new SplittingIterator(splitter, toSplit) {
+ @Override public int separatorStart(int start) {
+ int nextChunkStart = start + length;
+ return (nextChunkStart < toSplit.length() ? nextChunkStart : -1);
+ }
+
+ @Override public int separatorEnd(int separatorPosition) {
+ return separatorPosition;
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * Returns a splitter that behaves equivalently to {@code this} splitter, but
+ * automatically omits empty strings from the results. For example, {@code
+ * Splitter.on(',').omitEmptyStrings().split(",a,,,b,c,,")} returns an
+ * iterable containing only {@code ["a", "b", "c"]}.
+ *
+ * <p>If either {@code trimResults} option is also specified when creating a
+ * splitter, that splitter always trims results first before checking for
+ * emptiness. So, for example, {@code
+ * Splitter.on(':').omitEmptyStrings().trimResults().split(": : : ")} returns
+ * an empty iterable.
+ *
+ * <p>Note that it is ordinarily not possible for {@link #split(CharSequence)}
+ * to return an empty iterable, but when using this option, it can (if the
+ * input sequence consists of nothing but separators).
+ *
+ * @return a splitter with the desired configuration
+ */
+ @CheckReturnValue
+ public Splitter omitEmptyStrings() {
+ return new Splitter(strategy, true, trimmer, limit);
+ }
+
+ /**
+ * Returns a splitter that behaves equivalently to {@code this} splitter but
+ * stops splitting after it reaches the limit.
+ * The limit defines the maximum number of items returned by the iterator.
+ *
+ * <p>For example,
+ * {@code Splitter.on(',').limit(3).split("a,b,c,d")} returns an iterable
+ * containing {@code ["a", "b", "c,d"]}. When omitting empty strings, the
+ * omitted strings do no count. Hence,
+ * {@code Splitter.on(',').limit(3).omitEmptyStrings().split("a,,,b,,,c,d")}
+ * returns an iterable containing {@code ["a", "b", "c,d"}.
+ * When trim is requested, all entries, including the last are trimmed. Hence
+ * {@code Splitter.on(',').limit(3).trimResults().split(" a , b , c , d ")}
+ * results in @{code ["a", "b", "c , d"]}.
+ *
+ * @param limit the maximum number of items returns
+ * @return a splitter with the desired configuration
+ * @since 9.0
+ */
+ @CheckReturnValue
+ public Splitter limit(int limit) {
+ checkArgument(limit > 0, "must be greater than zero: %s", limit);
+ return new Splitter(strategy, omitEmptyStrings, trimmer, limit);
+ }
+
+ /**
+ * Returns a splitter that behaves equivalently to {@code this} splitter, but
+ * automatically removes leading and trailing {@linkplain
+ * CharMatcher#WHITESPACE whitespace} from each returned substring; equivalent
+ * to {@code trimResults(CharMatcher.WHITESPACE)}. For example, {@code
+ * Splitter.on(',').trimResults().split(" a, b ,c ")} returns an iterable
+ * containing {@code ["a", "b", "c"]}.
+ *
+ * @return a splitter with the desired configuration
+ */
+ @CheckReturnValue
+ public Splitter trimResults() {
+ return trimResults(CharMatcher.WHITESPACE);
+ }
+
+ /**
+ * Returns a splitter that behaves equivalently to {@code this} splitter, but
+ * removes all leading or trailing characters matching the given {@code
+ * CharMatcher} from each returned substring. For example, {@code
+ * Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__")}
+ * returns an iterable containing {@code ["a ", "b_ ", "c"]}.
+ *
+ * @param trimmer a {@link CharMatcher} that determines whether a character
+ * should be removed from the beginning/end of a subsequence
+ * @return a splitter with the desired configuration
+ */
+ // TODO(kevinb): throw if a trimmer was already specified!
+ @CheckReturnValue
+ public Splitter trimResults(CharMatcher trimmer) {
+ checkNotNull(trimmer);
+ return new Splitter(strategy, omitEmptyStrings, trimmer, limit);
+ }
+
+ /**
+ * Splits {@code sequence} into string components and makes them available
+ * through an {@link Iterator}, which may be lazily evaluated.
+ *
+ * @param sequence the sequence of characters to split
+ * @return an iteration over the segments split from the parameter.
+ */
+ public Iterable<String> split(final CharSequence sequence) {
+ checkNotNull(sequence);
+
+ return new Iterable<String>() {
+ @Override public Iterator<String> iterator() {
+ return spliterator(sequence);
+ }
+ @Override public String toString() {
+ return Joiner.on(", ")
+ .appendTo(new StringBuilder().append('['), this)
+ .append(']')
+ .toString();
+ }
+ };
+ }
+
+ private Iterator<String> spliterator(CharSequence sequence) {
+ return strategy.iterator(this, sequence);
+ }
+
+ /**
+ * Returns a {@code MapSplitter} which splits entries based on this splitter,
+ * and splits entries into keys and values using the specified separator.
+ *
+ * @since 10.0
+ */
+ @CheckReturnValue
+ @Beta
+ public MapSplitter withKeyValueSeparator(String separator) {
+ return withKeyValueSeparator(on(separator));
+ }
+
+ /**
+ * Returns a {@code MapSplitter} which splits entries based on this splitter,
+ * and splits entries into keys and values using the specified key-value
+ * splitter.
+ *
+ * @since 10.0
+ */
+ @CheckReturnValue
+ @Beta
+ public MapSplitter withKeyValueSeparator(Splitter keyValueSplitter) {
+ return new MapSplitter(this, keyValueSplitter);
+ }
+
+ /**
+ * An object that splits strings into maps as {@code Splitter} splits
+ * iterables and lists. Like {@code Splitter}, it is thread-safe and
+ * immutable.
+ *
+ * @since 10.0
+ */
+ @Beta
+ public static final class MapSplitter {
+ private static final String INVALID_ENTRY_MESSAGE =
+ "Chunk [%s] is not a valid entry";
+ private final Splitter outerSplitter;
+ private final Splitter entrySplitter;
+
+ private MapSplitter(Splitter outerSplitter, Splitter entrySplitter) {
+ this.outerSplitter = outerSplitter; // only "this" is passed
+ this.entrySplitter = checkNotNull(entrySplitter);
+ }
+
+ /**
+ * Splits {@code sequence} into substrings, splits each substring into
+ * an entry, and returns an unmodifiable map with each of the entries. For
+ * example, <code>
+ * Splitter.on(';').trimResults().withKeyValueSeparator("=>")
+ * .split("a=>b ; c=>b")
+ * </code> will return a mapping from {@code "a"} to {@code "b"} and
+ * {@code "c"} to {@code b}.
+ *
+ * <p>The returned map preserves the order of the entries from
+ * {@code sequence}.
+ *
+ * @throws IllegalArgumentException if the specified sequence does not split
+ * into valid map entries, or if there are duplicate keys
+ */
+ public Map<String, String> split(CharSequence sequence) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ for (String entry : outerSplitter.split(sequence)) {
+ Iterator<String> entryFields = entrySplitter.spliterator(entry);
+
+ checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
+ String key = entryFields.next();
+ checkArgument(!map.containsKey(key), "Duplicate key [%s] found.", key);
+
+ checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
+ String value = entryFields.next();
+ map.put(key, value);
+
+ checkArgument(!entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
+ }
+ return Collections.unmodifiableMap(map);
+ }
+ }
+
+ private interface Strategy {
+ Iterator<String> iterator(Splitter splitter, CharSequence toSplit);
+ }
+
+ private abstract static class SplittingIterator extends AbstractIterator<String> {
+ final CharSequence toSplit;
+ final CharMatcher trimmer;
+ final boolean omitEmptyStrings;
+
+ /**
+ * Returns the first index in {@code toSplit} at or after {@code start}
+ * that contains the separator.
+ */
+ abstract int separatorStart(int start);
+
+ /**
+ * Returns the first index in {@code toSplit} after {@code
+ * separatorPosition} that does not contain a separator. This method is only
+ * invoked after a call to {@code separatorStart}.
+ */
+ abstract int separatorEnd(int separatorPosition);
+
+ int offset = 0;
+ int limit;
+
+ protected SplittingIterator(Splitter splitter, CharSequence toSplit) {
+ this.trimmer = splitter.trimmer;
+ this.omitEmptyStrings = splitter.omitEmptyStrings;
+ this.limit = splitter.limit;
+ this.toSplit = toSplit;
+ }
+
+ @Override protected String computeNext() {
+ /*
+ * The returned string will be from the end of the last match to the
+ * beginning of the next one. nextStart is the start position of the
+ * returned substring, while offset is the place to start looking for a
+ * separator.
+ */
+ int nextStart = offset;
+ while (offset != -1) {
+ int start = nextStart;
+ int end;
+
+ int separatorPosition = separatorStart(offset);
+ if (separatorPosition == -1) {
+ end = toSplit.length();
+ offset = -1;
+ } else {
+ end = separatorPosition;
+ offset = separatorEnd(separatorPosition);
+ }
+ if (offset == nextStart) {
+ /*
+ * This occurs when some pattern has an empty match, even if it
+ * doesn't match the empty string -- for example, if it requires
+ * lookahead or the like. The offset must be increased to look for
+ * separators beyond this point, without changing the start position
+ * of the next returned substring -- so nextStart stays the same.
+ */
+ offset++;
+ if (offset >= toSplit.length()) {
+ offset = -1;
+ }
+ continue;
+ }
+
+ while (start < end && trimmer.matches(toSplit.charAt(start))) {
+ start++;
+ }
+ while (end > start && trimmer.matches(toSplit.charAt(end - 1))) {
+ end--;
+ }
+
+ if (omitEmptyStrings && start == end) {
+ // Don't include the (unused) separator in next split string.
+ nextStart = offset;
+ continue;
+ }
+
+ if (limit == 1) {
+ // The limit has been reached, return the rest of the string as the
+ // final item. This is tested after empty string removal so that
+ // empty strings do not count towards the limit.
+ end = toSplit.length();
+ offset = -1;
+ // Since we may have changed the end, we need to trim it again.
+ while (end > start && trimmer.matches(toSplit.charAt(end - 1))) {
+ end--;
+ }
+ } else {
+ limit--;
+ }
+
+ return toSplit.subSequence(start, end).toString();
+ }
+ return endOfData();
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Stopwatch.java b/guava/src/com/google/common/base/Stopwatch.java
new file mode 100644
index 0000000..9e1b6f6
--- /dev/null
+++ b/guava/src/com/google/common/base/Stopwatch.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An object that measures elapsed time in nanoseconds. It is useful to measure
+ * elapsed time using this class instead of direct calls to {@link
+ * System#nanoTime} for a few reasons:
+ *
+ * <ul>
+ * <li>An alternate time source can be substituted, for testing or performance
+ * reasons.
+ * <li>As documented by {@code nanoTime}, the value returned has no absolute
+ * meaning, and can only be interpreted as relative to another timestamp
+ * returned by {@code nanoTime} at a different time. {@code Stopwatch} is a
+ * more effective abstraction because it exposes only these relative values,
+ * not the absolute ones.
+ * </ul>
+ *
+ * <p>Basic usage:
+ * <pre>
+ * Stopwatch stopwatch = new Stopwatch().{@link #start start}();
+ * doSomething();
+ * stopwatch.{@link #stop stop}(); // optional
+ *
+ * long millis = stopwatch.{@link #elapsedMillis elapsedMillis}();
+ *
+ * log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
+ * </pre>
+ *
+ * <p>Stopwatch methods are not idempotent; it is an error to start or stop a
+ * stopwatch that is already in the desired state.
+ *
+ * <p>When testing code that uses this class, use the {@linkplain
+ * #Stopwatch(Ticker) alternate constructor} to supply a fake or mock ticker.
+ * <!-- TODO(kevinb): restore the "such as" --> This allows you to
+ * simulate any valid behavior of the stopwatch.
+ *
+ * <p><b>Note:</b> This class is not thread-safe.
+ *
+ * @author Kevin Bourrillion
+ * @since 10.0
+ */
+@Beta
+@GwtCompatible(emulated=true)
+public final class Stopwatch {
+ private final Ticker ticker;
+ private boolean isRunning;
+ private long elapsedNanos;
+ private long startTick;
+
+ /**
+ * Creates (but does not start) a new stopwatch using {@link System#nanoTime}
+ * as its time source.
+ */
+ public Stopwatch() {
+ this(Ticker.systemTicker());
+ }
+
+ /**
+ * Creates (but does not start) a new stopwatch, using the specified time
+ * source.
+ */
+ public Stopwatch(Ticker ticker) {
+ this.ticker = checkNotNull(ticker);
+ }
+
+ /**
+ * Returns {@code true} if {@link #start()} has been called on this stopwatch,
+ * and {@link #stop()} has not been called since the last call to {@code
+ * start()}.
+ */
+ public boolean isRunning() {
+ return isRunning;
+ }
+
+ /**
+ * Starts the stopwatch.
+ *
+ * @return this {@code Stopwatch} instance
+ * @throws IllegalStateException if the stopwatch is already running.
+ */
+ public Stopwatch start() {
+ checkState(!isRunning);
+ isRunning = true;
+ startTick = ticker.read();
+ return this;
+ }
+
+ /**
+ * Stops the stopwatch. Future reads will return the fixed duration that had
+ * elapsed up to this point.
+ *
+ * @return this {@code Stopwatch} instance
+ * @throws IllegalStateException if the stopwatch is already stopped.
+ */
+ public Stopwatch stop() {
+ long tick = ticker.read();
+ checkState(isRunning);
+ isRunning = false;
+ elapsedNanos += tick - startTick;
+ return this;
+ }
+
+ /**
+ * Sets the elapsed time for this stopwatch to zero,
+ * and places it in a stopped state.
+ *
+ * @return this {@code Stopwatch} instance
+ */
+ public Stopwatch reset() {
+ elapsedNanos = 0;
+ isRunning = false;
+ return this;
+ }
+
+ private long elapsedNanos() {
+ return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;
+ }
+
+ /**
+ * Returns the current elapsed time shown on this stopwatch, expressed
+ * in the desired time unit, with any fraction rounded down.
+ *
+ * <p>Note that the overhead of measurement can be more than a microsecond, so
+ * it is generally not useful to specify {@link TimeUnit#NANOSECONDS}
+ * precision here.
+ */
+ public long elapsedTime(TimeUnit desiredUnit) {
+ return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
+ }
+
+ /**
+ * Returns the current elapsed time shown on this stopwatch, expressed
+ * in milliseconds, with any fraction rounded down. This is identical to
+ * {@code elapsedTime(TimeUnit.MILLISECONDS}.
+ */
+ public long elapsedMillis() {
+ return elapsedTime(MILLISECONDS);
+ }
+
+ /**
+ * Returns a string representation of the current elapsed time.
+ */
+ @GwtIncompatible("String.format()")
+ @Override public String toString() {
+ return toString(4);
+ }
+
+ /**
+ * Returns a string representation of the current elapsed time, choosing an
+ * appropriate unit and using the specified number of significant figures.
+ * For example, at the instant when {@code elapsedTime(NANOSECONDS)} would
+ * return {1234567}, {@code toString(4)} returns {@code "1.235 ms"}.
+ *
+ * @deprecated Use {@link #toString()} instead. This method is scheduled
+ * to be removed in Guava release 15.0.
+ */
+ @Deprecated
+ @GwtIncompatible("String.format()")
+ public String toString(int significantDigits) {
+ long nanos = elapsedNanos();
+
+ TimeUnit unit = chooseUnit(nanos);
+ double value = (double) nanos / NANOSECONDS.convert(1, unit);
+
+ // Too bad this functionality is not exposed as a regular method call
+ return String.format("%." + significantDigits + "g %s",
+ value, abbreviate(unit));
+ }
+
+ private static TimeUnit chooseUnit(long nanos) {
+ if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return SECONDS;
+ }
+ if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MILLISECONDS;
+ }
+ if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MICROSECONDS;
+ }
+ return NANOSECONDS;
+ }
+
+ private static String abbreviate(TimeUnit unit) {
+ switch (unit) {
+ case NANOSECONDS:
+ return "ns";
+ case MICROSECONDS:
+ return "\u03bcs"; // μs
+ case MILLISECONDS:
+ return "ms";
+ case SECONDS:
+ return "s";
+ default:
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Strings.java b/guava/src/com/google/common/base/Strings.java
new file mode 100644
index 0000000..45007fd
--- /dev/null
+++ b/guava/src/com/google/common/base/Strings.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.Formatter;
+
+import javax.annotation.Nullable;
+
+/**
+ * Static utility methods pertaining to {@code String} or {@code CharSequence}
+ * instances.
+ *
+ * @author Kevin Bourrillion
+ * @since 3.0
+ */
+@GwtCompatible
+public final class Strings {
+ private Strings() {}
+
+ /**
+ * Returns the given string if it is non-null; the empty string otherwise.
+ *
+ * @param string the string to test and possibly return
+ * @return {@code string} itself if it is non-null; {@code ""} if it is null
+ */
+ public static String nullToEmpty(@Nullable String string) {
+ return (string == null) ? "" : string;
+ }
+
+ /**
+ * Returns the given string if it is nonempty; {@code null} otherwise.
+ *
+ * @param string the string to test and possibly return
+ * @return {@code string} itself if it is nonempty; {@code null} if it is
+ * empty or null
+ */
+ public static @Nullable String emptyToNull(@Nullable String string) {
+ return isNullOrEmpty(string) ? null : string;
+ }
+
+ /**
+ * Returns {@code true} if the given string is null or is the empty string.
+ *
+ * <p>Consider normalizing your string references with {@link #nullToEmpty}.
+ * If you do, you can use {@link String#isEmpty()} instead of this
+ * method, and you won't need special null-safe forms of methods like {@link
+ * String#toUpperCase} either. Or, if you'd like to normalize "in the other
+ * direction," converting empty strings to {@code null}, you can use {@link
+ * #emptyToNull}.
+ *
+ * @param string a string reference to check
+ * @return {@code true} if the string is null or is the empty string
+ */
+ public static boolean isNullOrEmpty(@Nullable String string) {
+ return string == null || string.length() == 0; // string.isEmpty() in Java 6
+ }
+
+ /**
+ * Returns a string, of length at least {@code minLength}, consisting of
+ * {@code string} prepended with as many copies of {@code padChar} as are
+ * necessary to reach that length. For example,
+ *
+ * <ul>
+ * <li>{@code padStart("7", 3, '0')} returns {@code "007"}
+ * <li>{@code padStart("2010", 3, '0')} returns {@code "2010"}
+ * </ul>
+ *
+ * <p>See {@link Formatter} for a richer set of formatting capabilities.
+ *
+ * @param string the string which should appear at the end of the result
+ * @param minLength the minimum length the resulting string must have. Can be
+ * zero or negative, in which case the input string is always returned.
+ * @param padChar the character to insert at the beginning of the result until
+ * the minimum length is reached
+ * @return the padded string
+ */
+ public static String padStart(String string, int minLength, char padChar) {
+ checkNotNull(string); // eager for GWT.
+ if (string.length() >= minLength) {
+ return string;
+ }
+ StringBuilder sb = new StringBuilder(minLength);
+ for (int i = string.length(); i < minLength; i++) {
+ sb.append(padChar);
+ }
+ sb.append(string);
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string, of length at least {@code minLength}, consisting of
+ * {@code string} appended with as many copies of {@code padChar} as are
+ * necessary to reach that length. For example,
+ *
+ * <ul>
+ * <li>{@code padEnd("4.", 5, '0')} returns {@code "4.000"}
+ * <li>{@code padEnd("2010", 3, '!')} returns {@code "2010"}
+ * </ul>
+ *
+ * <p>See {@link Formatter} for a richer set of formatting capabilities.
+ *
+ * @param string the string which should appear at the beginning of the result
+ * @param minLength the minimum length the resulting string must have. Can be
+ * zero or negative, in which case the input string is always returned.
+ * @param padChar the character to append to the end of the result until the
+ * minimum length is reached
+ * @return the padded string
+ */
+ public static String padEnd(String string, int minLength, char padChar) {
+ checkNotNull(string); // eager for GWT.
+ if (string.length() >= minLength) {
+ return string;
+ }
+ StringBuilder sb = new StringBuilder(minLength);
+ sb.append(string);
+ for (int i = string.length(); i < minLength; i++) {
+ sb.append(padChar);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string consisting of a specific number of concatenated copies of
+ * an input string. For example, {@code repeat("hey", 3)} returns the string
+ * {@code "heyheyhey"}.
+ *
+ * @param string any non-null string
+ * @param count the number of times to repeat it; a nonnegative integer
+ * @return a string containing {@code string} repeated {@code count} times
+ * (the empty string if {@code count} is zero)
+ * @throws IllegalArgumentException if {@code count} is negative
+ */
+ public static String repeat(String string, int count) {
+ checkNotNull(string); // eager for GWT.
+
+ if (count <= 1) {
+ checkArgument(count >= 0, "invalid count: %s", count);
+ return (count == 0) ? "" : string;
+ }
+
+ // IF YOU MODIFY THE CODE HERE, you must update StringsRepeatBenchmark
+ final int len = string.length();
+ final long longSize = (long) len * (long) count;
+ final int size = (int) longSize;
+ if (size != longSize) {
+ throw new ArrayIndexOutOfBoundsException("Required array size too large: "
+ + String.valueOf(longSize));
+ }
+
+ final char[] array = new char[size];
+ string.getChars(0, len, array, 0);
+ int n;
+ for (n = len; n < size - n; n <<= 1) {
+ System.arraycopy(array, 0, array, n, n);
+ }
+ System.arraycopy(array, 0, array, n, size - n);
+ return new String(array);
+ }
+
+ /**
+ * Returns the longest string {@code prefix} such that
+ * {@code a.toString().startsWith(prefix) && b.toString().startsWith(prefix)},
+ * taking care not to split surrogate pairs. If {@code a} and {@code b} have
+ * no common prefix, returns the empty string.
+ *
+ * @since 11.0
+ */
+ public static String commonPrefix(CharSequence a, CharSequence b) {
+ checkNotNull(a);
+ checkNotNull(b);
+
+ int maxPrefixLength = Math.min(a.length(), b.length());
+ int p = 0;
+ while (p < maxPrefixLength && a.charAt(p) == b.charAt(p)) {
+ p++;
+ }
+ if (validSurrogatePairAt(a, p - 1) || validSurrogatePairAt(b, p - 1)) {
+ p--;
+ }
+ return a.subSequence(0, p).toString();
+ }
+
+ /**
+ * Returns the longest string {@code suffix} such that
+ * {@code a.toString().endsWith(suffix) && b.toString().endsWith(suffix)},
+ * taking care not to split surrogate pairs. If {@code a} and {@code b} have
+ * no common suffix, returns the empty string.
+ *
+ * @since 11.0
+ */
+ public static String commonSuffix(CharSequence a, CharSequence b) {
+ checkNotNull(a);
+ checkNotNull(b);
+
+ int maxSuffixLength = Math.min(a.length(), b.length());
+ int s = 0;
+ while (s < maxSuffixLength
+ && a.charAt(a.length() - s - 1) == b.charAt(b.length() - s - 1)) {
+ s++;
+ }
+ if (validSurrogatePairAt(a, a.length() - s - 1)
+ || validSurrogatePairAt(b, b.length() - s - 1)) {
+ s--;
+ }
+ return a.subSequence(a.length() - s, a.length()).toString();
+ }
+
+ /**
+ * True when a valid surrogate pair starts at the given {@code index} in the
+ * given {@code string}. Out-of-range indexes return false.
+ */
+ @VisibleForTesting
+ static boolean validSurrogatePairAt(CharSequence string, int index) {
+ return index >= 0 && index <= (string.length() - 2)
+ && Character.isHighSurrogate(string.charAt(index))
+ && Character.isLowSurrogate(string.charAt(index + 1));
+ }
+}
diff --git a/guava/src/com/google/common/base/Supplier.java b/guava/src/com/google/common/base/Supplier.java
new file mode 100644
index 0000000..ab8b908
--- /dev/null
+++ b/guava/src/com/google/common/base/Supplier.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * A class that can supply objects of a single type. Semantically, this could
+ * be a factory, generator, builder, closure, or something else entirely. No
+ * guarantees are implied by this interface.
+ *
+ * @author Harry Heymann
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public interface Supplier<T> {
+ /**
+ * Retrieves an instance of the appropriate type. The returned object may or
+ * may not be a new instance, depending on the implementation.
+ *
+ * @return an instance of the appropriate type
+ */
+ T get();
+}
diff --git a/guava/src/com/google/common/base/Suppliers.java b/guava/src/com/google/common/base/Suppliers.java
new file mode 100644
index 0000000..add5117
--- /dev/null
+++ b/guava/src/com/google/common/base/Suppliers.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+
+/**
+ * Useful suppliers.
+ *
+ * <p>All methods return serializable suppliers as long as they're given
+ * serializable parameters.
+ *
+ * @author Laurence Gonsalves
+ * @author Harry Heymann
+ * @since 2.0 (imported from Google Collections Library)
+ */
+@GwtCompatible
+public final class Suppliers {
+ private Suppliers() {}
+
+ /**
+ * Returns a new supplier which is the composition of the provided function
+ * and supplier. In other words, the new supplier's value will be computed by
+ * retrieving the value from {@code supplier}, and then applying
+ * {@code function} to that value. Note that the resulting supplier will not
+ * call {@code supplier} or invoke {@code function} until it is called.
+ */
+ public static <F, T> Supplier<T> compose(
+ Function<? super F, T> function, Supplier<F> supplier) {
+ Preconditions.checkNotNull(function);
+ Preconditions.checkNotNull(supplier);
+ return new SupplierComposition<F, T>(function, supplier);
+ }
+
+ private static class SupplierComposition<F, T>
+ implements Supplier<T>, Serializable {
+ final Function<? super F, T> function;
+ final Supplier<F> supplier;
+
+ SupplierComposition(Function<? super F, T> function, Supplier<F> supplier) {
+ this.function = function;
+ this.supplier = supplier;
+ }
+
+ @Override
+ public T get() {
+ return function.apply(supplier.get());
+ }
+
+ @Override
+ public String toString() {
+ return "Suppliers.compose(" + function + ", " + supplier + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier which caches the instance retrieved during the first
+ * call to {@code get()} and returns that value on subsequent calls to
+ * {@code get()}. See:
+ * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>
+ *
+ * <p>The returned supplier is thread-safe. The supplier's serialized form
+ * does not contain the cached value, which will be recalculated when {@code
+ * get()} is called on the reserialized instance.
+ *
+ * <p>If {@code delegate} is an instance created by an earlier call to {@code
+ * memoize}, it is returned directly.
+ */
+ public static <T> Supplier<T> memoize(Supplier<T> delegate) {
+ return (delegate instanceof MemoizingSupplier)
+ ? delegate
+ : new MemoizingSupplier<T>(Preconditions.checkNotNull(delegate));
+ }
+
+ @VisibleForTesting
+ static class MemoizingSupplier<T> implements Supplier<T>, Serializable {
+ final Supplier<T> delegate;
+ transient volatile boolean initialized;
+ // "value" does not need to be volatile; visibility piggy-backs
+ // on volatile read of "initialized".
+ transient T value;
+
+ MemoizingSupplier(Supplier<T> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public T get() {
+ // A 2-field variant of Double Checked Locking.
+ if (!initialized) {
+ synchronized (this) {
+ if (!initialized) {
+ T t = delegate.get();
+ value = t;
+ initialized = true;
+ return t;
+ }
+ }
+ }
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return "Suppliers.memoize(" + delegate + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier that caches the instance supplied by the delegate and
+ * removes the cached value after the specified time has passed. Subsequent
+ * calls to {@code get()} return the cached value if the expiration time has
+ * not passed. After the expiration time, a new value is retrieved, cached,
+ * and returned. See:
+ * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>
+ *
+ * <p>The returned supplier is thread-safe. The supplier's serialized form
+ * does not contain the cached value, which will be recalculated when {@code
+ * get()} is called on the reserialized instance.
+ *
+ * @param duration the length of time after a value is created that it
+ * should stop being returned by subsequent {@code get()} calls
+ * @param unit the unit that {@code duration} is expressed in
+ * @throws IllegalArgumentException if {@code duration} is not positive
+ * @since 2.0
+ */
+ public static <T> Supplier<T> memoizeWithExpiration(
+ Supplier<T> delegate, long duration, TimeUnit unit) {
+ return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
+ }
+
+ @VisibleForTesting static class ExpiringMemoizingSupplier<T>
+ implements Supplier<T>, Serializable {
+ final Supplier<T> delegate;
+ final long durationNanos;
+ transient volatile T value;
+ // The special value 0 means "not yet initialized".
+ transient volatile long expirationNanos;
+
+ ExpiringMemoizingSupplier(
+ Supplier<T> delegate, long duration, TimeUnit unit) {
+ this.delegate = Preconditions.checkNotNull(delegate);
+ this.durationNanos = unit.toNanos(duration);
+ Preconditions.checkArgument(duration > 0);
+ }
+
+ @Override
+ public T get() {
+ // Another variant of Double Checked Locking.
+ //
+ // We use two volatile reads. We could reduce this to one by
+ // putting our fields into a holder class, but (at least on x86)
+ // the extra memory consumption and indirection are more
+ // expensive than the extra volatile reads.
+ long nanos = expirationNanos;
+ long now = Platform.systemNanoTime();
+ if (nanos == 0 || now - nanos >= 0) {
+ synchronized (this) {
+ if (nanos == expirationNanos) { // recheck for lost race
+ T t = delegate.get();
+ value = t;
+ nanos = now + durationNanos;
+ // In the very unlikely event that nanos is 0, set it to 1;
+ // no one will notice 1 ns of tardiness.
+ expirationNanos = (nanos == 0) ? 1 : nanos;
+ return t;
+ }
+ }
+ }
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ // This is a little strange if the unit the user provided was not NANOS,
+ // but we don't want to store the unit just for toString
+ return "Suppliers.memoizeWithExpiration(" + delegate + ", " +
+ durationNanos + ", NANOS)";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier that always supplies {@code instance}.
+ */
+ public static <T> Supplier<T> ofInstance(@Nullable T instance) {
+ return new SupplierOfInstance<T>(instance);
+ }
+
+ private static class SupplierOfInstance<T>
+ implements Supplier<T>, Serializable {
+ final T instance;
+
+ SupplierOfInstance(@Nullable T instance) {
+ this.instance = instance;
+ }
+
+ @Override
+ public T get() {
+ return instance;
+ }
+
+ @Override
+ public String toString() {
+ return "Suppliers.ofInstance(" + instance + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier whose {@code get()} method synchronizes on
+ * {@code delegate} before calling it, making it thread-safe.
+ */
+ public static <T> Supplier<T> synchronizedSupplier(Supplier<T> delegate) {
+ return new ThreadSafeSupplier<T>(Preconditions.checkNotNull(delegate));
+ }
+
+ private static class ThreadSafeSupplier<T>
+ implements Supplier<T>, Serializable {
+ final Supplier<T> delegate;
+
+ ThreadSafeSupplier(Supplier<T> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public T get() {
+ synchronized (delegate) {
+ return delegate.get();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Suppliers.synchronizedSupplier(" + delegate + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a function that accepts a supplier and returns the result of
+ * invoking {@link Supplier#get} on that supplier.
+ *
+ * @since 8.0
+ */
+ @Beta
+ @SuppressWarnings("unchecked") // SupplierFunction works for any T.
+ public static <T> Function<Supplier<T>, T> supplierFunction() {
+ return (Function) SupplierFunction.INSTANCE;
+ }
+
+ private enum SupplierFunction implements Function<Supplier<?>, Object> {
+ INSTANCE;
+
+ @Override
+ public Object apply(Supplier<?> input) {
+ return input.get();
+ }
+
+ @Override
+ public String toString() {
+ return "Suppliers.supplierFunction()";
+ }
+ }
+}
diff --git a/guava/src/com/google/common/base/Throwables.java b/guava/src/com/google/common/base/Throwables.java
new file mode 100644
index 0000000..5e4d6ec
--- /dev/null
+++ b/guava/src/com/google/common/base/Throwables.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Static utility methods pertaining to instances of {@link Throwable}.
+ *
+ * <p>See the Guava User Guide entry on <a href=
+ * "http://code.google.com/p/guava-libraries/wiki/ThrowablesExplained">
+ * Throwables</a>.
+ *
+ * @author Kevin Bourrillion
+ * @author Ben Yu
+ * @since 1.0
+ */
+public final class Throwables {
+ private Throwables() {}
+
+ /**
+ * Propagates {@code throwable} exactly as-is, if and only if it is an
+ * instance of {@code declaredType}. Example usage:
+ * <pre>
+ * try {
+ * someMethodThatCouldThrowAnything();
+ * } catch (IKnowWhatToDoWithThisException e) {
+ * handle(e);
+ * } catch (Throwable t) {
+ * Throwables.propagateIfInstanceOf(t, IOException.class);
+ * Throwables.propagateIfInstanceOf(t, SQLException.class);
+ * throw Throwables.propagate(t);
+ * }
+ * </pre>
+ */
+ public static <X extends Throwable> void propagateIfInstanceOf(
+ @Nullable Throwable throwable, Class<X> declaredType) throws X {
+ // Check for null is needed to avoid frequent JNI calls to isInstance().
+ if (throwable != null && declaredType.isInstance(throwable)) {
+ throw declaredType.cast(throwable);
+ }
+ }
+
+ /**
+ * Propagates {@code throwable} exactly as-is, if and only if it is an
+ * instance of {@link RuntimeException} or {@link Error}. Example usage:
+ * <pre>
+ * try {
+ * someMethodThatCouldThrowAnything();
+ * } catch (IKnowWhatToDoWithThisException e) {
+ * handle(e);
+ * } catch (Throwable t) {
+ * Throwables.propagateIfPossible(t);
+ * throw new RuntimeException("unexpected", t);
+ * }
+ * </pre>
+ */
+ public static void propagateIfPossible(@Nullable Throwable throwable) {
+ propagateIfInstanceOf(throwable, Error.class);
+ propagateIfInstanceOf(throwable, RuntimeException.class);
+ }
+
+ /**
+ * Propagates {@code throwable} exactly as-is, if and only if it is an
+ * instance of {@link RuntimeException}, {@link Error}, or
+ * {@code declaredType}. Example usage:
+ * <pre>
+ * try {
+ * someMethodThatCouldThrowAnything();
+ * } catch (IKnowWhatToDoWithThisException e) {
+ * handle(e);
+ * } catch (Throwable t) {
+ * Throwables.propagateIfPossible(t, OtherException.class);
+ * throw new RuntimeException("unexpected", t);
+ * }
+ * </pre>
+ *
+ * @param throwable the Throwable to possibly propagate
+ * @param declaredType the single checked exception type declared by the
+ * calling method
+ */
+ public static <X extends Throwable> void propagateIfPossible(
+ @Nullable Throwable throwable, Class<X> declaredType) throws X {
+ propagateIfInstanceOf(throwable, declaredType);
+ propagateIfPossible(throwable);
+ }
+
+ /**
+ * Propagates {@code throwable} exactly as-is, if and only if it is an
+ * instance of {@link RuntimeException}, {@link Error}, {@code declaredType1},
+ * or {@code declaredType2}. In the unlikely case that you have three or more
+ * declared checked exception types, you can handle them all by invoking these
+ * methods repeatedly. See usage example in {@link
+ * #propagateIfPossible(Throwable, Class)}.
+ *
+ * @param throwable the Throwable to possibly propagate
+ * @param declaredType1 any checked exception type declared by the calling
+ * method
+ * @param declaredType2 any other checked exception type declared by the
+ * calling method
+ */
+ public static <X1 extends Throwable, X2 extends Throwable>
+ void propagateIfPossible(@Nullable Throwable throwable,
+ Class<X1> declaredType1, Class<X2> declaredType2) throws X1, X2 {
+ checkNotNull(declaredType2);
+ propagateIfInstanceOf(throwable, declaredType1);
+ propagateIfPossible(throwable, declaredType2);
+ }
+
+ /**
+ * Propagates {@code throwable} as-is if it is an instance of
+ * {@link RuntimeException} or {@link Error}, or else as a last resort, wraps
+ * it in a {@code RuntimeException} then propagates.
+ * <p>
+ * This method always throws an exception. The {@code RuntimeException} return
+ * type is only for client code to make Java type system happy in case a
+ * return value is required by the enclosing method. Example usage:
+ * <pre>
+ * T doSomething() {
+ * try {
+ * return someMethodThatCouldThrowAnything();
+ * } catch (IKnowWhatToDoWithThisException e) {
+ * return handle(e);
+ * } catch (Throwable t) {
+ * throw Throwables.propagate(t);
+ * }
+ * }
+ * </pre>
+ *
+ * @param throwable the Throwable to propagate
+ * @return nothing will ever be returned; this return type is only for your
+ * convenience, as illustrated in the example above
+ */
+ public static RuntimeException propagate(Throwable throwable) {
+ propagateIfPossible(checkNotNull(throwable));
+ throw new RuntimeException(throwable);
+ }
+
+ /**
+ * Returns the innermost cause of {@code throwable}. The first throwable in a
+ * chain provides context from when the error or exception was initially
+ * detected. Example usage:
+ * <pre>
+ * assertEquals("Unable to assign a customer id",
+ * Throwables.getRootCause(e).getMessage());
+ * </pre>
+ */
+ public static Throwable getRootCause(Throwable throwable) {
+ Throwable cause;
+ while ((cause = throwable.getCause()) != null) {
+ throwable = cause;
+ }
+ return throwable;
+ }
+
+ /**
+ * Gets a {@code Throwable} cause chain as a list. The first entry in the
+ * list will be {@code throwable} followed by its cause hierarchy. Note
+ * that this is a snapshot of the cause chain and will not reflect
+ * any subsequent changes to the cause chain.
+ *
+ * <p>Here's an example of how it can be used to find specific types
+ * of exceptions in the cause chain:
+ *
+ * <pre>
+ * Iterables.filter(Throwables.getCausalChain(e), IOException.class));
+ * </pre>
+ *
+ * @param throwable the non-null {@code Throwable} to extract causes from
+ * @return an unmodifiable list containing the cause chain starting with
+ * {@code throwable}
+ */
+ @Beta // TODO(kevinb): decide best return type
+ public static List<Throwable> getCausalChain(Throwable throwable) {
+ checkNotNull(throwable);
+ List<Throwable> causes = new ArrayList<Throwable>(4);
+ while (throwable != null) {
+ causes.add(throwable);
+ throwable = throwable.getCause();
+ }
+ return Collections.unmodifiableList(causes);
+ }
+
+ /**
+ * Returns a string containing the result of
+ * {@link Throwable#toString() toString()}, followed by the full, recursive
+ * stack trace of {@code throwable}. Note that you probably should not be
+ * parsing the resulting string; if you need programmatic access to the stack
+ * frames, you can call {@link Throwable#getStackTrace()}.
+ */
+ public static String getStackTraceAsString(Throwable throwable) {
+ StringWriter stringWriter = new StringWriter();
+ throwable.printStackTrace(new PrintWriter(stringWriter));
+ return stringWriter.toString();
+ }
+}
diff --git a/guava/src/com/google/common/base/Ticker.java b/guava/src/com/google/common/base/Ticker.java
new file mode 100644
index 0000000..6c34aef
--- /dev/null
+++ b/guava/src/com/google/common/base/Ticker.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * A time source; returns a time value representing the number of nanoseconds elapsed since some
+ * fixed but arbitrary point in time. Note that most users should use {@link Stopwatch} instead of
+ * interacting with this class directly.
+ *
+ * <p><b>Warning:</b> this interface can only be used to measure elapsed time, not wall time.
+ *
+ * @author Kevin Bourrillion
+ * @since 10.0
+ * (<a href="http://code.google.com/p/guava-libraries/wiki/Compatibility"
+ * >mostly source-compatible</a> since 9.0)
+ */
+@Beta
+@GwtCompatible
+public abstract class Ticker {
+ /**
+ * Constructor for use by subclasses.
+ */
+ protected Ticker() {}
+
+ /**
+ * Returns the number of nanoseconds elapsed since this ticker's fixed
+ * point of reference.
+ */
+ public abstract long read();
+
+ /**
+ * A ticker that reads the current time using {@link System#nanoTime}.
+ *
+ * @since 10.0
+ */
+ public static Ticker systemTicker() {
+ return SYSTEM_TICKER;
+ }
+
+ private static final Ticker SYSTEM_TICKER = new Ticker() {
+ @Override
+ public long read() {
+ return Platform.systemNanoTime();
+ }
+ };
+}
diff --git a/guava/src/com/google/common/base/internal/Finalizer.java b/guava/src/com/google/common/base/internal/Finalizer.java
new file mode 100644
index 0000000..0934aa6
--- /dev/null
+++ b/guava/src/com/google/common/base/internal/Finalizer.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base.internal;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Thread that finalizes referents. All references should implement
+ * {@code com.google.common.base.FinalizableReference}.
+ *
+ * <p>While this class is public, we consider it to be *internal* and not part
+ * of our published API. It is public so we can access it reflectively across
+ * class loaders in secure environments.
+ *
+ * <p>This class can't depend on other Google Collections code. If we were
+ * to load this class in the same class loader as the rest of
+ * Google Collections, this thread would keep an indirect strong reference
+ * to the class loader and prevent it from being garbage collected. This
+ * poses a problem for environments where you want to throw away the class
+ * loader. For example, dynamically reloading a web application or unloading
+ * an OSGi bundle.
+ *
+ * <p>{@code com.google.common.base.FinalizableReferenceQueue} loads this class
+ * in its own class loader. That way, this class doesn't prevent the main
+ * class loader from getting garbage collected, and this class can detect when
+ * the main class loader has been garbage collected and stop itself.
+ */
+public class Finalizer implements Runnable {
+
+ private static final Logger logger
+ = Logger.getLogger(Finalizer.class.getName());
+
+ /** Name of FinalizableReference.class. */
+ private static final String FINALIZABLE_REFERENCE
+ = "com.google.common.base.FinalizableReference";
+
+ /**
+ * Starts the Finalizer thread. FinalizableReferenceQueue calls this method
+ * reflectively.
+ *
+ * @param finalizableReferenceClass FinalizableReference.class
+ * @param frq reference to instance of FinalizableReferenceQueue that started
+ * this thread
+ * @return ReferenceQueue which Finalizer will poll
+ */
+ public static ReferenceQueue<Object> startFinalizer(
+ Class<?> finalizableReferenceClass, Object frq) {
+ /*
+ * We use FinalizableReference.class for two things:
+ *
+ * 1) To invoke FinalizableReference.finalizeReferent()
+ *
+ * 2) To detect when FinalizableReference's class loader has to be garbage
+ * collected, at which point, Finalizer can stop running
+ */
+ if (!finalizableReferenceClass.getName().equals(FINALIZABLE_REFERENCE)) {
+ throw new IllegalArgumentException(
+ "Expected " + FINALIZABLE_REFERENCE + ".");
+ }
+
+ Finalizer finalizer = new Finalizer(finalizableReferenceClass, frq);
+ Thread thread = new Thread(finalizer);
+ thread.setName(Finalizer.class.getName());
+ thread.setDaemon(true);
+
+ try {
+ if (inheritableThreadLocals != null) {
+ inheritableThreadLocals.set(thread, null);
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "Failed to clear thread local values inherited"
+ + " by reference finalizer thread.", t);
+ }
+
+ thread.start();
+ return finalizer.queue;
+ }
+
+ private final WeakReference<Class<?>> finalizableReferenceClassReference;
+ private final PhantomReference<Object> frqReference;
+ private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+
+ private static final Field inheritableThreadLocals
+ = getInheritableThreadLocalsField();
+
+ /** Constructs a new finalizer thread. */
+ private Finalizer(Class<?> finalizableReferenceClass, Object frq) {
+ this.finalizableReferenceClassReference
+ = new WeakReference<Class<?>>(finalizableReferenceClass);
+
+ // Keep track of the FRQ that started us so we know when to stop.
+ this.frqReference = new PhantomReference<Object>(frq, queue);
+ }
+
+ /**
+ * Loops continuously, pulling references off the queue and cleaning them up.
+ */
+ @SuppressWarnings("InfiniteLoopStatement")
+ @Override
+ public void run() {
+ try {
+ while (true) {
+ try {
+ cleanUp(queue.remove());
+ } catch (InterruptedException e) { /* ignore */ }
+ }
+ } catch (ShutDown shutDown) { /* ignore */ }
+ }
+
+ /**
+ * Cleans up a single reference. Catches and logs all throwables.
+ */
+ private void cleanUp(Reference<?> reference) throws ShutDown {
+ Method finalizeReferentMethod = getFinalizeReferentMethod();
+ do {
+ /*
+ * This is for the benefit of phantom references. Weak and soft
+ * references will have already been cleared by this point.
+ */
+ reference.clear();
+
+ if (reference == frqReference) {
+ /*
+ * The client no longer has a reference to the
+ * FinalizableReferenceQueue. We can stop.
+ */
+ throw new ShutDown();
+ }
+
+ try {
+ finalizeReferentMethod.invoke(reference);
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
+ }
+
+ /*
+ * Loop as long as we have references available so as not to waste
+ * CPU looking up the Method over and over again.
+ */
+ } while ((reference = queue.poll()) != null);
+ }
+
+ /**
+ * Looks up FinalizableReference.finalizeReferent() method.
+ */
+ private Method getFinalizeReferentMethod() throws ShutDown {
+ Class<?> finalizableReferenceClass
+ = finalizableReferenceClassReference.get();
+ if (finalizableReferenceClass == null) {
+ /*
+ * FinalizableReference's class loader was reclaimed. While there's a
+ * chance that other finalizable references could be enqueued
+ * subsequently (at which point the class loader would be resurrected
+ * by virtue of us having a strong reference to it), we should pretty
+ * much just shut down and make sure we don't keep it alive any longer
+ * than necessary.
+ */
+ throw new ShutDown();
+ }
+ try {
+ return finalizableReferenceClass.getMethod("finalizeReferent");
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ public static Field getInheritableThreadLocalsField() {
+ try {
+ Field inheritableThreadLocals
+ = Thread.class.getDeclaredField("inheritableThreadLocals");
+ inheritableThreadLocals.setAccessible(true);
+ return inheritableThreadLocals;
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "Couldn't access Thread.inheritableThreadLocals."
+ + " Reference finalizer threads will inherit thread local"
+ + " values.");
+ return null;
+ }
+ }
+
+ /** Indicates that it's time to shut down the Finalizer. */
+ @SuppressWarnings("serial") // Never serialized or thrown out of this class.
+ private static class ShutDown extends Exception {}
+}
diff --git a/guava/src/com/google/common/base/package-info.java b/guava/src/com/google/common/base/package-info.java
new file mode 100644
index 0000000..66e7177
--- /dev/null
+++ b/guava/src/com/google/common/base/package-info.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Basic utility libraries and interfaces.
+ *
+ * <p>This package is a part of the open-source
+ * <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
+ *
+ * <h2>Contents</h2>
+ *
+ * <h3>String-related utilities</h3>
+ *
+ * <ul>
+ * <li>{@link com.google.common.base.Ascii}
+ * <li>{@link com.google.common.base.CaseFormat}
+ * <li>{@link com.google.common.base.CharMatcher}
+ * <li>{@link com.google.common.base.Charsets}
+ * <li>{@link com.google.common.base.Joiner}
+ * <li>{@link com.google.common.base.Splitter}
+ * <li>{@link com.google.common.base.Strings}
+ * </ul>
+ *
+ * <h3>Function types</h3>
+ *
+ * <ul>
+ * <li>{@link com.google.common.base.Function},
+ * {@link com.google.common.base.Functions}
+ * <li>{@link com.google.common.base.Predicate},
+ * {@link com.google.common.base.Predicates}
+ * <li>{@link com.google.common.base.Equivalence},
+ * {@link com.google.common.base.Equivalences}
+ * <li>{@link com.google.common.base.Supplier},
+ * {@link com.google.common.base.Suppliers}
+ * </ul>
+ *
+ * <h3>Other</h3>
+ *
+ * <ul>
+ * <li>{@link com.google.common.base.Defaults}
+ * <li>{@link com.google.common.base.Enums}
+ * <li>{@link com.google.common.base.Objects}
+ * <li>{@link com.google.common.base.Optional}
+ * <li>{@link com.google.common.base.Preconditions}
+ * <li>{@link com.google.common.base.Stopwatch}
+ * <li>{@link com.google.common.base.Throwables}
+ * </ul>
+ *
+ */
+@ParametersAreNonnullByDefault
+package com.google.common.base;
+
+import javax.annotation.ParametersAreNonnullByDefault;