/*
 * Copyright (C) 2009-2011 Mathias Doenitz
 *
 * 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 org.parboiled.common;

import com.google.common.collect.ForwardingList;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.ListIterator;

// TODO: get rid of it
public class ImmutableLinkedList<T>
    extends ForwardingList<T>
{
    private static final ImmutableLinkedList<Object> NIL
        = new ImmutableLinkedList<Object>(ImmutableList.of())
    {
        @Override
        public Object head()
        {
            throw new UnsupportedOperationException("head of empty list");
        }

        @Override
        public ImmutableLinkedList<Object> tail()
        {
            throw new UnsupportedOperationException("tail of empty list");
        }

        @Override
        public Object last()
        {
            throw new UnsupportedOperationException("last of empty list");
        }

        @Override
        protected List<Object> delegate()
        {
            return ImmutableList.of();
        }

        @Override
        public ListIterator<Object> listIterator(final int index)
        {
            return ImmutableList.of().listIterator();
        }
    };

    private final List<T> elements;

    @Override
    protected List<T> delegate()
    {
        return elements;
    }

    @SuppressWarnings("unchecked")
    public static <T> ImmutableLinkedList<T> nil()
    {
        return (ImmutableLinkedList<T>) NIL;
    }

    public ImmutableLinkedList(final T head, final ImmutableLinkedList<T> tail)
    {
        elements = ImmutableList.<T>builder().add(head)
            .addAll(tail).build();
    }

    private ImmutableLinkedList(final List<T> elements)
    {
        this.elements = ImmutableList.copyOf(elements);
    }

    public T head()
    {
        return Iterables.getFirst(elements, null);
    }

    public ImmutableLinkedList<T> tail()
    {
        return new ImmutableLinkedList<T>(elements.subList(1, elements.size()));
    }

    public T last()
    {
        return Iterables.getLast(elements);
    }

    public ImmutableLinkedList<T> prepend(final T object)
    {
        return new ImmutableLinkedList<T>(object, this);
    }

    public ImmutableLinkedList<T> reverse()
    {
        return new ImmutableLinkedList<T>(Lists.reverse(elements));
    }
}

@@ -42,16 +42,84 @@
 nitz%0A *%0A
+ * Heavy modifications by Francis Galiegue %3Cfgaliegue@gmail.com%3E%0A *%0A
  * Licen
@@ -906,991 +906,105 @@
 st;%0A
-import java.util.ListIterator;%0A%0A// TODO: get rid of it%0Apublic class ImmutableLinkedList%3CT%3E%0A    extends ForwardingList%3CT%3E%0A%7B%0A    private static final ImmutableLinkedList%3CObject%3E NIL%0A        = new ImmutableLinkedList%3CObject%3E(ImmutableList.of())%0A    %7B%0A        @Override%0A        public Object head()%0A        %7B%0A            throw new UnsupportedOperationException(%22head of empty list%22);%0A        %7D%0A%0A        @Override%0A        public ImmutableLinkedList%3CObject%3E tail()%0A        %7B%0A            throw new UnsupportedOperationException(%22tail of empty list%22);%0A        %7D%0A%0A        @Override%0A        public Object last()%0A        %7B%0A            throw new UnsupportedOperationException(%22last of empty list%22);%0A        %7D%0A%0A        @Override%0A        protected List%3CObject%3E delegate()%0A        %7B%0A            return ImmutableList.of();%0A        %7D%0A%0A        @Override%0A        public ListIterator%3CObject%3E listIterator(final int index)%0A        %7B%0A            return ImmutableList.of().listIterator();%0A        %7D%0A    %7D;%0A
+%0A// TODO: get rid of it%0Apublic final class ImmutableLinkedList%3CT%3E%0A    extends ForwardingList%3CT%3E%0A%7B
 %0A   
@@ -1126,43 +1126,8 @@
  %7D%0A%0A
-    @SuppressWarnings(%22unchecked%22)%0A
     
@@ -1194,17 +1194,20 @@
  return 
-(
+new 
 Immutabl
@@ -1224,13 +1224,31 @@
 t%3CT%3E
-) NIL
+(ImmutableList.%3CT%3Eof())
 ;%0A  
@@ -1249,37 +1249,38 @@
 ));%0A    %7D%0A%0A    p
-ublic
+rivate
  ImmutableLinked
@@ -1398,21 +1398,8 @@
 ead)
-%0A            
 .add

Make ImmutableLinkedList final