/*******************************************************************************
 * Copyright (c) 2010, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Red Hat Inc. - generification
 *******************************************************************************/
package org.eclipse.swt.browser;


import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.charset.*;
import java.time.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
import org.eclipse.swt.internal.webkit.*;
import org.eclipse.swt.internal.webkit.GdkRectangle;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

/**
 * VERSIONS:
 * Versioning for webkit is somewhat confusing because it's trying to incorporate webkit, gtk and (various linux distribution) versions.
 * The way they version webkitGTK is different from webkit.
 *   WebkitGTK:
 *    2.5 is webkit2.                    [2.4-..)  is Gtk3.
 *  Further, linux distributions might refer to webkit2 bindings linked against gtk3 differently.
 *  E.g on Fedora:
 *     webkitgtk4 = webkit2 / Gtk3
 *     webkit2gtk3 = WebKit2/ Gtk3
 *
 * Webkit2 loading:
 * - Dynamic bindings are auto generated and linked when the @dynamic keyword is used in WebKitGTK.java
 *   Unlike in OS.java, you don't have to add any code saying what lib the dynamic method is linked to. It's auto-linked to webkit lib by default.
 * - At no point should you have hard-compiled code, because this will cause crashes on older machines without webkit2.
 *   (the exception is the webextension, because it runs as a separate process and is only loaded dynamically).
 * - Try to keep all of your logic in Java and avoid writing custom C-code. (I went down this pit). Because if you
 *   use native code, then you have to write dynamic native code (get function pointers, cast types etc.. big pain in the ass).
 *   (Webextension is again an exception).
 * - Don't try to add webkit2 include flags to pkg-config, as this will tie the swt-glue code to specific webkit versions. Thou shall not do this.
 *   (webextension is an exception).
 *
 * Webextension:
 * - On Webkit2, a webextension is used to provide browserfunction/javascript callback functionality. (See the whole WebkitGDBus.java business).
 * - I've initially implemented javascript execution by running javascript and then waiting in a display-loop until webkit makes a return call.
 *   I then added a whole bunch of logic to avoid deadlocks.
 *   In retrospec, the better approach would be to send things off via GDBus and let the webextension run the javascript synchronously.
 *   But this would take another 1-2 months of implementation time and wouldn't guarantee dead-lock free behaviour as callbacks could potentailly still
 *   cause deadlocks. It's an interesting thought however..
 * - Note, most GDBus tutorials talk about compiling GDBus bindings. But using them dynamically I found is much easier. See this guide:
 *   http://www.cs.grinnell.edu/~rebelsky/Courses/CSC195/2013S/Outlines/
 *
 *
 * EVENT_HANDLING_DOC:
 * - On webkit2, signals are implemented via regular gtk mechanism, hook events and pass them along as we receive them.
 *   I haven't found a need to use the dom events, because webkitgtk seems to adequately meet the requirements via regular gtk
 *   events, but maybe I missed something? Who knows.
 *
 * setUrl(..) with 'post data' was implemented in a very hacky way, via native Java due to missing webkit2gtk api.
 * It's the best that could be done at the time, but it could result in strange behavior like some webpages loading in funky ways if post-data is used.
 *
 * Some good resources that I found are as following:
 * - Webkit2 reference: https://webkitgtk.org/reference/webkit2gtk/stable/
 *
 * - My github repository has a lot of snippets to prototype individual features (e.g gdbus, barebone webkit extension, GVariants etc..):
 *   https://github.com/LeoUfimtsev/LeoGtk3
 *   Be also mindful about snippets found in org.eclipse.swt.gtk.linux.x86_64 -> snippets -> widget.browser.
 *
 * - To understand GDBus, consider reading this guide:
 *   http://www.cs.grinnell.edu/~rebelsky/Courses/CSC195/2013S/Outlines/
 *   And then see the relevant reference I made in WebkitGDBus.java.
 *   Note, DBus is not the same as GDBus. GDBus is an implementation of the DBus protocol (with it's own quirks).
 *
 * - This is a good starting point for webkit2 extension reading:
 *   https://blogs.igalia.com/carlosgc/2013/09/10/webkit2gtk-web-process-extensions/
 *
 *   [April 2018]
 *   Note on WebKitContext:
 *    We only use a single webcontext, so WebKitGTK.webkit_web_context_get_default() works well for getting this when
 *    needed.
 *
 *
 *
 * ~May the force be with you.
 */
class WebKit extends WebBrowser {
	long webView;
	long pageId;

	int failureCount, lastKeyCode, lastCharCode;

	boolean ignoreDispose;
	boolean tlsError;
	long tlsErrorCertificate;
	String tlsErrorUriString;
	URI tlsErrorUri;
	String tlsErrorType;

	boolean firstLoad = true;

	/**
	 * Timeout used for javascript execution / deadlock detection.
	 * Loosely based on the 10s limit commonly found in browsers.
	 * (Except for SWT browser we use 3s as chunks of the UI is blocked).
	 * https://www.nczonline.net/blog/2009/01/05/what-determines-that-a-script-is-long-running/
	 * https://stackoverflow.com/questions/3030024/maximum-execution-time-for-javascript
	 */
	static final int ASYNC_EXEC_TIMEOUT_MS = 10000;

	/** Workaround for bug 522733 */
	static boolean bug522733FirstInstanceCreated = false;

	/** Part of workaround in Bug 527738. Prevent old request overring newer request */
	static AtomicInteger w2_bug527738LastRequestCounter = new AtomicInteger();

	/**
	 * Webkit2: In a few situations, evaluate() should not wait for it's asynchronous callback to finish.
	 * This is to avoid deadlocks, see Bug 512001.<br>
	 * 0 means evaluate should wait for callback. <br>
	 * >0 means evaluate should not block. In this case 'null' is returned. This condition is rare. <br>
	 *
	 * <p>Note: This has to be *static*.
	 * Webkit2 seems to share one event queue, as such two webkit2 instances can interfere with each other.
	 * An example of this interfering is when you open a link in a javadoc hover. The new webkit2 in the new tab
	 * interferes with the old instance in the hoverbox.
	 * As such, any locks should apply to all webkit2 instances.</p>
	 */
	private static int nonBlockingEvaluate = 0;

	static Map<LONG, Integer> webKitDownloadStatus = new HashMap<> ();

	static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
	static final String CLASSNAME_EXTERNAL = "External"; //$NON-NLS-1$
	static final String FUNCTIONNAME_CALLJAVA = "callJava"; //$NON-NLS-1$
	static final String HEADER_CONTENTTYPE = "content-type"; //$NON-NLS-1$
	static final String MIMETYPE_FORMURLENCODED = "application/x-www-form-urlencoded"; //$NON-NLS-1$
	static final String OBJECTNAME_EXTERNAL = "external"; //$NON-NLS-1$
	static final String PROPERTY_LENGTH = "length"; //$NON-NLS-1$
	static final String PROPERTY_PROXYHOST = "network.proxy_host"; //$NON-NLS-1$
	static final String PROPERTY_PROXYPORT = "network.proxy_port"; //$NON-NLS-1$
	static final String PROTOCOL_FILE = "file://"; //$NON-NLS-1$
	static final String PROTOCOL_HTTP = "http://"; //$NON-NLS-1$
	static final String URI_FILEROOT = "file:///"; //$NON-NLS-1$
	static final String USER_AGENT = "user-agent"; //$NON-NLS-1$
	static final int MAX_PORT = 65535;
	static final int MAX_PROGRESS = 100;
	static final int[] MIN_VERSION = {1, 2, 0};
	static final int SENTINEL_KEYPRESS = -1;
	static final char SEPARATOR_FILE = File.separatorChar;
	static final int STOP_PROPOGATE = 1;

	static final String DOMEVENT_DRAGSTART = "dragstart"; //$NON-NLS-1$
	static final String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$
	static final String DOMEVENT_KEYPRESS = "keypress"; //$NON-NLS-1$
	static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEOUT = "mouseout"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEOVER = "mouseover"; //$NON-NLS-1$
	static final String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$

	/* WebKit signal data */
	static final int NOTIFY_PROGRESS = 1;
	static final int NOTIFY_TITLE = 2;
	static final int CREATE_WEB_VIEW = 3;
	static final int WEB_VIEW_READY = 4;
	static final int CLOSE_WEB_VIEW = 5;
	static final int LOAD_CHANGED = 6;
	static final int DECIDE_POLICY = 7;
	static final int MOUSE_TARGET_CHANGED = 8;
	static final int CONTEXT_MENU = 9;
	static final int AUTHENTICATE = 10;
	static final int DECIDE_DESTINATION = 11;
	static final int FAILED = 12;
	static final int FINISHED = 13;
	static final int DOWNLOAD_STARTED = 14;
	static final int WIDGET_EVENT = 15; // Used for events like keyboard/mouse input. See Bug 528549 and Bug 533833.
	static final int LOAD_FAILED_TLS = 16;

	static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$

	static final String SWT_WEBKITGTK_VERSION = "org.eclipse.swt.internal.webkitgtk.version"; //$NON-NLS-1$

	/* the following Callbacks are never freed */
	static Callback Proc2, Proc3, Proc4, Proc5;

	/** Process key/mouse events from javascript. */
	static Callback JSDOMEventProc;

	/** Flag indicating whether TLS errors (like self-signed certificates) are to be ignored. */
	static final boolean ignoreTls;

	static {
			Proc2 = new Callback (WebKit.class, "Proc", 2); //$NON-NLS-1$
			Proc3 = new Callback (WebKit.class, "Proc", 3); //$NON-NLS-1$
			Proc4 = new Callback (WebKit.class, "Proc", 4); //$NON-NLS-1$
			Proc5 = new Callback (WebKit.class, "Proc", 5); //$NON-NLS-1$
			new Webkit2AsyncToSync();

			WebKitExtension.init();

			JSDOMEventProc = new Callback (WebKit.class, "JSDOMEventProc", 3); //$NON-NLS-1$

			NativeClearSessions = () -> {
				if (!WebKitGTK.LibraryLoaded) return;
				if (WebKitGTK.webkit_get_minor_version() >= 16) {
					long context = WebKitGTK.webkit_web_context_get_default();
					long manager = WebKitGTK.webkit_web_context_get_website_data_manager (context);
					WebKitGTK.webkit_website_data_manager_clear(manager, WebKitGTK.WEBKIT_WEBSITE_DATA_COOKIES, 0, 0, 0, 0);
				} else {
					System.err.println("SWT WebKit: clear sessions only supported on WebKitGtk version 2.16 and above. "
							+ "Your version is: " + internalGetWebKitVersionStr());
				}
			};

			NativeGetCookie = () -> {
				if (!WebKitGTK.LibraryLoaded) return;
				if (WebKitGTK.webkit_get_minor_version() >= 20) {
					CookieValue = Webkit2AsyncToSync.getCookie(CookieUrl, CookieName);
				} else {
					System.err.println("SWT WebKit: getCookie() only supported on WebKitGTK version 2.20 and above. "
							+ "Your version is: " + internalGetWebKitVersionStr());
				}
			};

			NativeSetCookie = () -> {
				if (!WebKitGTK.LibraryLoaded) return;
				if (WebKitGTK.webkit_get_minor_version() >= 20) {
					CookieResult = Webkit2AsyncToSync.setCookie(CookieUrl, CookieValue);
				} else {
					System.err.println("SWT WebKit: setCookie() only supported on WebKitGTK version 2.20 and above. "
							+ "Your version is: " + internalGetWebKitVersionStr());
				}
			};

			if (NativePendingCookies != null) {
				SetPendingCookies (NativePendingCookies);
				NativePendingCookies = null;
			}
			ignoreTls = "true".equals(System.getProperty("org.eclipse.swt.internal.webkitgtk.ignoretlserrors"));
	}

	@Override
	public void createFunction(BrowserFunction function) {
		if (!WebkitGDBus.initialized) {
			System.err.println("SWT webkit: WebkitGDBus and/or Webkit2Extension not loaded, BrowserFunction will not work." +
				"Tried to create "+ function.name);
			return;
		}
		super.createFunction(function);
		String url = this.getUrl().isEmpty() ? "nullURL" : this.getUrl();
		/*
		 * If the proxy to the extension has not yet been loaded, store the BrowserFunction page ID,
		 * function string, and URL in a HashMap. Once the proxy to the extension is loaded, these
		 * functions will be sent to and registered in the extension.
		 */
		if (!WebkitGDBus.connectionToExtensionCreated) {
			WebkitGDBus.functionsPending = true;
			ArrayList<ArrayList<String>> list = new ArrayList<>();
			ArrayList<String> functionAndUrl = new ArrayList<>();
			functionAndUrl.add(0, function.functionString);
			functionAndUrl.add(1, url);
			list.add(functionAndUrl);
			ArrayList<ArrayList<String>> existing = WebkitGDBus.pendingBrowserFunctions.putIfAbsent(this.pageId, list);
			if (existing != null) {
				existing.add(functionAndUrl);
			}
		} else {
			// If the proxy to the extension is already loaded, register the function in the extension via DBus
			boolean successful = webkit_extension_modify_function(this.pageId, function.functionString, url, "register");
			if (!successful) {
				System.err.println("SWT webkit: failure registering BrowserFunction " + function.name);
			}
		}
	}

	@Override
	public void destroyFunction (BrowserFunction function) {
		// Only deregister functions if the proxy to the extension has been loaded
		if (WebkitGDBus.connectionToExtensionCreated) {
			String url = this.getUrl().isEmpty() ? "nullURL" : this.getUrl();
			boolean successful = webkit_extension_modify_function(this.pageId, function.functionString, url, "deregister");
			if (!successful) {
				System.err.println("SWT webkit: failure deregistering BrowserFunction from extension " + function.name);
			}
		}
		super.destroyFunction(function);
	}

	private static String getInternalErrorMsg () {
		String reportErrMsg = "Please report this issue *with steps to reproduce* via:\n"
				+ " https://bugs.eclipse.org/bugs/enter_bug.cgi?"
				+ "alias=&assigned_to=platform-swt-inbox%40eclipse.org&attach_text=&blocked=&bug_file_loc=http%3A%2F%2F&bug_severity=normal"
				+ "&bug_status=NEW&comment=&component=SWT&contenttypeentry=&contenttypemethod=autodetect&contenttypeselection=text%2Fplain"
				+ "&data=&defined_groups=1&dependson=&description=&flag_type-1=X&flag_type-11=X&flag_type-12=X&flag_type-13=X&flag_type-14=X"
				+ "&flag_type-15=X&flag_type-16=X&flag_type-2=X&flag_type-4=X&flag_type-6=X&flag_type-7=X&flag_type-8=X&form_name=enter_bug"
				+ "&keywords=&maketemplate=Remember%20values%20as%20bookmarkable%20template&op_sys=Linux&product=Platform&qa_contact="
				+ "&rep_platform=PC&requestee_type-1=&requestee_type-2=&short_desc=webkit2_BrowserProblem";

		return reportErrMsg + "\nFor bug report, please atatch this stack trace:\n" + getStackTrace();
	}


