/*
 * Copyright 2000 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 4323074
 * @summary Basic test for Collections.indexOfSubList/lastIndexOfSubList
 */

import java.util.*;

public class FindSubList {
    public static void main(String[] args) throws Exception {
        int N = 500;
        List source = new ArrayList(3 * N);
        List target[]= new List[N+1];
        int  index[] = new  int[N+1];
        for (int i=0; i<=N; i++) {
            List t = new ArrayList();
            String s = Integer.toString(i, 2);
            for (int j=0, len = s.length(); j<len; j++)
                t.add(s.charAt(j)=='1' ? "1" : "0");
            target[i] = t;
            if (i == N) {
                index[i] = -1;
            } else {
                index[i] = source.size();
                source.addAll(t);
                source.add("*");
            }
        }

        List src[] = {source, new LinkedList(source), new Vector(source),
                      Arrays.asList(source.toArray())};
        for (int j=0; j<src.length; j++) {
            List s = src[j];

            for (int i=0; i<=N; i++) {
                int idx = Collections.indexOfSubList(s, target[i]);
                if (idx != index[i])
                    throw new Exception(s.getClass()+" indexOfSubList: " + i +
                                        "is " + idx + ", should be "+index[i]);
            }

            if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
                                                                 "0")) != -1)
               throw new Exception(s.getClass()+" indexOfSubList: big target");

        }

        Collections.reverse(source);
        int srcSize = source.size();
        for (int i=0; i<=N; i++) {
            Collections.reverse(target[i]);
            if (i != N)
                index[i] = srcSize - index[i] - target[i].size();
        }
        List src2[] = {source, new LinkedList(source), new Vector(source),
                       Arrays.asList(source.toArray())};
        for (int j=0; j<src2.length; j++) {
            List s = src2[j];

            for (int i=0; i<=N; i++) {
                int idx = Collections.lastIndexOfSubList(s, target[i]);
                if (idx != index[i])
                    throw new Exception(s.getClass()+" lastIdexOfSubList: "+i +
                                        "is " + idx + ", should be "+index[i]);
            }
            if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
                                                                 "0")) != -1)
              throw new Exception(s.getClass()+" lastIndexOfSubList: big tgt");
        }
    }
}
