11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ArrayList;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ListIterator;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.RandomAccess;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * GWT emulated version of {@link ImmutableList}.
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Hayward Chan
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@SuppressWarnings("serial") // we're overriding default serialization
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class ImmutableList<E> extends ForwardingImmutableCollection<E>
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    implements List<E>, RandomAccess {
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private transient final List<E> delegate;
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  ImmutableList(List<E> delegate) {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super(delegate);
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.delegate = Collections.unmodifiableList(delegate);
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  ImmutableList() {
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this(Collections.<E>emptyList());
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Casting to any type is safe because the list will never hold any elements.
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked")
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of() {
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (ImmutableList<E>) EmptyImmutableList.INSTANCE;
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E element) {
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new SingletonImmutableList<E>(element);
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E e1, E e2) {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList.<E>nullCheckedList(e1, e2));
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList.<E>nullCheckedList(e1, e2, e3));
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList.<E>nullCheckedList(e1, e2, e3, e4));
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5));
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6));
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert         ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7));
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert         ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7, e8));
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert         ImmutableList.<E>nullCheckedList(e1, e2, e3, e4, e5, e6, e7, e8, e9));
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11,
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      E e12, E... others) {
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final int paramCount = 12;
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] array = new Object[paramCount + others.length];
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    arrayCopy(array, 0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12);
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    arrayCopy(array, paramCount, others);
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(array));
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> of(E[] elements) {
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(elements); // for GWT
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (elements.length) {
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 0:
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return ImmutableList.of();
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 1:
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new SingletonImmutableList<E>(elements[0]);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new RegularImmutableList<E>(
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            ImmutableList.<E>nullCheckedList(elements));
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static void arrayCopy(Object[] dest, int pos, Object... source) {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    System.arraycopy(source, 0, dest, pos, source.length);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(elements); // for GWT
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (elements instanceof Collection)
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ? copyOf((Collection<? extends E>) elements)
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : copyOf(elements.iterator());
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copyFromCollection(Lists.newArrayList(elements));
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (elements instanceof ImmutableCollection) {
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * TODO: When given an ImmutableList that's a sublist, copy the referenced
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * portion of the array into a new array to save space?
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @SuppressWarnings("unchecked") // all supported methods are covariant
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableCollection<E> list = (ImmutableCollection<E>) elements;
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return list.asList();
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copyFromCollection(elements);
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> ImmutableList<E> copyOf(E[] elements) {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(elements); // eager for GWT
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copyOf(Arrays.asList(elements));
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> ImmutableList<E> copyFromCollection(
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<? extends E> collection) {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] elements = collection.toArray();
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (elements.length) {
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 0:
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return of();
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 1:
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @SuppressWarnings("unchecked") // collection had only Es in it
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return list;
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(elements));
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Factory method that skips the null checks.  Used only when the elements
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // are guaranteed to be null.
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static <E> ImmutableList<E> unsafeDelegateList(List<? extends E> list) {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (list.size()) {
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 0:
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return of();
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case 1:
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new SingletonImmutableList<E>(list.iterator().next());
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @SuppressWarnings("unchecked")
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        List<E> castedList = (List<E>) list;
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new RegularImmutableList<E>(castedList);
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static <E> ImmutableList<E> backedBy(E[] elements) {
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return unsafeDelegateList(Arrays.asList(elements));
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> List<E> nullCheckedList(Object... array) {
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0, len = array.length; i < len; i++) {
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (array[i] == null) {
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throw new NullPointerException("at index " + i);
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    E[] castedArray = (E[]) array;
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Arrays.asList(castedArray);
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int indexOf(@Nullable Object object) {
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.indexOf(object);
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int lastIndexOf(@Nullable Object object) {
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.lastIndexOf(object);
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final boolean addAll(int index, Collection<? extends E> newElements) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final E set(int index, E element) {
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final void add(int index, E element) {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final E remove(int index) {
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public E get(int index) {
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.get(index);
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ImmutableList<E> subList(int fromIndex, int toIndex) {
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return unsafeDelegateList(delegate.subList(fromIndex, toIndex));
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ListIterator<E> listIterator() {
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.listIterator();
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ListIterator<E> listIterator(int index) {
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.listIterator(index);
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public ImmutableList<E> asList() {
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return this;
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ImmutableList<E> reverse(){
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<E> list = Lists.newArrayList(this);
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collections.reverse(list);
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return unsafeDelegateList(list);
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public Object[] toArray() {
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Note that ArrayList.toArray() doesn't work here because it returns E[]
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // instead of Object[].
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.toArray(new Object[size()]);
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public boolean equals(Object obj) {
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.equals(obj);
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public int hashCode() {
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return delegate.hashCode();
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> Builder<E> builder() {
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new Builder<E>();
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final class Builder<E> extends ImmutableCollection.Builder<E> {
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final ArrayList<E> contents = Lists.newArrayList();
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder() {}
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Builder<E> add(E element) {
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      contents.add(checkNotNull(element));
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Builder<E> addAll(Iterable<? extends E> elements) {
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.addAll(elements);
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Builder<E> add(E... elements) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(elements);  // for GWT
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.add(elements);
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Builder<E> addAll(Iterator<? extends E> elements) {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.addAll(elements);
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ImmutableList<E> build() {
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return copyOf(contents);
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
319