/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tools.internal;
import java.io.*;
import java.util.*;

/* Produces the java classes mapping to XPCOM Mozilla objects */
public class MozillaGenerator {
	FileReader r = null;
	FileWriter w = null;
	int maxLines = 1000;
	int cntLines = 0;
	int n = 0;
	String[] b = null;
	String body = null;
	int nMethods = 0;
	String uuidName;
	String uuidValue;
	String className;
	String parentName;
	String[] constantNames;
	String[] constantValues;
	String[] methodNames;
	String[][] argTypes;
	String[][] argNames;
	String bodyOrder;
	Hashtable<Integer, Vector<String>> vtbls;

	static boolean DEBUG = false;

	// Contains the characters found before a method name
	// Useful to extract the method name. e.g.
	//  NS_IMETHOD QueryInterface(const nsIID & uuid, void * *result) = 0;
	//  NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
	// method name follows: QueryInterface, AddRef etc.
	static String[] BEFORE_METHOD_NAME = {
		"  NS_IMETHOD ",
		"  NS_IMETHOD_(nsrefcnt) ",
		"  NS_IMETHOD_(void *) ",
		"  NS_IMETHOD_(void) ",
		"  NS_IMETHOD_(nsresult) ",
		"  NS_SCRIPTABLE NS_IMETHOD ",
		"  NS_SCRIPTABLE NS_IMETHOD_(nsrefcnt) ",
		"  NS_SCRIPTABLE NS_IMETHOD_(void *) ",
		"  NS_SCRIPTABLE NS_IMETHOD_(void) ",
		"  NS_SCRIPTABLE NS_IMETHOD_(nsresult) ",
	};
	static String NO_SUPER_CLASS = "SWT_NO_SUPER_CLASS";
	
	static String[][] TYPES_C2JAVA = { 
		{ "PRBool *", "int[]" },
		{ "nsIID &", "nsID" },
		{ "nsCID &", "nsID" },
		{ "nsCID * *", "int /*long*/" }, // nsID[] not supported by jnigen
		{ "* *", "int /*long*/[]" },
		{ "**", "int /*long*/[]" },
		{ "* &", "int /*long*/[]" },
		{ "PRUint32 *", "int[]" }, 
		{ "PRInt32 *", "int[]" },
		{ "PRInt64 *", "long[]" },
		{ "PRUnichar *", "char[]" },
		{ "char *", "byte[]" },
		{ "float *", "float[]" },
		{ "PRUint16 *", "short[]" },
		{ "nativeWindow *", "int /*long*/[]" },
		{ "nsWriteSegmentFun", "int /*long*/" },
		{ "nativeWindow", "int /*long*/" },

		{ "*", "int /*long*/" }, // c type containing one or more * (and any other character, and did not match previous patterns) is a simple pointer
		{ "&", "int /*long*/" }, 

		{ "PRUint32", "int" },
		{ "PRInt32", "int" }, 
		{ "PRInt64", "long" }, 
		{ "nsresult", "int" },
		{ "PRBool", "int" },
		{ "float", "float" },
		{ "PRUint16", "short" },
		{ "size_t", "int" },
		};

