/*
 * Copyright (C) 2009-2011 Mathias Doenitz
 *
 * 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.
 */

package org.parboiled;

import static org.parboiled.common.Preconditions.*;
import org.parboiled.transform.ParserTransformer;

import java.lang.reflect.Constructor;

import static org.parboiled.common.Utils.findConstructor;

/**
 * Main class providing the high-level entry point into the parboiled library.
 */
public class Parboiled {

    protected Parboiled() {}

    /**
     * <p>Creates a parser object whose rule creation methods can then be used with one of the {@link org.parboiled.parserunners.ParseRunner} implementations.</p>
     * <p>Since parboiled needs to extend your parser with certain extra logic (e.g. to prevent infinite recursions
     * in recursive rule definitions) you cannot create your parser object yourself, but have to go through this method.
     * Also your parser class has to be derived from {@link BaseParser}. If you want to use a non-default constructor
     * you can provide its arguments to this method. Make sure your non-default constructor does not use primitive
     * type parameters (like "int") but rather their boxed counterparts (like "Integer"), otherwise the constructor
     * will not be found.</p>
     * <p>Performing the rule analysis and extending the parser class is an expensive process (time-wise) and can
     * take up to several hundred milliseconds for large grammars. However, this cost is only incurred once per
     * parser class and class loader. Subsequent calls to this method are therefore fast once the initial extension
     * has been performed.</p>
     *
     * @param parserClass     the type of the parser to create
     * @param constructorArgs optional arguments to the parser class constructor
     * @return the ready to use parser instance
     */
    @SuppressWarnings({"unchecked"})
    public static <P extends BaseParser<V>, V> P createParser(Class<P> parserClass, Object... constructorArgs) {
        checkArgNotNull(parserClass, "parserClass");
        try {
            Class<?> extendedClass = ParserTransformer.transformParser(parserClass);
            Constructor constructor = findConstructor(extendedClass, constructorArgs);
            return (P) constructor.newInstance(constructorArgs);
        } catch (Exception e) {
            throw new RuntimeException("Error creating extended parser class: " + e.getMessage(), e);
        }
    }

}

@@ -626,60 +626,8 @@
 d;%0A%0A
-import static org.parboiled.common.Preconditions.*;%0A
 impo
@@ -751,29 +751,67 @@
 mon.
-Utils.findConstructor
+Preconditions.*;%0Aimport static org.parboiled.common.Utils.*
 ;%0A%0A/
@@ -2924,10 +2924,946 @@
 %0A    %7D%0A%0A
+    /**%0A     * Generate the byte code of a transformed parser class%0A     *%0A     * %3Cp%3EWhen you create a parser using %7B@link%0A     * #createParser(Class, Object...)%7D, Parboiled generates a new class which%0A     * is the one you actually use for parsing. This method allows to get the%0A     * byte code of such a generated class in a byte array.%3C/p%3E%0A     *%0A     * @param parserClass the parser class%0A     * @param %3CP%3E class of the parser%0A     * @param %3CV%3E see %7B@link BaseParser%7D%0A     * @return the byte code%0A     * @throws RuntimeException byte code generation failure%0A     *%0A     * @see ParserTransformer#getByteCode(Class)%0A     */%0A    public static %3CP extends BaseParser%3CV%3E, V%3E byte%5B%5D getByteCode(%0A        final Class%3CP%3E parserClass)%0A    %7B%0A        try %7B%0A            return ParserTransformer.getByteCode(parserClass);%0A        %7D catch (Exception e) %7B%0A            throw new RuntimeException(%22failed to generate byte code%22, e);%0A        %7D%0A    %7D%0A
 %7D%0A

add a .getByteCode() method