	private static String getStackTrace() {
		// Get a stacktrace. Note, this doesn't actually throw anything, we just get the stacktrace.
		StringWriter sw = new StringWriter();
		new Throwable("").printStackTrace(new PrintWriter(sw));
		return sw.toString();
	}

	/**
	 * This class deals with the WebKit extension.
	 *
	 * Extension is separately loaded and deals Javascript callbacks to Java.
	 * Extension is needed so that Javascript can receive a return value from Java
	 * (for which currently there is no api in WebkitGtk 2.18)
	 */
	static class WebKitExtension {
		/** Note, if updating this, you need to change it also in webkitgtk_extension.c */
		private static final String javaScriptFunctionName = "webkit2callJava";  // $NON-NLS-1$
		private static final String webkitWebExtensionIdentifier = "webkitWebExtensionIdentifier";  // $NON-NLS-1$
		private static Callback initializeWebExtensions_callback;

		/** GDBusServer returned by WebkitGDBus */
		private static long dBusServer = 0;

		/**
		 * Don't continue initialization if something failed. This allows Browser to carryout some functionality
		 * even if the webextension failed to load.
		 */
		private static boolean loadFailed;

		static String getJavaScriptFunctionName() {
			return javaScriptFunctionName;
		}
		static String getWebExtensionIdentifier() {
			return webkitWebExtensionIdentifier;
		}
		static String getJavaScriptFunctionDeclaration(long webView) {
			return "if (!window.callJava) {\n"
			+ "		window.callJava = function callJava(index, token, args) {\n"
			+ "          return " + javaScriptFunctionName + "('" + String.valueOf(webView) +  "', index, token, args);\n"
			+ "		}\n"
			+ "};\n";
		}

		static void init() {
			/*
			 * Initialize GDBus before the extension, as the extension initialization callback at the C level
			 * sends data back to SWT via GDBus. Failure to load GDBus here will result in crashes.
			 * See bug 536141.
			 */
			dBusServer = gdbus_init();
			if (dBusServer == 0) {
				System.err.println("SWT WebKit: error initializing DBus server, dBusServer == 0");
			}
			initializeWebExtensions_callback = new Callback(WebKitExtension.class, "initializeWebExtensions_callback", void.class, new Type [] {long.class, long.class});
			if (WebKitGTK.webkit_get_minor_version() >= 4) { // Callback exists only since 2.04
				OS.g_signal_connect (WebKitGTK.webkit_web_context_get_default(), WebKitGTK.initialize_web_extensions, initializeWebExtensions_callback.getAddress(), 0);
			}
		}

		/**
		 * GDbus initialization can cause performance slow downs. So we int GDBus in lazy way.
		 * It can be initialized upon first use of BrowserFunction.
		 */
		static long gdbus_init() {
			if (WebKitGTK.webkit_get_minor_version() < 4) {
				System.err.println("SWT Webkit: Warning, You are using an old version of webkitgtk. (pre 2.4)"
						+ " BrowserFunction functionality will not be avaliable");
				return 0;
			}


			if (!loadFailed) {
				return WebkitGDBus.init();
			} else {
				return 0;
			}
		}

		/**
		 * This callback is called to initialize webextension.
		 * It is the optimum place to set extension directory and set initialization user data.
		 *
		 * I've experimented with loading webextension later (to see if we can get performance gains),
		 * but found breakage. Webkitgtk doc says it should be loaded as early as possible and specifically best
		 * to do it in this calllback.
		 *
		 * See documenation: WebKitWebExtension (Description)
		 */
		@SuppressWarnings("unused") // Only called directly from C
		private static void initializeWebExtensions_callback (long WebKitWebContext, long user_data) {
			// 1) GDBus:
			// Normally we'd first initialize gdbus channel. But gdbus makes Browser slower and isn't always needed.
			// So WebkitGDBus is lazy-initialized, although it can be initialized here if gdbus is ever needed
			// for more than BrowserFunction, like:
			// WebkitGDBus.init(String.valueOf(uniqueID));
			// Also consider only loading gdbus if the extension initialized properly.

			// 2) Load Webkit Extension:
			// Webkit extensions should be in their own directory.
			String swtVersion = Library.getVersionString();
			File extension;
			try {
				extension = Library.findResource("webkitextensions" + swtVersion ,"swt-webkit2extension", true);
				if (extension == null){
					throw new UnsatisfiedLinkError("SWT Webkit could not find it's webextension");
				}
			} catch (UnsatisfiedLinkError e) {
				System.err.println("SWT Webkit.java Error: Could not find webkit extension. BrowserFunction functionality will not be available. \n"
						+ "(swt version: " + swtVersion + ")" + WebKitGTK.swtWebkitGlueCodeVersion + WebKitGTK.swtWebkitGlueCodeVersionInfo);
				int [] vers = internalGetWebkitVersion();
				System.err.println(String.format("WebKit2Gtk version %s.%s.%s", vers[0], vers[1], vers[2]));
				System.err.println(getInternalErrorMsg());
				loadFailed = true;
				return;
			}

			String extensionsFolder = extension.getParent();
			/* Dev note:
			 * As per
			 * - WebkitSrc: WebKitExtensionManager.cpp,
			 * - IRC discussion with annulen
			 * you cannot load the webextension GModule directly, (webkitgtk 2.18). You can only specify directory and user data.
			 * So we need to treat this  '.so' in a special way.
			 * (as a note, the webprocess would have to load the gmodule).
			 */
			WebKitGTK.webkit_web_context_set_web_extensions_directory(WebKitGTK.webkit_web_context_get_default(), Converter.wcsToMbcs (extensionsFolder, true));
			long clientAddress = OS.g_dbus_server_get_client_address(dBusServer);
			String clientAddressJava = Converter.cCharPtrToJavaString(clientAddress, false);
			long gvariantUserData = OS.g_variant_new_string(clientAddress);
			WebKitGTK.webkit_web_context_set_web_extensions_initialization_user_data(WebKitGTK.webkit_web_context_get_default(), gvariantUserData);
		}

		/**
		 * @param cb_args Raw callback arguments by function.
		 */
		static Object webkit2callJavaCallback(Object [] cb_args) {
			assert cb_args.length == 4;
			Object returnValue = null;
			Long webViewLocal = (Double.valueOf((String) cb_args[0])).longValue();
			Browser browser = FindBrowser((long ) webViewLocal.longValue());
			Integer functionIndex = ((Double) cb_args[1]).intValue();
			String token = (String) cb_args[2];

			BrowserFunction function = browser.webBrowser.functions.get(functionIndex);
			if (function == null) {
				System.err.println("SWT Webkit Error: Failed to find function with index: " + functionIndex);
				return null;
			}
			if (!function.token.equals(token)) {
				System.err.println("SWT Webkit Error: token mismatch for function with index: " + functionIndex);
				return null;
			}
			try {
				// Call user code. Exceptions can occur.
				nonBlockingEvaluate++;
				Object [] user_args = (Object []) cb_args[3];
				returnValue = function.function(user_args);
			} catch (Exception e ) {
				// - Something went wrong in user code.
				System.err.println("SWT Webkit: Exception occured in user code of function: " + function.name);
				returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
			} finally {
				nonBlockingEvaluate--;
			}
			return returnValue;
		}
	}

	@Override
	String getJavaCallDeclaration() {
		return WebKitExtension.getJavaScriptFunctionDeclaration(webView);
	}

	/**
	 * Gets the webkit version, within an <code>int[3]</code> array with
	 * <code>{major, minor, micro}</code> version
	 */
	private static int[] internalGetWebkitVersion(){
		int [] vers = new int[3];
		vers[0] = WebKitGTK.webkit_get_major_version ();
		vers[1] = WebKitGTK.webkit_get_minor_version ();
		vers[2] = WebKitGTK.webkit_get_micro_version ();
		return vers;
	}

