1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License.
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License.
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport com.google.common.annotations.GwtCompatible;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Preconditions;
23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.InvalidObjectException;
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectInputStream;
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.Serializable;
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.ArrayList;
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection;
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collections;
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Iterator;
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.List;
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.RandomAccess;
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable;
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * A high-performance, immutable, random-access {@code List} implementation.
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Does not permit null elements.
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Unlike {@link Collections#unmodifiableList}, which is a <i>view</i> of a
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * separate collection that can still change, an instance of {@code
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ImmutableList} contains its own private data and will <i>never</i> change.
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@code ImmutableList} is convenient for {@code public static final} lists
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ("constant lists") and also lets you easily make a "defensive copy" of a list
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * provided to your class by a caller.
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * it has no public or protected constructors. Thus, instances of this type are
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * guaranteed to be immutable.
50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @see ImmutableMap
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @see ImmutableSet
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(serializable = true, emulated = true)
57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson@SuppressWarnings("serial") // we're overriding default serialization
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic abstract class ImmutableList<E> extends ImmutableCollection<E>
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    implements List<E>, RandomAccess {
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns the empty immutable list. This set behaves and performs comparably
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * to {@link Collections#emptyList}, and is preferable mainly for consistency
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * and maintainability of your code.
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Casting to any type is safe because the list will never hold any elements.
66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @SuppressWarnings("unchecked")
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of() {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (ImmutableList<E>) EmptyImmutableList.INSTANCE;
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable list containing a single element. This list behaves
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * and performs comparably to {@link Collections#singleton}, but will not
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * accept a null element. It is preferable mainly for consistency and
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * maintainability of your code.
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if {@code element} is null
78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E element) {
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new SingletonImmutableList<E>(element);
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E e1, E e2) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2);
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3);
99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4);
108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5);
117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6);
126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(
134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6, e7);
136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(
144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6, e7, e8);
146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
151090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(
154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);
156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
162090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
163090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(
164090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
166090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
167090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
168090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
170090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
171090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any element is null
172090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
173090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> of(
174090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
176090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
177090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
178090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // These go up to eleven. After that, you just get the varargs form, and
179090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // whatever warnings might come along with it. :(
180090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
181090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
182090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable list containing the given elements, in order.
183090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if any element is null
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 3.0 (source-compatible since 2.0)
186090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12,
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E... others) {
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] array = new Object[12 + others.length];
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[0] = e1;
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[1] = e2;
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[2] = e3;
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[3] = e4;
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[4] = e5;
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[5] = e6;
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[6] = e7;
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[7] = e8;
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[8] = e9;
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[9] = e10;
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[10] = e11;
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[11] = e12;
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    System.arraycopy(others, 0, array, 12, others.length);
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return construct(array);
205090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
206090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
207090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns an immutable list containing the given elements, in order. If
209bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code elements} is a {@link Collection}, this method behaves exactly as
210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@link #copyOf(Collection)}; otherwise, it behaves exactly as {@code
211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * copyOf(elements.iterator()}.
212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws NullPointerException if any of {@code elements} is null
214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(elements); // TODO(kevinb): is this here only for GWT?
217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return (elements instanceof Collection)
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ? copyOf(Collections2.cast(elements))
219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      : copyOf(elements.iterator());
220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns an immutable list containing the given elements, in order.
224090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Despite the method name, this method attempts to avoid actually copying
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the data when it is safe to do so. The exact circumstances under which a
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * copy will or will not be performed are undocumented and subject to change.
228090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>Note that if {@code list} is a {@code List<String>}, then {@code
230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * containing each of the strings in {@code list}, while
232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * containing one element (the given list itself).
234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>This method is safe to use even when {@code elements} is a synchronized
236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * or concurrent collection that is currently being modified by another
237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * thread.
238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
239090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any of {@code elements} is null
240090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (elements instanceof ImmutableCollection) {
243090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      @SuppressWarnings("unchecked") // all supported methods are covariant
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return list.isPartialView() ? copyFromCollection(list) : list;
246090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return copyFromCollection(elements);
248090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
249090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
250090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
251090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable list containing the given elements, in order.
252090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
253090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any of {@code elements} is null
254090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
255090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return copyFromCollection(Lists.newArrayList(elements));
257090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
258090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable list containing the given elements, in order.
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if any of {@code elements} is null
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 3.0
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> copyOf(E[] elements) {
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (elements.length) {
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 0:
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return ImmutableList.of();
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 1:
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new SingletonImmutableList<E>(elements[0]);
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return construct(elements.clone());
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
276bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static <E> ImmutableList<E> copyFromCollection(
277bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      Collection<? extends E> collection) {
278bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    Object[] elements = collection.toArray();
279bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    switch (elements.length) {
280090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      case 0:
281090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        return of();
282090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      case 1:
283bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        @SuppressWarnings("unchecked") // collection had only Es in it
284bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
285bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return list;
286090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      default:
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // safe to use the array without copying it
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // as specified by Collection.toArray().
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return construct(elements);
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** {@code elements} has to be internally created array. */
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> ImmutableList<E> construct(Object... elements) {
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < elements.length; i++) {
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkElementNotNull(elements[i], i);
297090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(elements);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // We do this instead of Preconditions.checkNotNull to save boxing and array
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // creation cost.
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static Object checkElementNotNull(Object element, int index) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (element == null) {
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new NullPointerException("at index " + index);
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return element;
308090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
309090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
310090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  ImmutableList() {}
311090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
312090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // This declaration is needed to make List.iterator() and
313090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // ImmutableCollection.iterator() consistent.
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public UnmodifiableIterator<E> iterator() {
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return listIterator();
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public UnmodifiableListIterator<E> listIterator() {
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return listIterator(0);
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract UnmodifiableListIterator<E> listIterator(int index);
323090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
324090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Mark these two methods with @Nullable
325090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
327090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public abstract int indexOf(@Nullable Object object);
328090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
330090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public abstract int lastIndexOf(@Nullable Object object);
331090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
332090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // constrain the return type to ImmutableList<E>
333090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
334090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
335090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable list of the elements between the specified {@code
336090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code
337090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * fromIndex} and {@code toIndex} are equal, the empty immutable list is
338090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * returned.)
339090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
341090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public abstract ImmutableList<E> subList(int fromIndex, int toIndex);
342090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
343090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
344090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the list unmodified.
345090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
346090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
347090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
349090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public final boolean addAll(int index, Collection<? extends E> newElements) {
350090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
351090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
352090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
353090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
354090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the list unmodified.
355090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
356090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
357090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
359090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public final E set(int index, E element) {
360090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
361090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
362090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
363090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
364090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the list unmodified.
365090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
366090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
367090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
369090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public final void add(int index, E element) {
370090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
371090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
372090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
373090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
374090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the list unmodified.
375090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
376090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
377090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
379090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public final E remove(int index) {
380090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
381090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
382090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
383bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
384bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns this list instance.
385bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 2.0
387bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
388bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  @Override public ImmutableList<E> asList() {
389bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return this;
390090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
391090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of this immutable list in reverse order. For example, {@code
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ImmutableList.of(1, 2, 3).reverse()} is equivalent to {@code
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ImmutableList.of(3, 2, 1)}.
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a view of this immutable list in reverse order
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 7.0
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ImmutableList<E> reverse() {
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ReverseImmutableList<E>(this);
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class ReverseImmutableList<E> extends ImmutableList<E> {
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient final ImmutableList<E> forwardList;
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient final int size;
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ReverseImmutableList(ImmutableList<E> backingList) {
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.forwardList = backingList;
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.size = backingList.size();
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private int reverseIndex(int index) {
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (size - 1) - index;
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private int reversePosition(int index) {
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return size - index;
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ImmutableList<E> reverse() {
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList;
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(@Nullable Object object) {
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.contains(object);
4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsAll(Collection<?> targets) {
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.containsAll(targets);
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int indexOf(@Nullable Object object) {
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int index = forwardList.lastIndexOf(object);
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (index >= 0) ? reverseIndex(index) : -1;
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int lastIndexOf(@Nullable Object object) {
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int index = forwardList.indexOf(object);
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (index >= 0) ? reverseIndex(index) : -1;
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Preconditions.checkPositionIndexes(fromIndex, toIndex, size);
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.subList(
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          reversePosition(toIndex), reversePosition(fromIndex)).reverse();
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public E get(int index) {
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Preconditions.checkElementIndex(index, size);
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.get(reverseIndex(index));
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public UnmodifiableListIterator<E> listIterator(int index) {
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Preconditions.checkPositionIndex(index, size);
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final UnmodifiableListIterator<E> forward =
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          forwardList.listIterator(reversePosition(index));
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new UnmodifiableListIterator<E>() {
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasNext() {
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return forward.hasPrevious();
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasPrevious() {
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return forward.hasNext();
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public E next() {
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return forward.previous();
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public int nextIndex() {
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return reverseIndex(forward.previousIndex());
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public E previous() {
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return forward.next();
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public int previousIndex() {
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return reverseIndex(forward.nextIndex());
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return size;
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.isEmpty();
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override boolean isPartialView() {
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardList.isPartialView();
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public boolean equals(Object obj) {
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Lists.equalsImpl(this, obj);
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public int hashCode() {
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Lists.hashCodeImpl(this);
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
506090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /*
507090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Serializes ImmutableLists as their logical contents. This ensures that
508090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * implementation types do not leak into the serialized representation.
509090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
510090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static class SerializedForm implements Serializable {
511090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    final Object[] elements;
512090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    SerializedForm(Object[] elements) {
513090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      this.elements = elements;
514090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
515090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Object readResolve() {
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return copyOf(elements);
517090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
518090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private static final long serialVersionUID = 0;
519090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
520090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
521090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void readObject(ObjectInputStream stream)
522090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      throws InvalidObjectException {
523090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new InvalidObjectException("Use SerializedForm");
524090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
525090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
526090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override Object writeReplace() {
527090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new SerializedForm(toArray());
528090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
529090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
530090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
531090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new builder. The generated builder is equivalent to the builder
532090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * created by the {@link Builder} constructor.
533090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
534090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E> Builder<E> builder() {
535090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new Builder<E>();
536090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
537090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
538090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A builder for creating immutable list instances, especially {@code public
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * static final} lists ("constant lists"). Example: <pre>   {@code
541090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
542090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *   public static final ImmutableList<Color> GOOGLE_COLORS
543090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *       = new ImmutableList.Builder<Color>()
544090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .addAll(WEBSAFE_COLORS)
545090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .add(new Color(0, 191, 255))
546090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .build();}</pre>
547090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Builder instances can be reused; it is safe to call {@link #build} multiple
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * times to build multiple lists in series. Each new list contains all the
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * elements of the ones created before it.
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 2.0 (imported from Google Collections Library)
553090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
554090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static final class Builder<E> extends ImmutableCollection.Builder<E> {
555090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private final ArrayList<E> contents = Lists.newArrayList();
556090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
557090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
558090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Creates a new builder. The returned builder is equivalent to the builder
559090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * generated by {@link ImmutableList#builder}.
560090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
561090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    public Builder() {}
562090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
563090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
564090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Adds {@code element} to the {@code ImmutableList}.
565090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
566090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @param element the element to add
567090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @return this {@code Builder} object
568090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @throws NullPointerException if {@code element} is null
569090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
570090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<E> add(E element) {
571090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      contents.add(checkNotNull(element));
572090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
573090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
574090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
575090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
576090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Adds each element of {@code elements} to the {@code ImmutableList}.
577090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
578090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
579090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @return this {@code Builder} object
580090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @throws NullPointerException if {@code elements} is null or contains a
581090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *     null element
582090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
583090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<E> addAll(Iterable<? extends E> elements) {
584090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      if (elements instanceof Collection) {
585090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        Collection<?> collection = (Collection<?>) elements;
586090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        contents.ensureCapacity(contents.size() + collection.size());
587090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
588090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      super.addAll(elements);
589090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
590090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
591090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
592090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
593090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Adds each element of {@code elements} to the {@code ImmutableList}.
594090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
595090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
596090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @return this {@code Builder} object
597090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @throws NullPointerException if {@code elements} is null or contains a
598090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *     null element
599090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
600090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<E> add(E... elements) {
601090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      contents.ensureCapacity(contents.size() + elements.length);
602090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      super.add(elements);
603090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
604090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
605090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
606090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
607090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Adds each element of {@code elements} to the {@code ImmutableList}.
608090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
609090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @param elements the {@code Iterable} to add to the {@code ImmutableList}
610090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @return this {@code Builder} object
611090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @throws NullPointerException if {@code elements} is null or contains a
612090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *     null element
613090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
614090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<E> addAll(Iterator<? extends E> elements) {
615090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      super.addAll(elements);
616090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
617090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
618090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
619090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
620090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Returns a newly-created {@code ImmutableList} based on the contents of
621090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * the {@code Builder}.
622090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
623090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public ImmutableList<E> build() {
624090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return copyOf(contents);
625090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
626090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
627090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
628