/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.royale.compiler.clients;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.flex.tools.FlexTool;
import org.apache.royale.compiler.clients.problems.ProblemFormatter;
import org.apache.royale.compiler.clients.problems.ProblemPrinter;
import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.config.Configurator;
import org.apache.royale.compiler.config.PlayerglobalcConfigurator;
import org.apache.royale.compiler.targets.ITarget.TargetType;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * Generates .as source files to build playerglobal.swc and airglobal.swc from
 * the ASDoc DITA XML files.
 */
class PLAYERGLOBALC implements FlexTool {

	static enum ExitCode {
		SUCCESS(0), PRINT_HELP(1), FAILED_WITH_PROBLEMS(2), FAILED_WITH_EXCEPTIONS(3), FAILED_WITH_CONFIG_PROBLEMS(4);

		ExitCode(int code) {
			this.code = code;
		}

		final int code;
	}

	private static final List<String> VECTOR_SUFFIXES = Arrays.asList("$double", "$int", "$uint", "$object");
	// From the docs: Methods of the Object class are dynamically created on
	// Object's prototype.
	private static final List<String> OBJECT_PROTOTYPE_METHODS = Arrays.asList("hasOwnProperty", "isPrototypeOf",
			"propertyIsEnumerable", "setPropertyIsEnumerable", "toString", "toLocaleString", "valueOf");
	private static final List<String> ANY_CONSTRUCTORS = Arrays.asList("ArgumentError", "Boolean", "Date",
			"DefinitionError", "Error", "EvalError", "int", "Number", "RangeError", "ReferenceError", "RegExp",
			"SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList");
	private static final Map<String, String> GLOBAL_CONSTANTS = new HashMap<String, String>();
	{
		GLOBAL_CONSTANTS.put("Infinity", "1 / 0");
		GLOBAL_CONSTANTS.put("NaN", "0 / 0");
		GLOBAL_CONSTANTS.put("undefined", "void 0");
	}
	private static final Map<String, List<String>> REST_METHODS = new HashMap<String, List<String>>();
	{
		REST_METHODS.put("Array", Arrays.asList("splice"));
		REST_METHODS.put("__AS3__.vec.Vector$object", Arrays.asList("sort"));
		REST_METHODS.put("__AS3__.vec.Vector$double", Arrays.asList("sort"));
		REST_METHODS.put("__AS3__.vec.Vector$int", Arrays.asList("sort"));
		REST_METHODS.put("__AS3__.vec.Vector$uint", Arrays.asList("sort"));
	}
	private static final Map<String, List<String>> NULL_DEFAULT_METHODS = new HashMap<String, List<String>>();
	{
		NULL_DEFAULT_METHODS.put("Date",
				Arrays.asList("setFullYear", "setMonth", "setDate", "setHours", "setMinutes", "setSeconds",
						"setMilliseconds", "setUTCFullYear", "setUTCMonth", "setUTCDate", "setUTCHours",
						"setUTCMinutes", "setUTCSeconds", "setUTCMilliseconds", "setTime"));
	}
	private static final Map<String, List<String>> ANY_METHODS = new HashMap<String, List<String>>();
	{
		ANY_METHODS.put("Date",
				Arrays.asList("setFullYear", "setMonth", "setDate", "setHours", "setMinutes", "setSeconds",
						"setMilliseconds", "setUTCFullYear", "setUTCMonth", "setUTCDate", "setUTCHours",
						"setUTCMinutes", "setUTCSeconds", "setUTCMilliseconds", "setTime", "UTC"));
		ANY_METHODS.put("XML", Arrays.asList("addNamespace", "appendChild", "attribute", "child", "contains",
				"descendants", "elements", "insertChildAfter", "insertChildBefore", "namespace", "prependChild",
				"processingInstructions", "removeNamespace", "replace", "setChildren", "setName", "setNamespace"));
		ANY_METHODS.put("XMLList", Arrays.asList("addNamespace", "appendChild", "attribute", "child", "contains",
				"descendants", "elements", "insertChildAfter", "insertChildBefore", "namespace", "prependChild",
				"processingInstructions", "removeNamespace", "replace", "setChildren", "setName", "setNamespace"));
	}
	private static final Map<String, List<String>> ANY_VARIABLES = new HashMap<String, List<String>>();
	{
		ANY_VARIABLES.put("Object", Arrays.asList("constructor"));
	}
	private static final Map<String, List<String>> EXTRA_MEMBERS = new HashMap<String, List<String>>();
	{
		EXTRA_MEMBERS.put("flash.display.DisplayObjectContainer", Arrays
				.asList("public native function removeChildren(beginIndex:int = 0, endIndex:int = 0x7fffffff):void"));
		EXTRA_MEMBERS.put("flash.display.Graphics", Arrays.asList(
				"public native function cubicCurveTo(controlX1:Number, controlY1:Number, controlX2:Number, controlY2:Number, anchorX:Number, anchorY:Number):void",
				"public native function drawRoundRectComplex(x:Number, y:Number, width:Number, height:Number, topLeftRadius:Number, topRightRadius:Number, bottomLeftRadius:Number, bottomRightRadius:Number):void"));
		EXTRA_MEMBERS.put("flash.events.EventDispatcher", Arrays.asList("public native function toString():String"));
		EXTRA_MEMBERS.put("flash.media.Camera",
				Arrays.asList("public native function copyToByteArray(rect:Rectangle, destination:ByteArray):void"));
	}

	protected ProblemQuery problems;
	protected Configurator projectConfigurator;
	protected PlayerglobalcConfiguration configuration;
	private File sourceFolder;
	private File targetFolder;
	private File currentFile;

	/**
	 * Java program entry point.
	 * 
	 * @param args command line arguments
	 */
	public static void main(final String[] args) {
		PLAYERGLOBALC compiler = new PLAYERGLOBALC();
		int exitCode = compiler.execute(args);
		System.exit(exitCode);
	}

	public PLAYERGLOBALC() {

	}

	@Override
	public String getName() {
		// TODO: Change this to a flex-tool-api constant ...
		return "PLAYERGLOBALC";
	}

	/**
	 * Create a new Configurator. This method may be overridden to allow
	 * Configurator subclasses to be created that have custom configurations.
	 * 
	 * @return a new instance or subclass of {@link Configurator}.
	 */
	protected Configurator createConfigurator() {
		return new PlayerglobalcConfigurator(PlayerglobalcConfiguration.class);
	}

	protected boolean configure(String[] args) {
		projectConfigurator = createConfigurator();
		projectConfigurator.setConfiguration(args, "asdoc-root", false);
		projectConfigurator.getTargetSettings(TargetType.SWC);
		configuration = ((PlayerglobalcConfiguration) projectConfigurator.getConfiguration());
		problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
		problems.addAll(projectConfigurator.getConfigurationProblems());
		if (problems.hasErrors() || configuration == null) {
			return false;
		}
		return true;
	}