	private static String internalGetWebKitVersionStr () {
		int [] vers = internalGetWebkitVersion();
		return String.valueOf(vers[0]) + "." + String.valueOf(vers[1]) + "." + String.valueOf(vers[2]);
	}


static String getString (long strPtr) {
	int length = C.strlen (strPtr);
	byte [] buffer = new byte [length];
	C.memmove (buffer, strPtr, length);
	return new String (Converter.mbcsToWcs (buffer));
}

static Browser FindBrowser (long webView) {
	if (webView == 0) return null;
	long parent = GTK.gtk_widget_get_parent (webView);
	return (Browser)Display.getCurrent ().findWidget (parent);
}

static boolean IsInstalled () {
	if (GTK.GTK4) return false;
	if (!WebKitGTK.LibraryLoaded) return false;
	// TODO webkit_check_version() should take care of the following, but for some
	// reason this symbol is missing from the latest build.  If it is present in
	// Linux distro-provided builds then replace the following with this call.
	int [] vers = internalGetWebkitVersion();
	int major = vers[0], minor = vers[1], micro = vers[2];
	return major > MIN_VERSION[0] ||
		(major == MIN_VERSION[0] && minor > MIN_VERSION[1]) ||
		(major == MIN_VERSION[0] && minor == MIN_VERSION[1] && micro >= MIN_VERSION[2]);
}

static long JSDOMEventProc (long arg0, long event, long user_data) {
	if (user_data == WIDGET_EVENT) {
		/*
		* Only consider using GDK events to create SWT events to send if JS is disabled
		* in one or more WebKit instances (indicates that this instance may not be
		* receiving events from the DOM).  This check is done up-front for performance.
		*/
		final Browser browser = FindBrowser (arg0);
		if (browser != null && user_data == WIDGET_EVENT){
			/* this instance does need to use the GDK event to create an SWT event to send */
			switch (GDK.GDK_EVENT_TYPE (event)) {
				case GDK.GDK_KEY_PRESS: {
					if (browser.isFocusControl ()) {
						int [] key = new int [1];
						int [] state = new int[1];
						if (GTK.GTK4) {
							key[0] = GDK.gdk_key_event_get_keyval(event);
							state[0] = GDK.gdk_event_get_modifier_state(event);
						} else {
							GDK.gdk_event_get_keyval(event, key);
							GDK.gdk_event_get_state(event, state);
						}

						switch (key[0]) {
							case GDK.GDK_ISO_Left_Tab:
							case GDK.GDK_Tab: {
								if ((state[0] & (GDK.GDK_CONTROL_MASK | GDK.GDK_MOD1_MASK)) == 0) {
									browser.getDisplay ().asyncExec (() -> {
										if (browser.isDisposed ()) return;
										if (browser.getDisplay ().getFocusControl () == null) {
											int traversal = (state[0] & GDK.GDK_SHIFT_MASK) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
											browser.traverse (traversal);
										}
									});
								}
								break;
							}
							case GDK.GDK_Escape: {
								Event keyEvent = new Event ();
								keyEvent.widget = browser;
								keyEvent.type = SWT.KeyDown;
								keyEvent.keyCode = keyEvent.character = SWT.ESC;
								if ((state[0] & GDK.GDK_MOD1_MASK) != 0) keyEvent.stateMask |= SWT.ALT;
								if ((state[0] & GDK.GDK_SHIFT_MASK) != 0) keyEvent.stateMask |= SWT.SHIFT;
								if ((state[0]& GDK.GDK_CONTROL_MASK) != 0) keyEvent.stateMask |= SWT.CONTROL;
								try { // to avoid deadlocks, evaluate() should not block during listener. See Bug 512001
									  // I.e, evaluate() can be called and script will be executed, but no return value will be provided.
									nonBlockingEvaluate++;
								browser.webBrowser.sendKeyEvent (keyEvent);
								} catch (Exception e) {
									throw e;
								} finally {
									nonBlockingEvaluate--;
								}
								return 1;
							}
						}
					}
					break;
				}
			}
			if (browser != null) {
				GTK3.gtk_widget_event (browser.handle, event);
			}
		}
		return 0;
	}
	return 0;
}

static long Proc (long handle, long user_data) {
	long webView  = handle;

	if (user_data == FINISHED) {
		// Special case, callback from WebKitDownload instead of webview.
		long webKitDownload = handle;
		return webkit_download_finished(webKitDownload);
	}

	Browser browser = FindBrowser (webView);
	if (browser == null) return 0;
	WebKit webkit = (WebKit)browser.webBrowser;
	return webkit.webViewProc (handle, user_data);
}

static long Proc (long handle, long arg0, long user_data) {
	// As a note, don't use instance checks like 'G_TYPE_CHECK_INSTANCE_TYPE '
	// to determine difference between webview and webcontext as these
	// don't seem to work reliably for all clients. For some clients they always return true.
	// Instead use user_data.

	{ // Deal with Special cases where callback comes not from webview. Handle is not a webview.

		if (user_data == DOWNLOAD_STARTED) {
			// This callback comes from WebKitWebContext as oppose to the WebView. So handle is WebContext not Webview.
			// user_function (WebKitWebContext *context, WebKitDownload  *download,  gpointer  user_data)
			long webKitDownload = arg0;
			webkit_download_started(webKitDownload);
			return 0;
		}

		if (user_data == DECIDE_DESTINATION) {
			// This callback comes from WebKitDownload, so handle is WebKitDownload not webview.
			// gboolean  user_function (WebKitDownload *download, gchar   *suggested_filename, gpointer  user_data)
			long webKitDownload = handle;
			long suggested_filename = arg0;
			return webkit_download_decide_destination(webKitDownload,suggested_filename);
		}

		if (user_data == FAILED) {
			// void user_function (WebKitDownload *download, GError *error, gpointer user_data)
			long webKitDownload = handle;
			return webkit_download_failed(webKitDownload);
		}
	}

	{ // Callbacks connected with a WebView.
		assert handle != 0 : "Webview shouldn't be null here";
		long webView = handle;
		Browser browser = FindBrowser (webView);
		if (browser == null) return 0;
		WebKit webkit = (WebKit)browser.webBrowser;
		return webkit.webViewProc (webView, arg0, user_data);
	}
}

static long Proc (long handle, long arg0, long arg1, long user_data) {
	Browser browser = FindBrowser (handle);
	if (browser == null) return 0;
	WebKit webkit = (WebKit)browser.webBrowser;
	return webkit.webViewProc (handle, arg0, arg1, user_data);
}

static long Proc (long handle, long arg0, long arg1, long arg2, long user_data) {
	long webView = handle;
	Browser browser = FindBrowser (webView);
	if (browser == null) return 0;
	WebKit webkit = (WebKit)browser.webBrowser;

	return webkit.webViewProc (handle, arg0, arg1, arg2, user_data);
}

/**
 * gboolean user_function (WebKitWebView *web_view, WebKitAuthenticationRequest *request, gpointer user_data)
 * - https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView-authenticate
 */
long webkit_authenticate (long web_view, long request){

	/* authentication challenges are currently the only notification received from the session */
	if (!WebKitGTK.webkit_authentication_request_is_retry(request)) {
		failureCount = 0;
	} else {
		if (++failureCount >= 3) return 0;
	}

	String location = getUrl();

	for (int i = 0; i < authenticationListeners.length; i++) {
		AuthenticationEvent event = new AuthenticationEvent (browser);
		event.location = location;

		try { // to avoid deadlocks, evaluate() should not block during authentication listener. See Bug 512001
			  // I.e, evaluate() can be called and script will be executed, but no return value will be provided.
			nonBlockingEvaluate++;
			authenticationListeners[i].authenticate (event);
		} catch (Exception e) {
			throw e;
		} finally {
			nonBlockingEvaluate--;
		}

		if (!event.doit) {
			WebKitGTK.webkit_authentication_request_cancel (request);
			return 0;
		}
		if (event.user != null && event.password != null) {
			byte[] userBytes = Converter.wcsToMbcs (event.user, true);
			byte[] passwordBytes = Converter.wcsToMbcs (event.password, true);
			long credentials = WebKitGTK.webkit_credential_new (userBytes, passwordBytes, WebKitGTK.WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
			WebKitGTK.webkit_authentication_request_authenticate(request, credentials);
			WebKitGTK.webkit_credential_free(credentials);
			return 0;
		}
	}
	return 0;
}

long webViewProc (long handle, long user_data) {
	switch ((int)user_data) {
		case CLOSE_WEB_VIEW: return webkit_close_web_view (handle);
		case WEB_VIEW_READY: return webkit_web_view_ready (handle);
		default: return 0;
	}
}

long webViewProc (long handle, long arg0, long user_data) {
	switch ((int)user_data) {
		case CREATE_WEB_VIEW: return webkit_create_web_view (handle, arg0);
		case LOAD_CHANGED: return webkit_load_changed (handle, (int) arg0, user_data);
		case NOTIFY_PROGRESS: return webkit_notify_progress (handle, arg0);
		case NOTIFY_TITLE: return webkit_notify_title (handle, arg0);
		case AUTHENTICATE: return webkit_authenticate (handle, arg0);
		default: return 0;
	}
}

long webViewProc (long handle, long arg0, long arg1, long user_data) {
	switch ((int)user_data) {
		case MOUSE_TARGET_CHANGED: return webkit_mouse_target_changed (handle, arg0, arg1); // Webkit2 only.
		case DECIDE_POLICY: return webkit_decide_policy(handle, arg0, (int)arg1, user_data);
		default: return 0;
	}
}

long webViewProc (long handle, long arg0, long arg1, long arg2, long user_data) {
	switch ((int)user_data) {
		case CONTEXT_MENU: return webkit_context_menu(handle, arg0, arg1, arg2);
		case LOAD_FAILED_TLS: return webkit_load_failed_tls(handle, arg0, arg1, arg2);
		default: return 0;
	}
}

@Override
public void create (Composite parent, int style) {
	int [] vers = internalGetWebkitVersion();
	System.setProperty(SWT_WEBKITGTK_VERSION,
			String.format("%s.%s.%s", vers[0], vers[1], vers[2])); // $NON-NLS-1$
	if (Device.DEBUG) {
		System.out.println(String.format("WebKit version %s.%s.%s", vers[0], vers[1], vers[2])); //$NON-NLS-1$
	}
	/*
	 * Set this Browser instance to Webki2AsyncToSync in order for cookie
	 * functionality to work. See bug 522181.
	 */
	Webkit2AsyncToSync.setCookieBrowser(browser);


	Composite parentShell = parent.getParent();
	Browser parentBrowser = null;
	if (parentShell != null) {
		Control[] children = parentShell.getChildren();
		for (int i = 0; i < children.length; i++) {
			if (children[i] instanceof Browser) {
				parentBrowser = (Browser) children[i];
				break;
			}
		}
	}

	if (parentBrowser == null) {
		webView = WebKitGTK.webkit_web_view_new();
	} else {
		webView = WebKitGTK.webkit_web_view_new_with_related_view(((WebKit)parentBrowser.webBrowser).webView);
	}

	// Bug 522733 Webkit2 workaround for crash
	//   As of Webkitgtk 2.18, webkitgtk2 crashes if the first instance of webview is not referenced when JVM shuts down.
	//   There is a exit handler that tries to dereference the first instance [which if not referenced]
	//   leads to a crash. This workaround would benefit from deeper investigation (find root cause etc...).
	// [edit] Bug 530678. Note, it seems that as of Webkit2.18, webkit auto-disposes itself if parent get's disposed.
	//        While not directly related, see onDispose() for how to deal with disposal of this.
	if (!bug522733FirstInstanceCreated && vers[0] == 2 && vers[1] >= 18) {
		bug522733FirstInstanceCreated = true;
		OS.g_object_ref(webView);
	}
	if (ignoreTls) {
		WebKitGTK.webkit_web_context_set_tls_errors_policy(WebKitGTK.webkit_web_view_get_context(webView),
				WebKitGTK.WEBKIT_TLS_ERRORS_POLICY_IGNORE);
		System.out.println("***WARNING: WebKitGTK is configured to ignore TLS errors via -Dorg.eclipse.swt.internal.webkitgtk.ignoretlserrors=true .");
		System.out.println("***WARNING: Please use for development purposes only!");
	}

	// Webkit2 Signal Documentation: https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView--title
	GTK3.gtk_container_add (browser.handle, webView);
	OS.g_signal_connect (webView, WebKitGTK.close, Proc2.getAddress (), CLOSE_WEB_VIEW);
	OS.g_signal_connect (webView, WebKitGTK.ready_to_show, Proc2.getAddress (), WEB_VIEW_READY);
	OS.g_signal_connect (webView, WebKitGTK.decide_policy, Proc4.getAddress (), DECIDE_POLICY);
	OS.g_signal_connect (webView, WebKitGTK.mouse_target_changed, Proc4.getAddress (), MOUSE_TARGET_CHANGED);
	OS.g_signal_connect (webView, WebKitGTK.context_menu, Proc5.getAddress (), CONTEXT_MENU);
	OS.g_signal_connect (webView, WebKitGTK.load_failed_with_tls_errors, Proc5.getAddress (), LOAD_FAILED_TLS);

	// GtkWidget* user_function (WebKitWebView *web_view, WebKitNavigationAction *navigation_action,  gpointer  user_data)
	OS.g_signal_connect (webView, WebKitGTK.create, 						Proc3.getAddress (), CREATE_WEB_VIEW);
	//void user_function (WebKitWebView  *web_view,  WebKitLoadEvent load_event,  gpointer  user_data)
	OS.g_signal_connect (webView, WebKitGTK.load_changed, 					Proc3.getAddress (), LOAD_CHANGED);
	// Property change: of 'estimated-load-progress'   args: webview, pspec
	OS.g_signal_connect (webView, WebKitGTK.notify_estimated_load_progress, Proc3.getAddress (), NOTIFY_PROGRESS);

	// gboolean user_function (WebKitWebView *web_view,  WebKitAuthenticationRequest *request,  gpointer user_data)
	OS.g_signal_connect (webView, WebKitGTK.authenticate, 					Proc3.getAddress (), AUTHENTICATE);

	// (!) Note this one's a 'webContext' signal, not webview. See:
	// https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebContext.html#WebKitWebContext-download-started
	OS.g_signal_connect (WebKitGTK.webkit_web_context_get_default(), WebKitGTK.download_started, Proc3.getAddress (), DOWNLOAD_STARTED);

	GTK.gtk_widget_show (webView);
	GTK.gtk_widget_show (browser.handle);

	// Webview 'title' property
	OS.g_signal_connect (webView, WebKitGTK.notify_title, 						Proc3.getAddress (), NOTIFY_TITLE);

	OS.g_signal_connect (webView, OS.button_press_event, JSDOMEventProc.getAddress (), WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.button_release_event, JSDOMEventProc.getAddress (), WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.focus_in_event, JSDOMEventProc.getAddress (), 	WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.focus_out_event, JSDOMEventProc.getAddress (), WIDGET_EVENT);
	// if connecting any other special gtk event to webkit, add SWT.* to w2_passThroughSwtEvents above.

	this.pageId = WebKitGTK.webkit_web_view_get_page_id (webView);

	OS.g_signal_connect (webView, OS.key_press_event, JSDOMEventProc.getAddress (),  	WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.key_release_event, JSDOMEventProc.getAddress (),	WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.scroll_event, JSDOMEventProc.getAddress (), 		WIDGET_EVENT);
	OS.g_signal_connect (webView, OS.motion_notify_event, JSDOMEventProc.getAddress (), WIDGET_EVENT);

	byte[] utfBytes = Converter.wcsToMbcs ("UTF-8", true); // $NON-NLS-1$

	long settings = WebKitGTK.webkit_web_view_get_settings (webView);
	OS.g_object_set (settings, WebKitGTK.javascript_can_open_windows_automatically, 1, 0);
	OS.g_object_set (settings, WebKitGTK.enable_webgl, 1, 0);
	OS.g_object_set (settings, WebKitGTK.enable_developer_extras, 1, 0);

	OS.g_object_set (settings, WebKitGTK.default_charset, utfBytes, 0);
	if (WebKitGTK.webkit_get_minor_version() >= 14) {
		OS.g_object_set (settings, WebKitGTK.allow_universal_access_from_file_urls, 1, 0);
		if (WebKitGTK.webkit_get_minor_version() >= 24) {
			OS.g_object_set (settings, WebKitGTK.enable_back_forward_navigation_gestures, 1, 0);
		}
	} else {
		System.err.println("SWT WEBKIT: Warning, you are using Webkitgtk below version 2.14. Your version is: "
				+ "Your version is: " + internalGetWebKitVersionStr()
				+ "\nJavascript execution limited to same origin due to unimplemented feature of this version.");
	}

	Listener listener = event -> {
		switch (event.type) {
			case SWT.Dispose: {
				/* make this handler run after other dispose listeners */
				if (ignoreDispose) {
					ignoreDispose = false;
					break;
				}
				ignoreDispose = true;
				browser.notifyListeners (event.type, event);
				event.type = SWT.NONE;
				onDispose (event);
				break;
			}
			case SWT.FocusIn: {
				if (webView != 0)
					GTK.gtk_widget_grab_focus (webView);
				break;
			}
			case SWT.Resize: {
				onResize (event);
				break;
			}
		}
	};
	browser.addListener (SWT.Dispose, listener);
	browser.addListener (SWT.FocusIn, listener);
	browser.addListener (SWT.KeyDown, listener);
	browser.addListener (SWT.Resize, listener);

	/*
	* Bug in WebKitGTK.  MouseOver/MouseLeave events are not consistently sent from
	* the DOM when the mouse enters and exits the browser control, see
	* https://bugs.webkit.org/show_bug.cgi?id=35246.  As a workaround for sending
	* MouseEnter/MouseExit events, swt's default mouse enter/exit mechanism is used,
	* but in order to do this the Browser's default sub-window check behavior must
	* be changed.
	*/
	browser.setData (KEY_CHECK_SUBWINDOW, Boolean.FALSE);

	/*
	 * Bug in WebKitGTK.  In WebKitGTK 1.10.x a crash can occur if an
	 * attempt is made to show a browser before a size has been set on
	 * it.  The workaround is to temporarily give it a size that forces
	 * the native resize events to fire.
	 */
	int major = vers[0], minor = vers[1];
	if (major == 1 && minor >= 10) {
		Rectangle minSize = browser.computeTrim (0, 0, 2, 2);
		Point size = browser.getSize ();
		size.x += minSize.width; size.y += minSize.height;
		browser.setSize (size);
		size.x -= minSize.width; size.y -= minSize.height;
		browser.setSize (size);
	}
}

@Override
public boolean back () {
	if (WebKitGTK.webkit_web_view_can_go_back (webView) == 0) return false;
	WebKitGTK.webkit_web_view_go_back (webView);
	return true;
}

@Override
public boolean close () {
	return close (true);
}

// Developer note:
// @return true = leads to disposal. In Browser.java, user is told widget is disposed. Ex in Snippe326 close button is grayed out.
//         false = blocks disposal. In Browser.java, user is told widget was not disposed.
// See Snippet326.
boolean close (boolean showPrompters) {
	// don't execute any JavaScript if it's disabled or requested to get disabled
	// we need to check jsEnabledOnNextPage here because jsEnabled is updated asynchronously
	// and may not reflect the proper state (bug 571746 and bug 567881)
	if (!jsEnabled || !jsEnabledOnNextPage) return true;

	String message1 = Compatibility.getMessage("SWT_OnBeforeUnload_Message1"); // $NON-NLS-1$
	String message2 = Compatibility.getMessage("SWT_OnBeforeUnload_Message2"); // $NON-NLS-1$
	String functionName = EXECUTE_ID + "CLOSE"; // $NON-NLS-1$
	StringBuilder buffer = new StringBuilder ("function "); // $NON-NLS-1$
	buffer.append (functionName);
	buffer.append ("(win) {\n"); // $NON-NLS-1$
	buffer.append ("var fn = win.onbeforeunload; if (fn != null) {try {var str = fn(); "); // $NON-NLS-1$
	if (showPrompters) {
		buffer.append ("if (str != null) { "); // $NON-NLS-1$
		buffer.append ("var result = confirm('"); // $NON-NLS-1$
		buffer.append (message1);
		buffer.append ("\\n\\n'+str+'\\n\\n"); // $NON-NLS-1$
		buffer.append (message2);
		buffer.append ("');"); // $NON-NLS-1$
		buffer.append ("if (!result) return false;}"); // $NON-NLS-1$
	}
	buffer.append ("} catch (e) {}}"); // $NON-NLS-1$
	buffer.append ("try {for (var i = 0; i < win.frames.length; i++) {var result = "); // $NON-NLS-1$
	buffer.append (functionName);
	buffer.append ("(win.frames[i]); if (!result) return false;}} catch (e) {} return true;"); // $NON-NLS-1$
	buffer.append ("\n};"); // $NON-NLS-1$
	nonBlockingExecute (buffer.toString ());

	Boolean result;
	/*
	 * Sometimes if a disposal is already underway (ex parent shell disposed), then
	 * Javascript execution can throw. We have to account for that.
	 */
	try {
		result = (Boolean)evaluate ("return " + functionName +"(window);"); // $NON-NLS-1$ // $NON-NLS-2$
		if (result == null) return true; // Default to assume that webkit is disposed and allow disposal of Browser.
	} catch (SWTException e) {
		return true; // Permit browser to be disposed if javascript execution failed.
	}
	return result.booleanValue ();
}


private boolean isJavascriptEnabled() {
	// If you try to run Javascript while Javascript is turned off, then an exception is thrown.
	return webkit_settings_get(WebKitGTK.enable_javascript) != 0;
}

@Override
void nonBlockingExecute(String script) {
	try {
		nonBlockingEvaluate++;
		execute(script);
	} finally {
		nonBlockingEvaluate--;
	}
}

/**
 * Modifies a BrowserFunction in the web extension. This method can be used to register/deregister BrowserFunctions
 * in the web extension, so that those BrowserFunctions are executed upon triggering of the object_cleared callback (in
 * the extension, not in Java).
 *
 * This function will return true if: the operation succeeds synchronously, or if the synchronous call timed out and an
 * asynchronous call was performed instead. All other cases will return false.
 *
 * Supported actions: "register" and "deregister"
 *
 * @param pageId the page ID of the WebKit instance/web page
 * @param function the function string
 * @param url the URL
 * @param action the action being performed on the function, which will be used to form the DBus method name.
 * @return true if the action succeeded (or was performed asynchronously), false if it failed
 */
private boolean webkit_extension_modify_function (long pageId, String function, String url, String action){
	long args[] = { OS.g_variant_new_uint64(pageId),
			OS.g_variant_new_string (Converter.javaStringToCString(function)),
			OS.g_variant_new_string (Converter.javaStringToCString(url))};
	final long argsTuple = OS.g_variant_new_tuple(args, args.length);
	if (argsTuple == 0) return false;
	String dbusMethodName = "webkitgtk_extension_" + action + "_function";
	Object returnVal = WebkitGDBus.callExtensionSync(argsTuple, dbusMethodName);
	if (returnVal instanceof Boolean) {
		return (Boolean) returnVal;
	} else if (returnVal instanceof String) {
		String returnString = (String) returnVal;
		/*
		 * Call the extension asynchronously if a synchronous call times out.
		 * Note: this is a pretty rare case, and usually only happens when running test cases.
		 * See bug 536141.
		 */
		if ("timeout".equals(returnString)) {
			return WebkitGDBus.callExtensionAsync(argsTuple, dbusMethodName);
		}
	}
	return false;
}

@Override
public boolean execute (String script) {
	if (!isJavascriptEnabled()) {
		System.err.println("SWT Webkit Warning: Attempting to execute javascript when javascript is dissabled."
				+ "Execution has no effect. Script:\n" + script);
		return false;
	}
	try {
		Webkit2AsyncToSync.runjavascript(script, this.browser, webView);
	} catch (SWTException e) {
		return false;
	}
	return true;
}

/**
 * Webkit2 introduces async api. However SWT has sync execution model. This class it to convert async api to sync.
 *
 * Be careful about using these methods in synchronous callbacks from webkit, as those can cause deadlocks. (See inner javadocs).
 *
 * The mechanism generates an ID for each callback and waits for that callback to complete.
 */
private static class Webkit2AsyncToSync {
	/** We need a way to associate a Browser instance with this class for cookie functionality */
	private static Browser cookieBrowser;
	private static Callback runjavascript_callback;
	private static Callback getText_callback;
	private static Callback setCookie_callback;
	private static Callback getCookie_callback;

	static {
		runjavascript_callback = new Callback(Webkit2AsyncToSync.class, "runjavascript_callback", void.class, new Type[] {long.class, long.class, long.class});
		getText_callback = new Callback(Webkit2AsyncToSync.class, "getText_callback", void.class, new Type[] {long.class, long.class, long.class});
		setCookie_callback = new Callback(Webkit2AsyncToSync.class, "setCookie_callback", void.class, new Type[] {long.class, long.class, long.class});
		getCookie_callback = new Callback(Webkit2AsyncToSync.class, "getCookie_callback", void.class, new Type[] {long.class, long.class, long.class});
	}

	/** Object used to return data from callback to original call */
	private static class Webkit2AsyncReturnObj {
		boolean callbackFinished = false;
		Object returnValue = null; // As note, if browser is disposed during excution, null is returned.

		/** 0=no error. >0 means error. **/
		int errorNum = 0;
		String errorMsg;

		/** Set to true if call timed out. Not set by javascript execution itself */
		boolean swtAsyncTimeout;
	}

	/**
	 * Every callback is tagged with a unique ID.
	 * The ID is used for the callback to find the object via which data is returned
	 * and allow the original call to finish.
	 *
	 * Note: The reason each callback is tagged with an ID is because two(or more) subsequent
	 * evaluate() calls can be started before the first callback comes back.
	 * As such, there would be ambiguity as to which call a callback belongs to, which in turn causes deadlocks.
	 * This is typically seen when a webkit2 signal (e.g closeListener) makes a call to evaluate(),
	 * when the closeListener was triggered by evaluate("window.close()").
	 * An example test case where this is seen is:
	 * org.eclipse.swt.tests.junit.Test_org_eclipse_swt_browser_Browser.test_execute_and_closeListener()
	 */
	private static class CallBackMap {
		private static HashMap<Integer, Webkit2AsyncReturnObj> callbackMap = new HashMap<>();

		static int putObject(Webkit2AsyncReturnObj obj) {
			int id = getNextId();
			callbackMap.put(id, obj);
			return id;
		}
		static Webkit2AsyncReturnObj getObj(int id) {
			return callbackMap.get(id);
		}
		static void removeObject(int id) {
			callbackMap.remove(id);
			removeId(id);
		}

		// Mechanism to generate unique ID's
		private static int nextCallbackId = 1;
		private static HashSet<Integer> usedCallbackIds = new HashSet<>();
		static int getNextId() {
			int value = 0;
			boolean unique = false;
			while (unique == false) {
				value = nextCallbackId;
				unique = !usedCallbackIds.contains(value);
				if (nextCallbackId != Integer.MAX_VALUE)
					nextCallbackId++;
				else
					nextCallbackId = 1;
			}
			usedCallbackIds.add(value);
			return value;
		}
		private static void removeId(int id) {
			usedCallbackIds.remove(id);
		}
	}

	static Object evaluate (String script, Browser browser, long webView)  {
//		/* Wrap script around a temporary function for backwards compatibility,
//		 * user can specify 'return', which may not be at the beginning of the script.
//		 *  Valid scripts:
//		 *      'hi'
//		 *  	return 'hi'
//		 *  	var x = 1; return 'hi'
//		 */
		String swtUniqueExecFunc = "SWTWebkit2TempFunc" + CallBackMap.getNextId() + "()";
		String wrappedScript = "function " + swtUniqueExecFunc +"{" + script + "}; " + swtUniqueExecFunc;
		return runjavascript(wrappedScript, browser, webView);

	}

	/**
	 * Run javascript, wait for a return value.
	 *
	 * Developer note:
	 * Be EXTRA careful with this method, it can cause deadlocks in situations where
	 * javascript is executed in a callback that provides a return value to webkit.
	 * In otherwords, if webkit does a sync callback (one that requires a return value),
	 * then running javascript will lead to a deadlock because webkit will not execute
	 * the javascript until it's sync callback finished.
	 * As a note, SWT's callback mechanism hard-codes 'long' return even when a callback
	 * is actually 'void'. So reference webkit callback signature documentation and not
	 * SWT implementation.
	 *
	 * If in doubt, you should use nonBlockingExecute() where possible :-).
	 *
	 * TODO_SOMEDAY:
	 * - Instead of async js execution and waiting for return value, it might be
	 *   better to use gdbus, connect to webextension and execute JS synchronously.
	 *   See: https://blogs.igalia.com/carlosgc/2013/09/10/webkit2gtk-web-process-extensions/
	 *    'Extending JavaScript'
	 *   Pros:
	 *    - less likely deadlocks would occur due to developer error/not being careful.
	 *    - js execution can work in synchronous callbacks from webkit.
	 *   Cons:
	 *    - High implementation cost/complexity.
	 *    - Unexpected errors/behaviour due to GDBus timeouts.
	 *   Proof of concept:
	 *   https://git.eclipse.org/r/#/c/23416/16/bundles/org.eclipse.swt/Eclipse+SWT+WebKit/gtk/library/webkit_extension.c
	 *     > 'webkit_extension_execute_script'
	 *   Tennative structure:
	 *   - Webextension should create gdbus server, make & communicate UniqueID (pid) to main proc
	 *   - main proc should make a note of webextension's name+uniqueID
	 *   - implement mechanism for packaging Java objects into gvariants, (see WebkitGDBus.java),
	 *   - call webextension over gdbus, parse return value.
	 *
	 */
	static Object runjavascript(String script, Browser browser, long webView) {
		if (nonBlockingEvaluate > 0) {
			// Execute script, but do not wait for async call to complete. (assume it does). Bug 512001.
			WebKitGTK.webkit_web_view_run_javascript(webView, Converter.wcsToMbcs(script, true), 0, 0, 0);
			return null;
		} else {
			// Callback logic: Initiate an async callback and wait for it to finish.
			// The callback comes back in runjavascript_callback(..) below.
			Consumer <Integer> asyncFunc = (callbackId) -> {
				WebKitGTK.webkit_web_view_run_javascript(webView, Converter.wcsToMbcs(script, true), 0, runjavascript_callback.getAddress(), callbackId);
			};

			Webkit2AsyncReturnObj retObj = execAsyncAndWaitForReturn(browser, asyncFunc, " The following javascript was executed:\n" + script +"\n\n");

			if (retObj.swtAsyncTimeout) {
				return null;
			} else if (retObj.errorNum != 0) {
				throw new SWTException(retObj.errorNum, retObj.errorMsg +"\nScript that was evaluated:\n" + script);
			} else {
				// This is also the implicit case where browser was disposed while javascript was executing. It returns null.
				return retObj.returnValue;
			}
		}
	}

	@SuppressWarnings("unused") // Only called directly from C (from javascript).
	private static void runjavascript_callback (long GObject_source, long GAsyncResult, long user_data) {
		int callbackId = (int) user_data;
		Webkit2AsyncReturnObj retObj = CallBackMap.getObj(callbackId);

		if (retObj != null) { // retObj can be null if there was a timeout.
			long [] gerror = new long [1]; // GError **
			long js_result = WebKitGTK.webkit_web_view_run_javascript_finish(GObject_source, GAsyncResult, gerror);
			if (js_result == 0) {
				long errMsg = OS.g_error_get_message(gerror[0]);
				String msg = Converter.cCharPtrToJavaString(errMsg, false);
				OS.g_error_free(gerror[0]);

				retObj.errorNum = SWT.ERROR_FAILED_EVALUATE;
				retObj.errorMsg = msg != null ? msg : "";
			} else {
				long context = WebKitGTK.webkit_javascript_result_get_global_context (js_result);
				long value = WebKitGTK.webkit_javascript_result_get_value (js_result);

				try {
					retObj.returnValue = convertToJava(context, value);
				} catch (IllegalArgumentException ex) {
					retObj.errorNum = SWT.ERROR_INVALID_RETURN_VALUE;
					retObj.errorMsg = "Type of return value not is not valid. For supported types see: Browser.evaluate() JavaDoc";
				}
				WebKitGTK.webkit_javascript_result_unref (js_result);
			}
			retObj.callbackFinished = true;
		}
		Display.getCurrent().wake();
	}

	static String getText(Browser browser, long webView) {
		long WebKitWebResource = WebKitGTK.webkit_web_view_get_main_resource(webView);
		if (WebKitWebResource == 0) { // No page yet loaded.
			return "";
		}
		if (nonBlockingEvaluate > 0) {
			System.err.println("SWT Webkit Warning: getText() called inside a synchronous callback, which can lead to a deadlock.\n"
					+ "Avoid using getText in OpenWindowListener, Authentication listener and when webkit is about to change to a new page\n"
					+ "Return value is empty string '' instead of actual text");
			return "";
		}

		Consumer<Integer> asyncFunc = (callbackId) -> WebKitGTK.webkit_web_resource_get_data(WebKitWebResource, 0, getText_callback.getAddress(), callbackId);
		Webkit2AsyncReturnObj retObj = execAsyncAndWaitForReturn(browser, asyncFunc, " getText() was called");

		if (retObj.swtAsyncTimeout)
			return "SWT WEBKIT TIMEOUT ERROR";
		else
			return (String) retObj.returnValue;
	}

	@SuppressWarnings("unused") // Callback only called only by C directly
	private static void getText_callback(long WebResource, long GAsyncResult, long user_data) {
		int callbackId = (int) user_data;
		Webkit2AsyncReturnObj retObj = CallBackMap.getObj(callbackId);

		long [] gsize_len = new long [1];
		long [] gerrorRes = new long [1]; // GError **
		long guchar_data = WebKitGTK.webkit_web_resource_get_data_finish(WebResource, GAsyncResult, gsize_len, gerrorRes);
		if (gerrorRes[0] != 0 || guchar_data == 0) {
			OS.g_error_free(gerrorRes[0]);
			retObj.returnValue = (String) "";
		} else {
			int len = (int) gsize_len[0];
			byte[] buffer = new byte [len];
			C.memmove (buffer, guchar_data, len);
			String text = Converter.byteToStringViaHeuristic(buffer);
			retObj.returnValue = text;
		}

		retObj.callbackFinished = true;
		Display.getCurrent().wake();
	}

	/**
	 * Associates a Browser instance with this class, mainly so we can get its Display
	 * and check for disposal.
	 * @param toSet the Browser instance to set
	 */
	static void setCookieBrowser (Browser toSet) {
		if (toSet != null) cookieBrowser = toSet;
	}

	static boolean setCookie(String cookieUrl, String cookieValue) {
		long context = WebKitGTK.webkit_web_context_get_default();
		long cookieManager = WebKitGTK.webkit_web_context_get_cookie_manager(context);
		byte[] bytes = Converter.wcsToMbcs (cookieUrl, true);
		long uri = WebKitGTK.soup_uri_new (bytes);
		if (uri == 0) {
			System.err.println("SWT WebKit: SoupURI == 0 when setting cookie");
			return false;
		}
		bytes = Converter.wcsToMbcs (cookieValue, true);
		long soupCookie = WebKitGTK.soup_cookie_parse (bytes, uri);

		if (nonBlockingEvaluate > 0) {
			System.err.println("SWT Webkit: setCookie() called inside a synchronous callback, which can lead to a deadlock.\n"
					+ "Return value is false.");
			return false;
		}

		Consumer<Integer> asyncFunc = (callbackID) -> WebKitGTK.webkit_cookie_manager_add_cookie(cookieManager, soupCookie, 0,
				setCookie_callback.getAddress(), callbackID);
		Webkit2AsyncReturnObj retObj = execAsyncAndWaitForReturn(cookieBrowser, asyncFunc, " setCookie() was called");

		WebKitGTK.soup_uri_free (uri);

		if (retObj.swtAsyncTimeout) {
			return false;
		} else {
			return (Boolean) retObj.returnValue;
		}
	}

	@SuppressWarnings("unused") // Callback only called only by C directly
	private static void setCookie_callback(long cookieManager, long result, long user_data) {
		int callbackID = (int) user_data;
		Webkit2AsyncReturnObj retObj = CallBackMap.getObj(callbackID);

		long [] error = new long [1];
		retObj.returnValue = WebKitGTK.webkit_cookie_manager_add_cookie_finish(cookieManager, result, error);

		if (error[0] != 0) {
			long errorMessageC = OS.g_error_get_message(error[0]);
			String errorMessageStr = Converter.cCharPtrToJavaString(errorMessageC, false);
			System.err.println("SWT WebKit: error setting cookie: " + errorMessageStr);
			OS.g_error_free(error[0]);
		}

		retObj.callbackFinished = true;
		Display.getCurrent().wake();

	}

	static String getCookie(String cookieUrl, String cookieName) {
		long context = WebKitGTK.webkit_web_context_get_default();
		long cookieManager = WebKitGTK.webkit_web_context_get_cookie_manager(context);
		byte[] uri = Converter.wcsToMbcs (cookieUrl, true);
		if (nonBlockingEvaluate > 0) {
			System.err.println("SWT Webkit: getCookie() called inside a synchronous callback, which can lead to a deadlock.\n"
					+ "Return value is an empty string '' instead of actual cookie value.");
			return "";
		}

		/*
		 * We package the cookie name and callbackID into a GVariant which can be passed to the callback.
		 * The callbackID is necessary so we can find our way back to the correct Browser instance, and
		 * the cookie name is necessary as the field could have been modified by the time the callback
		 * triggers.
		 */
		Consumer<Integer> asyncFunc = (callbackID) -> WebKitGTK.webkit_cookie_manager_get_cookies(cookieManager, uri, 0,
				getCookie_callback.getAddress(), WebkitGDBus.convertJavaToGVariant(new Object [] {cookieName, callbackID}));
		Webkit2AsyncReturnObj retObj = execAsyncAndWaitForReturn(cookieBrowser, asyncFunc, " getCookie() was called");

		if (retObj.swtAsyncTimeout) {
			return "SWT WEBKIT TIMEOUT ERROR";
		} else {
			return (String) retObj.returnValue;
		}
	}

	@SuppressWarnings("unused") // Callback only called only by C directly
	private static void getCookie_callback(long cookieManager, long result, long user_data) {
		Object resultObject = WebkitGDBus.convertGVariantToJava(user_data);

		// We are expecting a GVariant tuple, anything else means something went wrong
		if (resultObject instanceof Object []) {
			// Unpack callback ID and cookie name
			Object [] nameAndId = (Object []) resultObject;
			String cookieName = (String) nameAndId[0];
			int callbackId = ((Number) nameAndId[1]).intValue();
			Webkit2AsyncReturnObj retObj = CallBackMap.getObj(callbackId);

			// Get GSList of cookies
			long [] error = new long [1];
			long cookieList = WebKitGTK.webkit_cookie_manager_get_cookies_finish(cookieManager, result, error);
			if (error[0] != 0) {
				long errorMessageC = OS.g_error_get_message(error[0]);
				String errorMessageStr = Converter.cCharPtrToJavaString(errorMessageC, false);
				System.err.println("SWT WebKit: error getting cookie: " + errorMessageStr);
				OS.g_error_free(error[0]);
				retObj.returnValue = (String) "";
			}

			int length = OS.g_slist_length (cookieList);
			long current = cookieList;
			for (int i = 0; i < length; i++) {
				long soupCookie = OS.g_slist_data (current);
				long soupName = WebKitGTK.soup_cookie_get_name(soupCookie);
				String soupNameStr = Converter.cCharPtrToJavaString(soupName, false);
				if (soupNameStr != null && soupNameStr.equals(cookieName)) {
					long soupValue = WebKitGTK.soup_cookie_get_value(soupCookie);
					retObj.returnValue = Converter.cCharPtrToJavaString(soupValue, false);
					break;
				}
				current = OS.g_slist_next (current);
			}
			OS.g_slist_free (cookieList);

			retObj.callbackFinished = true;
			Display.getCurrent().wake();
		} else {
			System.err.println("SWT WebKit: something went wrong unpacking GVariant tuple for getCookie_callback");
		}
	}

	/**
	 * You should check 'retObj.swtAsyncTimeout' after making a call to this.
	 */
	private static Webkit2AsyncReturnObj execAsyncAndWaitForReturn(Browser browser, Consumer<Integer> asyncFunc, String additionalErrorInfo) {
		Webkit2AsyncReturnObj retObj = new Webkit2AsyncReturnObj();
		int callbackId = CallBackMap.putObject(retObj);
		asyncFunc.accept(callbackId);
		final Instant timeOut = Instant.now().plusMillis(ASYNC_EXEC_TIMEOUT_MS);
		while (!browser.isDisposed()) {
			if (retObj.callbackFinished)
				break;
			else if (Instant.now().isAfter(timeOut)) {
				System.err.println("SWT call to Webkit timed out after " + ASYNC_EXEC_TIMEOUT_MS
						+ "ms. No return value will be provided.\n"
						+ "Possible reasons:\n"
						+ "1) Problem: Your javascript needs more than " + ASYNC_EXEC_TIMEOUT_MS +"ms to execute.\n"
						+ "   Solution: Don't run such javascript, it blocks Eclipse's UI. SWT currently allows such code to complete, but this error is thrown \n"
						+ "     and the return value of execute()/evalute() will be false/null.\n\n"
						+ "2) However, if you believe that your application should execute as expected (in under" + ASYNC_EXEC_TIMEOUT_MS + " ms),\n"
						+ " then it might be a deadlock in SWT/Browser/webkit2 logic.\n"
						+ " I.e, it might be a bug in SWT (e.g this does not occur on Windows/Cocoa, but occurs on Linux). If you believe it to be a bug in SWT, then\n"
						+ getInternalErrorMsg()
						+ "\n Additional information about the error is as following:\n"
						+ additionalErrorInfo);
				retObj.swtAsyncTimeout = true;
				break;
			}
			else {
				if (GTK.GTK4) {
					OS.g_main_context_iteration (0, true);
				} else {
					GTK3.gtk_main_iteration_do (true);
				}
			}
		}
		CallBackMap.removeObject(callbackId);
		return retObj;
	}
}

@Override
public Object evaluate (String script) throws SWTException {
	if ("".equals(script)) {
		return null; // A litte optimization. Sometimes evaluate() is called with a generated script, where the generated script is sometimes empty.
	}
	if (!isJavascriptEnabled()) {
		return null;
	}
	return Webkit2AsyncToSync.evaluate(script, this.browser, webView);
}

@Override
public boolean forward () {
	if (webView == 0) {
		assert false;
		System.err.println("SWT Webkit: forward() called after widget disposed. Should not have happened.\n" + getInternalErrorMsg());
		return false; // Disposed.
	}
	if (WebKitGTK.webkit_web_view_can_go_forward (webView) == 0) return false;
	WebKitGTK.webkit_web_view_go_forward (webView);
	return true;
}

@Override
public String getBrowserType () {
	return "webkit"; //$NON-NLS-1$
}

@Override
public String getText () {
	return Webkit2AsyncToSync.getText(browser, webView);
}

@Override
public String getUrl () {
	if (webView == 0) {
		assert false;
		System.err.println("SWT Webkit: getUrl() called after widget disposed. Should not have happened.\n" + getInternalErrorMsg());
		return null; // Disposed.
	}
	long uri = WebKitGTK.webkit_web_view_get_uri (webView);

	/* WebKit auto-navigates to about:blank at startup */
	if (uri == 0) return ABOUT_BLANK;

	int length = C.strlen (uri);
	byte[] bytes = new byte[length];
	C.memmove (bytes, uri, length);

	String url = new String (Converter.mbcsToWcs (bytes));
	/*
	 * If the URI indicates that the page is being rendered from memory
	 * (via setText()) then set it to about:blank to be consistent with IE.
	 */
	if (url.equals (URI_FILEROOT)) {
		url = ABOUT_BLANK;
	} else {
		length = URI_FILEROOT.length ();
		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
			url = ABOUT_BLANK + url.substring (length);
		}
	}
	return url;
}

boolean handleDOMEvent (long event, int type) {
	/*
	* This method handles JS events that are received through the DOM
	* listener API that was introduced in WebKitGTK 1.4.
	*/
	String typeString = null;
	boolean isMouseEvent = false;
	switch (type) {
		case SWT.DragDetect: {
			typeString = "dragstart"; //$NON-NLS-1$
			isMouseEvent = true;
			break;
		}
		case SWT.MouseDown: {
			typeString = "mousedown"; //$NON-NLS-1$
			isMouseEvent = true;
			break;
		}
		case SWT.MouseMove: {
			typeString = "mousemove"; //$NON-NLS-1$
			isMouseEvent = true;
			break;
		}
		case SWT.MouseUp: {
			typeString = "mouseup"; //$NON-NLS-1$
			isMouseEvent = true;
			break;
		}
		case SWT.MouseWheel: {
			typeString = "mousewheel"; //$NON-NLS-1$
			isMouseEvent = true;
			break;
		}
		case SWT.KeyDown: {
			typeString = "keydown"; //$NON-NLS-1$
			break;
		}
		case SWT.KeyUp: {
			typeString = "keyup"; //$NON-NLS-1$
			break;
		}
		case SENTINEL_KEYPRESS: {
			typeString = "keypress"; //$NON-NLS-1$
			break;
		}
	}

	if (isMouseEvent) {
		int screenX = (int)WebKitGTK.webkit_dom_mouse_event_get_screen_x (event);
		int screenY = (int)WebKitGTK.webkit_dom_mouse_event_get_screen_y (event);
		int button = (int)WebKitGTK.webkit_dom_mouse_event_get_button (event) + 1;
		boolean altKey = WebKitGTK.webkit_dom_mouse_event_get_alt_key (event) != 0;
		boolean ctrlKey = WebKitGTK.webkit_dom_mouse_event_get_ctrl_key (event) != 0;
		boolean shiftKey = WebKitGTK.webkit_dom_mouse_event_get_shift_key (event) != 0;
		boolean metaKey = WebKitGTK.webkit_dom_mouse_event_get_meta_key (event) != 0;
		int detail = (int)WebKitGTK.webkit_dom_ui_event_get_detail (event);
		boolean hasRelatedTarget = false; //WebKitGTK.webkit_dom_mouse_event_get_related_target (event) != 0;
		return handleMouseEvent(typeString, screenX, screenY, detail, button, altKey, ctrlKey, shiftKey, metaKey, hasRelatedTarget);
	}

	/* key event */
	int keyEventState = 0;
	long eventPtr = GTK3.gtk_get_current_event ();
	if (eventPtr != 0) {
		int eventType = GDK.gdk_event_get_event_type(eventPtr);
		int [] state = new int[1];
		if (GTK.GTK4) {
			state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
		} else {
			GDK.gdk_event_get_state(eventPtr, state);
		}
		switch (eventType) {
			case GDK.GDK_KEY_PRESS:
			case GDK.GDK_KEY_RELEASE:
				keyEventState = state[0];
				break;
		}
		if (GTK.GTK4) {
			OS.g_object_unref(eventPtr);
		} else {
			GDK.gdk_event_free (eventPtr);
		}
	}
	int keyCode = (int)WebKitGTK.webkit_dom_ui_event_get_key_code (event);
	int charCode = (int)WebKitGTK.webkit_dom_ui_event_get_char_code (event);
	boolean altKey = (keyEventState & GDK.GDK_MOD1_MASK) != 0;
	boolean ctrlKey = (keyEventState & GDK.GDK_CONTROL_MASK) != 0;
	boolean shiftKey = (keyEventState & GDK.GDK_SHIFT_MASK) != 0;
	return handleKeyEvent(typeString, keyCode, charCode, altKey, ctrlKey, shiftKey, false);
}

boolean handleEventFromFunction (Object[] arguments) {
	/*
	* Prior to WebKitGTK 1.4 there was no API for hooking DOM listeners.
	* As a workaround, eventFunction was introduced to capture JS events
	* and report them back to the java side.  This method handles these
	* events by extracting their arguments and passing them to the
	* handleKeyEvent()/handleMouseEvent() event handler methods.
	*/

	/*
	* The arguments for key events are:
	* 	argument 0: type (String)
	* 	argument 1: keyCode (Double)
	* 	argument 2: charCode (Double)
	* 	argument 3: altKey (Boolean)
	* 	argument 4: ctrlKey (Boolean)
	* 	argument 5: shiftKey (Boolean)
	* 	argument 6: metaKey (Boolean)
	* 	returns doit
	*
	* The arguments for mouse events are:
	* 	argument 0: type (String)
	* 	argument 1: screenX (Double)
	* 	argument 2: screenY (Double)
	* 	argument 3: detail (Double)
	* 	argument 4: button (Double)
	* 	argument 5: altKey (Boolean)
	* 	argument 6: ctrlKey (Boolean)
	* 	argument 7: shiftKey (Boolean)
	* 	argument 8: metaKey (Boolean)
	* 	argument 9: hasRelatedTarget (Boolean)
	* 	returns doit
	*/

	String type = (String)arguments[0];
	if (type.equals (DOMEVENT_KEYDOWN) || type.equals (DOMEVENT_KEYPRESS) || type.equals (DOMEVENT_KEYUP)) {
		return handleKeyEvent(
			type,
			((Double)arguments[1]).intValue (),
			((Double)arguments[2]).intValue (),
			((Boolean)arguments[3]).booleanValue (),
			((Boolean)arguments[4]).booleanValue (),
			((Boolean)arguments[5]).booleanValue (),
			((Boolean)arguments[6]).booleanValue ());
	}

	return handleMouseEvent(
		type,
		((Double)arguments[1]).intValue (),
		((Double)arguments[2]).intValue (),
		((Double)arguments[3]).intValue (),
		(arguments[4] != null ? ((Double)arguments[4]).intValue () : 0) + 1,
		((Boolean)arguments[5]).booleanValue (),
		((Boolean)arguments[6]).booleanValue (),
		((Boolean)arguments[7]).booleanValue (),
		((Boolean)arguments[8]).booleanValue (),
		((Boolean)arguments[9]).booleanValue ());
}

boolean handleKeyEvent (String type, int keyCode, int charCode, boolean altKey, boolean ctrlKey, boolean shiftKey, boolean metaKey) {
	if (type.equals (DOMEVENT_KEYDOWN)) {
		keyCode = translateKey (keyCode);
		lastKeyCode = keyCode;
		switch (keyCode) {
			case SWT.SHIFT:
			case SWT.CONTROL:
			case SWT.ALT:
			case SWT.CAPS_LOCK:
			case SWT.NUM_LOCK:
			case SWT.SCROLL_LOCK:
			case SWT.COMMAND:
			case SWT.ESC:
			case SWT.TAB:
			case SWT.PAUSE:
			case SWT.BS:
			case SWT.INSERT:
			case SWT.DEL:
			case SWT.HOME:
			case SWT.END:
			case SWT.PAGE_UP:
			case SWT.PAGE_DOWN:
			case SWT.ARROW_DOWN:
			case SWT.ARROW_UP:
			case SWT.ARROW_LEFT:
			case SWT.ARROW_RIGHT:
			case SWT.F1:
			case SWT.F2:
			case SWT.F3:
			case SWT.F4:
			case SWT.F5:
			case SWT.F6:
			case SWT.F7:
			case SWT.F8:
			case SWT.F9:
			case SWT.F10:
			case SWT.F11:
			case SWT.F12: {
				/* keypress events will not be received for these keys, so send KeyDowns for them now */

				Event keyEvent = new Event ();
				keyEvent.widget = browser;
				keyEvent.type = type.equals (DOMEVENT_KEYDOWN) ? SWT.KeyDown : SWT.KeyUp;
				keyEvent.keyCode = keyCode;
				switch (keyCode) {
					case SWT.BS: keyEvent.character = SWT.BS; break;
					case SWT.DEL: keyEvent.character = SWT.DEL; break;
					case SWT.ESC: keyEvent.character = SWT.ESC; break;
					case SWT.TAB: keyEvent.character = SWT.TAB; break;
				}
				lastCharCode = keyEvent.character;
				keyEvent.stateMask = (altKey ? SWT.ALT : 0) | (ctrlKey ? SWT.CTRL : 0) | (shiftKey ? SWT.SHIFT : 0) | (metaKey ? SWT.COMMAND : 0);
				keyEvent.stateMask &= ~keyCode;		/* remove current keydown if it's a state key */
				final int stateMask = keyEvent.stateMask;
				if (!sendKeyEvent (keyEvent) || browser.isDisposed ()) return false;

				if (browser.isFocusControl ()) {
					if (keyCode == SWT.TAB && (stateMask & (SWT.CTRL | SWT.ALT)) == 0) {
						browser.getDisplay ().asyncExec (() -> {
							if (browser.isDisposed ()) return;
							if (browser.getDisplay ().getFocusControl () == null) {
								int traversal = (stateMask & SWT.SHIFT) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
								browser.traverse (traversal);
							}
						});
					}
				}
				break;
			}
		}
		return true;
	}

	if (type.equals (DOMEVENT_KEYPRESS)) {
		/*
		* if keydown could not determine a keycode for this key then it's a
		* key for which key events are not sent (eg.- the Windows key)
		*/
		if (lastKeyCode == 0) return true;

		lastCharCode = charCode;
		if (ctrlKey && (0 <= lastCharCode && lastCharCode <= 0x7F)) {
			if ('a' <= lastCharCode && lastCharCode <= 'z') lastCharCode -= 'a' - 'A';
			if (64 <= lastCharCode && lastCharCode <= 95) lastCharCode -= 64;
		}

		Event keyEvent = new Event ();
		keyEvent.widget = browser;
		keyEvent.type = SWT.KeyDown;
		keyEvent.keyCode = lastKeyCode;
		keyEvent.character = (char)lastCharCode;
		keyEvent.stateMask = (altKey ? SWT.ALT : 0) | (ctrlKey ? SWT.CTRL : 0) | (shiftKey ? SWT.SHIFT : 0) | (metaKey ? SWT.COMMAND : 0);
		return sendKeyEvent (keyEvent) && !browser.isDisposed ();
	}

	/* keyup */

	keyCode = translateKey (keyCode);
	if (keyCode == 0) {
		/* indicates a key for which key events are not sent */
		return true;
	}
	if (keyCode != lastKeyCode) {
		/* keyup does not correspond to the last keydown */
		lastKeyCode = keyCode;
		lastCharCode = 0;
	}

	Event keyEvent = new Event ();
	keyEvent.widget = browser;
	keyEvent.type = SWT.KeyUp;
	keyEvent.keyCode = lastKeyCode;
	keyEvent.character = (char)lastCharCode;
	keyEvent.stateMask = (altKey ? SWT.ALT : 0) | (ctrlKey ? SWT.CTRL : 0) | (shiftKey ? SWT.SHIFT : 0) | (metaKey ? SWT.COMMAND : 0);
	switch (lastKeyCode) {
		case SWT.SHIFT:
		case SWT.CONTROL:
		case SWT.ALT:
		case SWT.COMMAND: {
			keyEvent.stateMask |= lastKeyCode;
		}
	}
	browser.notifyListeners (keyEvent.type, keyEvent);
	lastKeyCode = lastCharCode = 0;
	return keyEvent.doit && !browser.isDisposed ();
}

boolean handleMouseEvent (String type, int screenX, int screenY, int detail, int button, boolean altKey, boolean ctrlKey, boolean shiftKey, boolean metaKey, boolean hasRelatedTarget) {
	/*
	 * MouseOver and MouseOut events are fired any time the mouse enters or exits
	 * any element within the Browser.  To ensure that SWT events are only
	 * fired for mouse movements into or out of the Browser, do not fire an
	 * event if there is a related target element.
	 */

	/*
	* The following is intentionally commented because MouseOver and MouseOut events
	* are not being hooked until https://bugs.webkit.org/show_bug.cgi?id=35246 is fixed.
	*/
	//if (type.equals (DOMEVENT_MOUSEOVER) || type.equals (DOMEVENT_MOUSEOUT)) {
	//	if (((Boolean)arguments[9]).booleanValue ()) return true;
	//}

	/*
	 * The position of mouse events is received in screen-relative coordinates
	 * in order to handle pages with frames, since frames express their event
	 * coordinates relative to themselves rather than relative to their top-
	 * level page.  Convert screen-relative coordinates to be browser-relative.
	 */
	Point position = new Point (screenX, screenY);
	position = browser.getDisplay ().map (null, browser, position);

	Event mouseEvent = new Event ();
	mouseEvent.widget = browser;
	mouseEvent.x = position.x;
	mouseEvent.y = position.y;
	int mask = (altKey ? SWT.ALT : 0) | (ctrlKey ? SWT.CTRL : 0) | (shiftKey ? SWT.SHIFT : 0) | (metaKey ? SWT.COMMAND : 0);
	mouseEvent.stateMask = mask;

	if (type.equals (DOMEVENT_MOUSEDOWN)) {
		mouseEvent.type = SWT.MouseDown;
		mouseEvent.count = detail;
		mouseEvent.button = button;
		browser.notifyListeners (mouseEvent.type, mouseEvent);
		if (browser.isDisposed ()) return true;
		if (detail == 2) {
			mouseEvent = new Event ();
			mouseEvent.type = SWT.MouseDoubleClick;
			mouseEvent.widget = browser;
			mouseEvent.x = position.x;
			mouseEvent.y = position.y;
			mouseEvent.stateMask = mask;
			mouseEvent.count = detail;
			mouseEvent.button = button;
			browser.notifyListeners (mouseEvent.type, mouseEvent);
		}
		return true;
	}

	if (type.equals (DOMEVENT_MOUSEUP)) {
		mouseEvent.type = SWT.MouseUp;
		mouseEvent.count = detail;
		mouseEvent.button = button;
	} else if (type.equals (DOMEVENT_MOUSEMOVE)) {
		mouseEvent.type = SWT.MouseMove;
	} else if (type.equals (DOMEVENT_MOUSEWHEEL)) {
		mouseEvent.type = SWT.MouseWheel;
		mouseEvent.count = detail;

	/*
	* The following is intentionally commented because MouseOver and MouseOut events
	* are not being hooked until https://bugs.webkit.org/show_bug.cgi?id=35246 is fixed.
	*/
	//} else if (type.equals (DOMEVENT_MOUSEOVER)) {
	//	mouseEvent.type = SWT.MouseEnter;
	//} else if (type.equals (DOMEVENT_MOUSEOUT)) {
	//	mouseEvent.type = SWT.MouseExit;

	} else if (type.equals (DOMEVENT_DRAGSTART)) {
		mouseEvent.type = SWT.DragDetect;
		mouseEvent.button = button;
		switch (mouseEvent.button) {
			case 1: mouseEvent.stateMask |= SWT.BUTTON1; break;
			case 2: mouseEvent.stateMask |= SWT.BUTTON2; break;
			case 3: mouseEvent.stateMask |= SWT.BUTTON3; break;
			case 4: mouseEvent.stateMask |= SWT.BUTTON4; break;
			case 5: mouseEvent.stateMask |= SWT.BUTTON5; break;
		}
	}

	browser.notifyListeners (mouseEvent.type, mouseEvent);
	return true;
}

long handleLoadCommitted (long uri, boolean top) {
	int length = C.strlen (uri);
	byte[] bytes = new byte[length];
	C.memmove (bytes, uri, length);
	String url = new String (Converter.mbcsToWcs (bytes));
	/*
	 * If the URI indicates that the page is being rendered from memory
	 * (via setText()) then set it to about:blank to be consistent with IE.
	 */
	if (url.equals (URI_FILEROOT)) {
		url = ABOUT_BLANK;
	} else {
		length = URI_FILEROOT.length ();
		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
			url = ABOUT_BLANK + url.substring (length);
		}
	}

