org.apache.camel.util.MainSupport

public abstract class MainSupport extends ServiceSupport {
    protected static final Log LOG = LogFactory.getLog(MainSupport.class);
    protected String dotOutputDir;
    private List<Option> options = new ArrayList<Option>();
    private CountDownLatch latch = new CountDownLatch(1);
    private AtomicBoolean completed = new AtomicBoolean(false);
    private long duration = -1;
    private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
    private String routesOutputFile;
    private boolean aggregateDot;
    private boolean debug;
    private boolean trace;
    private List<RouteBuilder> routeBuilders = new ArrayList<RouteBuilder>();
    private List<CamelContext> camelContexts = new ArrayList<CamelContext>();
    private ProducerTemplate camelTemplate;

    protected MainSupport() {
        addOption(new Option("h", "help", "Displays the help screen") {
            protected void doProcess(String arg, LinkedList<String> remainingArgs) {
                showOptions();
                completed();
            }
        });
        addOption(new ParameterOption("o", "outdir",
                "Sets the DOT output directory where the visual representations of the routes are generated",
                "dot") {
            protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
                setDotOutputDir(parameter);
            }
        });
        addOption(new ParameterOption("ad", "aggregate-dot",
                "Aggregates all routes (in addition to individual route generation) into one context to create one monolithic DOT file for visual representations the entire system.",
                "aggregate-dot") {
            protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
                setAggregateDot("true".equals(parameter));
            }
        });
        addOption(new ParameterOption("d", "duration",
                "Sets the time duration that the applicaiton will run for, by default in milliseconds. You can use '10s' for 10 seconds etc",
                "duration") {
            protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
                String value = parameter.toUpperCase();
                if (value.endsWith("S")) {
                    value = value.substring(0, value.length() - 1);
                    setTimeUnit(TimeUnit.SECONDS);
                }
                setDuration(Integer.parseInt(value));
            }
        });

        addOption(new Option("x", "debug", "Enables the debugger") {
            protected void doProcess(String arg, LinkedList<String> remainingArgs) {
                enableDebug();
            }
        });
        addOption(new Option("t", "trace", "Enables tracing") {
            protected void doProcess(String arg, LinkedList<String> remainingArgs) {
                enableTrace();
            }
        });
        addOption(new ParameterOption("out", "output", "Output all routes to the specified XML file", "filename") {
            protected void doProcess(String arg, String parameter,
                    LinkedList<String> remainingArgs) {
                setRoutesOutputFile(parameter);
            }
        });
    }

    /**
     * Runs this process with the given arguments
     */
    public void run() {
        if (!completed.get()) {
            try {
                start();
                waitUntilCompleted();
                stop();
            } catch (Exception e) {
                LOG.error("Failed: " + e, e);
            }
        }
    }

    /**
     * Marks this process as being completed
     */
    public void completed() {
        completed.set(true);
        latch.countDown();
    }

    /**
     * Displays the command line options
     */
    public void showOptions() {
        showOptionsHeader();

        for (Option option : options) {
            System.out.println(option.getInformation());
        }
    }

    /**
     * Parses the command line arguments
     */
    public void parseArguments(String[] arguments) {
        LinkedList<String> args = new LinkedList<String>(Arrays.asList(arguments));

        boolean valid = true;
        while (!args.isEmpty()) {
            String arg = args.removeFirst();

            boolean handled = false;
            for (Option option : options) {
                if (option.processOption(arg, args)) {
                    handled = true;
                    break;
                }
            }
            if (!handled) {
                System.out.println("Unknown option: " + arg);
                System.out.println();
                valid = false;
                break;
            }
        }
        if (!valid) {
            showOptions();
            completed();
        }
    }

    public void addOption(Option option) {
        options.add(option);
    }

    public long getDuration() {
        return duration;
    }

    /**
     * Sets the duration to run the application for in milliseconds until it
     * should be terminated. Defaults to -1. Any value <= 0 will run forever.
     */
    public void setDuration(long duration) {
        this.duration = duration;
    }

    public TimeUnit getTimeUnit() {
        return timeUnit;
    }

    /**
     * Sets the time unit duration
     */
    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }

    public String getDotOutputDir() {
        return dotOutputDir;
    }

    /**
     * Sets the output directory of the generated DOT Files to show the visual
     * representation of the routes. A null value disables the dot file
     * generation
     */
    public void setDotOutputDir(String dotOutputDir) {
        this.dotOutputDir = dotOutputDir;
    }

    public void setAggregateDot(boolean aggregateDot) {
        this.aggregateDot = aggregateDot;
    }

    public boolean isAggregateDot() {
        return aggregateDot;
    }

    public boolean isDebug() {
        return debug;
    }

    public void enableDebug() {
        this.debug = true;
    }

    public boolean isTrace() {
        return trace;
    }

    public void enableTrace() {
        this.trace = true;
    }

    public void setRoutesOutputFile(String routesOutputFile) {
        this.routesOutputFile = routesOutputFile;
    }

    public String getRoutesOutputFile() {
        return routesOutputFile;
    }

    /**
     * Returns the currently active debugger if one is enabled
     *
     * @return the current debugger or null if none is active
     * @see #enableDebug()
     */
    public Debugger getDebugger() {
        for (CamelContext camelContext : camelContexts) {
            Debugger debugger = Debugger.getDebugger(camelContext);
            if (debugger != null) {
                return debugger;
            }
        }
        return null;
    }

    protected void doStop() throws Exception {
        LOG.info("Apache Camel " + getVersion() + " stopping");
        completed();
    }

    protected void doStart() throws Exception {
        LOG.info("Apache Camel " + getVersion() + " starting");
    }

    protected void waitUntilCompleted() {
        while (!completed.get()) {
            try {
                if (duration > 0) {
                    TimeUnit unit = getTimeUnit();
                    LOG.info("Waiting for: " + duration + " " + unit);
                    latch.await(duration, unit);
                    completed.set(true);
                } else {
                    latch.await();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * Parses the command line arguments then runs the program
     */
    public void run(String[] args) {
        parseArguments(args);
        run();
    }

    /**
     * Displays the header message for the command line options
     */
    public void showOptionsHeader() {
        System.out.println("Apache Camel Runner takes the following options");
        System.out.println();
    }

    public List<CamelContext> getCamelContexts() {
        return camelContexts;
    }

    public List<RouteBuilder> getRouteBuilders() {
        return routeBuilders;
    }

    public void setRouteBuilders(List<RouteBuilder> routeBuilders) {
        this.routeBuilders = routeBuilders;
    }

    public List<RouteType> getRouteDefinitions() {
        List<RouteType> answer = new ArrayList<RouteType>();
        for (CamelContext camelContext : camelContexts) {
            answer.addAll(camelContext.getRouteDefinitions());
        }
        return answer;
    }

    /**
     * Returns a {@link org.apache.camel.ProducerTemplate} from the Spring {@link org.springframework.context.ApplicationContext} instances
     * or lazily creates a new one dynamically
     */
    public ProducerTemplate getCamelTemplate() {
        if (camelTemplate == null) {
            camelTemplate = findOrCreateCamelTemplate();
        }
        return camelTemplate;
    }

    protected abstract ProducerTemplate findOrCreateCamelTemplate();

    protected abstract Map<String, CamelContext> getCamelContextMap();

    protected void postProcessContext() throws Exception {
        Map<String, CamelContext> map = getCamelContextMap();
        Set<Map.Entry<String, CamelContext>> entries = map.entrySet();
        int size = entries.size();
        for (Map.Entry<String, CamelContext> entry : entries) {
            String name = entry.getKey();
            CamelContext camelContext = entry.getValue();
            camelContexts.add(camelContext);
            generateDot(name, camelContext, size);
            postProcesCamelContext(camelContext);
        }

        if (isAggregateDot()) {
            generateDot("aggregate", aggregateCamelContext(), 1);
        }

        if (!"".equals(getRoutesOutputFile())) {
            outputRoutesToFile();
        }
    }

    protected void outputRoutesToFile() throws IOException, JAXBException {
        if (ObjectHelper.isNotNullAndNonEmpty(getRoutesOutputFile())) {
            LOG.info("Generating routes as XML in the file named: " + getRoutesOutputFile());
            ModelFileGenerator generator = createModelFileGenerator();
            generator.marshalRoutesUsingJaxb(getRoutesOutputFile(), getRouteDefinitions());
        }
    }

    protected abstract ModelFileGenerator createModelFileGenerator() throws JAXBException;

    protected void generateDot(String name, CamelContext camelContext, int size) throws IOException {
        String outputDir = dotOutputDir;
        if (ObjectHelper.isNotNullAndNonEmpty(outputDir)) {
            if (size > 1) {
                outputDir += "/" + name;
            }
            RouteDotGenerator generator = new RouteDotGenerator(outputDir);
            LOG.info("Generating DOT file for routes: " + outputDir + " for: " + camelContext + " with name: " + name);
            generator.drawRoutes(camelContext);
        }
    }

    /**
     * Used for aggregate dot generation, generate a single camel context containing all of the available contexts
     */
    private CamelContext aggregateCamelContext() throws Exception {
        if (camelContexts.size() == 1) {
            return camelContexts.get(0);
        } else {
            DefaultCamelContext answer = new DefaultCamelContext();
            for (CamelContext camelContext : camelContexts) {
                answer.addRouteDefinitions(camelContext.getRouteDefinitions());
            }
            return answer;
        }
    }

    protected void postProcesCamelContext(CamelContext camelContext) throws Exception {
        for (RouteBuilder routeBuilder : routeBuilders) {
            camelContext.addRoutes(routeBuilder);
        }
    }

    public void addRouteBuilder(RouteBuilder routeBuilder) {
        getRouteBuilders().add(routeBuilder);
    }

    public abstract class Option {
        private String abbreviation;
        private String fullName;
        private String description;

        protected Option(String abbreviation, String fullName, String description) {
            this.abbreviation = "-" + abbreviation;
            this.fullName = "-" + fullName;
            this.description = description;
        }

        public boolean processOption(String arg, LinkedList<String> remainingArgs) {
            if (arg.equalsIgnoreCase(abbreviation) || fullName.startsWith(arg)) {
                doProcess(arg, remainingArgs);
                return true;
            }
            return false;
        }

        public String getAbbreviation() {
            return abbreviation;
        }

        public String getDescription() {
            return description;
        }

        public String getFullName() {
            return fullName;
        }

        public String getInformation() {
            return "  " + getAbbreviation() + " or " + getFullName() + " = " + getDescription();
        }

        protected abstract void doProcess(String arg, LinkedList<String> remainingArgs);
    }

    public abstract class ParameterOption extends Option {
        private String parameterName;

        protected ParameterOption(String abbreviation, String fullName, String description,
                String parameterName) {
            super(abbreviation, fullName, description);
            this.parameterName = parameterName;
        }

        protected void doProcess(String arg, LinkedList<String> remainingArgs) {
            if (remainingArgs.isEmpty()) {
                System.err.println("Expected fileName for ");
                showOptions();
                completed();
            } else {
                String parameter = remainingArgs.removeFirst();
                doProcess(arg, parameter, remainingArgs);
            }
        }

        public String getInformation() {
            return "  " + getAbbreviation() + " or " + getFullName()
                    + " <" + parameterName + "> = " + getDescription();
        }

        protected abstract void doProcess(String arg, String parameter, LinkedList<String> remainingArgs);

FUNC_DECL IF CALL TRY CATCH CALL CALL CALL CALL BINARY_OP LITERAL_ANCHOR

FUNC_DECL RETURN LOOP VAR_DECL CALL CALL CALL

FUNC_DECL IF CALL VAR_DECL CALL CALL CALL CALL CALL CALL BINARY_OP CALL LITERAL_ANCHOR


public final class PrefixLines
    extends BaseParamFilterReader
    implements ChainableReader {
    /** Parameter name for the prefix. */
    private static final String PREFIX_KEY = "prefix";

    /** The prefix to be used. */
    private String prefix = null;

    /** Data that must be read from, if not null. */
    private String queuedData = null;

    /**
     * Constructor for "dummy" instances.
     *
     * @see BaseFilterReader#BaseFilterReader()
     */
    public PrefixLines() {
        super();
    }

    /**
     * Creates a new filtered reader.
     *
     * @param in A Reader object providing the underlying stream.
     *           Must not be null.
     */
    public PrefixLines(final Reader in) {
        super(in);
    }

    /**
     * Returns the next character in the filtered stream. One line is read
     * from the original input, and the prefix added. The resulting
     * line is then used until it ends, at which point the next original line
     * is read, etc.
     *
     * @return the next character in the resulting stream, or -1
     * if the end of the resulting stream has been reached
     *
     * @exception IOException if the underlying stream throws an IOException
     * during reading
     */
    public int read() throws IOException {
        if (!getInitialized()) {
            initialize();
            setInitialized(true);
        }

        int ch = -1;

        if (queuedData != null && queuedData.length() == 0) {
            queuedData = null;
        }

        if (queuedData != null) {
            ch = queuedData.charAt(0);
            queuedData = queuedData.substring(1);
            if (queuedData.length() == 0) {
                queuedData = null;
            }
        } else {
            queuedData = readLine();
            if (queuedData == null) {
                ch = -1;
            } else {
                if (prefix != null) {
                    queuedData = prefix + queuedData;
                }
                return read();
            }
        }
        return ch;
    }

    /**
     * Sets the prefix to add at the start of each input line.
     *
     * @param prefix The prefix to add at the start of each input line.
     *               May be null, in which case no prefix
     *               is added.
     */
    public void setPrefix(final String prefix) {
        this.prefix = prefix;
    }

    /**
     * Returns the prefix which will be added at the start of each input line.
     *
     * @return the prefix which will be added at the start of each input line
     */
    private String getPrefix() {
        return prefix;
    }

    /**
     * Creates a new PrefixLines filter using the passed in
     * Reader for instantiation.
     *
     * @param rdr A Reader object providing the underlying stream.
     *            Must not be null.
     *
     * @return a new filter based on this configuration, but filtering
     *         the specified reader
     */
    public Reader chain(final Reader rdr) {
        PrefixLines newFilter = new PrefixLines(rdr);
        newFilter.setPrefix(getPrefix());
        newFilter.setInitialized(true);
        return newFilter;
    }

    /**
     * Initializes the prefix if it is available from the parameters.
     */
    private void initialize() {
        Parameter[] params = getParameters();
        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                if (PREFIX_KEY.equals(params[i].getName())) {
                    prefix = params[i].getValue();
                    break;

FUNC_DECL RETURN VAR_DECL PARAM CALL CALL LITERAL_ANCHOR CALL CALL

    public PrefixLines() {
        super();


bsh.BSHLHSPrimarySuffix

class BSHLHSPrimarySuffix extends SimpleNode
{
	public static final int
		INDEX = 1,
		NAME = 2,
		PROPERTY = 3;

	public int operation;	// field access or index
	Object index;			// the index value if any
	/*
		If this is a simple field access field is the field
		If we're hopscotching a method to a field, method is the
		method name and field is the field of the resulting object
	*/
	public String field;
	public String method;

	BSHLHSPrimarySuffix(int id) { super(id); }

	public LHS doLHSSuffix(
		Object obj, CallStack callstack, Interpreter interpreter)
		throws EvalError
	{
		try
		{
			switch(operation)
			{
				case INDEX:
					return doIndex(obj, callstack, interpreter);

				case NAME:
					return doName(obj, callstack, interpreter);

				case PROPERTY:
					return doProperty(obj, callstack, interpreter);

				default:
					throw new InterpreterError("LHS suffix");
			}
		}
		catch(ReflectError e)
		{
			throw new EvalError("reflection error: " + e, this);
		}
		catch(InvocationTargetException e)
		{
			throw new TargetError(
				"target exception", e.getTargetException(), this, true);
		}
	}

	private LHS doName(
		Object obj, CallStack callstack, Interpreter interpreter)
		throws EvalError, ReflectError, InvocationTargetException
	{
		if (jjtGetNumChildren() == 0)
			// simple field access
			return Reflect.getLHSObjectField(obj, field);
		else {
			// intermediate method invocation, and field access
			Object[] oa = ((BSHArguments)jjtGetChild(0)).getArguments(
				callstack, interpreter);
			try {
				obj = Reflect.invokeObjectMethod(interpreter, obj, method, oa, this);
			} catch ( EvalError ee ) {
				// catch and re-throw to get line number right
				throw new EvalError( ee.getMessage(), this );
			}
			return Reflect.getLHSObjectField(obj, field);
		}
	}

	private LHS doIndex(
		Object obj, CallStack callstack, Interpreter interpreter)
		throws EvalError, ReflectError
	{
		int index = BSHPrimarySuffix.getIndexAux(
			obj, callstack, interpreter, this );
		return new LHS(obj, index);
	}

	private LHS doProperty(
		Object obj, CallStack callstack, Interpreter interpreter)
		throws EvalError, ReflectError
	{
		if(obj == Primitive.VOID)
			throw new EvalError("Attempt to access property on a void type", this);

		else if(obj instanceof Primitive)
			throw new EvalError("Attempt to access property on a primitive", this);

		Object value = ((SimpleNode)jjtGetChild(0)).eval(
			callstack, interpreter);

		if(!(value instanceof String))
			throw new EvalError("Property expression must be a String or identifier.", this);

		if ( Interpreter.DEBUG ) Interpreter.debug("LHS property access: ");
		return new LHS(obj, (String)value);

FUNC_DECL IF PARAM PARAM PARAM RETURN BINARY_OP RETURN TRY VAR_DECL CALL LITERAL_ANCHOR CALL CALL CATCH THROW_RAISE ASSIGN CALL CALL CALL CALL LITERAL_ANCHOR

FUNC_DECL RETURN VAR_DECL PARAM PARAM PARAM CALL CALL


org.gjt.sp.jedit.options.ModeOptionPane

public class ModeOptionPane extends AbstractOptionPane
{
	//{{{ ModeOptionPane constructor
	public ModeOptionPane()
	{
		super("mode");
	} //}}}

	//{{{ _init() method
	protected void _init()
	{
		Mode[] modes = jEdit.getModes();
		String[] modeNames = new String[modes.length];
		modeProps = new ModeProperties[modes.length];
		for(int i = 0; i < modes.length; i++)
		{
			modeProps[i] = new ModeProperties(modes[i]);
			modeNames[i] = modes[i].getName();
		}
		mode = new JComboBox(modeNames);
		mode.addActionListener(new ActionHandler());

		addComponent(jEdit.getProperty("options.mode.mode"),mode);

		useDefaults = new JCheckBox(jEdit.getProperty("options.mode.useDefaults"));
		useDefaults.addActionListener(new ActionHandler());
		addComponent(useDefaults);

		addComponent(jEdit.getProperty("options.mode.filenameGlob"),
			filenameGlob = new JTextField());

		addComponent(jEdit.getProperty("options.mode.firstlineGlob"),
			firstlineGlob = new JTextField());

		addComponent(jEdit.getProperty("options.editing.noWordSep"),
			noWordSep = new JTextField());

		String[] foldModes = FoldHandler.getFoldModes();
		addComponent(jEdit.getProperty("options.editing.folding"),
			folding = new JComboBox(foldModes));

		addComponent(jEdit.getProperty("options.editing.collapseFolds"),
			collapseFolds = new JTextField());

		String[] wrapModes = {
			"none",
			"soft",
			"hard"
		};
		addComponent(jEdit.getProperty("options.editing.wrap"),
			wrap = new JComboBox(wrapModes));

		String[] lineLens = { "0", "72", "76", "80" };
		addComponent(jEdit.getProperty("options.editing.maxLineLen"),
			maxLineLen = new JComboBox(lineLens));
		maxLineLen.setEditable(true);

		String[] tabSizes = { "2", "4", "8" };
		addComponent(jEdit.getProperty("options.editing.tabSize"),
			tabSize = new JComboBox(tabSizes));
		tabSize.setEditable(true);

		addComponent(jEdit.getProperty("options.editing.indentSize"),
			indentSize = new JComboBox(tabSizes));
		indentSize.setEditable(true);

		addComponent(noTabs = new JCheckBox(jEdit.getProperty(
			"options.editing.noTabs")));

		addComponent(indentOnTab = new JCheckBox(jEdit.getProperty(
			"options.editing.indentOnTab")));

		addComponent(indentOnEnter = new JCheckBox(jEdit.getProperty(
			"options.editing.indentOnEnter")));

		selectMode();
	} //}}}

	//{{{ _save() method
	protected void _save()
	{
		saveMode();

		for(int i = 0; i < modeProps.length; i++)
		{
			modeProps[i].save();
		}
	} //}}}

	//{{{ Private members

	//{{{ Instance variables
	private ModeProperties[] modeProps;
	private ModeProperties current;
	private JComboBox mode;
	private JCheckBox useDefaults;
	private JTextField filenameGlob;
	private JTextField firstlineGlob;
	private JTextField noWordSep;
	private JComboBox folding;
	private JTextField collapseFolds;
	private JComboBox wrap;
	private JComboBox maxLineLen;
	private JComboBox tabSize;
	private JComboBox indentSize;
	private JCheckBox noTabs;
	private JCheckBox indentOnTab;
	private JCheckBox indentOnEnter;
	//}}}

	//{{{ saveMode() method
	private void saveMode()
	{
		current.useDefaults = useDefaults.isSelected();
		current.filenameGlob = filenameGlob.getText();
		current.firstlineGlob = firstlineGlob.getText();
		current.noWordSep = noWordSep.getText();
		current.folding = (String)folding.getSelectedItem();
		current.collapseFolds = collapseFolds.getText();
		current.wrap = (String)wrap.getSelectedItem();
		current.maxLineLen = (String)maxLineLen.getSelectedItem();
		current.tabSize = (String)tabSize.getSelectedItem();
		current.indentSize = (String)indentSize.getSelectedItem();
		current.noTabs = noTabs.isSelected();
		current.indentOnEnter = indentOnEnter.isSelected();
		current.indentOnTab = indentOnTab.isSelected();
	} //}}}

	//{{{ selectMode() method
	private void selectMode()
	{
		current = modeProps[mode.getSelectedIndex()];
		current.edited = true;
		current.load();

		useDefaults.setSelected(current.useDefaults);
		filenameGlob.setText(current.filenameGlob);
		firstlineGlob.setText(current.firstlineGlob);
		noWordSep.setText(current.noWordSep);
		folding.setSelectedItem(current.folding);
		collapseFolds.setText(current.collapseFolds);
		wrap.setSelectedItem(current.wrap);
		maxLineLen.setSelectedItem(current.maxLineLen);
		tabSize.setSelectedItem(current.tabSize);
		indentSize.setSelectedItem(current.indentSize);
		noTabs.setSelected(current.noTabs);
		indentOnTab.setSelected(current.indentOnTab);
		indentOnEnter.setSelected(current.indentOnEnter);

		updateEnabled();
	} //}}}

	//{{{ updateEnabled() method
	private void updateEnabled()
	{
		boolean enabled = !modeProps[mode.getSelectedIndex()].useDefaults;
		filenameGlob.setEnabled(enabled);
		firstlineGlob.setEnabled(enabled);
		noWordSep.setEnabled(enabled);
		folding.setEnabled(enabled);
		collapseFolds.setEnabled(enabled);
		wrap.setEnabled(enabled);
		maxLineLen.setEnabled(enabled);
		tabSize.setEnabled(enabled);
		indentSize.setEnabled(enabled);
		noTabs.setEnabled(enabled);
		indentOnTab.setEnabled(enabled);
		indentOnEnter.setEnabled(enabled);
	} //}}}

	//}}}

	//{{{ ActionHandler class
	class ActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			if(evt.getSource() == mode)
			{
				saveMode();
				selectMode();
			}
			else if(evt.getSource() == useDefaults)
			{
				modeProps[mode.getSelectedIndex()].useDefaults =
					useDefaults.isSelected();
				updateEnabled();
			}
		}
	} //}}}

	//{{{ ModeProperties class
	class ModeProperties
	{
		//{{{ Instance variables
		Mode mode;
		boolean edited;
		boolean loaded;

		boolean useDefaults;
		String filenameGlob;
		String firstlineGlob;
		String noWordSep;
		String folding;
		String collapseFolds;
		String wrap;
		String maxLineLen;
		String tabSize;
		String indentSize;
		boolean noTabs;
		boolean indentOnTab;
		boolean indentOnEnter;
		//}}}

		//{{{ ModeProperties constructor
		ModeProperties(Mode mode)
		{
			this.mode = mode;
		} //}}}

		//{{{ load() method
		void load()
		{
			if(loaded)
				return;

			loaded = true;

			mode.loadIfNecessary();

			useDefaults = !jEdit.getBooleanProperty("mode."
				+ mode.getName() + ".customSettings");
			filenameGlob = (String)mode.getProperty("filenameGlob");
			firstlineGlob = (String)mode.getProperty("firstlineGlob");
			noWordSep = (String)mode.getProperty("noWordSep");
			folding = mode.getProperty("folding").toString();
			collapseFolds = mode.getProperty("collapseFolds").toString();
			wrap = mode.getProperty("wrap").toString();
			maxLineLen = mode.getProperty("maxLineLen").toString();
			tabSize = mode.getProperty("tabSize").toString();
			indentSize = mode.getProperty("indentSize").toString();
			noTabs = mode.getBooleanProperty("noTabs");
			indentOnTab = mode.getBooleanProperty("indentOnTab");
			indentOnEnter = mode.getBooleanProperty("indentOnEnter");
		} //}}}

		//{{{ save() method
		void save()
		{
			// don't do anything if the user didn't change
			// any settings
			if(!edited)
				return;

			String prefix = "mode." + mode.getName() + ".";
			jEdit.setBooleanProperty(prefix + "customSettings",!useDefaults);

			if(useDefaults)
			{
				jEdit.resetProperty(prefix + "filenameGlob");
				jEdit.resetProperty(prefix + "firstlineGlob");
				jEdit.resetProperty(prefix + "noWordSep");
				jEdit.resetProperty(prefix + "folding");
				jEdit.resetProperty(prefix + "collapseFolds");
				jEdit.resetProperty(prefix + "wrap");
				jEdit.resetProperty(prefix + "maxLineLen");
				jEdit.resetProperty(prefix + "tabSize");
				jEdit.resetProperty(prefix + "indentSize");
				jEdit.resetProperty(prefix + "noTabs");
				jEdit.resetProperty(prefix + "indentOnTab");
				jEdit.resetProperty(prefix + "indentOnEnter");
			}
			else
			{
				jEdit.setProperty(prefix + "filenameGlob",filenameGlob);
				jEdit.setProperty(prefix + "firstlineGlob",firstlineGlob);
				jEdit.setProperty(prefix + "noWordSep",noWordSep);
				jEdit.setProperty(prefix + "folding",folding);
				jEdit.setProperty(prefix + "collapseFolds",collapseFolds);
				jEdit.setProperty(prefix + "wrap",wrap);
				jEdit.setProperty(prefix + "maxLineLen",maxLineLen);
				jEdit.setProperty(prefix + "tabSize",tabSize);
				jEdit.setProperty(prefix + "indentSize",indentSize);
				jEdit.setBooleanProperty(prefix + "noTabs",noTabs);
				jEdit.setBooleanProperty(prefix + "indentOnTab",indentOnTab);
				jEdit.setBooleanProperty(prefix + "indentOnEnter",indentOnEnter);

FUNC_DECL VAR_DECL VAR_DECL VAR_DECL VAR_DECL LOOP VAR_DECL VAR_DECL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL ASSIGN CALL CALL ASSIGN BINARY_OP ASSIGN ASSIGN ASSIGN ASSIGN LITERAL_ANCHOR ASSIGN CALL LITERAL_ANCHOR ASSIGN CALL LITERAL_ANCHOR ASSIGN CALL ASSIGN CALL ASSIGN CALL ASSIGN CALL CALL ASSIGN CALL ASSIGN CALL ASSIGN CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR ASSIGN ASSIGN LITERAL_ANCHOR CALL CALL CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR CALL

FUNC_DECL ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL

FUNC_DECL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL ASSIGN ASSIGN LITERAL_ANCHOR CALL

FUNC_DECL VAR_DECL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL


public class LogLog {

  /**
     Defining this value makes log4j print log4j-internal debug
     statements to System.out.

 The value of this string is log4j.debug.

Note that the search for all option names is case sensitive.  */
  public static final String DEBUG_KEY="log4j.debug";

  /**
     Defining this value makes log4j components print log4j-internal
     debug statements to System.out.

 The value of this string is log4j.configDebug.

Note that the search for all option names is case sensitive.

    @deprecated Use {@link #DEBUG_KEY} instead.
  */
  public static final String CONFIG_DEBUG_KEY="log4j.configDebug";

  protected static boolean debugEnabled = false;

  /**
     In quietMode not even errors generate any output.
   */
  private static boolean quietMode = false;

  private static final String PREFIX = "log4j: ";
  private static final String ERR_PREFIX = "log4j:ERROR ";
  private static final String WARN_PREFIX = "log4j:WARN ";

  static {
    String key = OptionConverter.getSystemProperty(DEBUG_KEY, null);

    if(key == null) {
      key = OptionConverter.getSystemProperty(CONFIG_DEBUG_KEY, null);
    }

    if(key != null) {
      debugEnabled = OptionConverter.toBoolean(key, true);
    }
  }

  /**
     Allows to enable/disable log4j internal logging.
   */
  static
  public
  void setInternalDebugging(boolean enabled) {
    debugEnabled = enabled;
  }

  /**
     This method is used to output log4j internal debug
     statements. Output goes to System.out.
  */
  public
  static
  void debug(String msg) {
    if(debugEnabled && !quietMode) {
      System.out.println(PREFIX+msg);
    }
  }

  /**
     This method is used to output log4j internal debug
     statements. Output goes to System.out.
  */
  public
  static
  void debug(String msg, Throwable t) {
    if(debugEnabled && !quietMode) {
      System.out.println(PREFIX+msg);
      if(t != null)
	t.printStackTrace(System.out);
    }
  }

  /**
     This method is used to output log4j internal error
     statements. There is no way to disable error statements.
     Output goes to System.err.
  */
  public
  static
  void error(String msg) {
    if(quietMode)
      return;
    System.err.println(ERR_PREFIX+msg);
  }

  /**
     This method is used to output log4j internal error
     statements. There is no way to disable error statements.
     Output goes to System.err.
  */
  public
  static
  void error(String msg, Throwable t) {
    if(quietMode)
      return;

    System.err.println(ERR_PREFIX+msg);
    if(t != null) {
      t.printStackTrace();
    }
  }

  /**
     In quite mode no LogLog generates strictly no output, not even
     for errors.

     @param quietMode A true for not
  */
  public
  static
  void setQuietMode(boolean quietMode) {
    LogLog.quietMode = quietMode;
  }

  /**
     This method is used to output log4j internal warning
     statements. There is no way to disable warning statements.
     Output goes to System.err.  */
  public
  static
  void warn(String msg) {
    if(quietMode)
      return;

    System.err.println(WARN_PREFIX+msg);
  }

  /**
     This method is used to output log4j internal warnings. There is
     no way to disable warning statements.  Output goes to
     System.err.  */
  public
  static
  void warn(String msg, Throwable t) {
    if(quietMode)
      return;

    System.err.println(WARN_PREFIX+msg);
    if(t != null) {
      t.printStackTrace();

FUNC_DECL IF PARAM CALL RETURN BINARY_OP


org.apache.xalan.xsltc.dom.StepIterator

public class StepIterator extends DTMAxisIteratorBase {

    /**
     * A reference to the "outer" iterator.
     */
    protected DTMAxisIterator _source;

    /**
     * A reference to the "inner" iterator.
     */
    protected DTMAxisIterator _iterator;

    /**
     * Temp variable to store a marked position.
     */
    private int _pos = -1;

    public StepIterator(DTMAxisIterator source, DTMAxisIterator iterator) {
	_source = source;
	_iterator = iterator;
    }

    public void setRestartable(boolean isRestartable) {
	_isRestartable = isRestartable;
	_source.setRestartable(isRestartable);
    }

    public DTMAxisIterator cloneIterator() {
	_isRestartable = false;
	try {
	    final StepIterator clone = (StepIterator) super.clone();
	    clone._source = _source.cloneIterator();
	    clone._iterator = _iterator.cloneIterator();
	    clone._isRestartable = false;
	    return clone.reset();
	}
	catch (CloneNotSupportedException e) {
	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
				      e.toString());
	    return null;
	}
    }

    public DTMAxisIterator setStartNode(int node) {
	if (_isRestartable) {
	    _source.setStartNode(_startNode = node);

	    _iterator.setStartNode(_includeSelf ? _startNode : _source.next());
	    return resetPosition();
	}
	return this;
    }

    public DTMAxisIterator reset() {
	_source.reset();
	_iterator.setStartNode(_includeSelf ? _startNode : _source.next());
	return resetPosition();
    }

    public int next() {
	for (int node;;) {
	    if ((node = _iterator.next()) != END) {
		return returnNode(node);
	    }
	    else if ((node = _source.next()) == END) {
		return END;
	    }
	    else {
		_iterator.setStartNode(node);
	    }
	}
    }

    public void setMark() {
	_source.setMark();
	_iterator.setMark();
    }

    public void gotoMark() {
	_source.gotoMark();
	_iterator.gotoMark();

FUNC_DECL TRY CATCH RETURN VAR_DECL ASSIGN RETURN CALL ASSIGN ASSIGN ASSIGN LITERAL_ANCHOR LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL CALL CALL

FUNC_DECL RETURN IF PARAM RETURN CALL CALL CALL COND_EXPR ASSIGN CALL

FUNC_DECL RETURN CALL CALL CALL COND_EXPR CALL

FUNC_DECL LOOP IF IF BINARY_OP BINARY_OP RETURN ASSIGN RETURN ASSIGN CALL CALL CALL CALL


org.apache.xpath.axes.AttributeIterator

public class AttributeIterator extends ChildTestIterator
{

  /**
   * Create a AttributeIterator object.
   *
   * @param compiler A reference to the Compiler that contains the op map.
   * @param opPos The position within the op map, which contains the
   * location path expression for this itterator.
   *
   * @throws javax.xml.transform.TransformerException
   */
  AttributeIterator(Compiler compiler, int opPos, int analysis)
          throws javax.xml.transform.TransformerException
  {
    super(compiler, opPos, analysis);
  }

  /**
   * Get the next node via getFirstAttribute && getNextAttribute.
   */
  protected int getNextNode()
  {
    m_lastFetched = (DTM.NULL == m_lastFetched)
                     ? m_cdtm.getFirstAttribute(m_context)
                     : m_cdtm.getNextAttribute(m_lastFetched);
    return m_lastFetched;
  }

  /**
   * Returns the axis being iterated, if it is known.
   *
   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple
   * types.
   */
  public int getAxis()
  {
    return org.apache.xml.dtm.Axis.ATTRIBUTE;


org.apache.tools.ant.AntClassLoader

public class AntClassLoader extends ClassLoader implements SubBuildListener {

    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    /**
     * An enumeration of all resources of a given name found within the
     * classpath of this class loader. This enumeration is used by the
     * ClassLoader.findResources method, which is in
     * turn used by the ClassLoader.getResources method.
     *
     * @see AntClassLoader#findResources(String)
     * @see java.lang.ClassLoader#getResources(String)
     */
    private class ResourceEnumeration implements Enumeration {
        /**
         * The name of the resource being searched for.
         */
        private String resourceName;

        /**
         * The index of the next classpath element to search.
         */
        private int pathElementsIndex;

        /**
         * The URL of the next resource to return in the enumeration. If this
         * field is null then the enumeration has been completed,
         * i.e., there are no more elements to return.
         */
        private URL nextResource;

        /**
         * Constructs a new enumeration of resources of the given name found
         * within this class loader's classpath.
         *
         * @param name the name of the resource to search for.
         */
        ResourceEnumeration(String name) {
            this.resourceName = name;
            this.pathElementsIndex = 0;
            findNextResource();
        }

        /**
         * Indicates whether there are more elements in the enumeration to
         * return.
         *
         * @return true if there are more elements in the
         *         enumeration; false otherwise.
         */
        public boolean hasMoreElements() {
            return (this.nextResource != null);
        }

        /**
         * Returns the next resource in the enumeration.
         *
         * @return the next resource in the enumeration
         */
        public Object nextElement() {
            URL ret = this.nextResource;
            findNextResource();
            return ret;
        }

        /**
         * Locates the next resource of the correct name in the classpath and
         * sets nextResource to the URL of that resource. If no
         * more resources can be found, nextResource is set to
         * null.
         */
        private void findNextResource() {
            URL url = null;
            while ((pathElementsIndex < pathComponents.size())
                   && (url == null)) {
                try {
                    File pathComponent
                        = (File) pathComponents.elementAt(pathElementsIndex);
                    url = getResourceURL(pathComponent, this.resourceName);
                    pathElementsIndex++;
                } catch (BuildException e) {
                }
            }
            this.nextResource = url;
        }
    }

    /**
     * The size of buffers to be used in this classloader.
     */
    private static final int BUFFER_SIZE = 8192;
    /**
     * Number of array elements in a test array of strings
     */
    private static final int NUMBER_OF_STRINGS = 256;

    /**
     * The components of the classpath that the classloader searches
     * for classes.
     */
    private Vector pathComponents  = new Vector();

    /**
     * The project to which this class loader belongs.
     */
    private Project project;

    /**
     * Indicates whether the parent class loader should be
     * consulted before trying to load with this class loader.
     */
    private boolean parentFirst = true;

    /**
     * These are the package roots that are to be loaded by the parent class
     * loader regardless of whether the parent class loader is being searched
     * first or not.
     */
    private Vector systemPackages = new Vector();

    /**
     * These are the package roots that are to be loaded by this class loader
     * regardless of whether the parent class loader is being searched first
     * or not.
     */
    private Vector loaderPackages = new Vector();

    /**
     * Whether or not this classloader will ignore the base
     * classloader if it can't find a class.
     *
     * @see #setIsolated(boolean)
     */
    private boolean ignoreBase = false;

    /**
     * The parent class loader, if one is given or can be determined.
     */
    private ClassLoader parent = null;

    /**
     * A hashtable of zip files opened by the classloader (File to ZipFile).
     */
    private Hashtable zipFiles = new Hashtable();

    /** Static map of jar file/time to manifest class-path entries */
    private static Map/*<String,String>*/ pathMap = Collections.synchronizedMap(new HashMap());

    /**
     * The context loader saved when setting the thread's current
     * context loader.
     */
    private ClassLoader savedContextLoader = null;
    /**
     * Whether or not the context loader is currently saved.
     */
    private boolean isContextLoaderSaved = false;

    /**
     * Create an Ant ClassLoader for a given project, with
     * a parent classloader and an initial classpath.
     * @since Ant 1.7.
     * @param parent the parent for this classloader.
     * @param project The project to which this classloader is to
     *                belong.
     * @param classpath The classpath to use to load classes.
     */
    public AntClassLoader(
        ClassLoader parent, Project project, Path classpath) {
        setParent(parent);
        setClassPath(classpath);
        setProject(project);
    }

    /**
     * Create an Ant Class Loader
     */
    public AntClassLoader() {
        setParent(null);
    }

    /**
     * Creates a classloader for the given project using the classpath given.
     *
     * @param project The project to which this classloader is to belong.
     *                Must not be null.
     * @param classpath The classpath to use to load the classes.  This
     *                is combined with the system classpath in a manner
     *                determined by the value of ${build.sysclasspath}.
     *                May be null, in which case no path
     *                elements are set up to start with.
     */
    public AntClassLoader(Project project, Path classpath) {
        setParent(null);
        setProject(project);
        setClassPath(classpath);
    }

    /**
     * Creates a classloader for the given project using the classpath given.
     *
     * @param parent The parent classloader to which unsatisfied loading
     *               attempts are delegated. May be null,
     *               in which case the classloader which loaded this
     *               class is used as the parent.
     * @param project The project to which this classloader is to belong.
     *                Must not be null.
     * @param classpath the classpath to use to load the classes.
     *                  May be null, in which case no path
     *                  elements are set up to start with.
     * @param parentFirst If true, indicates that the parent
     *                    classloader should be consulted  before trying to
     *                    load the a class through this loader.
     */
    public AntClassLoader(ClassLoader parent, Project project, Path classpath,
                          boolean parentFirst) {
        this(project, classpath);
        if (parent != null) {
            setParent(parent);
        }
        setParentFirst(parentFirst);
        addJavaLibraries();
    }

    /**
     * Creates a classloader for the given project using the classpath given.
     *
     * @param project The project to which this classloader is to belong.
     *                Must not be null.
     * @param classpath The classpath to use to load the classes. May be
     *                  null, in which case no path
     *                  elements are set up to start with.
     * @param parentFirst If true, indicates that the parent
     *                    classloader should be consulted before trying to
     *                    load the a class through this loader.
     */
    public AntClassLoader(Project project, Path classpath,
                          boolean parentFirst) {
        this(null, project, classpath, parentFirst);
    }

    /**
     * Creates an empty class loader. The classloader should be configured
     * with path elements to specify where the loader is to look for
     * classes.
     *
     * @param parent The parent classloader to which unsatisfied loading
     *               attempts are delegated. May be null,
     *               in which case the classloader which loaded this
     *               class is used as the parent.
     * @param parentFirst If true, indicates that the parent
     *                    classloader should be consulted before trying to
     *                    load the a class through this loader.
     */
    public AntClassLoader(ClassLoader parent, boolean parentFirst) {
        setParent(parent);
        project = null;
        this.parentFirst = parentFirst;
    }

    /**
     * Set the project associated with this class loader
     *
     * @param project the project instance
     */
    public void setProject(Project project) {
        this.project = project;
        if (project != null) {
            project.addBuildListener(this);
        }
    }

    /**
     * Set the classpath to search for classes to load. This should not be
     * changed once the classloader starts to server classes
     *
     * @param classpath the search classpath consisting of directories and
     *        jar/zip files.
     */
    public void setClassPath(Path classpath) {
        pathComponents.removeAllElements();
        if (classpath != null) {
            Path actualClasspath = classpath.concatSystemClasspath("ignore");
            String[] pathElements = actualClasspath.list();
            for (int i = 0; i < pathElements.length; ++i) {
                try {
                    addPathElement(pathElements[i]);
                } catch (BuildException e) {
                }
            }
        }
    }

    /**
     * Set the parent for this class loader. This is the class loader to which
     * this class loader will delegate to load classes
     *
     * @param parent the parent class loader.
     */
    public void setParent(ClassLoader parent) {
        if (parent == null) {
            this.parent = AntClassLoader.class.getClassLoader();
        } else {
            this.parent = parent;
        }
    }

    /**
     * Control whether class lookup is delegated to the parent loader first
     * or after this loader. Use with extreme caution. Setting this to
     * false violates the class loader hierarchy and can lead to Linkage errors
     *
     * @param parentFirst if true, delegate initial class search to the parent
     *                    classloader.
     */
    public void setParentFirst(boolean parentFirst) {
        this.parentFirst = parentFirst;
    }

    /**
     * Logs a message through the project object if one has been provided.
     *
     * @param message The message to log.
     *                Should not be null.
     *
     * @param priority The logging priority of the message.
     */
    protected void log(String message, int priority) {
        if (project != null) {
            project.log(message, priority);
        }
    }

    /**
     * Sets the current thread's context loader to this classloader, storing
     * the current loader value for later resetting.
     */
    public void setThreadContextLoader() {
        if (isContextLoaderSaved) {
            throw new BuildException("Context loader has not been reset");
        }
        if (LoaderUtils.isContextLoaderAvailable()) {
            savedContextLoader = LoaderUtils.getContextClassLoader();
            ClassLoader loader = this;
            if (project != null
                && "only".equals(project.getProperty("build.sysclasspath"))) {
                loader = this.getClass().getClassLoader();
            }
            LoaderUtils.setContextClassLoader(loader);
            isContextLoaderSaved = true;
        }
    }

    /**
     * Resets the current thread's context loader to its original value.
     */
    public void resetThreadContextLoader() {
        if (LoaderUtils.isContextLoaderAvailable()
            && isContextLoaderSaved) {
            LoaderUtils.setContextClassLoader(savedContextLoader);
            savedContextLoader = null;
            isContextLoaderSaved = false;
        }
    }

    /**
     * Adds an element to the classpath to be searched.
     *
     * @param pathElement The path element to add. Must not be
     *                    null.
     *
     * @exception BuildException if the given path element cannot be resolved
     *                           against the project.
     */
    public void addPathElement(String pathElement) throws BuildException {
        File pathComponent
            = project != null ? project.resolveFile(pathElement)
            : new File(pathElement);
        try {
            addPathFile(pathComponent);
        } catch (IOException e) {
            throw new BuildException(e);
        }
    }

    /**
     * Add a path component.
     * This simply adds the file, unlike addPathElement
     * it does not open jar files and load files from
     * their CLASSPATH entry in the manifest file.
     * @param file the jar file or directory to add.
     */
    public void addPathComponent(File file) {
        if (pathComponents.contains(file)) {
            return;
        }
        pathComponents.addElement(file);
    }

    /**
     * Add a file to the path.
     * Reads the manifest, if available, and adds any additional class path jars
     * specified in the manifest.
     *
     * @param pathComponent the file which is to be added to the path for
     *                      this class loader
     *
     * @throws IOException if data needed from the file cannot be read.
     */
    protected void addPathFile(File pathComponent) throws IOException {
        pathComponents.addElement(pathComponent);
        if (pathComponent.isDirectory()) {
            return;
        }

        String absPathPlusTimeAndLength =
            pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-"
            + pathComponent.length();
        String classpath = (String) pathMap.get(absPathPlusTimeAndLength);
        if (classpath == null) {
            ZipFile jarFile = null;
            InputStream manifestStream = null;
            try {
                jarFile = new ZipFile(pathComponent);
                manifestStream
                    = jarFile.getInputStream(new ZipEntry("META-INF/MANIFEST.MF"));

                if (manifestStream == null) {
                    return;
                }
                Reader manifestReader
                    = new InputStreamReader(manifestStream, "UTF-8");
                org.apache.tools.ant.taskdefs.Manifest manifest
                    = new org.apache.tools.ant.taskdefs.Manifest(manifestReader);
                classpath
                    = manifest.getMainSection().getAttributeValue("Class-Path");

            } catch (org.apache.tools.ant.taskdefs.ManifestException e) {
            } finally {
                FileUtils.close(manifestStream);
                if (jarFile != null) {
                    jarFile.close();
                }
            }
            if (classpath == null) {
                classpath = "";
            }
            pathMap.put(absPathPlusTimeAndLength, classpath);
        }

        if (!"".equals(classpath)) {
            URL baseURL = FILE_UTILS.getFileURL(pathComponent);
            StringTokenizer st = new StringTokenizer(classpath);
            while (st.hasMoreTokens()) {
                String classpathElement = st.nextToken();
                URL libraryURL = new URL(baseURL, classpathElement);
                if (!libraryURL.getProtocol().equals("file")) {
                    log("Skipping jar library " + classpathElement
                        + " since only relative URLs are supported by this"
                        + " loader", Project.MSG_VERBOSE);
                    continue;
                }
                String decodedPath = Locator.decodeUri(libraryURL.getFile());
                File libraryFile = new File(decodedPath);
                if (libraryFile.exists() && !isInPath(libraryFile)) {
                    addPathFile(libraryFile);
                }
            }
        }
    }

    /**
     * Returns the classpath this classloader will consult.
     *
     * @return the classpath used for this classloader, with elements
     *         separated by the path separator for the system.
     */
    public String getClasspath() {
        StringBuffer sb = new StringBuffer();
        boolean firstPass = true;
        Enumeration componentEnum = pathComponents.elements();
        while (componentEnum.hasMoreElements()) {
            if (!firstPass) {
                sb.append(System.getProperty("path.separator"));
            } else {
                firstPass = false;
            }
            sb.append(((File) componentEnum.nextElement()).getAbsolutePath());
        }
        return sb.toString();
    }

    /**
     * Sets whether this classloader should run in isolated mode. In
     * isolated mode, classes not found on the given classpath will
     * not be referred to the parent class loader but will cause a
     * ClassNotFoundException.
     *
     * @param isolated Whether or not this classloader should run in
     *                 isolated mode.
     */
    public synchronized void setIsolated(boolean isolated) {
        ignoreBase = isolated;
    }

    /**
     * Forces initialization of a class in a JDK 1.1 compatible, albeit hacky
     * way.
     *
     * @param theClass The class to initialize.
     *                 Must not be null.
     *
     * @deprecated since 1.6.x.
     *             Use Class.forName with initialize=true instead.
     */
    public static void initializeClass(Class theClass) {

        final Constructor[] cons = theClass.getDeclaredConstructors();
        if (cons != null) {
            if (cons.length > 0 && cons[0] != null) {
                final String[] strs = new String[NUMBER_OF_STRINGS];
                try {
                    cons[0].newInstance((Object[]) strs);
                } catch (Exception e) {
                }
            }
        }
    }

    /**
     * Adds a package root to the list of packages which must be loaded on the
     * parent loader.
     *
     * All subpackages are also included.
     *
     * @param packageRoot The root of all packages to be included.
     *                    Should not be null.
     */
    public void addSystemPackageRoot(String packageRoot) {
        systemPackages.addElement(packageRoot
                                  + (packageRoot.endsWith(".") ? "" : "."));
    }

    /**
     * Adds a package root to the list of packages which must be loaded using
     * this loader.
     *
     * All subpackages are also included.
     *
     * @param packageRoot The root of all packages to be included.
     *                    Should not be null.
     */
    public void addLoaderPackageRoot(String packageRoot) {
        loaderPackages.addElement(packageRoot
                                  + (packageRoot.endsWith(".") ? "" : "."));
    }

    /**
     * Loads a class through this class loader even if that class is available
     * on the parent classpath.
     *
     * This ensures that any classes which are loaded by the returned class
     * will use this classloader.
     *
     * @param classname The name of the class to be loaded.
     *                  Must not be null.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     *                                   on this loader's classpath.
     */
    public Class forceLoadClass(String classname)
        throws ClassNotFoundException {
        log("force loading " + classname, Project.MSG_DEBUG);

        Class theClass = findLoadedClass(classname);

        if (theClass == null) {
            theClass = findClass(classname);
        }

        return theClass;
    }

    /**
     * Loads a class through this class loader but defer to the parent class
     * loader.
     *
     * This ensures that instances of the returned class will be compatible
     * with instances which have already been loaded on the parent
     * loader.
     *
     * @param classname The name of the class to be loaded.
     *                  Must not be null.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     * on this loader's classpath.
     */
    public Class forceLoadSystemClass(String classname)
        throws ClassNotFoundException {
        log("force system loading " + classname, Project.MSG_DEBUG);

        Class theClass = findLoadedClass(classname);

        if (theClass == null) {
            theClass = findBaseClass(classname);
        }

        return theClass;
    }

    /**
     * Returns a stream to read the requested resource name.
     *
     * @param name The name of the resource for which a stream is required.
     *             Must not be null.
     *
     * @return a stream to the required resource or null if the
     *         resource cannot be found on the loader's classpath.
     */
    public InputStream getResourceAsStream(String name) {

        InputStream resourceStream = null;
        if (isParentFirst(name)) {
            resourceStream = loadBaseResource(name);
            if (resourceStream != null) {
                log("ResourceStream for " + name
                    + " loaded from parent loader", Project.MSG_DEBUG);

            } else {
                resourceStream = loadResource(name);
                if (resourceStream != null) {
                    log("ResourceStream for " + name
                        + " loaded from ant loader", Project.MSG_DEBUG);
                }
            }
        } else {
            resourceStream = loadResource(name);
            if (resourceStream != null) {
                log("ResourceStream for " + name
                    + " loaded from ant loader", Project.MSG_DEBUG);

            } else {
                resourceStream = loadBaseResource(name);
                if (resourceStream != null) {
                    log("ResourceStream for " + name
                        + " loaded from parent loader", Project.MSG_DEBUG);
                }
            }
        }

        if (resourceStream == null) {
            log("Couldn't load ResourceStream for " + name,
                Project.MSG_DEBUG);
        }

        return resourceStream;
    }

    /**
     * Returns a stream to read the requested resource name from this loader.
     *
     * @param name The name of the resource for which a stream is required.
     *             Must not be null.
     *
     * @return a stream to the required resource or null if
     *         the resource cannot be found on the loader's classpath.
     */
    private InputStream loadResource(String name) {
        InputStream stream = null;

        Enumeration e = pathComponents.elements();
        while (e.hasMoreElements() && stream == null) {
            File pathComponent = (File) e.nextElement();
            stream = getResourceStream(pathComponent, name);
        }
        return stream;
    }

    /**
     * Finds a system resource (which should be loaded from the parent
     * classloader).
     *
     * @param name The name of the system resource to load.
     *             Must not be null.
     *
     * @return a stream to the named resource, or null if
     *         the resource cannot be found.
     */
    private InputStream loadBaseResource(String name) {
        if (parent == null) {
            return getSystemResourceAsStream(name);
        } else {
            return parent.getResourceAsStream(name);
        }
    }

    /**
     * Returns an inputstream to a given resource in the given file which may
     * either be a directory or a zip file.
     *
     * @param file the file (directory or jar) in which to search for the
     *             resource. Must not be null.
     * @param resourceName The name of the resource for which a stream is
     *                     required. Must not be null.
     *
     * @return a stream to the required resource or null if
     *         the resource cannot be found in the given file.
     */
    private InputStream getResourceStream(File file, String resourceName) {
        try {
            ZipFile zipFile = (ZipFile) zipFiles.get(file);
            if (zipFile == null && file.isDirectory()) {
                File resource = new File(file, resourceName);

                if (resource.exists()) {
                    return new FileInputStream(resource);
                }
            } else {
                if (zipFile == null) {
                    if (file.exists()) {

                        zipFile = new ZipFile(file);
                        zipFiles.put(file, zipFile);
                    } else {
                        return null;
                    }
                    zipFile = (ZipFile) zipFiles.get(file);
                }
                ZipEntry entry = zipFile.getEntry(resourceName);
                if (entry != null) {
                    return zipFile.getInputStream(entry);
                }
            }
        } catch (Exception e) {
            log("Ignoring Exception " + e.getClass().getName() + ": "
                    + e.getMessage() + " reading resource " + resourceName
                    + " from " + file, Project.MSG_VERBOSE);
        }

        return null;
    }

    /**
     * Tests whether or not the parent classloader should be checked for a
     * resource before this one. If the resource matches both the "use parent
     * classloader first" and the "use this classloader first" lists, the latter
     * takes priority.
     *
     * @param resourceName
     *            The name of the resource to check. Must not be
     *            null.
     *
     * @return whether or not the parent classloader should be checked for a
     *         resource before this one is.
     */
    private boolean isParentFirst(String resourceName) {

        boolean useParentFirst = parentFirst;

        for (Enumeration e = systemPackages.elements(); e.hasMoreElements();) {
            String packageName = (String) e.nextElement();
            if (resourceName.startsWith(packageName)) {
                useParentFirst = true;
                break;
            }
        }

        for (Enumeration e = loaderPackages.elements(); e.hasMoreElements();) {
            String packageName = (String) e.nextElement();
            if (resourceName.startsWith(packageName)) {
                useParentFirst = false;
                break;
            }
        }

        return useParentFirst;
    }

    /**
     * Used for isolated resource seaching.
     * @return the root classloader of AntClassLoader.
     */
    private ClassLoader getRootLoader() {
        ClassLoader ret = getClass().getClassLoader();
        while (ret != null && ret.getParent() != null) {
            ret = ret.getParent();
        }
        return ret;
    }

    /**
     * Finds the resource with the given name. A resource is
     * some data (images, audio, text, etc) that can be accessed by class
     * code in a way that is independent of the location of the code.
     *
     * @param name The name of the resource for which a stream is required.
     *             Must not be null.
     *
     * @return a URL for reading the resource, or null if the
     *         resource could not be found or the caller doesn't have
     *         adequate privileges to get the resource.
     */
    public URL getResource(String name) {
        URL url = null;
        if (isParentFirst(name)) {
            url = (parent == null) ? super.getResource(name)
                : parent.getResource(name);
        }

        if (url != null) {
            log("Resource " + name + " loaded from parent loader",
                Project.MSG_DEBUG);

        } else {
            Enumeration e = pathComponents.elements();
            while (e.hasMoreElements() && url == null) {
                File pathComponent = (File) e.nextElement();
                url = getResourceURL(pathComponent, name);
                if (url != null) {
                    log("Resource " + name
                        + " loaded from ant loader",
                        Project.MSG_DEBUG);
                }
            }
        }

        if (url == null && !isParentFirst(name)) {
            if (ignoreBase) {
                url = (getRootLoader() == null) ? null
                    : getRootLoader().getResource(name);
            } else {
                url = (parent == null) ? super.getResource(name)
                    : parent.getResource(name);
            }
            if (url != null) {
                log("Resource " + name + " loaded from parent loader",
                    Project.MSG_DEBUG);
            }
        }

        if (url == null) {
            log("Couldn't load Resource " + name, Project.MSG_DEBUG);
        }

        return url;
    }

    /**
     * Returns an enumeration of URLs representing all the resources with the
     * given name by searching the class loader's classpath.
     *
     * @param name The resource name to search for.
     *             Must not be null.
     * @return an enumeration of URLs for the resources
     * @exception IOException if I/O errors occurs (can't happen)
     */
    protected Enumeration/*<URL>*/ findResources(String name) throws IOException {
        Enumeration/*<URL>*/ mine = new ResourceEnumeration(name);
        Enumeration/*<URL>*/ base;
        if (parent != null && parent != getParent()) {
            base = parent.getResources(name);
        } else {
            base = new CollectionUtils.EmptyEnumeration();
        }
        if (isParentFirst(name)) {
            return CollectionUtils.append(base, mine);
        } else if (ignoreBase) {
            return getRootLoader() == null
                ? mine
                : CollectionUtils.append(
                    mine, getRootLoader().getResources(name));
        } else {
            return CollectionUtils.append(mine, base);
        }
    }

    /**
     * Returns the URL of a given resource in the given file which may
     * either be a directory or a zip file.
     *
     * @param file The file (directory or jar) in which to search for
     *             the resource. Must not be null.
     * @param resourceName The name of the resource for which a stream
     *                     is required. Must not be null.
     *
     * @return a stream to the required resource or null if the
     *         resource cannot be found in the given file object.
     */
    protected URL getResourceURL(File file, String resourceName) {
        try {
            ZipFile zipFile = (ZipFile) zipFiles.get(file);
            if (zipFile == null && file.isDirectory()) {
                File resource = new File(file, resourceName);

                if (resource.exists()) {
                    try {
                        return FILE_UTILS.getFileURL(resource);
                    } catch (MalformedURLException ex) {
                        return null;
                    }
                }
            } else {
                if (zipFile == null) {
                    if (file.exists()) {
                        zipFile = new ZipFile(file);
                        zipFiles.put(file, zipFile);
                    } else {
                        return null;
                    }
                }
                ZipEntry entry = zipFile.getEntry(resourceName);
                if (entry != null) {
                    try {
                        return new URL("jar:" + FILE_UTILS.getFileURL(file)
                                       + "!/" + entry);
                    } catch (MalformedURLException ex) {
                        return null;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Loads a class with this class loader.
     *
     * This class attempts to load the class in an order determined by whether
     * or not the class matches the system/loader package lists, with the
     * loader package list taking priority. If the classloader is in isolated
     * mode, failure to load the class in this loader will result in a
     * ClassNotFoundException.
     *
     * @param classname The name of the class to be loaded.
     *                  Must not be null.
     * @param resolve true if all classes upon which this class
     *                depends are to be loaded.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     * on the system classpath (when not in isolated mode) or this loader's
     * classpath.
     */
    protected synchronized Class loadClass(String classname, boolean resolve)
        throws ClassNotFoundException {

        Class theClass = findLoadedClass(classname);
        if (theClass != null) {
            return theClass;
        }

        if (isParentFirst(classname)) {
            try {
                theClass = findBaseClass(classname);
                log("Class " + classname + " loaded from parent loader "
                    + "(parentFirst)", Project.MSG_DEBUG);
            } catch (ClassNotFoundException cnfe) {
                theClass = findClass(classname);
                log("Class " + classname + " loaded from ant loader "
                    + "(parentFirst)", Project.MSG_DEBUG);
            }
        } else {
            try {
                theClass = findClass(classname);
                log("Class " + classname + " loaded from ant loader",
                    Project.MSG_DEBUG);
            } catch (ClassNotFoundException cnfe) {
                if (ignoreBase) {
                    throw cnfe;
                }
                theClass = findBaseClass(classname);
                log("Class " + classname + " loaded from parent loader",
                    Project.MSG_DEBUG);
            }
        }

        if (resolve) {
            resolveClass(theClass);
        }

        return theClass;
    }

    /**
     * Converts the class dot notation to a filesystem equivalent for
     * searching purposes.
     *
     * @param classname The class name in dot format (eg java.lang.Integer).
     *                  Must not be null.
     *
     * @return the classname in filesystem format (eg java/lang/Integer.class)
     */
    private String getClassFilename(String classname) {
        return classname.replace('.', '/') + ".class";
    }

    /**
     * Define a class given its bytes
     *
     * @param container the container from which the class data has been read
     *                  may be a directory or a jar/zip file.
     *
     * @param classData the bytecode data for the class
     * @param classname the name of the class
     *
     * @return the Class instance created from the given data
     *
     * @throws IOException if the class data cannot be read.
     */
    protected Class defineClassFromData(File container, byte[] classData,
                                        String classname) throws IOException {
        definePackage(container, classname);
        return defineClass(classname, classData, 0, classData.length,
                           Project.class.getProtectionDomain());
    }

    /**
     * Define the package information associated with a class.
     *
     * @param container the file containing the class definition.
     * @param className the class name of for which the package information
     *        is to be determined.
     *
     * @exception IOException if the package information cannot be read from the
     *            container.
     */
    protected void definePackage(File container, String className)
        throws IOException {
        int classIndex = className.lastIndexOf('.');
        if (classIndex == -1) {
            return;
        }

        String packageName = className.substring(0, classIndex);
        if (getPackage(packageName) != null) {
            return;
        }

        Manifest manifest = getJarManifest(container);

        if (manifest == null) {
            definePackage(packageName, null, null, null, null, null,
                          null, null);
        } else {
            definePackage(container, packageName, manifest);
        }
    }

    /**
     * Get the manifest from the given jar, if it is indeed a jar and it has a
     * manifest
     *
     * @param container the File from which a manifest is required.
     *
     * @return the jar's manifest or null is the container is not a jar or it
     *         has no manifest.
     *
     * @exception IOException if the manifest cannot be read.
     */
    private Manifest getJarManifest(File container) throws IOException {
        if (container.isDirectory()) {
            return null;
        }
        JarFile jarFile = null;
        try {
            jarFile = new JarFile(container);
            return jarFile.getManifest();
        } finally {
            if (jarFile != null) {
                jarFile.close();
            }
        }
    }

    /**
     * Define the package information when the class comes from a
     * jar with a manifest
     *
     * @param container the jar file containing the manifest
     * @param packageName the name of the package being defined.
     * @param manifest the jar's manifest
     */
    protected void definePackage(File container, String packageName,
                                 Manifest manifest) {
        String sectionName = packageName.replace('.', '/') + "/";

        String specificationTitle = null;
        String specificationVendor = null;
        String specificationVersion = null;
        String implementationTitle = null;
        String implementationVendor = null;
        String implementationVersion = null;
        String sealedString = null;
        URL sealBase = null;

        Attributes sectionAttributes = manifest.getAttributes(sectionName);
        if (sectionAttributes != null) {
            specificationTitle
                = sectionAttributes.getValue(Name.SPECIFICATION_TITLE);
            specificationVendor
                = sectionAttributes.getValue(Name.SPECIFICATION_VENDOR);
            specificationVersion
                = sectionAttributes.getValue(Name.SPECIFICATION_VERSION);
            implementationTitle
                = sectionAttributes.getValue(Name.IMPLEMENTATION_TITLE);
            implementationVendor
                = sectionAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
            implementationVersion
                = sectionAttributes.getValue(Name.IMPLEMENTATION_VERSION);
            sealedString
                = sectionAttributes.getValue(Name.SEALED);
        }

        Attributes mainAttributes = manifest.getMainAttributes();
        if (mainAttributes != null) {
            if (specificationTitle == null) {
                specificationTitle
                    = mainAttributes.getValue(Name.SPECIFICATION_TITLE);
            }
            if (specificationVendor == null) {
                specificationVendor
                    = mainAttributes.getValue(Name.SPECIFICATION_VENDOR);
            }
            if (specificationVersion == null) {
                specificationVersion
                    = mainAttributes.getValue(Name.SPECIFICATION_VERSION);
            }
            if (implementationTitle == null) {
                implementationTitle
                    = mainAttributes.getValue(Name.IMPLEMENTATION_TITLE);
            }
            if (implementationVendor == null) {
                implementationVendor
                    = mainAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
            }
            if (implementationVersion == null) {
                implementationVersion
                    = mainAttributes.getValue(Name.IMPLEMENTATION_VERSION);
            }
            if (sealedString == null) {
                sealedString
                    = mainAttributes.getValue(Name.SEALED);
            }
        }

        if (sealedString != null
                && sealedString.toLowerCase(Locale.ENGLISH).equals("true")) {
            try {
                sealBase = new URL(FileUtils.getFileUtils().toURI(container.getAbsolutePath()));
            } catch (MalformedURLException e) {
            }
        }

        definePackage(packageName, specificationTitle, specificationVersion,
                      specificationVendor, implementationTitle,
                      implementationVersion, implementationVendor, sealBase);
    }

    /**
     * Reads a class definition from a stream.
     *
     * @param stream The stream from which the class is to be read.
     *               Must not be null.
     * @param classname The name of the class in the stream.
     *                  Must not be null.
     * @param container the file or directory containing the class.
     *
     * @return the Class object read from the stream.
     *
     * @exception IOException if there is a problem reading the class from the
     * stream.
     * @exception SecurityException if there is a security problem while
     * reading the class from the stream.
     */
    private Class getClassFromStream(InputStream stream, String classname,
                                     File container)
        throws IOException, SecurityException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int bytesRead = -1;
        byte[] buffer = new byte[BUFFER_SIZE];

        while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }

        byte[] classData = baos.toByteArray();
        return defineClassFromData(container, classData, classname);
    }

    /**
     * Searches for and load a class on the classpath of this class loader.
     *
     * @param name The name of the class to be loaded. Must not be
     *             null.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     *                                   on this loader's classpath.
     */
    public Class findClass(String name) throws ClassNotFoundException {
        log("Finding class " + name, Project.MSG_DEBUG);

        return findClassInComponents(name);
    }

    /**
     * Indicate if the given file is in this loader's path
     *
     * @param component the file which is to be checked
     *
     * @return true if the file is in the class path
     */
    protected boolean isInPath(File component) {
        for (Enumeration e = pathComponents.elements(); e.hasMoreElements();) {
            File pathComponent = (File) e.nextElement();
            if (pathComponent.equals(component)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Finds a class on the given classpath.
     *
     * @param name The name of the class to be loaded. Must not be
     *             null.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     * on this loader's classpath.
     */
    private Class findClassInComponents(String name)
        throws ClassNotFoundException {
        InputStream stream = null;
        String classFilename = getClassFilename(name);
        try {
            Enumeration e = pathComponents.elements();
            while (e.hasMoreElements()) {
                File pathComponent = (File) e.nextElement();
                try {
                    stream = getResourceStream(pathComponent, classFilename);
                    if (stream != null) {
                        log("Loaded from " + pathComponent + " "
                            + classFilename, Project.MSG_DEBUG);
                        return getClassFromStream(stream, name, pathComponent);
                    }
                } catch (SecurityException se) {
                    throw se;
                } catch (IOException ioe) {
                    log("Exception reading component " + pathComponent
                        + " (reason: " + ioe.getMessage() + ")",
                        Project.MSG_VERBOSE);
                }
            }

            throw new ClassNotFoundException(name);
        } finally {
        	FileUtils.close(stream);
        }
    }

    /**
     * Finds a system class (which should be loaded from the same classloader
     * as the Ant core).
     *
     * For JDK 1.1 compatibility, this uses the findSystemClass method if
     * no parent classloader has been specified.
     *
     * @param name The name of the class to be loaded.
     *             Must not be null.
     *
     * @return the required Class object
     *
     * @exception ClassNotFoundException if the requested class does not exist
     * on this loader's classpath.
     */
    private Class findBaseClass(String name) throws ClassNotFoundException {
        if (parent == null) {
            return findSystemClass(name);
        } else {
            return parent.loadClass(name);
        }
    }

    /**
     * Cleans up any resources held by this classloader. Any open archive
     * files are closed.
     */
    public synchronized void cleanup() {
        for (Enumeration e = zipFiles.elements(); e.hasMoreElements();) {
            ZipFile zipFile = (ZipFile) e.nextElement();
            try {
                zipFile.close();
            } catch (IOException ioe) {
            }
        }
        zipFiles = new Hashtable();
        if (project != null) {
            project.removeBuildListener(this);
        }
        project = null;
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the buildStarted event
     */
    public void buildStarted(BuildEvent event) {
    }

    /**
     * Cleans up any resources held by this classloader at the end
     * of a build.
     *
     * @param event the buildFinished event
     */
    public void buildFinished(BuildEvent event) {
        cleanup();
    }

    /**
     * Cleans up any resources held by this classloader at the end of
     * a subbuild if it has been created for the subbuild's project
     * instance.
     *
     * @param event the buildFinished event
     *
     * @since Ant 1.6.2
     */
    public void subBuildFinished(BuildEvent event) {
        if (event.getProject() == project) {
            cleanup();
        }
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the buildStarted event
     *
     * @since Ant 1.6.2
     */
    public void subBuildStarted(BuildEvent event) {
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the targetStarted event
     */
    public void targetStarted(BuildEvent event) {
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the targetFinished event
     */
    public void targetFinished(BuildEvent event) {
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the taskStarted event
     */
    public void taskStarted(BuildEvent event) {
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the taskFinished event
     */
    public void taskFinished(BuildEvent event) {
    }

    /**
     * Empty implementation to satisfy the BuildListener interface.
     *
     * @param event the messageLogged event
     */
    public void messageLogged(BuildEvent event) {
    }

    /**
     * add any libraries that come with different java versions
     * here
     */
    public void addJavaLibraries() {
        Vector packages = JavaEnvUtils.getJrePackages();
        Enumeration e = packages.elements();
        while (e.hasMoreElements()) {
            String packageName = (String) e.nextElement();
            addSystemPackageRoot(packageName);
        }
    }

    /**
     * Returns a String representing this loader.
     * @return the path that this classloader has.
     */
    public String toString() {
        return "AntClassLoader[" + getClasspath() + "]";

FUNC_DECL IF PARAM BINARY_OP RETURN RETURN LITERAL_ANCHOR CALL CALL

FUNC_DECL RETURN LOOP LOOP VAR_DECL PARAM CALL CALL IF VAR_DECL IF VAR_DECL CALL CALL CALL CALL BREAK_CONTINUE BREAK_CONTINUE ASSIGN CALL ASSIGN CALL LITERAL_ANCHOR LITERAL_ANCHOR

FUNC_DECL IF IF VAR_DECL VAR_DECL PARAM IF CALL BINARY_OP RETURN BINARY_OP BINARY_OP CALL RETURN RETURN CALL ASSIGN ASSIGN CALL LITERAL_ANCHOR CALL COND_EXPR CALL CALL CALL BINARY_OP CALL LITERAL_ANCHOR CALL CALL

FUNC_DECL RETURN PARAM PARAM PARAM CALL CALL CALL LITERAL_ANCHOR

FUNC_DECL RETURN LOOP PARAM LITERAL_ANCHOR CALL IF VAR_DECL CALL CALL RETURN LITERAL_ANCHOR CALL

FUNC_DECL IF LOOP ASSIGN BINARY_OP ASSIGN CALL LITERAL_ANCHOR LITERAL_ANCHOR CALL TRY VAR_DECL CALL CATCH CALL CALL CALL

FUNC_DECL PARAM PARAM PARAM CALL CALL CALL

    public AntClassLoader() {
        setParent(null);

FUNC_DECL PARAM PARAM CALL CALL CALL LITERAL_ANCHOR

FUNC_DECL IF PARAM PARAM PARAM PARAM CALL CALL BINARY_OP LITERAL_ANCHOR CALL

FUNC_DECL PARAM PARAM ASSIGN ASSIGN CALL LITERAL_ANCHOR


public class JpaEndpoint extends ScheduledPollEndpoint<Exchange> {
    private EntityManagerFactory entityManagerFactory;
    private String persistenceUnit = "camel";
    private JpaTemplate template;
    private Expression<Exchange> producerExpression;
    private int maximumResults = -1;
    private Class<?> entityType;
    private Map entityManagerProperties;
    private boolean consumeDelete = true;
    private boolean consumeLockEntity = true;
    private boolean flushOnSend = true;

    public JpaEndpoint(String uri, JpaComponent component) {
        super(uri, component);
        entityManagerFactory = component.getEntityManagerFactory();
    }

    public JpaEndpoint(String endpointUri, EntityManagerFactory entityManagerFactory) {
        super(endpointUri);
        this.entityManagerFactory = entityManagerFactory;
    }

    public JpaEndpoint(String endpointUri) {
        super(endpointUri);
    }

    public Producer<Exchange> createProducer() throws Exception {
        validate();
        return new JpaProducer(this, getProducerExpression());
    }

    public Consumer<Exchange> createConsumer(Processor processor) throws Exception {
        validate();
        JpaConsumer consumer = new JpaConsumer(this, processor);
        configureConsumer(consumer);
        return consumer;
    }

    @Override
    public void configureProperties(Map options) {
        super.configureProperties(options);
        Map emProperties = IntrospectionSupport.extractProperties(options, "emf.");
        if (emProperties != null) {
            setEntityManagerProperties(emProperties);
        }
    }

    public boolean isSingleton() {
        return false;
    }

    public JpaTemplate getTemplate() {
        if (template == null) {
            template = createTemplate();
        }
        return template;
    }

    public void setTemplate(JpaTemplate template) {
        this.template = template;
    }

    public Expression<Exchange> getProducerExpression() {
        if (producerExpression == null) {
            producerExpression = createProducerExpression();
        }
        return producerExpression;
    }

    public void setProducerExpression(Expression<Exchange> producerExpression) {
        this.producerExpression = producerExpression;
    }

    public int getMaximumResults() {
        return maximumResults;
    }

    public void setMaximumResults(int maximumResults) {
        this.maximumResults = maximumResults;
    }

    public Class<?> getEntityType() {
        return entityType;
    }

    public void setEntityType(Class<?> entityType) {
        this.entityType = entityType;
    }

    public EntityManagerFactory getEntityManagerFactory() {
        if (entityManagerFactory == null) {
            entityManagerFactory = createEntityManagerFactory();
        }
        return entityManagerFactory;
    }

    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    public Map getEntityManagerProperties() {
        if (entityManagerProperties == null) {
            entityManagerProperties = System.getProperties();
        }
        return entityManagerProperties;
    }

    public void setEntityManagerProperties(Map entityManagerProperties) {
        this.entityManagerProperties = entityManagerProperties;
    }

    public String getPersistenceUnit() {
        return persistenceUnit;
    }

    public void setPersistenceUnit(String persistenceUnit) {
        this.persistenceUnit = persistenceUnit;
    }

    public boolean isConsumeDelete() {
        return consumeDelete;
    }

    public void setConsumeDelete(boolean consumeDelete) {
        this.consumeDelete = consumeDelete;
    }

    public boolean isConsumeLockEntity() {
        return consumeLockEntity;
    }

    public void setConsumeLockEntity(boolean consumeLockEntity) {
        this.consumeLockEntity = consumeLockEntity;
    }

    public boolean isFlushOnSend() {
        return flushOnSend;
    }

    public void setFlushOnSend(boolean flushOnSend) {
        this.flushOnSend = flushOnSend;
    }

    protected void validate() {
        ObjectHelper.notNull(getEntityManagerFactory(), "entityManagerFactory property");
    }

    protected JpaTemplate createTemplate() {
        return new JpaTemplate(getEntityManagerFactory());
    }

    protected EntityManagerFactory createEntityManagerFactory() {
        return Persistence.createEntityManagerFactory(persistenceUnit, getEntityManagerProperties());
    }

    protected EntityManager createEntityManager() {
        return getEntityManagerFactory().createEntityManager();
    }

    protected TransactionStrategy createTransactionStrategy() {
        EntityManagerFactory emf = getEntityManagerFactory();
        return JpaTemplateTransactionStrategy.newInstance(emf, getTemplate());
    }

    protected Expression<Exchange> createProducerExpression() {
        final Class<?> type = getEntityType();
        if (type == null) {
            return ExpressionBuilder.bodyExpression();
        } else {
            return new Expression<Exchange>() {
                public Object evaluate(Exchange exchange) {
                    Object answer = exchange.getIn().getBody(type);
                    if (answer == null) {
                        Object defaultValue = exchange.getIn().getBody();
                        if (defaultValue != null) {
                            throw new NoTypeConversionAvailableException(defaultValue, type);
                        }

                        answer = exchange.getContext().getInjector().newInstance(type);
                    }
                    return answer;

FUNC_DECL RETURN VAR_DECL PARAM CALL CALL CALL

FUNC_DECL RETURN VAR_DECL CALL CALL CALL