	@Override
	public int execute(String[] args) {
		ExitCode exitCode = ExitCode.SUCCESS;
		try {
			boolean continueGeneration = configure(args);
			if (continueGeneration) {
				sourceFolder = configuration.getASDocRoot();
				targetFolder = configuration.getAsRoot();
				generateSources();
			} else if (problems.hasFilteredProblems()) {
				exitCode = ExitCode.FAILED_WITH_CONFIG_PROBLEMS;
			} else {
				exitCode = ExitCode.PRINT_HELP;
			}
		} catch (Exception e) {
			System.err.println(e.getMessage());
			exitCode = ExitCode.FAILED_WITH_EXCEPTIONS;
		} finally {
			final ProblemFormatter formatter = new ProblemFormatter();
			final ProblemPrinter printer = new ProblemPrinter(formatter, System.err);
			printer.printProblems(problems.getFilteredProblems());
		}

		return exitCode.code;
	}

	public void generateSources() throws Exception {
		preclean();

		for (File sourceFile : sourceFolder.listFiles()) {
			if (sourceFile.isDirectory()) {
				continue;
			}
			String sourceFileName = sourceFile.getName();
			if (!sourceFileName.endsWith(".xml")) {
				continue;
			}
			if (sourceFileName.endsWith(".dita.xml")) {
				continue;
			}
			parseFile(sourceFile);
		}
	}

	private void preclean() throws Exception {
		FileUtils.deleteDirectory(targetFolder);
	}

	private void writeFileForDefinition(String fullyQualifiedName, boolean airOnly, String contents)
			throws IOException {
		StringBuilder fileNameBuilder = new StringBuilder();
		String[] parts = fullyQualifiedName.split("\\.");
		for (String part : parts) {
			fileNameBuilder.append("/");
			fileNameBuilder.append(part);
		}
		fileNameBuilder.append(".as");
		File targetFile = new File(this.targetFolder, fileNameBuilder.toString());
		FileUtils.writeStringToFile(targetFile, contents);
	}

	private boolean isAIROnly(Element prologElement) {
		if (prologElement == null) {
			return false;
		}
		Element asMetadataElement = prologElement.element("asMetadata");
		if (asMetadataElement == null) {
			return false;
		}
		Element apiVersionElement = asMetadataElement.element("apiVersion");
		if (apiVersionElement == null) {
			return false;
		}
		List<Element> apiPlatformElements = apiVersionElement.elements("apiPlatform");
		if (apiPlatformElements == null || apiPlatformElements.size() == 0) {
			return false;
		}
		for (Element apiPlatformElement : apiPlatformElements) {
			if (!"AIR".equals(apiPlatformElement.attributeValue("name"))) {
				return false;
			}
		}
		return true;
	}

	private void parseFile(File ditaFile) throws Exception {
		currentFile = ditaFile;
		String contents = null;
		try {
			contents = FileUtils.readFileToString(ditaFile, Charset.forName("utf8"));
		} catch (Exception e) {
			System.err.println("Failed to read XML file: " + ditaFile.getAbsolutePath());
			return;
		}

		SAXReader xmlReader = new SAXReader();
		Document xmlDoc = xmlReader.read(new StringReader(contents));

		Element apiPackageElement = xmlDoc.getRootElement();
		if (!"apiPackage".equals(apiPackageElement.getName())) {
			throw new Exception("No apiPackage root element: " + ditaFile.getAbsolutePath());
		}

		parsePackage(apiPackageElement);
		currentFile = null;
	}

	private void parsePackage(Element apiPackageElement) throws Exception {
		List<Element> apiOperationElements = apiPackageElement.elements("apiOperation");
		for (Element apiOperationElement : apiOperationElements) {
			parsePackageFunction(apiOperationElement);
		}
		List<Element> apiValueElements = apiPackageElement.elements("apiValue");
		for (Element apiValueElement : apiValueElements) {
			parsePackageVariable(apiValueElement);
		}
		List<Element> apiClassifierElements = apiPackageElement.elements("apiClassifier");
		for (Element apiClassifierElement : apiClassifierElements) {
			Element apiClassifierDetailElement = apiClassifierElement.element("apiClassifierDetail");
			if (apiClassifierDetailElement == null) {
				String fullyQualifiedName = apiClassifierElement.attributeValue("id");
				throw new Exception("Not found: " + fullyQualifiedName);
			}
			Element apiClassifierDefElement = apiClassifierDetailElement.element("apiClassifierDef");
			if (apiClassifierDefElement == null) {
				String fullyQualifiedName = apiClassifierElement.attributeValue("id");
				throw new Exception("Not found: " + fullyQualifiedName);
			}
			Element apiInterfaceElement = apiClassifierDefElement.element("apiInterface");
			if (apiInterfaceElement != null) {
				parseInterface(apiClassifierElement);
				continue;
			}
			parseClass(apiClassifierElement);
		}
	}

	private void parseClass(Element apiClassifierElement) throws Exception {
		String fullyQualifiedName = apiClassifierElement.attributeValue("id");
		if (fullyQualifiedName.startsWith("globalClassifier:")) {
			fullyQualifiedName = fullyQualifiedName.substring(17);
		}
		if (fullyQualifiedName.equals("Vector")) {
			// special case in the compiler that doesn't get exposed in docs
			fullyQualifiedName = "__AS3__.vec:Vector";
			StringBuilder vectorBuilder = new StringBuilder();
			vectorBuilder.append("// generated from: ");
			vectorBuilder.append(currentFile.getName());
			vectorBuilder.append("\n");
			vectorBuilder.append("package __AS3__.vec {\n");
			vectorBuilder.append("\tpublic final dynamic class Vector {\n");
			vectorBuilder.append("\tpublic native function Vector();\n");
			vectorBuilder.append("\t}\n");
			vectorBuilder.append("}\n");
			writeFileForDefinition("__AS3__.vec.Vector", false, vectorBuilder.toString());
			for (String suffix : VECTOR_SUFFIXES) {
				parseClassWithFullyQualifiedName(apiClassifierElement, fullyQualifiedName + suffix);
			}
			return;
		}
		parseClassWithFullyQualifiedName(apiClassifierElement, fullyQualifiedName);
	}