	LocationEvent event = new LocationEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	event.location = url;
	event.top = top;
	Runnable fireLocationChanged = () ->  {
		if (browser.isDisposed ()) return;
		for (int i = 0; i < locationListeners.length; i++) {
			locationListeners[i].changed (event);
		}
	};
	browser.getDisplay().asyncExec(fireLocationChanged);
	return 0;
}

/**
 * This method is reached by:
 * Webkit2: WebKitWebView load-changed signal
 * 	- void user_function (WebKitWebView  *web_view, WebKitLoadEvent load_event, gpointer user_data)
 *  - https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView-load-changed
 *  - Note: As there is no return value, safe to fire asynchronously.
 */
private void fireProgressCompletedEvent(){
	Runnable fireProgressEvents = () -> {
		if (browser.isDisposed() || progressListeners == null) return;
		ProgressEvent progress = new ProgressEvent (browser);
		progress.display = browser.getDisplay ();
		progress.widget = browser;
		progress.current = MAX_PROGRESS;
		progress.total = MAX_PROGRESS;
		for (int i = 0; i < progressListeners.length; i++) {
			progressListeners[i].completed (progress);
		}
	};
	browser.getDisplay().asyncExec(fireProgressEvents);
}

@Override
public boolean isBackEnabled () {
	if (webView == 0)
		return false; //disposed.
	return WebKitGTK.webkit_web_view_can_go_back (webView) != 0;
}