	static String GECKO = "/opt/mozilla/1.4/linux_gtk2/mozilla/dist/include/";
	static String TARGET_FOLDER = "/opt/workspace/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/";
	static String[] XPCOM_HEADERS = {
		"profile/nsIProfile.h",
		"widget/nsIAppShell.h",
		"widget/nsIBaseWindow.h",
		"xpcom/nsIComponentManager.h",
		"xpcom/nsIComponentRegistrar.h",
		"webbrwsr/nsIContextMenuListener.h", 
		"docshell/nsIDocShell.h",
		"dom/nsIDOMEvent.h",
		"dom/nsIDOMMouseEvent.h",
		"dom/nsIDOMUIEvent.h",
		"dom/nsIDOMWindow.h",
		"uriloader/nsIDownload.h", 
		"webbrwsr/nsIEmbeddingSiteWindow.h",
		"xpcom/nsIFactory.h", 
		"xpcom/nsIFile.h",
		"helperAppDlg/nsIHelperAppLauncherDialog.h",
		"exthandler/nsIExternalHelperAppService.h", // contains nsIHelperAppLauncher
		"xpcom/nsIInputStream.h", 
		"xpcom/nsIInterfaceRequestor.h",
		"necko/nsIIOService.h", 
		"xpcom/nsILocalFile.h", 
		"xpcom/nsIMemory.h",
		"progressDlg/nsIProgressDialog.h",
		"windowwatcher/nsIPromptService.h", 
		"xpcom/nsIServiceManager.h",
		"xpcom/nsISupports.h", 
		"webbrwsr/nsITooltipListener.h", 
		"necko/nsIURI.h",
		"uriloader/nsIURIContentListener.h", 
		"xpcom/nsIWeakReference.h",
		"webbrwsr/nsIWebBrowser.h", 
		"webbrwsr/nsIWebBrowserChrome.h",
		"webbrwsr/nsIWebBrowserChromeFocus.h",
		"webbrwsr/nsIWebBrowserFocus.h", 
		"docshell/nsIWebNavigation.h",
		"uriloader/nsIWebProgress.h", 
		"uriloader/nsIWebProgressListener.h",
		"embed_base/nsIWindowCreator.h", 
		"windowwatcher/nsIWindowWatcher.h" };

	public static void main(String[] args) {
		MozillaGenerator x = new MozillaGenerator();
		for (int i = 0; i < XPCOM_HEADERS.length; i++)
			x.parse(GECKO + XPCOM_HEADERS[i], TARGET_FOLDER);
		x.outputVtblCall();
		System.out.println("done");
	}

	public MozillaGenerator() {
		vtbls = new Hashtable<Integer, Vector<String>>();
	}