	private void parseClassWithFullyQualifiedName(Element apiClassifierElement, String fullyQualifiedName)
			throws Exception {

		String[] parts = fullyQualifiedName.split(":");
		String packageName = "";
		String className = fullyQualifiedName;
		if (parts.length > 1) {
			packageName = parts[0];
			className = parts[1];
			fullyQualifiedName = packageName + "." + className;
		}

		boolean isAIROnly = isAIROnly(apiClassifierElement.element("prolog"));
		if (isAIROnly && !configuration.getAir() && !fullyQualifiedName.equals("flash.display.NativeMenu")
				&& !fullyQualifiedName.equals("flash.display.NativeMenuItem")) {
			return;
		}

		boolean isVector = fullyQualifiedName.startsWith("__AS3__.vec.Vector$");

		Set<String> importFullyQualifiedNames = new HashSet<String>();
		collectImports(apiClassifierElement, packageName, importFullyQualifiedNames);

		String baseClassFullyQualifiedName = "";
		List<String> interfaceFullyQualifiedNames = new ArrayList<String>();
		String access = null;
		boolean isFinal = false;
		boolean isDynamic = false;

		Element apiClassifierDetailElement = apiClassifierElement.element("apiClassifierDetail");
		if (apiClassifierDetailElement == null) {
			throw new Exception("apiClassifierDetail not found for: " + className);
		}
		Element apiClassifierDefElement = apiClassifierDetailElement.element("apiClassifierDef");
		if (apiClassifierDefElement == null) {
			throw new Exception("apiClassifierDef not found for: " + className);
		}

		Element apiBaseClassifierElement = apiClassifierDefElement.element("apiBaseClassifier");
		if (apiBaseClassifierElement != null) {
			baseClassFullyQualifiedName = apiBaseClassifierElement.getTextTrim();
			baseClassFullyQualifiedName = baseClassFullyQualifiedName.replace(":", ".");
		}

		List<Element> apiBaseInterfaceElements = apiClassifierDefElement.elements("apiBaseInterface");
		for (Element apiBaseInterfaceElement : apiBaseInterfaceElements) {
			String interfaceFullyQualifiedName = apiBaseInterfaceElement.getTextTrim();
			interfaceFullyQualifiedName = interfaceFullyQualifiedName.replace(":", ".");
			interfaceFullyQualifiedNames.add(interfaceFullyQualifiedName);
		}

		Element apiAccessElement = apiClassifierDefElement.element("apiAccess");
		if (apiAccessElement != null) {
			access = apiAccessElement.attributeValue("value");
		}
		if (isVector) {
			access = "internal";
		}

		Element apiFinalElement = apiClassifierDefElement.element("apiFinal");
		if (apiFinalElement != null) {
			isFinal = true;
		}

		Element apiDynamicElement = apiClassifierDefElement.element("apiDynamic");
		if (apiDynamicElement != null) {
			isDynamic = true;
		}

		List<Element> apiConstructorElements = apiClassifierElement.elements("apiConstructor");
		List<Element> apiOperationElements = apiClassifierElement.elements("apiOperation");
		List<Element> apiValueElements = apiClassifierElement.elements("apiValue");

		StringBuilder classBuilder = new StringBuilder();
		classBuilder.append("// generated from: ");
		classBuilder.append(currentFile.getName());
		classBuilder.append("\n");
		classBuilder.append("package");
		if (packageName.length() > 0) {
			classBuilder.append(" ");
			classBuilder.append(packageName);
		}
		classBuilder.append(" ");
		classBuilder.append("{");
		classBuilder.append("\n");
		writeImports(importFullyQualifiedNames, classBuilder);
		classBuilder.append("\t");
		if (access != null && access.length() > 0) {
			classBuilder.append(access);
			classBuilder.append(" ");
		}
		if (isFinal) {
			classBuilder.append("final ");
		}
		if (isDynamic) {
			classBuilder.append("dynamic ");
		}
		classBuilder.append("class ");
		classBuilder.append(className);
		if (baseClassFullyQualifiedName != null && baseClassFullyQualifiedName.length() > 0
				&& !"Object".equals(baseClassFullyQualifiedName)) {
			classBuilder.append(" extends ");
			classBuilder.append(baseClassFullyQualifiedName);
		}
		for (int i = 0; i < interfaceFullyQualifiedNames.size(); i++) {
			String interfaceFullyQualifiedName = interfaceFullyQualifiedNames.get(i);
			if (i == 0) {
				classBuilder.append(" implements ");
			} else {
				classBuilder.append(", ");
			}
			classBuilder.append(interfaceFullyQualifiedName);
		}
		classBuilder.append(" ");
		classBuilder.append("{");
		classBuilder.append("\n");
		if (apiConstructorElements.size() > 0) {
			parseConstructor(apiConstructorElements, fullyQualifiedName, classBuilder);
		}
		for (Element apiOperationElement : apiOperationElements) {
			parseFunction(apiOperationElement, fullyQualifiedName, false, classBuilder);
		}
		for (Element apiValueElement : apiValueElements) {
			parseVariable(apiValueElement, fullyQualifiedName, false, classBuilder);
		}
		if (EXTRA_MEMBERS.containsKey(fullyQualifiedName)) {
			for (String member : EXTRA_MEMBERS.get(fullyQualifiedName)) {
				classBuilder.append("\t");
				classBuilder.append(member);
				classBuilder.append(";");
				classBuilder.append("\n");
			}
		}
		classBuilder.append("\t");
		classBuilder.append("}");
		classBuilder.append("\n");
		classBuilder.append("}");
		classBuilder.append("\n");

		writeFileForDefinition(fullyQualifiedName, isAIROnly, classBuilder.toString());
	}

