package com.google.common.collect;

import com.google.common.annotations.GwtCompatible;
import java.util.Comparator;
import java.util.NavigableSet;

@GwtCompatible(
   emulated = true
)
final class UnmodifiableSortedMultiset<E> extends Multisets.UnmodifiableMultiset<E> implements SortedMultiset<E> {
   private transient UnmodifiableSortedMultiset<E> descendingMultiset;
   private static final long serialVersionUID = 0L;

   UnmodifiableSortedMultiset(SortedMultiset<E> delegate) {
      super(delegate);
   }

   protected SortedMultiset<E> delegate() {
      return (SortedMultiset)super.delegate();
   }

   public Comparator<? super E> comparator() {
      return this.delegate().comparator();
   }

   NavigableSet<E> createElementSet() {
      return Sets.unmodifiableNavigableSet(this.delegate().elementSet());
   }

   public NavigableSet<E> elementSet() {
      return (NavigableSet)super.elementSet();
   }

   public SortedMultiset<E> descendingMultiset() {
      UnmodifiableSortedMultiset<E> result = this.descendingMultiset;
      if (result == null) {
         result = new UnmodifiableSortedMultiset(this.delegate().descendingMultiset());
         result.descendingMultiset = this;
         return this.descendingMultiset = result;
      } else {
         return result;
      }
   }

   public Multiset.Entry<E> firstEntry() {
      return this.delegate().firstEntry();
   }

   public Multiset.Entry<E> lastEntry() {
      return this.delegate().lastEntry();
   }

   public Multiset.Entry<E> pollFirstEntry() {
      throw new UnsupportedOperationException();
   }

   public Multiset.Entry<E> pollLastEntry() {
      throw new UnsupportedOperationException();
   }

   public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
      return Multisets.unmodifiableSortedMultiset(this.delegate().headMultiset(upperBound, boundType));
   }

   public SortedMultiset<E> subMultiset(E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) {
      return Multisets.unmodifiableSortedMultiset(this.delegate().subMultiset(lowerBound, lowerBoundType, upperBound, upperBoundType));
   }

   public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
      return Multisets.unmodifiableSortedMultiset(this.delegate().tailMultiset(lowerBound, boundType));
   }
}