@Override
public boolean isForwardEnabled () {
	return WebKitGTK.webkit_web_view_can_go_forward (webView) != 0;
}

void onDispose (Event e) {
	/* Browser could have been disposed by one of the Dispose listeners */
	if (!browser.isDisposed()) {
		/* invoke onbeforeunload handlers */
		if (!browser.isClosing) {
			close (false);
		}
	}

	for (BrowserFunction function : functions.values()) {
		function.dispose(false);
	}
	functions = null;

	if (WebKitGTK.webkit_get_minor_version() >= 18) {
		// Bug 530678.
		// * As of Webkit 2.18, (it seems) webkitGtk auto-disposes itself when the parent is disposed.
		// * This can cause a deadlock inside Webkit process if WebkitGTK widget's parent is disposed during a callback.
		//   This is because webkit process is waiting for it's callback to finish which never completes
		//   because parent's disposal also disposed webkitGTK widget. (Note Webkit process vs WebkitGtk widget).
		// * To break the deadlock, we unparent webkitGtk temporarily and unref (dispose) it later after callback is done.
		//
		// If you change dispose logic, to check that you haven't introduced memory leaks, test via:
		// org.eclipse.swt.tests.junit.memoryleak.Test_Memory_Leak.test_Browser()
		OS.g_object_ref (webView);
		GTK3.gtk_container_remove (GTK.gtk_widget_get_parent (webView), webView);
		long webViewTempRef = webView;
		Display.getDefault().asyncExec(() -> {
			OS.g_object_unref(webViewTempRef);
		});
		webView = 0;
	}
}