	private void parseInterface(Element apiClassifierElement) throws Exception {
		String fullyQualifiedName = apiClassifierElement.attributeValue("id");
		if (fullyQualifiedName.startsWith("globalClassifier:")) {
			fullyQualifiedName = fullyQualifiedName.substring(17);
		}

		String[] parts = fullyQualifiedName.split(":");
		String packageName = "";
		String interfaceName = fullyQualifiedName;
		if (parts.length > 1) {
			packageName = parts[0];
			interfaceName = parts[1];
			fullyQualifiedName = packageName + "." + interfaceName;
		}

		boolean isAIROnly = isAIROnly(apiClassifierElement.element("prolog"));
		if (isAIROnly && !configuration.getAir()) {
			return;
		}

		Set<String> importFullyQualifiedNames = new HashSet<String>();
		collectImports(apiClassifierElement, packageName, importFullyQualifiedNames);

		List<String> interfaceFullyQualifiedNames = new ArrayList<String>();
		String access = null;

		Element apiClassifierDetailElement = apiClassifierElement.element("apiClassifierDetail");
		if (apiClassifierDetailElement == null) {
			throw new Exception("apiClassifierDetail not found for: " + interfaceName);
		}
		Element apiClassifierDefElement = apiClassifierDetailElement.element("apiClassifierDef");
		if (apiClassifierDefElement == null) {
			throw new Exception("apiClassifierDef not found for: " + interfaceName);
		}

		List<Element> apiBaseInterfaceElements = apiClassifierDefElement.elements("apiBaseInterface");
		for (Element apiBaseInterfaceElement : apiBaseInterfaceElements) {
			String baseInterfaceFullyQualifiedName = apiBaseInterfaceElement.getTextTrim();
			baseInterfaceFullyQualifiedName = baseInterfaceFullyQualifiedName.replace(":", ".");
			interfaceFullyQualifiedNames.add(baseInterfaceFullyQualifiedName);
		}

		Element apiAccessElement = apiClassifierDefElement.element("apiAccess");
		if (apiAccessElement != null) {
			access = apiAccessElement.attributeValue("value");
		}

		List<Element> apiOperationElements = apiClassifierElement.elements("apiOperation");
		List<Element> apiValueElements = apiClassifierElement.elements("apiValue");

		StringBuilder interfaceBuilder = new StringBuilder();
		interfaceBuilder.append("// generated from: ");
		interfaceBuilder.append(currentFile.getName());
		interfaceBuilder.append("\n");
		interfaceBuilder.append("package");
		if (packageName.length() > 0) {
			interfaceBuilder.append(" ");
			interfaceBuilder.append(packageName);
		}
		interfaceBuilder.append(" ");
		interfaceBuilder.append("{");
		interfaceBuilder.append("\n");
		writeImports(importFullyQualifiedNames, interfaceBuilder);
		interfaceBuilder.append("\t");
		if (access != null && access.length() > 0) {
			interfaceBuilder.append(access);
			interfaceBuilder.append(" ");
		}
		interfaceBuilder.append("interface ");
		interfaceBuilder.append(interfaceName);
		for (int i = 0; i < interfaceFullyQualifiedNames.size(); i++) {
			String interfaceFullyQualifiedName = interfaceFullyQualifiedNames.get(i);
			if (i == 0) {
				interfaceBuilder.append(" extends ");
			} else {
				interfaceBuilder.append(", ");
			}
			interfaceBuilder.append(interfaceFullyQualifiedName);
		}
		interfaceBuilder.append(" ");
		interfaceBuilder.append("{");
		interfaceBuilder.append("\n");
		for (Element apiOperationElement : apiOperationElements) {
			parseFunction(apiOperationElement, null, true, interfaceBuilder);
		}
		for (Element apiValueElement : apiValueElements) {
			parseVariable(apiValueElement, fullyQualifiedName, true, interfaceBuilder);
		}
		interfaceBuilder.append("\t");
		interfaceBuilder.append("}");
		interfaceBuilder.append("\n");
		interfaceBuilder.append("}");
		interfaceBuilder.append("\n");

		writeFileForDefinition(fullyQualifiedName, isAIROnly, interfaceBuilder.toString());
	}

	private void parsePackageFunction(Element apiOperationElement) throws Exception {
		String fullyQualifiedName = apiOperationElement.attributeValue("id");
		if (fullyQualifiedName.startsWith("globalOperation:")) {
			fullyQualifiedName = fullyQualifiedName.substring(16);
		}
		if (fullyQualifiedName.equals("Vector")) {
			// special case in the compiler that doesn't get exposed in docs
			return;
		}

		String[] parts = fullyQualifiedName.split(":");
		String packageName = "";
		if (parts.length > 1) {
			packageName = parts[0];
			fullyQualifiedName = packageName + "." + parts[1];
		}

		boolean isAIROnly = isAIROnly(apiOperationElement.element("prolog"));
		if (isAIROnly && !configuration.getAir()) {
			return;
		}

		Set<String> importFullyQualifiedNames = new HashSet<String>();
		collectImports(apiOperationElement, packageName, importFullyQualifiedNames);

		StringBuilder functionBuilder = new StringBuilder();
		functionBuilder.append("// generated from: ");
		functionBuilder.append(currentFile.getName());
		functionBuilder.append("\n");
		functionBuilder.append("package");
		if (packageName != null && packageName.length() > 0) {
			functionBuilder.append(" ");
			functionBuilder.append(packageName);
		}
		functionBuilder.append(" ");
		functionBuilder.append("{");
		functionBuilder.append("\n");
		writeImports(importFullyQualifiedNames, functionBuilder);
		parseFunction(apiOperationElement, null, false, functionBuilder);
		functionBuilder.append("}");
		functionBuilder.append("\n");

		writeFileForDefinition(fullyQualifiedName, isAIROnly, functionBuilder.toString());
	}

	private void parsePackageVariable(Element apiValueElement) throws Exception {
		String fullyQualifiedName = apiValueElement.attributeValue("id");
		if (fullyQualifiedName.startsWith("globalValue:")) {
			fullyQualifiedName = fullyQualifiedName.substring(12);
		}

		String[] parts = fullyQualifiedName.split(":");
		String packageName = "";
		String variableName = fullyQualifiedName;
		if (parts.length > 1) {
			packageName = parts[0];
			variableName = parts[1];
			fullyQualifiedName = packageName + "." + variableName;
		}

		if (variableName.startsWith("-")) {
			// nothing to do here
			// it's just a negative value getting documented (like -Infinity)
			return;
		}

		boolean isAIROnly = isAIROnly(apiValueElement.element("prolog"));
		if (isAIROnly && !configuration.getAir()) {
			return;
		}

		Set<String> importFullyQualifiedNames = new HashSet<String>();
		collectImports(apiValueElement, packageName, importFullyQualifiedNames);

		StringBuilder variableBuilder = new StringBuilder();
		variableBuilder.append("// generated from: ");
		variableBuilder.append(currentFile.getName());
		variableBuilder.append("\n");
		variableBuilder.append("package");
		if (packageName != null && packageName.length() > 0) {
			variableBuilder.append(" ");
			variableBuilder.append(packageName);
		}
		variableBuilder.append(" ");
		variableBuilder.append("{");
		variableBuilder.append("\n");
		writeImports(importFullyQualifiedNames, variableBuilder);
		parseVariable(apiValueElement, null, false, variableBuilder);
		variableBuilder.append("}");
		variableBuilder.append("\n");

		writeFileForDefinition(fullyQualifiedName, isAIROnly, variableBuilder.toString());
	}

