package jetbrains.mps.internal.collections.runtime;

/*Generated by MPS */

import java.util.Set;
import java.io.Serializable;
import java.util.Collections;
import jetbrains.mps.internal.collections.runtime.impl.NullSetSequence;
import java.util.HashSet;
import java.util.List;
import java.util.Arrays;
import java.util.Collection;

public class SetSequence<T> extends AbstractSetSequence<T> implements ISetSequence<T>, Set<T>, Serializable {
  private static final long serialVersionUID = 541380543157727748L;
  protected SetSequence(Set<T> set) {
    super(set);
  }
  @Override
  public ISetSequence<T> asUnmodifiable() {
    return new SetSequence<T>(Collections.unmodifiableSet(getSet()));
  }
  @Override
  public ISetSequence<T> asSynchronized() {
    return new SetSequence<T>(Collections.unmodifiableSet(getSet()));
  }
  public static <U> ISetSequence<U> fromArray(U... array) {
    if (Sequence.USE_NULL_SEQUENCE) {
      if (array == null) {
        return NullSetSequence.instance();
      }
    }
    return SetSequence.fromSetAndArray(new HashSet<U>(), array);
  }
  public static <U> ISetSequence<U> fromSet(Set<U> set) {
    if (Sequence.USE_NULL_SEQUENCE) {
      if (set == null) {
        return NullSetSequence.instance();
      }
    }
    if (set instanceof ISetSequence) {
      return (ISetSequence<U>) set;
    }
    return new SetSequence<U>(set);
  }
  public static <U> ISetSequence<U> fromSetAndArray(Set<U> set, U... array) {
    if (Sequence.NULL_ARRAY_IS_SINGLETON) {
      if (array == null) {
        array = (U[]) Sequence.nullSingletonArray();
      }
    }
    if (Sequence.USE_NULL_SEQUENCE) {
      if (set == null && array == null) {
        return NullSetSequence.instance();
      } else
      if (set == null) {
        set = new HashSet<U>();
      } else
      if (array == null) {
        if (set instanceof ISetSequence) {
          return (ISetSequence<U>) set;
        }
        return new SetSequence<U>(set);
      }
    }
    List<U> input = Arrays.asList(array);
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : input) {
        if (u != null) {
          set.add(u);
        }
      }
    } else {
      set.addAll(input);
    }
    if (set instanceof ISetSequence) {
      return (ISetSequence<U>) set;
    }
    return new SetSequence<U>(set);
  }
  public static <U> ISetSequence<U> fromIterable(Iterable<U> it) {
    if (Sequence.USE_NULL_SEQUENCE) {
      if (it == null) {
        return NullSetSequence.instance();
      }
    }
    if (it instanceof ISetSequence) {
      return (ISetSequence<U>) it;
    }
    Set<U> set = new HashSet<U>();
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : it) {
        if (u != null) {
          set.add(u);
        }
      }
    } else
    if (it instanceof Collection) {
      set.addAll((Collection<? extends U>) it);
    } else {
      for (U u : it) {
        set.add(u);
      }
    }
    return new SetSequence<U>(set);
  }
  public static <U> ISetSequence<U> fromSetWithValues(Set<U> set, Iterable<? extends U> it) {
    Set<U> tmp = set;
    if (Sequence.USE_NULL_SEQUENCE) {
      if (set == null && it == null) {
        return NullSetSequence.instance();
      } else
      if (set == null) {
        tmp = new HashSet<U>();
      } else
      if (it == null) {
        return SetSequence.fromSet(set);
      }
    }
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : it) {
        if (u != null) {
          tmp.add(u);
        }
      }
    } else
    if (it instanceof Collection) {
      tmp.addAll((Collection<? extends U>) it);
    } else {
      for (U u : it) {
        tmp.add(u);
      }
    }
    if (tmp instanceof ISetSequence) {
      return (ISetSequence<U>) tmp;
    }
    return new SetSequence<U>(tmp);
  }
}