void onResize (Event e) {
	Rectangle rect = DPIUtil.autoScaleUp(browser.getClientArea ());
	if (webView == 0)
		return;
	GTK.gtk_widget_set_size_request (webView, rect.width, rect.height);
}

void openDownloadWindow (final long webkitDownload, final String suggested_filename) {
	final Shell shell = new Shell ();
	String msg = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$
	shell.setText (msg);
	GridLayout gridLayout = new GridLayout ();
	gridLayout.marginHeight = 15;
	gridLayout.marginWidth = 15;
	gridLayout.verticalSpacing = 20;
	shell.setLayout (gridLayout);

	String nameString = suggested_filename;

	long request = WebKitGTK.webkit_download_get_request(webkitDownload);
	long url = WebKitGTK.webkit_uri_request_get_uri(request);

	int length = C.strlen (url);
	byte[] bytes = new byte[length];
	C.memmove (bytes, url, length);
	String urlString = new String (Converter.mbcsToWcs (bytes));
	msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {nameString, urlString}); //$NON-NLS-1$
	Label nameLabel = new Label (shell, SWT.WRAP);
	nameLabel.setText (msg);
	GridData data = new GridData ();
	Monitor monitor = browser.getMonitor ();
	int maxWidth = monitor.getBounds ().width / 2;
	int width = nameLabel.computeSize (SWT.DEFAULT, SWT.DEFAULT).x;
	data.widthHint = Math.min (width, maxWidth);
	data.horizontalAlignment = GridData.FILL;
	data.grabExcessHorizontalSpace = true;
	nameLabel.setLayoutData (data);

	final Label statusLabel = new Label (shell, SWT.NONE);
	statusLabel.setText (Compatibility.getMessage ("SWT_Download_Started")); //$NON-NLS-1$
	data = new GridData (GridData.FILL_BOTH);
	statusLabel.setLayoutData (data);

	final Button cancel = new Button (shell, SWT.PUSH);
	cancel.setText (Compatibility.getMessage ("SWT_Cancel")); //$NON-NLS-1$
	data = new GridData ();
	data.horizontalAlignment = GridData.CENTER;
	cancel.setLayoutData (data);
	final Listener cancelListener = event -> {
		webKitDownloadStatus.put(new LONG(webkitDownload), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_CANCELLED);
		WebKitGTK.webkit_download_cancel (webkitDownload);
	};
	cancel.addListener (SWT.Selection, cancelListener);

	OS.g_object_ref (webkitDownload);
	final Display display = browser.getDisplay ();
	final int INTERVAL = 500;
	display.timerExec (INTERVAL, new Runnable () {
		@Override
		public void run () {
			int status =  webKitDownloadStatus.containsKey(new LONG(webkitDownload)) ? webKitDownloadStatus.get(new LONG(webkitDownload)) : 0;
			if (shell.isDisposed () || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_FINISHED || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_CANCELLED) {
				shell.dispose ();
				display.timerExec (-1, this);
				OS.g_object_unref (webkitDownload);
				webKitDownloadStatus.remove(new LONG(webkitDownload));
				return;
			}
			if (status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_ERROR) {
				statusLabel.setText (Compatibility.getMessage ("SWT_Download_Error")); //$NON-NLS-1$
				display.timerExec (-1, this);
				OS.g_object_unref (webkitDownload);
				cancel.removeListener (SWT.Selection, cancelListener);
				cancel.addListener (SWT.Selection, event -> shell.dispose ());
				webKitDownloadStatus.remove(new LONG(webkitDownload));
				return;
			}

			long current = WebKitGTK.webkit_download_get_received_data_length(webkitDownload) / 1024L;
			long response = WebKitGTK.webkit_download_get_response(webkitDownload);
			long total = WebKitGTK.webkit_uri_response_get_content_length(response) / 1024L;
			String message = Compatibility.getMessage ("SWT_Download_Status", new Object[] {current, total}); //$NON-NLS-1$
			statusLabel.setText (message);
			display.timerExec (INTERVAL, this);
		}
	});

	shell.pack ();
	shell.open ();
}