	private void parseVariable(Element apiValueElement, String contextClassName, boolean forInterface,
			StringBuilder variableBuilder) throws Exception {
		boolean isAIROnly = isAIROnly(apiValueElement.element("prolog"));
		if (isAIROnly && !configuration.getAir()) {
			return;
		}

		String variableName = apiValueElement.element("apiName").getTextTrim();

		boolean isGetter = false;
		boolean isSetter = false;
		boolean isConst = true;
		boolean isStatic = false;
		boolean isOverride = false;
		String variableType = "*";
		boolean forceAnyType = isVariableTypedAsAny(contextClassName, variableName);
		String access = null;

		Element apiValueDetailElement = apiValueElement.element("apiValueDetail");
		if (apiValueDetailElement == null) {
			throw new Exception("apiValueDetail not found for: " + variableName);
		}
		Element apiValueDefElement = apiValueDetailElement.element("apiValueDef");
		if (apiValueDefElement == null) {
			throw new Exception("apiValueDef not found for: " + variableName);
		}

		Element apiValueClassifierElement = apiValueDefElement.element("apiValueClassifier");
		if (apiValueClassifierElement != null) {
			variableType = apiValueClassifierElement.getTextTrim();
			variableType = variableType.replace(":", ".");
		}

		Element apiAccessElement = apiValueDefElement.element("apiAccess");
		if (!forInterface && apiAccessElement != null) {
			access = apiAccessElement.attributeValue("value");
		}

		Element apiStaticElement = apiValueDefElement.element("apiStatic");
		if (!forInterface && apiStaticElement != null) {
			isStatic = true;
		}

		Element apiDynamicElement = apiValueDefElement.element("apiDynamic");
		if (apiDynamicElement != null) {
			isConst = false;
		}

		Element apiValueAccessElement = apiValueDefElement.element("apiValueAccess");
		if (apiValueAccessElement != null) {
			String readwrite = apiValueAccessElement.attributeValue("value");
			isGetter = "readwrite".equals(readwrite) || "read".equals(readwrite);
			isSetter = "readwrite".equals(readwrite) || "write".equals(readwrite);
		}

		Element apiIsOverrideElement = apiValueDefElement.element("apiIsOverride");
		if (apiIsOverrideElement != null) {
			isOverride = true;
		}

		if (!forInterface && isGetter && isSetter && !isOverride
				&& apiValueElement.attributeValue("id").endsWith(":set")) {
			// skip the getter because it is already defined on the base class
			// example: flash.text.engine.TextElement.text
			isGetter = false;
		}

		Element apiDataElement = apiValueDefElement.element("apiData");

		if (isGetter) {
			variableBuilder.append("\t");
			if (access != null && access.length() > 0) {
				variableBuilder.append(access);
				variableBuilder.append(" ");
			}
			if (isStatic) {
				variableBuilder.append("static ");
			}
			if (!forInterface) {
				variableBuilder.append("native ");
			}
			if (isOverride) {
				variableBuilder.append("override ");
			}
			variableBuilder.append("function ");
			variableBuilder.append("get ");
			variableBuilder.append(variableName);
			variableBuilder.append("(");
			variableBuilder.append(")");
			variableBuilder.append(":");
			if (forceAnyType) {
				variableBuilder.append("*");
			} else {
				variableBuilder.append(variableType);
			}
			variableBuilder.append(";");
			variableBuilder.append("\n");
		}

		if (isSetter) {
			variableBuilder.append("\t");
			if (access != null && access.length() > 0) {
				variableBuilder.append(access);
				variableBuilder.append(" ");
			}
			if (isStatic) {
				variableBuilder.append("static ");
			}
			if (!forInterface) {
				variableBuilder.append("native ");
			}
			if (isOverride) {
				variableBuilder.append("override ");
			}
			variableBuilder.append("function ");
			variableBuilder.append("set ");
			variableBuilder.append(variableName);
			variableBuilder.append("(");
			variableBuilder.append("value");
			variableBuilder.append(":");
			if (forceAnyType) {
				variableBuilder.append("*");
			} else {
				variableBuilder.append(variableType);
			}
			variableBuilder.append(")");
			variableBuilder.append(":");
			variableBuilder.append("void");
			variableBuilder.append(";");
			variableBuilder.append("\n");
		}

		if (!isGetter && !isSetter) {
			variableBuilder.append("\t");
			if (access != null && access.length() > 0) {
				variableBuilder.append(access);
				variableBuilder.append(" ");
			}
			if (isStatic) {
				variableBuilder.append("static ");
			}
			if (isConst || (contextClassName == null && GLOBAL_CONSTANTS.containsKey(variableName))) {
				variableBuilder.append("const ");
			} else {
				variableBuilder.append("var ");
			}
			variableBuilder.append(variableName);
			variableBuilder.append(":");
			if (forceAnyType) {
				variableBuilder.append("*");
			} else {
				variableBuilder.append(variableType);
			}
			if (contextClassName == null && GLOBAL_CONSTANTS.containsKey(variableName)) {
				variableBuilder.append(" = ");
				variableBuilder.append(GLOBAL_CONSTANTS.get(variableName));
			} else if (apiDataElement != null) {
				writeVariableOrParameterValue(apiDataElement, variableType, variableBuilder);
			}
			variableBuilder.append(";");
			variableBuilder.append("\n");
		}
	}

	private void parseFunction(Element apiOperationElement, String contextClassName, boolean forInterface,
			StringBuilder functionBuilder) throws Exception {
		boolean isAIROnly = isAIROnly(apiOperationElement.element("prolog"));
		if (isAIROnly && !configuration.getAir()) {
			return;
		}

		String functionName = apiOperationElement.element("apiName").getTextTrim();

		boolean isStatic = false;
		boolean isOverride = false;
		String returnType = "*";
		String access = null;

		Element apiOperationDetailElement = apiOperationElement.element("apiOperationDetail");
		if (apiOperationDetailElement == null) {
			throw new Exception("apiOperationDetail not found for: " + functionName);
		}
		Element apiOperationDefElement = apiOperationDetailElement.element("apiOperationDef");
		if (apiOperationDefElement == null) {
			throw new Exception("apiOperationDef not found for: " + functionName);
		}

		Element apiIsOverrideElement = apiOperationDefElement.element("apiIsOverride");
		if (apiIsOverrideElement != null) {
			isOverride = true;
			if (!configuration.getAir() && "clone".equals(functionName)
					&& "flash.ui.ContextMenuItem".equals(contextClassName)) {
				isOverride = false;
			}
		}

		Element apiReturnElement = apiOperationDefElement.element("apiReturn");
		if (apiReturnElement != null) {
			Element apiTypeElement = apiReturnElement.element("apiType");
			if (apiTypeElement != null) {
				returnType = parseReturnOrParamType(apiTypeElement, contextClassName);
			}
			Element apiOperationClassifierElement = apiReturnElement.element("apiOperationClassifier");
			if (apiOperationClassifierElement != null) {
				returnType = apiOperationClassifierElement.getTextTrim();
				returnType = returnType.replace(":", ".");
			}
		}

		Element apiAccessElement = apiOperationDefElement.element("apiAccess");
		if (!forInterface && apiAccessElement != null) {
			access = apiAccessElement.attributeValue("value");
		}

		Element apiStaticElement = apiOperationDefElement.element("apiStatic");
		if (!forInterface && apiStaticElement != null) {
			isStatic = true;
		}

		List<Element> apiParamElements = apiOperationDefElement.elements("apiParam");

		if ("Object".equals(contextClassName) && OBJECT_PROTOTYPE_METHODS.contains(functionName)) {
			return;
		}
		if ("toString".equals(functionName) && isOverride) {
			return;
		}

		functionBuilder.append("\t");
		if (access != null && access.length() > 0) {
			functionBuilder.append(access);
			functionBuilder.append(" ");
		}
		if (isStatic) {
			functionBuilder.append("static ");
		}
		if (!forInterface) {
			functionBuilder.append("native ");
		}
		if (isOverride) {
			functionBuilder.append("override ");
		}
		functionBuilder.append("function ");
		functionBuilder.append(functionName);
		functionBuilder.append("(");
		parseParameters(apiParamElements, contextClassName, functionName, functionBuilder);
		functionBuilder.append(")");
		functionBuilder.append(":");
		functionBuilder.append(returnType);
		functionBuilder.append(";");
		functionBuilder.append("\n");
	}

