/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.
 */

public class Main {
    // Enough to trigger JIT.
    static final int loopIterations = 5000;
    static int counter = 0;

    static interface TheInterface {
      public void m();
    }

    static abstract class AbstractClass implements TheInterface {
    }

    static class ConcreteClass extends AbstractClass {
        public void m() {
            ++counter;
        }
    }

    static void doStuff(AbstractClass c) {
        for (int i = 0; i < loopIterations; ++i) {
            c.m();
        }
    }

    public static void main(String[] args) throws Exception {
        ConcreteClass o = new ConcreteClass();
        for (int i = 0; i < loopIterations; ++i) {
          doStuff(o);
        }
        if (counter != loopIterations * loopIterations) {
          System.out.println("Expected " + loopIterations * loopIterations + " got " + counter);
        }

        try {
            Class<?> b21646347 = Class.forName("B21646347");
            throw new RuntimeException("Expected a VerifyError");
        } catch (VerifyError expected) {
            System.out.println("b/21646347");
        } catch (Throwable t) {
            t.printStackTrace(System.out);
        }
        System.out.println("Finishing");
    }
}