@Override
public void refresh () {
	if (webView == 0)
		return; //disposed.
	WebKitGTK.webkit_web_view_reload (webView);
}

@Override
public boolean setText (String html, boolean trusted) {
	/* convert the String containing HTML to an array of bytes with UTF-8 data */
	byte[] html_bytes = (html + '\0').getBytes (StandardCharsets.UTF_8); //$NON-NLS-1$

	w2_bug527738LastRequestCounter.incrementAndGet();
	byte[] uriBytes;
	if (!trusted) {
		uriBytes = Converter.wcsToMbcs (ABOUT_BLANK, true);
	} else {
		uriBytes = Converter.wcsToMbcs (URI_FILEROOT, true);
	}
	WebKitGTK.webkit_web_view_load_html (webView, html_bytes, uriBytes);

	return true;
}

@Override
public boolean setUrl (String url, String postData, String[] headers) {
	w2_bug527738LastRequestCounter.incrementAndGet();

	if (webView == 0)
		return false; // disposed.

	/*
	* WebKitGTK attempts to open the exact url string that is passed to it and
	* will not infer a protocol if it's not specified.  Detect the case of an
	* invalid URL string and try to fix it by prepending an appropriate protocol.
	*/
	try {
		new URL(url);
	} catch (MalformedURLException e) {
		String testUrl = null;
		if (url.charAt (0) == SEPARATOR_FILE) {
			/* appears to be a local file */
			testUrl = PROTOCOL_FILE + url;
		} else {
			testUrl = PROTOCOL_HTTP + url;
		}
		try {
			new URL (testUrl);
			url = testUrl;		/* adding the protocol made the url valid */
		} catch (MalformedURLException e2) {
			/* adding the protocol did not make the url valid, so do nothing */
		}
	}

	/*
	* Feature of WebKit.  The user-agent header value cannot be overridden
	* by changing it in the resource request.  The workaround is to detect
	* here whether the user-agent is being overridden, and if so, temporarily
	* set the value on the WebView when initiating the load request and then
	* remove it afterwards.
	*/
	long settings = WebKitGTK.webkit_web_view_get_settings (webView);
	if (headers != null) {
		for (int i = 0; i < headers.length; i++) {
			String current = headers[i];
			if (current != null) {
				int index = current.indexOf (':');
				if (index != -1) {
					String key = current.substring (0, index).trim ();
					String value = current.substring (index + 1).trim ();
					if (key.length () > 0 && value.length () > 0) {
						if (key.equalsIgnoreCase (USER_AGENT)) {
							byte[] bytes = Converter.wcsToMbcs (value, true);
							OS.g_object_set (settings, WebKitGTK.user_agent, bytes, 0);
						}
					}
				}
			}
		}
	}

	byte[] uriBytes = Converter.wcsToMbcs (url, true);

	if (postData==null && headers != null) {
		long request = WebKitGTK.webkit_uri_request_new (uriBytes);
		long requestHeaders = WebKitGTK.webkit_uri_request_get_http_headers (request);
		if (requestHeaders != 0) {
			addRequestHeaders(requestHeaders, headers);
		}
		WebKitGTK.webkit_web_view_load_request (webView, request);
		OS.g_object_set (settings, WebKitGTK.user_agent, 0, 0);
		return true;
	}

	// Bug 527738
	// Webkit2 doesn't have api to set url with data. (2.18). While we wait for them to implement,
	// this  workaround uses java to query a server and then manually populate webkit with content.
	// This should be version guarded and replaced with proper functions once webkit2 has implemented api.
	if (postData != null) {
		final String base_url = url;

		// Use Webkit User-Agent
		long [] user_agent_str_ptr = new long [1];
		OS.g_object_get (settings, WebKitGTK.user_agent, user_agent_str_ptr, 0);
		final String userAgent = Converter.cCharPtrToJavaString(user_agent_str_ptr[0], true);
		final int lastRequest = w2_bug527738LastRequestCounter.incrementAndGet(); // Webkit 2 only
		Thread send_request = new Thread(() -> {
			String html = null;
			String mime_type = null;
			String encoding_type = null;
			try {
				URL base = new URL(base_url);
				URLConnection url_conn = base.openConnection();
				if (url_conn instanceof HttpURLConnection) {
					HttpURLConnection conn = (HttpURLConnection) url_conn;

					{ // Configure connection.
						conn.setRequestMethod("POST"); //$NON-NLS-1$

						// Use Webkit Accept
						conn.setRequestProperty( "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); //$NON-NLS-1$ $NON-NLS-2$

						conn.setRequestProperty("User-Agent", userAgent); //$NON-NLS-1$
						conn.setDoOutput(true); // because default value is false

						// Set headers
						if (headers != null) {
							for (String header : headers) {
								int index = header.indexOf(':');
								if (index > 0) {
									String key = header.substring(0, index).trim();
									String value = header.substring(index + 1).trim();
									conn.setRequestProperty(key, value);
								}
							}
						}
					}

					{ // Query server
						try (OutputStream out = conn.getOutputStream()) {
							out.write(postData.getBytes());
						}

						StringBuilder response = new StringBuilder();
						try (BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
							char [] cbuff = new char[4096];
							while (buff.read(cbuff, 0, cbuff.length) > 0) {
								response.append(new String(cbuff));
								Arrays.fill(cbuff, '\0');
							}
						}
						html = response.toString();
					}

					{ // Extract result meta data
						// Get Media Type from Content-Type
						String content_type = conn.getContentType();
						int paramaterSeparatorIndex = content_type.indexOf(';');
						mime_type = paramaterSeparatorIndex > 0 ? content_type.substring(0, paramaterSeparatorIndex) : content_type;

						// Get Encoding if defined
						if (content_type.indexOf(';') > 0) {
							String [] attrs = content_type.split(";");
							for (String attr : attrs) {
								int i = attr.indexOf('=');
								if (i > 0) {
									String key = attr.substring(0, i).trim();
									String value = attr.substring(i + 1).trim();
									if ("charset".equalsIgnoreCase(key)) { //$NON-NLS-1$
										encoding_type = value;
									}
								}
							}
						}
					}
				}
			} catch (IOException e) { // MalformedURLException is an IOException also.
				html = e.getMessage();
			} finally {
				if (html != null && lastRequest == w2_bug527738LastRequestCounter.get()) {
					final String final_html = html;
					final String final_mime_type = mime_type;
					final String final_encoding_type = encoding_type;
					Display.getDefault().syncExec(() -> {
						byte [] html_bytes = Converter.wcsToMbcs(final_html, false);
						byte [] mime_type_bytes = final_mime_type != null ? Converter.javaStringToCString(final_mime_type) : Converter.javaStringToCString("text/plain");
						byte [] encoding_bytes = final_encoding_type != null ? Converter.wcsToMbcs(final_encoding_type, true) : new byte [] {0};
						long gByte = OS.g_bytes_new(html_bytes, html_bytes.length);
						WebKitGTK.webkit_web_view_load_bytes (webView, gByte, mime_type_bytes, encoding_bytes, uriBytes);
						OS.g_bytes_unref (gByte); // as per glib/tests/keyfile:test_bytes()..
						OS.g_object_set (settings, WebKitGTK.user_agent, 0, 0);
					});
				}
			}
		});
		send_request.start();
	} else {
		WebKitGTK.webkit_web_view_load_uri (webView, uriBytes);
	}

	if (postData == null) {
		OS.g_object_set (settings, WebKitGTK.user_agent, 0, 0);
	}
	return true;
}

@Override
public void stop () {
	WebKitGTK.webkit_web_view_stop_loading (webView);
}

/**
 * WebKitWebView 'close' signal
 * void user_function (WebKitWebView *web_view, gpointer user_data); // observe *no* return value.
 * https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView-close
 */
long webkit_close_web_view (long web_view) {
	WindowEvent newEvent = new WindowEvent (browser);
	newEvent.display = browser.getDisplay ();
	newEvent.widget = browser;
	Runnable fireCloseWindowListeners = () -> {
		if (browser.isDisposed()) return;
		for (int i = 0; i < closeWindowListeners.length; i++) {
			closeWindowListeners[i].close (newEvent);
		}
		browser.dispose ();
	};
	// On WebKit2 this signal doesn't expect a return value.
	// As such, we can safley execute the SWT listeners later to avoid deadlocks. See bug 512001
	browser.getDisplay().asyncExec(fireCloseWindowListeners);
	return 0;
}

long webkit_create_web_view (long web_view, long frame) {
	WindowEvent newEvent = new WindowEvent (browser);
	newEvent.display = browser.getDisplay ();
	newEvent.widget = browser;
	newEvent.required = true;
	Runnable fireOpenWindowListeners = () -> {
		if (openWindowListeners != null) {
			for (int i = 0; i < openWindowListeners.length; i++) {
				openWindowListeners[i].open (newEvent);
			}
		}
	};
	try {
		nonBlockingEvaluate++; 	  // running evaluate() inside openWindowListener and waiting for return leads to deadlock. Bug 512001
		fireOpenWindowListeners.run();// Permit evaluate()/execute() to execute scripts in listener, but do not provide return value.
	} catch (Exception e) {
		throw e; // rethrow execption if thrown, but decrement counter first.
	} finally {
		nonBlockingEvaluate--;
	}
	Browser browser = null;
	if (newEvent.browser != null && newEvent.browser.webBrowser instanceof WebKit) {
		browser = newEvent.browser;
	}
	if (browser != null && !browser.isDisposed ()) {
		return ((WebKit)browser.webBrowser).webView;
	}
	return 0;
}

static long webkit_download_started(long webKitDownload) {
	OS.g_signal_connect(webKitDownload, WebKitGTK.decide_destination, Proc3.getAddress(), DECIDE_DESTINATION);
	OS.g_signal_connect(webKitDownload, WebKitGTK.failed, Proc3.getAddress(), FAILED);
	OS.g_signal_connect(webKitDownload, WebKitGTK.finished, Proc2.getAddress(), FINISHED);
	return 1;
}


static long webkit_download_decide_destination(long webKitDownload, long suggested_filename) {
	final String fileName = getString(suggested_filename);
	long webView = WebKitGTK.webkit_download_get_web_view(webKitDownload);
	if (webView != 0) {
		Browser browser = FindBrowser (webView);
		if (browser == null || browser.isDisposed() || browser.isClosing) return 0;

		FileDialog dialog = new FileDialog (browser.getShell (), SWT.SAVE);
		dialog.setFileName (fileName);
		String title = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$
		dialog.setText (title);
		String path = dialog.open ();
		if (path != null) {
			path = URI_FILEROOT + path;
			byte[] uriBytes = Converter.wcsToMbcs (path, true);

			if (WebKitGTK.webkit_get_minor_version() >= 6) {
				WebKitGTK.webkit_download_set_allow_overwrite (webKitDownload, true);
			}
			WebKitGTK.webkit_download_set_destination (webKitDownload, uriBytes);
			((WebKit)browser.webBrowser).openDownloadWindow(webKitDownload, fileName);
		}
	}
	return 0;
}

static long webkit_download_finished(long download) {
	// A failed signal may have been recorded prior. The finish signal is now being called.
	if (!webKitDownloadStatus.containsKey(new LONG(download))) {
		webKitDownloadStatus.put(new LONG(download), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_FINISHED);
	}
	return 0;
}

static long webkit_download_failed(long download) {
	// A cancel may have been issued resulting in this signal call. Preserve the original cause.
	if (!webKitDownloadStatus.containsKey(new LONG(download))) {
		webKitDownloadStatus.put(new LONG(download), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_ERROR);
	}
	return 0;
}

/**
 * WebkitWebView mouse-target-changed
 * - void user_function (WebKitWebView *web_view, WebKitHitTestResult *hit_test_result, guint modifiers, gpointer user_data)
 * - https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView-mouse-target-changed
 * */
long webkit_mouse_target_changed (long web_view, long hit_test_result, long modifiers) {
	if (WebKitGTK.webkit_hit_test_result_context_is_link(hit_test_result)){
		long uri = WebKitGTK.webkit_hit_test_result_get_link_uri(hit_test_result);
		long title = WebKitGTK.webkit_hit_test_result_get_link_title(hit_test_result);
		return webkit_hovering_over_link(web_view, title, uri);
	}

	return 0;
}

/**
 * Webkit2: WebkitWebView mouse-target-change
 * - Normally this signal is called for many different events, e.g hoveing over an image.
 *   But in our case, in webkit_mouse_target_changed() we filter out everything except mouse_over_link events.
 *
 *   Since there is no return value, it is safe to run asynchronously.
 */
long webkit_hovering_over_link (long web_view, long title, long uri) {
	if (uri != 0) {
		int length = C.strlen (uri);
		byte[] bytes = new byte[length];
		C.memmove (bytes, uri, length);
		String text = new String (Converter.mbcsToWcs (bytes));
		StatusTextEvent event = new StatusTextEvent (browser);
		event.display = browser.getDisplay ();
		event.widget = browser;
		event.text = text;
		Runnable fireStatusTextListener = () -> {
			if (browser.isDisposed() || statusTextListeners == null) return;
			for (int i = 0; i < statusTextListeners.length; i++) {
				statusTextListeners[i].changed (event);
			}
		};
		browser.getDisplay().asyncExec(fireStatusTextListener);
	}
	return 0;
}

long webkit_decide_policy (long web_view, long decision, int decision_type, long user_data) {
	switch (decision_type) {
	case WebKitGTK.WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
		long request = WebKitGTK. webkit_navigation_policy_decision_get_request(decision);
		if (request == 0){
			return 0;
		}
		long uri = WebKitGTK.webkit_uri_request_get_uri (request);
		String url = getString(uri);
		/*
		* If the URI indicates that the page is being rendered from memory
		* (via setText()) then set it to about:blank to be consistent with IE.
		*/
		if (url.equals (URI_FILEROOT)) {
			url = ABOUT_BLANK;
		} else {
			int length = URI_FILEROOT.length ();
			if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
				url = ABOUT_BLANK + url.substring (length);
			}
		}

		LocationEvent newEvent = new LocationEvent (browser);
		newEvent.display = browser.getDisplay ();
		newEvent.widget = browser;
		newEvent.location = url;
		newEvent.doit = true;

		try {
			nonBlockingEvaluate++;
			if (locationListeners != null) {
				for (int i = 0; i < locationListeners.length; i++) {
					locationListeners[i].changing (newEvent);
				}
			}
		} catch (Exception e) {
			throw e;
		} finally {
			nonBlockingEvaluate--;
		}

		if (newEvent.doit && !browser.isDisposed ()) {
			if (jsEnabled != jsEnabledOnNextPage) {
				jsEnabled = jsEnabledOnNextPage;
				webkit_settings_set(WebKitGTK.enable_javascript, jsEnabled ? 1 : 0);
			}
		}
		if(!newEvent.doit){
			WebKitGTK.webkit_policy_decision_ignore (decision);
		}
		break;
	case WebKitGTK.WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
		break;
	case WebKitGTK.WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
		long response = WebKitGTK.webkit_response_policy_decision_get_response(decision);
		long mime_type = WebKitGTK.webkit_uri_response_get_mime_type(response);
		boolean canShow = WebKitGTK.webkit_web_view_can_show_mime_type (webView, mime_type) != 0;
		if (!canShow) {
			WebKitGTK.webkit_policy_decision_download (decision);
			return 1;
		}
		break;
	default:
		/* Making no decision results in webkit_policy_decision_use(). */
		return 0;
	}
	return 0;
}