	/** Write callbacks */
	public void write(String data) {
		if (DEBUG) {
			System.out.print(data);
			return;
		}
		try {
			w.write(data);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void writeLine() {
		if (DEBUG) {
			System.out.println();
			return;
		}
		write("\r\n");
	}

	public void writeLine(String data) {
		if (DEBUG) {
			System.out.println(data);
			return;
		}
		write(data + "\r\n");
	}

	public void writeCopyrights() {
		writeLine(COPYRIGHTS);
	}

	public void writePackageDeclaration() {
		writeLine(PACKAGE_DECLARATION);
	}

	public void writeClassDeclaration(String className, String parentName) {
		String line = "public class " + className;
		if (!parentName.equals(NO_SUPER_CLASS)) line += " extends " + parentName;
		line += " {";
		writeLine(line);
	}

	public void writeLastMethodId(String parentName, int nMethods) {
		String line = "\tstatic final int LAST_METHOD_ID = ";
		if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + nMethods + ";";
		else line += "" + (nMethods - 1)+ ";"; // zero indexed
		writeLine(line);
	}

	public void writeIID(String uuidName, String uuidValue) {
		writeLine("\tpublic static final String " + uuidName + " =");
		writeLine("\t\t\"" + uuidValue + "\";");
		writeLine();
		String iid = uuidName.substring(0, uuidName.indexOf("_STR"));
		writeLine("\tpublic static final nsID " + iid + " =");
		writeLine("\t\tnew nsID(" + uuidName + ");");
	}

	public void writeAddressField() {
		writeLine("\tint /*long*/ address;");
	}
	public void writeConstructor(String className, String parentName) {
		writeLine("\tpublic " + className + "(int /*long*/ address) {");
		if (!parentName.equals(NO_SUPER_CLASS)) {
			writeLine("\t\tsuper(address);");
		} else {
			writeLine("\t\tthis.address = address;");
		}
		writeLine("\t}");
	}

	public void writeAddressGetter() {
		writeLine("\tpublic int /*long*/ getAddress() {");
		writeLine("\t\treturn this.address;");
		writeLine("\t}");
	}
	
	public void writeConstant(String name, String value) {
		writeLine("\tpublic static final int " + name + " = " + value + ";");
	}

	public void writeMethod(String name, String parentName, int methodIndex, String[] argTypes, String[] argNames) {
		write("\tpublic int " + name + "(");
		for (int i = 0; i < argTypes.length; i++) {
			write(argTypes[i] + " " + argNames[i]);
			if (i < argTypes.length - 1)
				write(", ");
		}
		write(") {");
		writeLine();
		String line = "\t\treturn XPCOM.VtblCall(";
		if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + (methodIndex + 1) + ", getAddress()";
		else line += methodIndex + ", getAddress()"; // zero indexed
		write(line);
		if (argTypes.length > 0)
			write(", ");
		for (int i = 0; i < argTypes.length; i++) {
			write(argNames[i]);
			if (i < argTypes.length - 1)
				write(", ");
		}
		writeLine(");");
		writeLine("\t}");
	}

	public void writeClassEnd() {
		write("}");
	}

	public void logVtblCall(String[] argTypes) {
		String vtbl = "static final native int VtblCall(int fnNumber, int /*long*/ ppVtbl";
		if (argTypes.length > 0)
			vtbl += ", ";
		for (int i = 0; i < argTypes.length; i++) {
			vtbl += argTypes[i] + " arg" + i;
			if (i < argTypes.length - 1)
				vtbl += ", ";
		}
		vtbl += ");";
		Integer key = new Integer(argTypes.length);
		Vector<String> list = vtbls.get(key);
		if (list == null) {
			list = new Vector<String>();
			vtbls.put(key, list);
		}
		boolean duplicate = false;
		Enumeration<String> e = list.elements();
		while (e.hasMoreElements()) {
			String s = e.nextElement();
			if (vtbl.equals(s)) {
				duplicate = true;
				break;
			}
		}
		if (!duplicate)
			list.add(vtbl);
	}

	public void outputVtblCall() {
		Enumeration<Integer> e = vtbls.keys();
		int n = 0;
		while (e.hasMoreElements()) {
			e.nextElement();
			n++;
		}
		Integer[] keys = new Integer[n];
		e = vtbls.keys();
		n = 0;
		while (e.hasMoreElements()) {
			keys[n] = e.nextElement();
			n++;
		}
		Arrays.sort(keys);
		for (int i = 0; i < keys.length; i++) {
			Vector<?> list = vtbls.get(keys[i]);
			Object[] elts = list.toArray();
			Arrays.sort(elts);
			for (int j = 0; j < elts.length; j++) {
				System.out.println(elts[j]);
			}
		}

	}

	/** Parsing invoking write callbacks */

	/*
	 * Convert a C header file into a Java source file matching SWT Mozilla
	 binding.
	 */
	public void parse(String src, String destPath) {
		if (DEBUG) writeLine("*** PARSING <"+src+"> to folder "+destPath);
		b = new String[maxLines];
		cntLines = 0;
		try {
			r = new FileReader(src);
			BufferedReader br = new BufferedReader(r);
			while ((b[cntLines] = br.readLine()) != null) {
				cntLines++;
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		n = 0;
		boolean lookForClasses = true;
		while (lookForClasses) {	
			/* parsing */
			lookForClasses = parse();
	
			String destFile = destPath + className + ".java";
			try {
				w = new FileWriter(destFile);
				if (DEBUG) writeLine("** CREATED JAVA FILE <"+destFile+">");
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
	
			/* writing */
			writeCopyrights();
			writePackageDeclaration();
			writeLine();
			writeClassDeclaration(className, parentName);
			writeLine();
			writeLastMethodId(parentName, nMethods);
			writeLine();
			writeIID(uuidName, uuidValue);
			writeLine();
			if (parentName.equals(NO_SUPER_CLASS)) {
				writeAddressField();
				writeLine();
			}
			writeConstructor(className, parentName);
			writeLine();
			
			if (parentName.equals(NO_SUPER_CLASS)) {
				writeAddressGetter();
				writeLine();
			}
	
			int constantIndex = 0, methodIndex = 0;
			for (int i = 0; i < bodyOrder.length(); i++) {
				if (bodyOrder.charAt(i) == 'C') {
					writeConstant(constantNames[constantIndex],
							constantValues[constantIndex]);
					if (i < bodyOrder.length() - 1) writeLine();
					constantIndex++;
				} else if (bodyOrder.charAt(i) == 'M') {
					writeMethod(methodNames[methodIndex], parentName, methodIndex,
							argTypes[methodIndex], argNames[methodIndex]);
					if (i < bodyOrder.length() - 1) writeLine();
					methodIndex++;
				}
			}
	
			writeClassEnd();
	
			try {
				w.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public String getPackages() {
		return "package org.eclipse.swt.internal.mozilla;";
	}

	public boolean parse() {
		if (!jumpToUuidDeclaration()) return false;
		uuidName = getUuidName(b[n]);
		if (DEBUG)
			System.out.println("UUID name: <" + uuidName + ">");
		uuidValue = getUuidValue(b[n]);
		if (DEBUG)
			System.out.println("UUID value: <" + uuidValue + ">");
		jumpToInterfaceDeclaration();
		className = getClassName(b[n]);
		if (DEBUG)
			System.out.println("Interface name: <" + className + ">");
		parentName = getParentName(b[n]);
		if (DEBUG)
			System.out.println("parentName: <" + parentName + ">");
		parseBody();
		return true;
	}

	boolean jumpToUuidDeclaration() {
		// jump to line matching: "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c""
		while (!(b[n].startsWith("#define ") && b[n].indexOf("_IID_STR \"") != -1)) {
			n++;
			if (n >= cntLines) return false;
		}
		return true;
	}

	//assume a declaration matching: "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c""
	//returns NS_IWEBBROWSERCHROME_IID_STR
	String getUuidName(String declaration) {
		return declaration.substring(declaration.indexOf("#define ")
				+ "#define ".length(), declaration.indexOf(" \""));
	}

	//assume a declaration matching: "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c""
	//returns ba434c60-9d52-11d3-afb0-00a024ffc08c
	String getUuidValue(String declaration) {
		return declaration.substring(declaration.indexOf("_IID_STR \"")
				+ "_IID_STR \"".length(), declaration.lastIndexOf('"'));
	}

	void jumpToInterfaceDeclaration() {
		// jump to line matching: "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {"
		while (!(b[n].startsWith("class NS_NO_VTABLE "))) {
			n++;
		}
	}

	// Assume a declaration matching: "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {"
	// or "class NS_NO_VTABLE NS_SCRIPTABLE nsIWebBrowserChrome : public nsISupports {" returns nsIWebBrowserChrome.
	// Special case for nsISupports that has no super class: class NS_NO_VTABLE nsISupports {
	String getClassName(String declaration) {
		int endIndex = declaration.indexOf(" :");
		// nsISupports special case (no super class)
		if (endIndex == -1) endIndex = declaration.indexOf(" {");
		String searchString = "class NS_NO_VTABLE NS_SCRIPTABLE";
		int startIndex = declaration.indexOf(searchString);
		if (startIndex == -1) {
			searchString = "class NS_NO_VTABLE ";
			startIndex = declaration.indexOf(searchString);
		}
		return declaration.substring(startIndex + searchString.length(), endIndex);
	}

	// assume a declaration matching: "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {"
	// returns nsISupports
	// special case for nsISupports that has no super class: class NS_NO_VTABLE nsISupports {
	String getParentName(String declaration) {
		if (declaration.indexOf(" :") == -1) return NO_SUPER_CLASS;
		return declaration.substring(declaration.indexOf(": public ")
				+ ": public ".length(), declaration.indexOf(" {"));
	}

	// parse methods and constants declarations starting at the current index
	// out:
	// .String body - contains the corresponding java content
	// .n - set to the end of the interface body declaration ( line with the enclosing "};" )
	// .nMethods    - set to the number of methods parsed
	void parseBody() {
		body = "";
		bodyOrder = "";
		int nConstants = 0;
		nMethods = 0;

		int tmp_n = n;
		while (true) {
			int type = jumpToNextConstantOrMethod();
			if (type == CONSTANT)
				nConstants++;
			if (type == METHOD)
				nMethods++;
			if (type == END_BODY)
				break;
			n++;
		}
		n = tmp_n;
		constantNames = new String[nConstants];
		constantValues = new String[nConstants];
		methodNames = new String[nMethods];
		argTypes = new String[nMethods][];
		argNames = new String[nMethods][];
		int constantIndex = 0, methodIndex = 0;
		while (true) {
			int type = jumpToNextConstantOrMethod();
			if (type == CONSTANT) {
				parseConstant(b[n], constantIndex);
				bodyOrder += "C";
				constantIndex++;
			}
			if (type == METHOD) {
				parseMethod(b[n], methodIndex);
				logVtblCall(argTypes[methodIndex]);
				bodyOrder += "M";
				methodIndex++;
			}
			if (type == END_BODY)
				return;
			n++;
		}
	}

	static int CONSTANT = 0;

	static int METHOD = 1;

	static int END_BODY = 2;

	boolean isEndOfInterfaceBody() {
		return b[n].startsWith("};");
	}

	int jumpToNextConstantOrMethod() {
		while (!isEndOfInterfaceBody()) {
			if (b[n].startsWith("  enum { ")) {
				return CONSTANT;
			}
			if (methodNameStartIndexOf(b[n]) != -1) {
				return METHOD;
			}
			n++;
		}
		return END_BODY;
	}

	void parseConstant(String constant, int constantIndex) {
		String constantName = constant.substring(constant.indexOf(" enum { ")
				+ " enum { ".length(), constant.indexOf(" ="));
		if (DEBUG)
			writeLine("constantName <" + constantName + ">");
		constantNames[constantIndex] = constantName;
		
		// most constants values have a trailing U
		// enum { APP_TYPE_UNKNOWN = 0U };
		int endIndex = constant.indexOf("U };");
		// a few others don't
		// enum { ENUMERATE_FORWARDS = 0 };		
		if (endIndex == -1) endIndex = constant.indexOf(" };");
		String constantValue = constant.substring(constant.indexOf(" = ")
				+ " = ".length(), endIndex);
		if (DEBUG)
			writeLine("constantValue <" + constantValue + ">");
		constantValues[constantIndex] = constantValue;
	}

	// NS_IMETHOD SetStatus(PRUint32 statusType, const PRUnichar *status) = 0;
	// identify:
	// method name: <SetStatus>
	// Nbr of arguments: 2
	// Type of argument 0: PRUint32
	// Name of argument 0: statusType
	// Type of argument 1: const PRUnichar *
	// Name of argument 1: status
	void parseMethod(String line, int methodIndex) {
		int start = methodNameStartIndexOf(line);
		int end = methodNameEndIndexOf(line);
		String methodName = line.substring(start, end);
		if (DEBUG)
			writeLine("method name: <" + methodName + ">");
		methodNames[methodIndex] = methodName;
		int argStart = end+"(".length();
		int argEnd = line.indexOf(")", argStart);
		parseArgs(line.substring(argStart, argEnd), methodIndex);
	}

	// Given a line, returns the start of the method name or -1
	// if the line does not contain a method declaration.
	int methodNameStartIndexOf(String line) {
		for (int i = 0; i < BEFORE_METHOD_NAME.length; i++) {
			int index = line.indexOf(BEFORE_METHOD_NAME[i]);
			if (index != -1) return index + BEFORE_METHOD_NAME[i].length();
		}
		return -1;
	}
	int methodNameEndIndexOf(String line) {
		int startIndex = methodNameStartIndexOf(line);
		return line.indexOf("(", startIndex);
	}
	void parseArgs(String args, int methodIndex) {
		int nArgs = -1;
		// methods with no args look like: () or (void)
		String[] noArgs = new String[] { "", "void" };
		for (int i = 0; i < noArgs.length; i++) {
			if (args.equals(noArgs[i])) {
				nArgs = 0;
				break;
			}
		}
		if (nArgs == -1)
			nArgs = count(args, ", ") + 1;
		String[] argTypes = new String[nArgs];
		this.argTypes[methodIndex] = argTypes;
		String[] argNames = new String[nArgs];
		this.argNames[methodIndex] = argNames;
		int typeStart = 0;

		// name is separated from its type by either of the following (sorted by decreasing size to find the most complete pattern */
		String[] typeNameSep = new String[] { " * *", " **", " * & ", " * ", " *",
				" & ", " " };
		for (int i = 0; i < nArgs; i++) {
			/* get the type */
			int nextTypeStart = i < nArgs - 1 ? args.indexOf(", ", typeStart)
					+ ", ".length() : args.length();
			int typeNameSepIndex = 0;
			int separatorIndex = 0;
			for (; typeNameSepIndex < typeNameSep.length; typeNameSepIndex++) {
				separatorIndex = args.indexOf(typeNameSep[typeNameSepIndex],
						typeStart);
				if (separatorIndex != -1 && separatorIndex < nextTypeStart)
					break;
			}
			String separator = typeNameSep[typeNameSepIndex];
			argTypes[i] = getC2JavaType(args.substring(typeStart,
					separatorIndex + separator.length()));
			if (DEBUG)
				writeLine("arg type" + i + ": <" + argTypes[i] + ">");
			/* get the name */
			int nameStart = separatorIndex + separator.length();
			int nameEnd = i < nArgs - 1 ? args.indexOf(", ", nameStart) : args
					.length();
			argNames[i] = args.substring(nameStart, nameEnd);
			if (DEBUG)
				writeLine("arg name" + i + ": <" + argNames[i] + ">");

			typeStart = nextTypeStart;
		}
	}

	String getC2JavaType(String cType) {
		for (int i = 0; i < TYPES_C2JAVA.length; i++) {
			if (cType.indexOf(TYPES_C2JAVA[i][0]) != -1)
				return TYPES_C2JAVA[i][1];
		}
		return "!ERROR UNKNOWN C TYPE <" + cType + ">!";
	}

	// how many times part can be found in s
	static int count(String s, String part) {
		int index = -1, cnt = 0;
		while ((index = s.indexOf(part, index + 1)) != -1)
			cnt++;
		return cnt;
	}

	static String COPYRIGHTS =
		"/* ***** BEGIN LICENSE BLOCK *****\r\n"
		+ " * Version: MPL 1.1\r\n"
		+ " *\r\n"
		+ " * The contents of this file are subject to the Mozilla Public License Version\r\n"
		+ " * 1.1 (the \"License\"); you may not use this file except in compliance with\r\n"
		+ " * the License. You may obtain a copy of the License at\r\n"
		+ " * http://www.mozilla.org/MPL/\r\n"
		+ " *\r\n"
		+ " * Software distributed under the License is distributed on an \"AS IS\" basis,\r\n"
		+ " * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r\n"
		+ " * for the specific language governing rights and limitations under the\r\n"
		+ " * License.\r\n"
		+ " *\r\n"
		+ " * The Original Code is Mozilla Communicator client code, released March 31, 1998.\r\n"
		+ " *\r\n"
		+ " * The Initial Developer of the Original Code is\r\n"
		+ " * Netscape Communications Corporation.\r\n"
		+ " * Portions created by Netscape are Copyright (C) 1998-1999\r\n"
		+ " * Netscape Communications Corporation.  All Rights Reserved.\r\n"
		+ " *\r\n" 
		+ " * Contributor(s):\r\n" 
		+ " *\r\n" 
		+ " * IBM\r\n"
		+ " * -  Binding to permit interfacing between Mozilla and SWT\r\n"
		+ " * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.\r\n"
		+ " *\r\n" + " * ***** END LICENSE BLOCK ***** */";

	static String PACKAGE_DECLARATION = "package org.eclipse.swt.internal.mozilla;";

}
