/*
 * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug 4189641
 * @summary Wrapping a null collection/array should blow up sooner
 *          rather than later
 */

import java.util.*;

public class WrappedNull {
      public static void main(String argv[]) throws Exception {
          boolean testSucceeded = false;
          try{
              List l = Arrays.asList(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("Arrays.asList");

          testSucceeded = false;
          try{
              Collection c = Collections.unmodifiableCollection(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableCollection");

          testSucceeded = false;
          try{
              Set c = Collections.unmodifiableSet(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableSet");

          testSucceeded = false;
          try{
              List c = Collections.unmodifiableList(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableList");

          testSucceeded = false;
          try{
              Map c = Collections.unmodifiableMap(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableMap");

          testSucceeded = false;
          try{
              SortedSet c = Collections.unmodifiableSortedSet(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableSortedSet");

          testSucceeded = false;
          try{
              SortedMap c = Collections.unmodifiableSortedMap(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("unmodifiableSortedMap");

          testSucceeded = false;
          try{
              Collection c = Collections.synchronizedCollection(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedCollection");

          testSucceeded = false;
          try{
              Set c = Collections.synchronizedSet(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedSet");

          testSucceeded = false;
          try{
              List c = Collections.synchronizedList(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedList");

          testSucceeded = false;
          try{
              Map c = Collections.synchronizedMap(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedMap");

          testSucceeded = false;
          try{
              SortedSet c = Collections.synchronizedSortedSet(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedSortedSet");

          testSucceeded = false;
          try{
              SortedMap c = Collections.synchronizedSortedMap(null);
          }
          catch (NullPointerException e) {
              testSucceeded = true;
          }
          if(!testSucceeded)
              throw new Exception("synchronizedSortedMap");

          // Make sure that non-null arguments don't throw exc.
          List l = Arrays.asList(new Object[0]);
          Collection c = Collections.unmodifiableCollection(
                             Collections.EMPTY_SET);
          Set s = Collections.unmodifiableSet(Collections.EMPTY_SET);
          l = Collections.unmodifiableList(Collections.EMPTY_LIST);
          Map m = Collections.unmodifiableMap(Collections.EMPTY_MAP);
          SortedSet ss = Collections.unmodifiableSortedSet(new TreeSet());
          SortedMap sm = Collections.unmodifiableSortedMap(new TreeMap());

          c = Collections.synchronizedCollection(Collections.EMPTY_SET);
          s = Collections.synchronizedSet(Collections.EMPTY_SET);
          l = Collections.synchronizedList(Collections.EMPTY_LIST);
          m = Collections.synchronizedMap(Collections.EMPTY_MAP);
          ss = Collections.synchronizedSortedSet(new TreeSet());
          sm = Collections.synchronizedSortedMap(new TreeMap());
      }
}