long webkit_load_changed (long web_view, int status, long user_data) {
	switch (status) {
		case WebKitGTK.WEBKIT2_LOAD_COMMITTED: {
			long uri = WebKitGTK.webkit_web_view_get_uri (webView);
			return handleLoadCommitted (uri, true);
		}
		case WebKitGTK.WEBKIT2_LOAD_FINISHED: {
			if (firstLoad) {
				GtkAllocation allocation = new GtkAllocation ();
				GTK.gtk_widget_get_allocation(browser.handle, allocation);
				GTK.gtk_widget_size_allocate(browser.handle, allocation);
				firstLoad = false;
			}

			fireProgressCompletedEvent();

			/*
			 * If there is a pending TLS error, handle it by prompting the user for input.
			 * This is done by popping up a message box and asking if the user would like
			 * ignore warnings for this host. Clicking yes will do so, clicking no will
			 * load the previous page.
			 *
			 *  Not applicable if the ignoreTls flag has been set. See bug 531341.
			 */
			if (tlsError && !ignoreTls) {
				tlsError = false;
				String javaHost = tlsErrorUri.getHost();
				MessageBox prompt = new MessageBox (browser.getShell(), SWT.YES | SWT.NO);
				prompt.setText(SWT.getMessage("SWT_InvalidCert_Title"));
				String specific = tlsErrorType.isEmpty() ? "\n\n" : "\n\n" + tlsErrorType + "\n\n";
				String message = SWT.getMessage("SWT_InvalidCert_Message", new Object[] {javaHost}) +
						specific + SWT.getMessage("SWT_InvalidCert_Connect");
				prompt.setMessage(message);
				int result = prompt.open();
				if (result == SWT.YES) {
					long webkitcontext = WebKitGTK.webkit_web_view_get_context(web_view);
					if (javaHost != null) {
						byte [] host = Converter.javaStringToCString(javaHost);
						WebKitGTK.webkit_web_context_allow_tls_certificate_for_host(webkitcontext, tlsErrorCertificate, host);
						WebKitGTK.webkit_web_view_reload (web_view);
					} else {
						System.err.println("***ERROR: Unable to parse host from URI!");
					}
				} else {
					back();
				}
				// De-reference Webkit certificate so it can be freed
				if (tlsErrorCertificate != 0) {
					OS.g_object_unref (tlsErrorCertificate);
					tlsErrorCertificate = 0;
				}
			}

			return 0;
		}
	}
	return 0;
}

/**
 * Called in cases where a web page failed to load due to TLS errors
 * (self-signed certificates, as an example).
 */
long webkit_load_failed_tls (long web_view, long failing_uri, long certificate, long error) {
	if (!ignoreTls) {
		// Set tlsError flag so that the user can be prompted once this "bad" page has finished loading
		tlsError = true;
		OS.g_object_ref(certificate);
		tlsErrorCertificate = certificate;
		convertUri (failing_uri);
		switch ((int)error) {
			case WebKitGTK.G_TLS_CERTIFICATE_UNKNOWN_CA: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_UnknownCA");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_BAD_IDENTITY: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_BadIdentity");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_NOT_ACTIVATED: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_NotActivated");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_EXPIRED: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_Expired");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_REVOKED: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_Revoked");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_INSECURE: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_Insecure");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_GENERIC_ERROR: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_GenericError");
				break;
			}
			case WebKitGTK.G_TLS_CERTIFICATE_VALIDATE_ALL: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_ValidateAll");
				break;
			}
			default: {
				tlsErrorType = SWT.getMessage("SWT_InvalidCert_GenericError");
				break;
			}
		}
	}
	return 0;
}

/**
 * Converts a WebKit URI into a Java URI object.
 *
 * @param webkitUri a long pointing to the URI in C string form (gchar *)
 * @throws URISyntaxException if the string violates RFC 2396, or is otherwise
 * malformed
 */
void convertUri (long webkitUri) {
	try {
		tlsErrorUriString = Converter.cCharPtrToJavaString(webkitUri, false);
		tlsErrorUri = new URI (tlsErrorUriString);
	} catch (URISyntaxException e) {
		System.err.println("***ERROR: Malformed URI from WebKit!");
		return;
	}
}

/**
 * Triggered by a change in property. (both gdouble[0,1])
 * Webkit2: WebkitWebview notify::estimated-load-progress
 *  https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#WebKitWebView--estimated-load-progress
 *
 *  No return value required. Thus safe to run asynchronously.
 */
long webkit_notify_progress (long web_view, long pspec) {
	ProgressEvent event = new ProgressEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	double progress = 0;
	progress = WebKitGTK.webkit_web_view_get_estimated_load_progress (webView);
	event.current = (int) (progress * MAX_PROGRESS);
	event.total = MAX_PROGRESS;
	Runnable fireProgressChangedEvents = () -> {
		if (browser.isDisposed() || progressListeners == null) return;
		for (int i = 0; i < progressListeners.length; i++) {
			progressListeners[i].changed (event);
		}
	};
	browser.getDisplay().asyncExec(fireProgressChangedEvents);
	return 0;
}

/**
 * Triggerd by webkit's 'notify::title' signal and forwarded to this function.
 * The signal doesn't have documentation (2.15.4), but is mentioned here:
 * https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-get-title
 *
 * It doesn't look it would require a return value, so running in asyncExec should be fine.
 */
long webkit_notify_title (long web_view, long pspec) {
	long title = WebKitGTK.webkit_web_view_get_title (webView);
	String titleString;
	if (title == 0) {
		titleString = ""; //$NON-NLS-1$
	} else {
		int length = C.strlen (title);
		byte[] bytes = new byte[length];
		C.memmove (bytes, title, length);
		titleString = new String (Converter.mbcsToWcs (bytes));
	}
	TitleEvent event = new TitleEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	event.title = titleString;
	Runnable fireTitleListener = () -> {
		for (int i = 0; i < titleListeners.length; i++) {
			titleListeners[i].changed (event);
		}
	};
	browser.getDisplay().asyncExec(fireTitleListener);
	return 0;
}

long webkit_context_menu (long web_view, long context_menu, long eventXXX, long hit_test_result) {
	Point pt = browser.getDisplay ().getCursorLocation (); // might break on Wayland? Wouldn't hurt to verify.
	Event event = new Event ();
	event.x = pt.x;
	event.y = pt.y;
	browser.notifyListeners (SWT.MenuDetect, event);
	if (!event.doit) {
		// Do not display the menu
		return 1;
	}

	Menu menu = browser.getMenu ();
	if (menu != null && !menu.isDisposed ()) {
		if (pt.x != event.x || pt.y != event.y) {
			menu.setLocation (event.x, event.y);
		}
		menu.setVisible (true);
		// Do not display the webkit menu
		return 1;
	}
	return 0;
}

private void addRequestHeaders(long requestHeaders, String[] headers){
	for (int i = 0; i < headers.length; i++) {
		String current = headers[i];
		if (current != null) {
			int index = current.indexOf (':');
			if (index != -1) {
				String key = current.substring (0, index).trim ();
				String value = current.substring (index + 1).trim ();
				if (key.length () > 0 && value.length () > 0) {
					byte[] nameBytes = Converter.wcsToMbcs (key, true);
					byte[] valueBytes = Converter.wcsToMbcs (value, true);
					WebKitGTK.soup_message_headers_append (requestHeaders, nameBytes, valueBytes);
				}
			}
		}
	}

}

/**
 * Emitted after "create" on the newly created WebKitWebView when it should be displayed to the user.
 * Webkit2 signal: ready-to-show
 *   https://webkitgtk.org/reference/webkitgtk/unstable/webkitgtk-webkitwebview.html#WebKitWebView-web-view-ready
 * Note in webkit2, no return value has to be provided in callback.
 */
long webkit_web_view_ready (long web_view) {
	WindowEvent newEvent = new WindowEvent (browser);
	newEvent.display = browser.getDisplay ();
	newEvent.widget = browser;

	long properties = WebKitGTK.webkit_web_view_get_window_properties(webView);
	newEvent.addressBar = webkit_settings_get(properties, WebKitGTK.locationbar_visible) != 0;
	newEvent.menuBar = webkit_settings_get(properties, WebKitGTK.menubar_visible) != 0;
	newEvent.statusBar = webkit_settings_get(properties, WebKitGTK.statusbar_visible) != 0;
	newEvent.toolBar = webkit_settings_get(properties, WebKitGTK.toolbar_visible) != 0;

	GdkRectangle rect = new GdkRectangle();
	WebKitGTK.webkit_window_properties_get_geometry(properties, rect);
	newEvent.location = new Point(Math.max(0, rect.x),Math.max(0, rect.y));

	int width = rect.width;
	int height = rect.height;
	if (height == 100 && width == 100) {
		// On Webkit2, if no height/width is specified, then minimum (which is 100) is allocated to popus.
		// This makes popups very small.
		// For better cross-platform consistency (Win/Cocoa/Gtk), we give more reasonable defaults (2/3 the size of a screen).
		Rectangle primaryMonitorBounds = browser.getDisplay ().getPrimaryMonitor().getBounds();
		height = (int) (primaryMonitorBounds.height * 0.66);
		width = (int) (primaryMonitorBounds.width * 0.66);
	}
	newEvent.size = new Point(width, height);

	Runnable fireVisibilityListeners = () -> {
		if (browser.isDisposed()) return;
		for (int i = 0; i < visibilityWindowListeners.length; i++) {
			visibilityWindowListeners[i].show (newEvent);
		}
	};
	// Postpone execution of listener, to avoid deadlocks in case evaluate() is
	// called in the listener while another signal is being handled. See bug 512001.
	// evaluate() can safely be called in this listener with no adverse effects.
	browser.getDisplay().asyncExec(fireVisibilityListeners);
	return 0;
}

/**
 * @return An integer value for the property is returned. For boolean settings, 0 indicates false,
 * 1 indicates true. -1= is error.
 */
private int webkit_settings_get(byte [] property) {
	if (webView == 0) { // already disposed.
		return -1; // error.
	}
	long settings = WebKitGTK.webkit_web_view_get_settings (webView);
	return webkit_settings_get(settings, property);
}

/** @return An integer value for the property is returned. For boolean settings, 0 indicates false, 1 indicates true */
private int webkit_settings_get(long settings, byte[] property) {
	int[] result = new int[1];
	OS.g_object_get (settings, property, result, 0);
	return result[0];
}

private void webkit_settings_set(byte [] property, int value) {
	if (webView == 0) { // already disposed.
		return;
	}
	long settings = WebKitGTK.webkit_web_view_get_settings (webView);
	OS.g_object_set(settings, property, value, 0);
}

long convertToJS (long ctx, Object value) {
	if (value == null) {
		return WebKitGTK.JSValueMakeUndefined (ctx);
	}
	if (value instanceof String) {
		byte[] bytes = ((String)value + '\0').getBytes (StandardCharsets.UTF_8); //$NON-NLS-1$
		long stringRef = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
		long result = WebKitGTK.JSValueMakeString (ctx, stringRef);
		WebKitGTK.JSStringRelease (stringRef);
		return result;
	}
	if (value instanceof Boolean) {
		return WebKitGTK.JSValueMakeBoolean (ctx, ((Boolean)value).booleanValue () ? 1 : 0);
	}
	if (value instanceof Number) {
		return WebKitGTK.JSValueMakeNumber (ctx, ((Number)value).doubleValue ());
	}
	if (value instanceof Object[]) {
		Object[] arrayValue = (Object[]) value;
		int length = arrayValue.length;
		long [] arguments = new long [length];
		for (int i = 0; i < length; i++) {
			Object javaObject = arrayValue[i];
			long jsObject = convertToJS (ctx, javaObject);
			arguments[i] = jsObject;
		}
		return WebKitGTK.JSObjectMakeArray (ctx, length, arguments, null);
	}
	SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
	return 0;
}

static Object convertToJava (long ctx, long value) {
	int type = WebKitGTK.JSValueGetType (ctx, value);
	switch (type) {
		case WebKitGTK.kJSTypeBoolean: {
			int result = (int)WebKitGTK.JSValueToNumber (ctx, value, null);
			return result != 0;
		}
		case WebKitGTK.kJSTypeNumber: {
			double result = WebKitGTK.JSValueToNumber (ctx, value, null);
			return Double.valueOf(result);
		}
		case WebKitGTK.kJSTypeString: {
			long string = WebKitGTK.JSValueToStringCopy (ctx, value, null);
			if (string == 0) return ""; //$NON-NLS-1$
			long length = WebKitGTK.JSStringGetMaximumUTF8CStringSize (string);
			byte[] bytes = new byte[(int)length];
			length = WebKitGTK.JSStringGetUTF8CString (string, bytes, length);
			WebKitGTK.JSStringRelease (string);
			/* length-1 is needed below to exclude the terminator character */
			return new String (bytes, 0, (int)length - 1, StandardCharsets.UTF_8);
		}
		case WebKitGTK.kJSTypeNull:
			// FALL THROUGH
		case WebKitGTK.kJSTypeUndefined: return null;
		case WebKitGTK.kJSTypeObject: {
			byte[] bytes = (PROPERTY_LENGTH + '\0').getBytes (StandardCharsets.UTF_8); //$NON-NLS-1$
			long propertyName = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
			long valuePtr = WebKitGTK.JSObjectGetProperty (ctx, value, propertyName, null);
			WebKitGTK.JSStringRelease (propertyName);
			type = WebKitGTK.JSValueGetType (ctx, valuePtr);
			if (type == WebKitGTK.kJSTypeNumber) {
				int length = (int)WebKitGTK.JSValueToNumber (ctx, valuePtr, null);
				Object[] result = new Object[length];
				for (int i = 0; i < length; i++) {
					long current = WebKitGTK.JSObjectGetPropertyAtIndex (ctx, value, i, null);
					if (current != 0) {
						result[i] = convertToJava (ctx, current);
					}
				}
				return result;
			}
		}
	}
	SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	return null;
}

}
