// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

[ Constructor ]
interface SequenceUser {
  sequence<ArbitraryInterface> getInterfaceSequence();
  sequence<sequence<sequence<ArbitraryInterface>>>
  getInterfaceSequenceSequenceSequence();
  sequence<long> getLongSequence();
  sequence<DOMString> getStringSequence();
  sequence<sequence<DOMString>> getStringSequenceSequence();
  (DOMString or sequence<DOMString>) getUnionOfStringAndStringSequence();
  sequence<(DOMString or ArbitraryInterface)> getUnionSequence();

  void setInterfaceSequence(sequence<ArbitraryInterface> elements);
  void setInterfaceSequenceSequenceSequence(
      sequence<sequence<sequence<ArbitraryInterface>>> elements);
  void setLongSequence(sequence<long> elements);
  void setStringSequence(sequence<DOMString> elements);
  void setStringSequenceSequence(sequence<sequence<DOMString>> elements);
  void setUnionOfStringAndStringSequence(
      (DOMString or sequence<DOMString>) elements);
  void setUnionSequence(sequence<(DOMString or ArbitraryInterface)> elements);
};