	private void parseConstructor(List<Element> apiConstructorElements, String contextClassName,
			StringBuilder functionBuilder) throws Exception {
		String constructorName = null;
		String access = null;
		List<Element> apiParamElements = null;

		for (Element apiConstructorElement : apiConstructorElements) {
			if (constructorName == null) {
				constructorName = apiConstructorElement.element("apiName").getTextTrim();
			}

			Element apiConstructorDetailElement = apiConstructorElement.element("apiConstructorDetail");
			if (apiConstructorDetailElement == null) {
				throw new Exception("apiConstructorDetail not found for: " + constructorName);
			}
			Element apiConstructorDefElement = apiConstructorDetailElement.element("apiConstructorDef");
			if (apiConstructorDefElement == null) {
				throw new Exception("apiConstructorDef not found for: " + constructorName);
			}

			Element apiAccessElement = apiConstructorDefElement.element("apiAccess");
			if (apiAccessElement != null) {
				access = apiAccessElement.attributeValue("value");
			}

			List<Element> newApiParamElements = apiConstructorDefElement.elements("apiParam");
			apiParamElements = mergeParameters(apiParamElements, newApiParamElements);
		}

		functionBuilder.append("\t");
		if (access != null && access.length() > 0) {
			functionBuilder.append(access);
			functionBuilder.append(" ");
		}
		functionBuilder.append("native ");
		functionBuilder.append("function ");
		functionBuilder.append(constructorName);
		functionBuilder.append("(");
		parseParameters(apiParamElements, contextClassName, constructorName, functionBuilder);
		functionBuilder.append(")");
		functionBuilder.append(";");
		functionBuilder.append("\n");
	}

	private List<Element> mergeParameters(List<Element> apiParamElements1, List<Element> apiParamElements2)
			throws Exception {
		if (apiParamElements1 == null) {
			return apiParamElements2;
		}
		if (apiParamElements2 == null) {
			return apiParamElements1;
		}
		ArrayList<Element> result = new ArrayList<Element>();
		for (int i = 0, count = Math.max(apiParamElements1.size(), apiParamElements2.size()); i < count; i++) {
			Element apiParamElement1 = (apiParamElements1.size() > i) ? apiParamElements1.get(i) : null;
			Element apiParamElement2 = (apiParamElements2.size() > i) ? apiParamElements2.get(i) : null;
			if (apiParamElement1 == null) {
				Element apiDataElement2 = apiParamElement2.element("apiData");
				if (apiDataElement2 == null) {
					apiDataElement2 = DocumentHelper.createElement("apiData");
					apiDataElement2.setText("null");
					apiParamElement2.add(apiDataElement2);
				}
				boolean isRest = false;
				Element apiTypeElement2 = apiParamElement2.element("apiType");
				if (apiTypeElement2 != null) {
					String apiTypeValue2 = apiTypeElement2.attributeValue("value");
					if ("restParam".equals(apiTypeValue2)) {
						isRest = true;
					}
					apiParamElement2.remove(apiTypeElement2);
				}
				apiTypeElement2 = DocumentHelper.createElement("apiType");
				if (isRest) {
					apiTypeElement2.addAttribute("value", "restParam");
				} else {
					apiTypeElement2.addAttribute("value", "any");
				}
				apiParamElement2.add(apiTypeElement2);
				Element apiOperationClassifierElement2 = apiParamElement2.element("apiOperationClassifier");
				if (apiOperationClassifierElement2 != null) {
					apiParamElement2.remove(apiOperationClassifierElement2);
				}
				result.add(apiParamElement2);
				if (isRest) {
					// nothing after rest
					break;
				}
				continue;
			}
			if (apiParamElement2 == null) {
				Element apiDataElement1 = apiParamElement1.element("apiData");
				if (apiDataElement1 == null) {
					apiDataElement1 = DocumentHelper.createElement("apiData");
					apiDataElement1.setText("null");
					apiParamElement1.add(apiDataElement1);
				}
				boolean isRest = false;
				Element apiTypeElement1 = apiParamElement1.element("apiType");
				if (apiTypeElement1 != null) {
					String apiTypeValue1 = apiTypeElement1.attributeValue("value");
					if ("restParam".equals(apiTypeValue1)) {
						isRest = true;
					}
					apiParamElement1.remove(apiTypeElement1);
				}
				apiTypeElement1 = DocumentHelper.createElement("apiType");
				if (isRest) {
					apiTypeElement1.addAttribute("value", "restParam");
				} else {
					apiTypeElement1.addAttribute("value", "any");
				}
				apiParamElement1.add(apiTypeElement1);
				Element apiOperationClassifierElement1 = apiParamElement1.element("apiOperationClassifier");
				if (apiOperationClassifierElement1 != null) {
					apiParamElement1.remove(apiOperationClassifierElement1);
				}
				result.add(apiParamElement1);
				if (isRest) {
					// nothing after rest
					break;
				}
				continue;
			}

			String paramName = "param" + i;
			boolean isRest = false;
			Element apiTypeElement1 = apiParamElement1.element("apiType");
			if (apiTypeElement1 != null) {
				String apiTypeValue1 = apiTypeElement1.attributeValue("value");
				if ("restParam".equals(apiTypeValue1)) {
					isRest = true;
					Element apiItemNameElement1 = apiParamElement1.element("apiItemName");
					if (apiItemNameElement1 != null) {
						// keep the existing name
						paramName = apiItemNameElement1.getTextTrim();
					}
				}
			}
			Element apiTypeElement2 = apiParamElement2.element("apiType");
			if (apiTypeElement2 != null) {
				String apiTypeValue2 = apiTypeElement2.attributeValue("value");
				if ("restParam".equals(apiTypeValue2)) {
					isRest = true;
					Element apiItemNameElement2 = apiParamElement2.element("apiItemName");
					if (apiItemNameElement2 != null) {
						// keep the existing name
						paramName = apiItemNameElement2.getTextTrim();
					}
				}
			}
			Element newApiParamElement = DocumentHelper.createElement("apiParam");
			Element apiItemNameElement = DocumentHelper.createElement("apiItemName");
			apiItemNameElement.setText(paramName);
			newApiParamElement.add(apiItemNameElement);
			Element newApiTypeElement = DocumentHelper.createElement("apiType");
			if (isRest) {
				newApiTypeElement.addAttribute("value", "restParam");
			} else {
				newApiTypeElement.addAttribute("value", "any");
			}
			newApiParamElement.add(newApiTypeElement);
			if (!isRest) {
				Element newApiDataElement = DocumentHelper.createElement("apiData");
				newApiDataElement.setText("null");
				newApiParamElement.add(newApiDataElement);
			}
			result.add(newApiParamElement);
			if (isRest) {
				// nothing after rest
				break;
			}
		}
		return result;
	}

	private String parseReturnOrParamType(Element apiTypeElement, String contextClassName) throws Exception {
		String apiTypeValue = apiTypeElement.attributeValue("value");
		if ("restParam".equals(apiTypeValue)) {
			return null;
		}
		if ("any".equals(apiTypeValue)) {
			return "*";
		}
		if ("T".equals(apiTypeValue)) {
			return "T";
		}
		if ("void".equals(apiTypeValue)) {
			return "void";
		}
		if (apiTypeValue.startsWith("Vector$")) {
			String[] parts = apiTypeValue.split("\\$");
			String vectorItemType = parts[1];
			vectorItemType = vectorItemType.replace(":", ".");
			if (contextClassName != null && contextClassName.startsWith("__AS3__.vec.Vector$")
					&& vectorItemType.equals("T")) {
				return contextClassName;
			}
			return "Vector.<" + vectorItemType + ">";
		} else {
			throw new Exception("Unknown apiType value: " + apiTypeValue);
		}
	}

	private boolean isConstructorThatNeedsParamsTypedAsAny(String contextClassName, String contextFunctionName) {
		if (!contextFunctionName.equals(contextClassName)) {
			return false;
		}
		return ANY_CONSTRUCTORS.contains(contextFunctionName);
	}

	private boolean isMethodThatNeedsParamsTypedAsAny(String contextClassName, String contextFunctionName) {
		if (!ANY_METHODS.containsKey(contextClassName)) {
			return false;
		}
		return ANY_METHODS.get(contextClassName).contains(contextFunctionName);
	}

	private boolean isMethodThatNeedsParamsWithDefaultNull(String contextClassName, String contextFunctionName) {
		if (!NULL_DEFAULT_METHODS.containsKey(contextClassName)) {
			return false;
		}
		return NULL_DEFAULT_METHODS.get(contextClassName).contains(contextFunctionName);
	}

	private boolean isMethodThatNeedsRestParamOnly(String contextClassName, String contextFunctionName) {
		if (!REST_METHODS.containsKey(contextClassName)) {
			return false;
		}
		return REST_METHODS.get(contextClassName).contains(contextFunctionName);
	}

	private boolean isVariableTypedAsAny(String contextClassName, String contextVariableName) {
		if (!ANY_VARIABLES.containsKey(contextClassName)) {
			return false;
		}
		return ANY_VARIABLES.get(contextClassName).contains(contextVariableName);
	}

	private void parseParameters(List<Element> apiParamElements, String contextClassName, String contextFunctionName,
			StringBuilder functionBuilder) throws Exception {
		boolean forceOptionalConstructor = isConstructorThatNeedsParamsTypedAsAny(contextClassName,
				contextFunctionName);
		boolean forceRest = isMethodThatNeedsRestParamOnly(contextClassName, contextFunctionName);
		boolean forceAnyType = isMethodThatNeedsParamsTypedAsAny(contextClassName, contextFunctionName);
		boolean forceNullDefault = isMethodThatNeedsParamsWithDefaultNull(contextClassName, contextFunctionName);
		for (int i = 0; i < apiParamElements.size(); i++) {
			if (i > 0) {
				functionBuilder.append(", ");
			}
			Element apiParamElement = apiParamElements.get(i);
			Element apiTypeElement = apiParamElement.element("apiType");
			String paramType = null;
			if (forceRest) {
				functionBuilder.append("...args");
				break;
			} else {
				if (apiTypeElement != null) {
					String apiTypeValue = apiTypeElement.attributeValue("value");
					if ("restParam".equals(apiTypeValue)) {
						functionBuilder.append("...");
					}
					paramType = parseReturnOrParamType(apiTypeElement, contextClassName);
				}
				Element apiItemNameElement = apiParamElement.element("apiItemName");
				if (apiItemNameElement == null) {
					throw new Exception("apiItemName not found");
				}
				functionBuilder.append(apiItemNameElement.getTextTrim());
				if (forceOptionalConstructor) {
					// workaround for missing data in asdoc dita
					functionBuilder.append(":* = null");
				} else {
					Element apiOperationClassifierElement = apiParamElement.element("apiOperationClassifier");
					if (apiOperationClassifierElement != null) {
						paramType = apiOperationClassifierElement.getTextTrim();
						paramType = paramType.replace(":", ".");
					}
					if (forceAnyType) {
						paramType = "*";
					}
					if (paramType != null) {
						functionBuilder.append(":");
						functionBuilder.append(paramType);
					}
					Element apiDataElement = apiParamElement.element("apiData");
					if (forceNullDefault) {
						functionBuilder.append(" = null");
					} else if (apiDataElement != null) {
						writeVariableOrParameterValue(apiDataElement, paramType, functionBuilder);
					} else if (("int".equals(contextClassName) || "uint".equals(contextClassName))
							&& "toString".equals(contextFunctionName)) {
						functionBuilder.append(" = 10");
					}
				}
			}
		}
	}

	private void writeVariableOrParameterValue(Element apiDataElement, String varType, StringBuilder builder) {
		builder.append(" = ");
		String paramValue = apiDataElement.getTextTrim();
		if ("unknown".equals(paramValue)) {
			paramValue = "null";
		}
		boolean isString = ("String".equals(varType) || paramValue.matches("[A-Za-z\\*]+"))
				&& !"undefined".equals(paramValue) && !"null".equals(paramValue) && !"NaN".equals(paramValue)
				&& !"true".equals(paramValue) && !"false".equals(paramValue);
		if (isString) {
			builder.append("\"");
		}
		builder.append(paramValue);
		if (isString) {
			builder.append("\"");
		}
	}

	private void collectImport(String fullyQualifiedName, String forPackage, Set<String> result) throws Exception {
		String[] parts = fullyQualifiedName.split(":");
		if (parts.length == 1) {
			// top-level package
			return;
		}
		String packageName = parts[0];
		if (packageName.equals(forPackage)) {
			// same package
			return;
		}
		result.add(packageName + "." + parts[1]);
	}

	private void collectImports(Element element, String forPackage, Set<String> result) throws Exception {
		String elementName = element.getName();
		if ("apiClassifier".equals(elementName)) {
			String className = element.element("apiName").getTextTrim();

			Element apiClassifierDetailElement = element.element("apiClassifierDetail");
			if (apiClassifierDetailElement == null) {
				throw new Exception("apiClassifierDetail not found for: " + className);
			}
			Element apiClassifierDefElement = apiClassifierDetailElement.element("apiClassifierDef");
			if (apiClassifierDefElement == null) {
				throw new Exception("apiClassifierDef not found for: " + className);
			}

			Element apiBaseClassifierElement = apiClassifierDefElement.element("apiBaseClassifier");
			if (apiBaseClassifierElement != null) {
				String baseClassType = apiBaseClassifierElement.getTextTrim();
				collectImport(baseClassType, forPackage, result);
			}

			List<Element> apiBaseInterfaceElements = apiClassifierDefElement.elements("apiBaseInterface");
			for (Element apiBaseInterfaceElement : apiBaseInterfaceElements) {
				String interfaceType = apiBaseInterfaceElement.getTextTrim();
				collectImport(interfaceType, forPackage, result);
			}

			Element apiConstructorElement = element.element("apiConstructor");
			if (apiConstructorElement != null) {
				collectImports(apiConstructorElement, forPackage, result);
			}

			List<Element> apiOperationElements = element.elements("apiOperation");
			for (Element apiOperationElement : apiOperationElements) {
				collectImports(apiOperationElement, forPackage, result);
			}

			List<Element> apiValueElements = element.elements("apiValue");
			for (Element apiValueElement : apiValueElements) {
				collectImports(apiValueElement, forPackage, result);
			}
		}
		if ("apiOperation".equals(elementName)) {
			boolean isAIROnly = isAIROnly(element.element("prolog"));
			if (isAIROnly && !configuration.getAir()) {
				return;
			}

			String functionName = element.element("apiName").getTextTrim();

			Element apiOperationDetailElement = element.element("apiOperationDetail");
			if (apiOperationDetailElement == null) {
				throw new Exception("apiOperationDetail not found for: " + functionName);
			}
			Element apiOperationDefElement = apiOperationDetailElement.element("apiOperationDef");
			if (apiOperationDefElement == null) {
				throw new Exception("apiOperationDef not found for: " + functionName);
			}

			Element apiReturnElement = apiOperationDefElement.element("apiReturn");
			if (apiReturnElement != null) {
				Element apiTypeElement = apiOperationDefElement.element("apiType");
				if (apiTypeElement != null) {
					String apiTypeValue = apiTypeElement.attributeValue("value");
					if (apiTypeValue.startsWith("Vector$")) {
						String[] parts = apiTypeValue.split("\\$");
						String vectorItemType = parts[1];
						collectImport(vectorItemType, forPackage, result);
					}
				}
				Element apiOperationClassifierElement = apiReturnElement.element("apiOperationClassifier");
				if (apiOperationClassifierElement != null) {
					String returnType = apiOperationClassifierElement.getTextTrim();
					collectImport(returnType, forPackage, result);
				}
			}

			List<Element> apiParamElements = apiOperationDefElement.elements("apiParam");
			for (Element apiParamElement : apiParamElements) {
				Element apiTypeElement = apiParamElement.element("apiType");
				if (apiTypeElement != null) {
					String apiTypeValue = apiTypeElement.attributeValue("value");
					if (apiTypeValue.startsWith("Vector$")) {
						String[] parts = apiTypeValue.split("\\$");
						String vectorItemType = parts[1];
						collectImport(vectorItemType, forPackage, result);
					}
				}
				Element apiOperationClassifierElement = apiParamElement.element("apiOperationClassifier");
				if (apiOperationClassifierElement != null) {
					String paramType = apiOperationClassifierElement.getTextTrim();
					collectImport(paramType, forPackage, result);
				}
			}
		}
		if ("apiConstructor".equals(elementName)) {
			String functionName = element.element("apiName").getTextTrim();

			Element aapiConstructorDetailElement = element.element("apiConstructorDetail");
			if (aapiConstructorDetailElement == null) {
				throw new Exception("apiConstructor not found for: " + functionName);
			}
			Element apiConstructorDefElement = aapiConstructorDetailElement.element("apiConstructorDef");
			if (apiConstructorDefElement == null) {
				throw new Exception("apiConstructorDef not found for: " + functionName);
			}

			List<Element> apiParamElements = apiConstructorDefElement.elements("apiParam");
			for (Element apiParamElement : apiParamElements) {
				Element apiTypeElement = apiParamElement.element("apiType");
				if (apiTypeElement != null) {
					String apiTypeValue = apiTypeElement.attributeValue("value");
					if (apiTypeValue.startsWith("Vector$")) {
						String[] parts = apiTypeValue.split("\\$");
						String vectorItemType = parts[1];
						collectImport(vectorItemType, forPackage, result);
					}
				}
				Element apiOperationClassifierElement = apiParamElement.element("apiOperationClassifier");
				if (apiOperationClassifierElement != null) {
					String paramType = apiOperationClassifierElement.getTextTrim();
					collectImport(paramType, forPackage, result);
				}
			}
		}
		if ("apiValue".equals(elementName)) {
			boolean isAIROnly = isAIROnly(element.element("prolog"));
			if (isAIROnly && !configuration.getAir()) {
				return;
			}

			String variableName = element.element("apiName").getTextTrim();

			Element apiValueDetailElement = element.element("apiValueDetail");
			if (apiValueDetailElement == null) {
				throw new Exception("apiValueDetail not found for: " + variableName);
			}
			Element apiValueDefElement = apiValueDetailElement.element("apiValueDef");
			if (apiValueDefElement == null) {
				throw new Exception("apiValueDef not found for: " + variableName);
			}

			Element apiValueClassifierElement = apiValueDefElement.element("apiValueClassifier");
			if (apiValueClassifierElement != null) {
				String variableType = apiValueClassifierElement.getTextTrim();
				collectImport(variableType, forPackage, result);
			}
		}
	}

	private void writeImports(Set<String> imports, StringBuilder builder) {
		for (String importName : imports) {
			builder.append("\t");
			builder.append("import ");
			builder.append(importName);
			builder.append(";");
			builder.append("\n");
		}
		if (imports.size() > 0) {
			builder.append("\n");
		}
	}
}