You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/04/26 05:39:41 UTC

[20/27] fdb with worker support

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionIsolateStatus.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionIsolateStatus.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionIsolateStatus.java
new file mode 100644
index 0000000..96700cb
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionIsolateStatus.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.concrete;
+
+public class PlayerSessionIsolateStatus {
+
+	/**
+	 * Corresponding to playersession::m_isHalted, but for isolate.
+	 */
+	public boolean m_isHalted;
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionManager.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionManager.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionManager.java
new file mode 100644
index 0000000..8f8f755
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/PlayerSessionManager.java
@@ -0,0 +1,1211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.concrete;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import flash.localization.LocalizationManager;
+import flash.tools.debugger.AIRLaunchInfo;
+import flash.tools.debugger.DebuggerLocalizer;
+import flash.tools.debugger.DefaultDebuggerCallbacks;
+import flash.tools.debugger.IDebuggerCallbacks;
+import flash.tools.debugger.ILaunchNotification;
+import flash.tools.debugger.ILauncher;
+import flash.tools.debugger.IProgress;
+import flash.tools.debugger.Player;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.SessionManager2;
+import flash.tools.debugger.VersionException;
+import flash.util.URLHelper;
+
+public class PlayerSessionManager implements SessionManager2
+{
+	private ServerSocket m_serverSocket;
+	private HashMap<String, Object> m_prefs;
+	private IDebuggerCallbacks m_debuggerCallbacks;
+	private static LocalizationManager m_localizationManager;
+	private Socket m_connectSocket;
+	private boolean m_cancelConnect;
+	
+	static
+	{
+        // set up for localizing messages
+        m_localizationManager = new LocalizationManager();
+        m_localizationManager.addLocalizer( new DebuggerLocalizer("flash.tools.debugger.concrete.djapi.") ); //$NON-NLS-1$
+	}
+
+	public PlayerSessionManager()
+	{
+		m_debuggerCallbacks = new DefaultDebuggerCallbacks();
+
+		m_serverSocket = null;
+		m_connectSocket = null;
+		m_cancelConnect = false;
+		m_prefs = new HashMap<String, Object>();
+
+		// manager
+		setPreference(PREF_ACCEPT_TIMEOUT, 120000); // 2 minutes
+		setPreference(PREF_URI_MODIFICATION, 1);
+		setPreference(PREF_CONNECT_TIMEOUT, 120000); // 2 minutes
+		setPreference(PREF_CONNECT_WAIT_INTERVAL, 250); // 0.25 seconds
+		setPreference(PREF_CONNECT_RETRY_ATTEMPTS, -1); // Retry till timeout
+		
+		// session
+
+		// response to requests
+		setPreference(PREF_SOCKET_TIMEOUT, -1); // no timeout by default
+		setPreference(PREF_RESPONSE_TIMEOUT, 750); // 0.75s
+		setPreference(PREF_CONTEXT_RESPONSE_TIMEOUT, 1000); // 1s
+		setPreference(PREF_GETVAR_RESPONSE_TIMEOUT, 1500); // 1.5s
+		setPreference(PREF_SETVAR_RESPONSE_TIMEOUT, 5000); // 5s
+		setPreference(PREF_SWFSWD_LOAD_TIMEOUT, 5000);  // 5s
+
+		// wait for a suspend to occur after a halt
+		setPreference(PREF_SUSPEND_WAIT, 7000);
+
+		// invoke getters by default
+		setPreference(PREF_INVOKE_GETTERS, 1);
+
+		// hierarchical variables view
+		setPreference(PREF_HIERARCHICAL_VARIABLES, 0);
+	}
+
+	/**
+	 * Set preference 
+	 * If an invalid preference is passed, it will be silently ignored.
+	 */
+	public void			setPreference(String pref, int value)	{ m_prefs.put(pref, new Integer(value)); }
+	public void			setPreference(String pref, String value){ m_prefs.put(pref, value);	}
+	public Set<String>	keySet()								{ return m_prefs.keySet(); }
+	public Object		getPreferenceAsObject(String pref)		{ return m_prefs.get(pref); }
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#getPreference(java.lang.String)
+	 */
+	public int getPreference(String pref)
+	{
+		int val = 0;
+		Integer i = (Integer)m_prefs.get(pref);
+		if (i == null)
+			throw new NullPointerException();
+		val = i.intValue();
+		return val;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#startListening()
+	 */
+	public void startListening() throws IOException 
+	{
+		if (m_serverSocket == null)
+			m_serverSocket = new ServerSocket(DProtocol.DEBUG_PORT);
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#stopListening()
+	 */
+	public void stopListening() throws IOException
+	{
+		if (m_serverSocket != null)
+		{
+			m_serverSocket.close();
+			m_serverSocket = null;
+		}
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#isListening()
+	 */
+	public boolean isListening()
+	{
+		return (m_serverSocket == null) ? false : true;
+	}
+
+	private class LaunchInfo
+	{
+		private String m_uri;
+
+		public LaunchInfo(String uri)
+		{
+			m_uri = uri;
+		}
+
+		public boolean isAbout()
+		{
+			return m_uri.startsWith("about:"); //$NON-NLS-1$
+		}
+
+		public boolean isHttpOrAbout()
+		{
+			return m_uri.startsWith("http:") || m_uri.startsWith("https:") || isAbout(); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		public boolean isWebPage()
+		{
+			return isHttpOrAbout() || m_uri.endsWith(".htm") || m_uri.endsWith(".html"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		public boolean isWebBrowserNativeLaunch()
+		{
+			return isWebPage() && (m_debuggerCallbacks.getHttpExe() != null);
+		}
+
+		public boolean isPlayerNativeLaunch()
+		{
+			return m_uri.length() > 0 && !isWebPage() && (m_debuggerCallbacks.getPlayerExe() != null);
+		}
+		
+		public boolean isAIRLaunch()
+		{
+			return m_uri.startsWith("file:") && (m_uri.endsWith("-app.xml") || m_uri.endsWith("application.xml")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+
+	private enum OS {
+		Mac,
+		Windows,
+		Unix
+	}
+
+	private OS getOS()
+	{
+		String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
+		if (osName.startsWith("mac os x")) //$NON-NLS-1$
+		{
+			return OS.Mac;
+		}
+		else if (osName.startsWith("windows")) //$NON-NLS-1$
+		{
+			return OS.Windows;
+		}
+		else
+		{
+			return OS.Unix;
+		}
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#launch(java.lang.String, flash.tools.debugger.AIRLaunchInfo, boolean, flash.tools.debugger.IProgress)
+	 */
+	public Session launch(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging, IProgress waitReporter, ILaunchNotification launchNotification) throws IOException
+	{
+		String[] launchCommand = getLaunchCommand(uri, airLaunchInfo,forDebugging);
+
+		// create the process and attach a thread to watch it during our accept phase
+		Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand);
+
+		ProcessListener processListener = startProcessListener(airLaunchInfo,forDebugging, launchNotification, launchCommand, proc,false); 
+		PlayerSession session = null;
+
+		if (forDebugging)
+		{
+			session = waitForConnection(uri, airLaunchInfo, waitReporter, proc, processListener);
+		}
+
+		return session;
+	}
+
+	private PlayerSession waitForConnection(String uri,
+			AIRLaunchInfo airLaunchInfo, IProgress waitReporter, Process proc,
+			ProcessListener pl) throws IOException {
+		/* now wait for a connection */
+		PlayerSession session = (PlayerSession)accept(pl, waitReporter);
+		session.setProcess(proc);
+		session.setLaunchUrl(uri);
+		session.setAIRLaunchInfo(airLaunchInfo);
+		return session;
+	}
+
+	/**
+	 * Tweaks the launch URI if necessary, e.g. may append "?debug=true"
+	 */
+	private String tweakNativeLaunchUri(String uri, boolean forDebugging,
+			LaunchInfo launchInfo) throws IOException, FileNotFoundException
+	{
+		// first let's see if it's an HTTP URL or not
+		if (launchInfo.isHttpOrAbout())
+		{
+			boolean modify = (getPreference(PREF_URI_MODIFICATION) != 0);
+
+			if (modify && forDebugging && !launchInfo.isAbout())
+			{
+				// escape spaces if we have any
+				uri = URLHelper.escapeSpace(uri);
+
+		        // be sure that ?debug=true is included in query string
+				URLHelper urlHelper = new URLHelper(uri);
+				Map<String, String> params = urlHelper.getParameterMap();
+				params.put("debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+				urlHelper.setParameterMap(params);
+
+				uri = urlHelper.getURL();
+		    }
+		}
+		else
+		{
+			// ok, its not an http: type request therefore we should be able to see
+			// it on the file system, right?  If not then it's probably not valid
+			File f = null;
+			if (uri.startsWith("file:")) //$NON-NLS-1$
+			{
+				try
+				{
+					f = new File(new URI(uri));
+				}
+				catch (URISyntaxException e)
+				{
+					IOException ioe = new IOException(e.getMessage());
+					ioe.initCause(e);
+					throw ioe;
+				}
+			}
+			else
+			{
+				f = new File(uri);
+			}
+
+			if (f != null && f.exists()) {
+				// Do not use getCanonicalPath() -- see FB-24595
+				uri = f.getAbsolutePath();
+			} else {
+				throw new FileNotFoundException(uri);
+			}
+		}
+
+		return uri;
+	}
+
+	/**
+	 * Gets the arguments needed for launching a swf that needs to run
+	 * in a web browser or the standalone player.
+	 */
+	private String[] getFlashLaunchArgs(String uri, LaunchInfo launchInfo) throws FileNotFoundException
+	{
+		String[] launchCommand;
+
+		OS os = getOS();
+
+		/**
+		 * Various ways to launch this stupid thing.  If we have the exe
+		 * values for the player, then we can launch it directly, monitor
+		 * it and kill it when we die; otherwise we launch it through
+		 * a command shell (cmd.exe, open, or bash) and our Process object
+		 * dies right away since it spawned another process to run the
+		 * Player within.
+		 */
+		if (os == OS.Mac)
+		{
+			if (launchInfo.isWebBrowserNativeLaunch())
+			{
+				File httpExe = m_debuggerCallbacks.getHttpExe();
+				String[] customParams = m_debuggerCallbacks.getBrowserParameters(uri);
+				if (customParams == null) {
+					launchCommand = new String[] { "/usr/bin/open", "-a", httpExe.toString(), uri }; //$NON-NLS-1$ //$NON-NLS-2$
+				}
+				else {
+					final int prependLen = 4;
+					launchCommand = new String[customParams.length + prependLen ];
+					launchCommand[0] = "/usr/bin/open"; //$NON-NLS-1$
+					launchCommand[1] = "-a"; //$NON-NLS-1$
+					launchCommand[2] = httpExe.toString();
+					launchCommand[3] = "--args"; //$NON-NLS-1$
+					for ( int i = 0; i < customParams.length; i++) {
+						launchCommand[i + prependLen] = customParams[i];
+					}
+				}
+			}
+			else if (launchInfo.isPlayerNativeLaunch())
+			{
+				File playerExe = m_debuggerCallbacks.getPlayerExe();
+				launchCommand = new String[] { "/usr/bin/open", "-a", playerExe.toString(), uri }; //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			else
+			{
+				launchCommand = new String[] { "/usr/bin/open", uri }; //$NON-NLS-1$
+			}
+		}
+		else // Windows or *nix
+		{
+			if (launchInfo.isWebBrowserNativeLaunch())
+			{
+				File httpExe = m_debuggerCallbacks.getHttpExe();
+				String[] customParams = m_debuggerCallbacks.getBrowserParameters(uri);
+				if (customParams == null) {
+					if (os == OS.Windows)
+						launchCommand = getWindowsBrowserLaunchArgs(httpExe, uri);
+					else
+						launchCommand = new String[] { httpExe.toString(), uri };
+				}
+				else {
+					final int prependLen = 1;
+					launchCommand = new String[customParams.length + prependLen];
+					launchCommand[0] = httpExe.toString();
+					for ( int i = 0; i < customParams.length; i++) {
+						launchCommand[i + prependLen] = customParams[i];
+					}
+				}
+			}
+			else if (launchInfo.isPlayerNativeLaunch())
+			{
+				File playerExe = m_debuggerCallbacks.getPlayerExe();
+				launchCommand = new String[] { playerExe.toString(), uri };
+			}
+			else
+			{
+				if (os == OS.Windows)
+				{
+					// We must quote all ampersands in the URL; if we don't, then
+					// cmd.exe will interpret the ampersand as a command separator.
+					uri = uri.replaceAll("&", "\"&\""); //$NON-NLS-1$ //$NON-NLS-2$
+
+					launchCommand = new String[] { "cmd", "/c", "start", uri }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				}
+				else
+				{
+					String exeName;
+					if (launchInfo.isWebPage())
+						exeName = m_debuggerCallbacks.getHttpExeName();
+					else
+						exeName = m_debuggerCallbacks.getPlayerExeName();
+					throw new FileNotFoundException(exeName);
+				}
+			}
+		}
+		return launchCommand;
+	}
+
+	
+
+	/**
+	 * Gets the arguments needed for launching a web browser on Windows.
+	 */
+	private String[] getWindowsBrowserLaunchArgs(File httpExe, String uri)
+	{
+		if (httpExe.getName().equalsIgnoreCase("chrome.exe")) //$NON-NLS-1$
+		{
+			// FB-16779: Adding "--disable-hang-monitor" to prevent Chrome
+			// from warning us that a plug-inappears to be hung; it does
+			// that when the user hits a breakpoint.
+			return new String[] { httpExe.toString(), "--disable-hang-monitor", uri }; //$NON-NLS-1$
+		}
+		else if (httpExe.getName().equalsIgnoreCase("iexplore.exe")) //$NON-NLS-1$
+		{
+			boolean isIE8 = false;
+
+			try
+			{
+				int[] ieVersion = m_debuggerCallbacks.getAppVersion(httpExe);
+				if (ieVersion != null)
+					isIE8 = (ieVersion[0] >= 8);
+			} catch (IOException e) {
+				// ignore
+			}
+
+			if (isIE8)
+			{
+				// FB-22107: Tell IE to keep using the new process we are
+				// launching, rather than merging the new process into the
+				// old one.  This allows us to terminate the new IE
+				// debugging session.
+				return new String[] { httpExe.toString(), "-noframemerging", uri }; //$NON-NLS-1$
+			}
+		}
+
+		return new String[] { httpExe.toString(), uri };
+	}
+
+	/**
+	 * Gets the arguments needed for launching a swf that needs to run
+	 * in AIR.
+	 */
+	private String[] getAIRLaunchArgs(String uri, AIRLaunchInfo airLaunchInfo)
+			throws IOException
+	{
+		List<String> cmdList = new LinkedList<String>();
+
+		cmdList.add(airLaunchInfo.airDebugLauncher.getPath());
+
+		if (airLaunchInfo.airRuntimeDir != null)
+		{
+			cmdList.add("-runtime"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.airRuntimeDir.getPath());
+		}
+
+		if (airLaunchInfo.airSecurityPolicy != null)
+		{
+			cmdList.add("-security-policy"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.airSecurityPolicy.getPath());
+		}
+
+		if (airLaunchInfo.airPublisherID != null && airLaunchInfo.airPublisherID.length() > 0)
+		{
+			cmdList.add("-pubid"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.airPublisherID);
+		}
+
+		if (airLaunchInfo.profile != null && airLaunchInfo.profile.length() > 0)
+		{
+			cmdList.add("-profile"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.profile);
+		}
+		
+		if (airLaunchInfo.screenSize != null && airLaunchInfo.screenSize.length() > 0)
+		{
+			cmdList.add("-screensize"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.screenSize);
+		}
+		
+		if (airLaunchInfo.dpi > 0)
+		{
+			//TODO: this is apparently only going to be used in AIR 2.5.
+			//Figure out permanent solution when AIR 3.0 comes along.
+			cmdList.add("-XscreenDPI"); //$NON-NLS-1$
+			cmdList.add(String.valueOf(airLaunchInfo.dpi));
+		}
+		
+		if (airLaunchInfo.versionPlatform != null && airLaunchInfo.versionPlatform.length() > 0)
+		{
+			cmdList.add("-XversionPlatform"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.versionPlatform);
+		}
+		
+		if (airLaunchInfo.extDir != null && airLaunchInfo.extDir.length() > 0) {
+			cmdList.add("-extdir"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.extDir);
+		}
+		
+		if (airLaunchInfo.deviceExtDir != null && airLaunchInfo.deviceExtDir.length() > 0) {
+			cmdList.add("-XdeviceExtDir"); //$NON-NLS-1$
+			cmdList.add(airLaunchInfo.deviceExtDir);
+		}
+		
+		// If it's a "file:" URL, then pass the actual filename; otherwise, use the URL
+		// ok, its not an http: type request therefore we should be able to see
+		// it on the file system, right?  If not then it's probably not valid
+		File f = null;
+		if (uri.startsWith("file:")) //$NON-NLS-1$
+		{
+			try
+			{
+				f = new File(new URI(uri));
+				cmdList.add(f.getPath());
+			}
+			catch (URISyntaxException e)
+			{
+				IOException ioe = new IOException(e.getMessage());
+				ioe.initCause(e);
+				throw ioe;
+			}
+		}
+		else
+		{
+			cmdList.add(uri);
+		}
+
+		if (airLaunchInfo.applicationContentRootDir != null)
+		{
+			cmdList.add(airLaunchInfo.applicationContentRootDir.getAbsolutePath());
+		}
+
+		List<String> args = null;
+		if (airLaunchInfo.applicationArgumentsArray != null)
+		{
+			args = Arrays.asList(airLaunchInfo.applicationArgumentsArray);
+		}
+		else if (airLaunchInfo.applicationArguments != null)
+		{
+			args = splitArgs(airLaunchInfo.applicationArguments);
+		}
+
+		if (args != null && args.size() > 0)
+		{
+			cmdList.add("--"); //$NON-NLS-1$
+			cmdList.addAll(args);
+		}
+
+		return cmdList.toArray(new String[cmdList.size()]);
+	}
+
+	/**
+	 * This is annoying: We must duplicate the operating system's behavior
+	 * with regard to splitting arguments.
+	 * 
+	 * @param arguments A single string of arguments that are intended to
+	 * be passed to an AIR application.  The tricky part is that some
+	 * of the arguments may be quoted, and if they are, then the quoting
+	 * will be in a way that is specific to the current platform.  For
+	 * example, on Windows, strings are quoted with the double-quote character
+	 * ("); on Mac and Unix, strings can be quoted with either double-quote
+	 * or single-quote.
+	 * @return The equivalent
+	 */
+	private List<String> splitArgs(String arguments)
+	{
+		List<String> retval = new ArrayList<String>();
+
+		arguments = arguments.trim();
+
+		// Windows quotes only with double-quote; Mac and Unix also allow single-quote.
+		boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("win"); //$NON-NLS-1$ //$NON-NLS-2$
+		boolean isMacOrUnix = !isWindows;
+
+		int i=0;
+		while (i<arguments.length()) {
+			char ch = arguments.charAt(i);
+			if (ch == ' ' || ch == '\t') {
+				// keep looping
+				i++;
+			} else if (ch == '"' || (isMacOrUnix && ch == '\'')) {
+				char quote = ch;
+				int nextQuote = arguments.indexOf(quote, i+1);
+				if (nextQuote == -1) {
+					retval.add(arguments.substring(i+1));
+					return retval;
+				} else {
+					retval.add(arguments.substring(i+1, nextQuote));
+					i = nextQuote+1;
+				}
+			} else {
+				int startPos = i;
+				while (i<arguments.length()) {
+					ch = arguments.charAt(i);
+					if (ch == ' ' || ch == '\t') {
+						break;
+					}
+					i++;
+				}
+				retval.add(arguments.substring(startPos, i));
+			}
+		}
+
+		return retval;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#playerForUri(java.lang.String, flash.tools.debugger.AIRLaunchInfo)
+	 */
+	public Player playerForUri(String url, AIRLaunchInfo airLaunchInfo)
+	{
+		LaunchInfo launchInfo = new LaunchInfo(url);
+
+		if (airLaunchInfo != null)
+		{
+			return new AIRPlayer(airLaunchInfo.airDebugLauncher);
+		}
+		else if (launchInfo.isAIRLaunch())
+		{
+			return new AIRPlayer(null);
+		}
+		else
+		{
+			// Find the Netscape plugin
+			if (getOS() == OS.Mac)
+			{
+				if (!launchInfo.isWebBrowserNativeLaunch())
+				{
+					File playerExe = m_debuggerCallbacks.getPlayerExe();
+					return new StandalonePlayer(playerExe);
+				}
+				File flashPlugin = new File("/Library/Internet Plug-Ins/Flash Player.plugin"); //$NON-NLS-1$
+				return new NetscapePluginPlayer(m_debuggerCallbacks.getHttpExe(), flashPlugin);
+			}
+			else
+			{
+				if (launchInfo.isWebBrowserNativeLaunch())
+				{
+					File httpExe = m_debuggerCallbacks.getHttpExe();
+					if (httpExe.getName().equalsIgnoreCase("iexplore.exe")) //$NON-NLS-1$
+					{
+						// IE on Windows: Find the ActiveX control
+						String activeXFile = null;
+						final String registryKey = "HKEY_CLASSES_ROOT\\CLSID\\{D27CDB6E-AE6D-11cf-96B8-444553540000}\\InprocServer32";  //$NON-NLS-1$
+						//check if this is a 64-bit machine
+						boolean is64Bit = (System.getenv("ProgramFiles(x86)") != null); //$NON-NLS-1$
+						try
+						{
+							if (is64Bit) {
+								//now we have to ensure that we only query the registry
+								//that is 32 or 64-bit depending upon whether we are
+								//launching 32 or 64-bit IE.
+								if (httpExe.getCanonicalPath().contains("(x86)")) { //$NON-NLS-1$
+									activeXFile = m_debuggerCallbacks.queryWindowsRegistry(registryKey, null, 1);
+								}
+								else { 
+									activeXFile = m_debuggerCallbacks.queryWindowsRegistry(registryKey, null, 2);
+								}	
+							}
+							else {
+								activeXFile = m_debuggerCallbacks.queryWindowsRegistry(registryKey, null, 1);
+							}
+							
+						}
+						catch (IOException e)
+						{
+							// ignore
+						}
+						if (activeXFile == null)
+							return null; // we couldn't find the player
+						File file = new File(activeXFile);
+						return new ActiveXPlayer(httpExe, file);
+					}
+					else
+					{
+						// Find the Netscape plugin
+						File browserDir = httpExe.getParentFile();
+	
+						// Opera puts plugins under "program\plugins" rather than under "plugins"
+						if (httpExe.getName().equalsIgnoreCase("opera.exe")) //$NON-NLS-1$
+							browserDir = new File(browserDir, "program"); //$NON-NLS-1$
+	
+						File pluginsDir = new File(browserDir, "plugins"); //$NON-NLS-1$
+						File flashPlugin = new File(pluginsDir, "NPSWF32.dll"); // WARNING, Windows-specific //$NON-NLS-1$
+
+						// Bug FB-4691: The player is now installed via a registry key, not
+						// in the "plugins" directory.
+						//
+						// Although Mozilla does not document this, the actual behavior of
+						// the browser seems to be that it looks first in the "plugins" directory,
+						// and then, if the file is not found there, it looks in the registry.
+						// So, we mimic that behavior.
+						if (!flashPlugin.exists())
+						{
+							File pathFromRegistry = getWindowsMozillaPlayerPathFromRegistry();
+
+							if (pathFromRegistry != null)
+								flashPlugin = pathFromRegistry;
+						}
+	
+						return new NetscapePluginPlayer(httpExe, flashPlugin);
+					}
+				}
+				else if (launchInfo.isPlayerNativeLaunch())
+				{
+					File playerExe = m_debuggerCallbacks.getPlayerExe();
+					return new StandalonePlayer(playerExe);
+				}
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Look in the Windows registry for the Mozilla version of the Flash player.
+	 */
+	private File getWindowsMozillaPlayerPathFromRegistry()
+	{
+		final String KEY = "\\SOFTWARE\\MozillaPlugins\\@adobe.com/FlashPlayer"; //$NON-NLS-1$
+		final String PATH = "Path"; //$NON-NLS-1$
+
+		// According to
+		//
+		//    http://developer.mozilla.org/en/docs/Plugins:_The_first_install_problem
+		//
+		// the MozillaPlugins key can be written to either HKEY_CURRENT_USER or
+		// HKEY_LOCAL_MACHINE.  Unfortunately, as of this writing, Firefox
+		// (version 2.0.0.2) doesn't actually work that way -- it only checks
+		// HKEY_LOCAL_MACHINE, but not HKEY_CURRENT_USER.
+		//
+		// But in hopeful anticipation of a fix for that, we are going to check both
+		// locations.  On current builds, that won't do any harm, because the
+		// current Flash Player installer only writes to HKEY_LOCAL_MACHINE.  In the
+		// future, if Mozilla gets fixed and then the Flash player installer gets
+		// updated, then our code will already work correctly.
+		//
+		// Another quirk: In my opinion, it would be better for Mozilla to look first
+		// in HKEY_CURRENT_USER, and then in HKEY_LOCAL_MACHINE.  However, according to
+		//
+		//    http://developer.mozilla.org/en/docs/Installing_plugins_to_Gecko_embedding_browsers_on_Windows
+		//
+		// they don't agree with that -- they want HKEY_LOCAL_MACHINE first.
+		String[] roots = { "HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER" }; //$NON-NLS-1$ //$NON-NLS-2$
+		for (int i=0; i<roots.length; ++i)
+		{
+			try
+			{
+				String path = m_debuggerCallbacks.queryWindowsRegistry(roots[i] + KEY, PATH, 1);
+				if (path != null)
+					return  new File(path);
+			}
+			catch (IOException e)
+			{
+				// ignore
+			}
+		}
+
+		return null;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#supportsLaunch()
+	 */
+	public boolean supportsLaunch()
+	{
+		return true;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#accept(flash.tools.debugger.IProgress)
+	 */
+	public Session accept(IProgress waitReporter) throws IOException
+	{
+		return accept(null, waitReporter);
+	}
+
+	/**
+	 * A private variation on <code>accept()</code> that also has an argument
+	 * indicating that the process we are waiting for has terminated.
+	 * 
+	 * @param pl
+	 *            Optional process listener. If non-null, this is used to detect
+	 *            if a process that was launched has terminated unexpectedly.
+	 *            For example, if launch() launches adl, but adl exits, then we
+	 *            don't want to continue to wait for a socket connection.
+	 */
+	private Session accept(ProcessListener pl, IProgress waitReporter) throws IOException
+	{
+		// get timeout 
+		int timeout = getPreference(PREF_ACCEPT_TIMEOUT);
+		int totalTimeout = timeout;
+		int iterateOn = 100;
+
+		PlayerSession session = null;
+		try
+		{
+			m_serverSocket.setSoTimeout(iterateOn);
+
+			// Wait 100ms per iteration.  We have to do that so that we can report how long
+			// we have been waiting.
+			Socket s = null;
+			while (s == null && !airAppTerminated(pl))
+			{
+				try
+				{
+					s = m_serverSocket.accept();
+				}
+				catch(IOException ste)
+				{
+					timeout -= iterateOn;
+					if (timeout < 0 || m_serverSocket == null || m_serverSocket.isClosed())
+						throw ste; // we reached the timeout, or someome called stopListening()
+				}
+
+				// Tell the progress monitor we've waited a little while longer,
+				// so that the Eclipse progress bar can keep chugging along
+				if (waitReporter != null)
+					waitReporter.setProgress(totalTimeout - timeout, totalTimeout);
+			}
+
+			if (s == null && airAppTerminated(pl))
+			{
+				throw pl.createLaunchFailureException();
+			}
+
+			/* create a new session around this socket */
+			session = PlayerSession.createFromSocketWithOptions(s, m_debuggerCallbacks, this);
+
+			// transfer preferences
+			session.setPreferences(m_prefs);
+		}
+		catch(NullPointerException npe)
+		{
+			throw new BindException(getLocalizationManager().getLocalizedTextString("serverSocketNotListening")); //$NON-NLS-1$
+		}
+
+		return session;
+	}
+
+	/**
+	 * Returns true if the passed-in process listener is for an AIR application
+	 * that has terminated. This is used by accept() in order to detect that it
+	 * should give up listening on the socket.
+	 * 
+	 * The reason we can't do this for Flash player-based apps is that unlike
+	 * AIR apps, the process that we launched sometimes acts as just sort of a
+	 * "launcher" process that terminates quickly, and the actual Flash player
+	 * is in some other process. For example, on Mac, we often invoke the "open"
+	 * program to open a web browser; and on Windows, if you launch firefox.exe
+	 * but it detects that there is already a running instance of firefox.exe,
+	 * the new instance will just pass a message to the old instance, and then
+	 * the new instance will terminate.
+	 * 
+	 * @param pl
+	 *            a process listener, or <code>null</code>
+	 * @return true if pl refers to an AIR app that has terminated.
+	 */
+	private boolean airAppTerminated(ProcessListener pl)
+	{
+		if (pl != null)
+		{
+			if (pl.isAIRApp())
+			{
+				if (pl.isProcessDead())
+				{
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#getDebuggerCallbacks()
+	 */
+	public IDebuggerCallbacks getDebuggerCallbacks()
+	{
+		return m_debuggerCallbacks;
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#setDebuggerCallbacks(flash.tools.debugger.IDebuggerCallbacks)
+	 */
+	public void setDebuggerCallbacks(IDebuggerCallbacks debuggerCallbacks)
+	{
+		m_debuggerCallbacks = debuggerCallbacks;
+	}
+	
+	/**
+	 * A private variation on <code>connect()</code> that also has an argument
+	 * indicating that the process we are waiting for has terminated.
+	 * 
+	 * @param pl
+	 *            Optional process listener. If non-null, this is used to detect
+	 *            if a process that was launched has terminated unexpectedly.
+	 *            For example, if launch() launches adl, but adl exits, then we
+	 *            don't want to continue to wait for a socket connection.
+	 */
+	public Session connect(int port, IProgress waitReporter) throws IOException
+	{
+		final int waitTime = getPreference(PREF_CONNECT_WAIT_INTERVAL);
+		final int maxRetryAttempts = getPreference(PREF_CONNECT_RETRY_ATTEMPTS);
+		final int totalTimeout = getPreference(PREF_CONNECT_TIMEOUT);
+		final long timeForConnectStart = System.currentTimeMillis();
+		
+		long elapsedTime = 0;
+		int retryAttempts = -1;
+		PlayerSession session = null;
+		Socket s = null;		
+		
+		m_cancelConnect = false;		
+		
+		// Try to see if a connect happens till totalTimeout
+		// If the connection was refused in between, retry
+		// again after waitTime until totalTimeout is elapsed.
+		// Retry mechanism is disabled if PREF_CONNECT_RETRY_ATTEMPTS
+		// is 0.
+		while (s == null)
+		{
+			try
+			{
+				InetSocketAddress localAddress = new InetSocketAddress(InetAddress.getByName(null), port);
+				s = new Socket();
+				//save the socket for canceling connect
+				m_connectSocket = s;
+				//connect to loopback address at the specified port
+				s.connect(localAddress, totalTimeout);
+			}
+			catch(IOException ste)
+			{
+				if (ste instanceof SocketTimeoutException) {
+					//if we timed out, abort connect
+					abortConnect(ste);
+				}
+
+				safeCloseSocket(s);
+				
+				s = null;
+				retryAttempts++;
+				
+				//if we should not retry, checkConnectTimeout 
+				//throws an exception
+				elapsedTime = checkConnectTimeout(waitTime, maxRetryAttempts,
+						totalTimeout, retryAttempts, timeForConnectStart, ste);
+			}
+
+			// Tell the progress monitor we've waited a little while longer,
+			// so that the Eclipse progress bar can keep chugging along
+			if (waitReporter != null)
+				waitReporter.setProgress((int)elapsedTime, totalTimeout);
+			
+			if (s != null) {
+				/** If we connected, make sure that we get some response 
+				 * back after sending the handshake. This is required because
+				 * of the way port forwarding works. A connect will be successful
+				 * if port forwarding is set up, but we won't get any response 
+				 * unless the application is actually listening. 				
+				 */				
+				/* create a new session around this socket */
+				session = PlayerSession.createFromSocketWithOptions(s, m_debuggerCallbacks, this);
+				// transfer preferences
+				session.setPreferences(m_prefs);
+				try {
+					session.bind();					
+				}
+				catch (VersionException ex) {
+					session.unbind();
+					safeCloseSocket(s);
+					
+					s = null;					
+					retryAttempts++;
+					
+					/** The VersionException here is considered as an IOException
+					 * because we do not know if there was even a valid application
+					 * listening on the port. Once the port is forwarded, connect
+					 * succeeds and we get a VersionException even if player is not
+					 * listening on that port.
+					 */
+					elapsedTime = checkConnectTimeout(waitTime, maxRetryAttempts, 
+							totalTimeout, retryAttempts, timeForConnectStart, 
+							new IOException(ex.getLocalizedMessage()));
+				}
+			}
+		}
+		m_connectSocket = null;
+		
+		return session;
+	}
+
+	/**
+	 * @param waitTime
+	 * @param maxRetryAttempts
+	 * @param totalTimeout
+	 * @param retryAttempts
+	 * @param startTime
+	 * @param caughtException
+	 * @return
+	 * @throws IOException
+	 */
+	private long checkConnectTimeout(final int waitTime,
+			final int maxRetryAttempts, final int totalTimeout,
+			int retryAttempts, final long startTime, IOException caughtException)
+			throws IOException {
+		long elapsedTime;
+		long endTime = System.currentTimeMillis();
+		elapsedTime = endTime - startTime;
+		
+		// check if we should retry
+		boolean retryFinished = (maxRetryAttempts != -1 && retryAttempts >= maxRetryAttempts);
+		
+		// check if we timed out or somebody called stopConnecting()
+		if (retryFinished ||
+				elapsedTime > totalTimeout || 
+				m_cancelConnect ) {
+			abortConnect(caughtException);
+		}
+
+		//wait a bit before retrying
+		try {
+			Thread.sleep(waitTime);
+		} catch (InterruptedException e) {
+			abortConnect(caughtException);
+		}
+
+		//check cancel before resuming
+		if (m_cancelConnect ) {
+			abortConnect(caughtException);
+		}
+		return elapsedTime;
+	}
+
+	/**
+	 * @param ste
+	 * @throws IOException
+	 */
+	private void abortConnect(IOException ste) throws IOException {
+		m_connectSocket = null;
+		m_cancelConnect = false;
+		throw ste;
+	}
+
+	/**
+	 * @param s
+	 */
+	private void safeCloseSocket(Socket s) {
+		//clean up the socket
+		if (s != null && !s.isClosed()) {
+			try {
+				s.close();
+			}
+			catch (IOException closeException) {
+				//ignore
+			}
+		}
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#stopConnecting()
+	 */
+	public void stopConnecting() throws IOException
+	{
+		if (!m_cancelConnect) {
+			m_cancelConnect = true;
+			if (m_connectSocket != null)
+			{			
+				m_connectSocket.close();
+				m_connectSocket = null;
+			}
+		}		
+	}
+
+	/*
+	 * @see flash.tools.debugger.SessionManager#isConnecting()
+	 */
+	public boolean isConnecting()
+	{
+		return (m_connectSocket == null) ? false : true;
+	}
+	
+	/**
+	 * Returns the localization manager.  Use this for all localized strings.
+	 */
+	public static LocalizationManager getLocalizationManager()
+	{
+		return m_localizationManager;
+	}
+
+	@Override
+	public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo,
+			IProgress waitReporter, ILaunchNotification launchNotification)
+			throws IOException {
+		String[] launchCommand = getLaunchCommand(uri, airLaunchInfo, false);
+
+		// create the process and attach a thread to watch it during our accept phase
+		Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand);
+		//forDebugging = false
+		// If launching an AIR app, and forDebugging=false (meaning we are just running it,
+		// not debugging it), start a background thread that will call the launchNotification
+		// when the launch is complete.
+		startProcessListener(airLaunchInfo, false,launchNotification,
+				launchCommand, proc,true);
+				
+		return proc;
+	}
+
+	private ProcessListener startProcessListener(AIRLaunchInfo airLaunchInfo, boolean forDebugging,
+			ILaunchNotification launchNotification, String[] launchCommand,
+			Process proc, boolean isRunLaunch) {
+
+		 ProcessListener processListener = new ProcessListener(launchCommand, proc, launchNotification, forDebugging, airLaunchInfo != null); // BUG FB-9874: launchNotifier added
+		 processListener.setIsRunLaunch(isRunLaunch);
+
+		// If launching an AIR app, and forDebugging=false (meaning we are just running it,
+		// not debugging it), start a background thread that will call the launchNotification
+		// when the launch is complete.
+		if (!forDebugging && airLaunchInfo != null && launchNotification != null)
+			processListener.startLaunchNotifier();
+
+		return processListener;
+	}
+
+	private String[] getLaunchCommand(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging)
+			throws IOException, FileNotFoundException {
+
+		String[] launchCommand;
+		
+		uri = uri.trim();
+
+		if (airLaunchInfo == null)
+		{
+			LaunchInfo launchInfo = new LaunchInfo(uri);
+
+			uri = tweakNativeLaunchUri(uri, forDebugging, launchInfo);
+
+			launchCommand = getFlashLaunchArgs(uri, launchInfo);
+		}
+		else // else, AIR
+		{
+			launchCommand = getAIRLaunchArgs(uri, airLaunchInfo);
+		}
+		return launchCommand;
+	}
+
+	@Override
+	public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo, IProgress waitReporter, ILaunchNotification launchNotification,
+			ILauncher launcher) throws IOException {
+
+		String[] launchCommand = getLaunchCommandForLauncher(uri, airLaunchInfo,false);
+
+		// create the process and attach a thread to watch it during our accept phase
+		Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand,launcher);
+		//forDebugging = false
+		// If launching an AIR app, and forDebugging=false (meaning we are just running it,
+		// not debugging it), start a background thread that will call the launchNotification
+		// when the launch is complete.
+		startProcessListener(airLaunchInfo, false,launchNotification,
+				launchCommand, proc, true);;
+				
+		return proc;
+	}
+
+	private String[] getLaunchCommandForLauncher(String uri, AIRLaunchInfo airLaunchInfo,boolean forDebugging)
+			throws IOException, FileNotFoundException {
+		String[] launchCommand;
+		if (airLaunchInfo == null)
+		{
+			LaunchInfo launchInfo = new LaunchInfo(uri);
+
+			uri = tweakNativeLaunchUri(uri, forDebugging, launchInfo);
+
+			launchCommand = new String[]{uri};
+		}
+		else // else, AIR
+		{
+			launchCommand = getAIRLaunchArgs(uri, airLaunchInfo);
+		}
+		return launchCommand;
+	}
+
+	@Override
+	public Session launch(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging, IProgress waitReporter,
+			ILaunchNotification launchNotification, ILauncher launcher) throws IOException {
+		
+		String[] launchCommand = getLaunchCommandForLauncher(uri, airLaunchInfo,forDebugging);
+
+		// create the process and attach a thread to watch it during our accept phase
+		Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand, launcher);
+
+		ProcessListener processListener = startProcessListener(airLaunchInfo,forDebugging, launchNotification, launchCommand, proc,false); 
+		PlayerSession session = null;
+
+		if (forDebugging)
+		{
+			session = waitForConnection(uri, airLaunchInfo, waitReporter, proc, processListener);
+			session.setLauncher(launcher);
+		}
+
+		return session;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/ProcessListener.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/ProcessListener.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/ProcessListener.java
new file mode 100644
index 0000000..5334aff
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/ProcessListener.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.concrete;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.StringWriter;
+
+import flash.tools.debugger.AlreadyActiveApplicationException;
+import flash.tools.debugger.CommandLineException;
+import flash.tools.debugger.ILaunchNotification;
+
+/**
+ * Listens to several things about a process: captures its stdout/stderr messages,
+ * detects when the process exits, and captures its exit code.
+ * <p>
+ * When a process exits, the ProcessListener can send out a notification.  If
+ * you want that to happen, call startLaunchNotifier().
+ */
+public class ProcessListener
+{
+	private Process					m_process;
+	private ILaunchNotification		m_launchNotification;
+	private boolean					m_isDebugging;
+	private boolean					m_isAIRapp;
+	private final String[]			m_launchCommand;
+	private StringWriter			m_processMessages;
+
+	/**
+	 * A background thread that will wait until the process terminates, and then
+	 * call the launch listener.
+	 */
+	private Thread m_launchNotifierThread = new Thread("DJAPI ProcessListener") //$NON-NLS-1$
+	{
+		@Override
+		public void run()
+		{
+			try
+			{
+				m_process.waitFor();
+
+				IOException e = null;
+				if (getProcessExitValue() != 0)
+					e = createLaunchFailureException();
+				m_launchNotification.notify(e);
+			}
+			catch (InterruptedException e)
+			{
+				// this will happen if anyone calls Thread.interrupt()
+			}
+		}
+	};
+	private boolean m_isRunLaunch;
+
+	/**
+	 * Starts listening to stdout and stderr of the launched process.  The caller
+	 * can later call getProcessMessages() to capture that output.
+	 */
+	public ProcessListener(String[] launchCommand, Process process, ILaunchNotification launchNotification, boolean forDebugging, boolean isAIRapp)
+	{
+		m_launchCommand = launchCommand;
+		m_process = process;
+		m_launchNotification = launchNotification;
+		m_isDebugging = forDebugging;
+		m_isAIRapp = isAIRapp;
+		m_processMessages = new StringWriter();
+		startMessageListener();
+	}
+
+	private void startMessageListener()
+	{
+		new StreamListener(new InputStreamReader(m_process.getInputStream()), m_processMessages).start();
+		new StreamListener(new InputStreamReader(m_process.getErrorStream()), m_processMessages).start();
+		try
+		{
+			OutputStream stm = m_process.getOutputStream();
+			if (stm != null)
+				stm.close();
+		}
+		catch (IOException e)
+		{
+			/* not serious; ignore */
+		}
+	}
+
+	/**
+	 * Creates a background thread that will call the launch notifier when the
+	 * process terminates.
+	 */
+	public void startLaunchNotifier()
+	{
+		if (m_launchNotification == null)
+			throw new NullPointerException();
+
+		m_launchNotifierThread.setDaemon(true);
+		m_launchNotifierThread.start();
+	}
+
+	/**
+	 * Returns the command args that were used to launch the process.
+	 */
+	public String[] getLaunchCommand()
+	{
+		return m_launchCommand;
+	}
+
+	public boolean isAIRApp()
+	{
+		return m_isAIRapp;
+	}
+
+	public boolean isProcessDead()
+	{
+		// If the process is still alive, then exitValue() will throw an exception:
+		try {
+			m_process.exitValue();
+			return true;
+		} catch (IllegalThreadStateException e) {
+			return false;
+		}
+	}
+
+	public int getProcessExitValue() throws IllegalThreadStateException
+	{
+		return m_process.exitValue();
+	}
+
+	/**
+	 * Returns all messages that were sent to stdout and stderr by the process,
+	 * combined into one string.
+	 */
+	public String getProcessMessages()
+	{
+		return m_processMessages.toString();
+	}
+
+	/**
+	 * Creates an exception indicating that the process terminated with some sort
+	 * of error.  The returned exception may be an AlreadyActiveApplicationException
+	 * or a CommandLineException.
+	 */
+	public IOException createLaunchFailureException()
+	{
+		IOException e = null;
+		String detailMessage;
+
+		if (m_isDebugging)
+		{
+			detailMessage = PlayerSessionManager.getLocalizationManager().getLocalizedTextString(
+					"processTerminatedWithoutDebuggerConnection"); //$NON-NLS-1$
+		}
+		else
+		{
+			detailMessage = PlayerSessionManager.getLocalizationManager().getLocalizedTextString(
+					"processTerminatedUnexpectedly"); //$NON-NLS-1$
+		}
+
+		// You can only call this function if the process has terminated
+		if (!isProcessDead())
+		{
+			throw new IllegalThreadStateException();
+		}
+
+		/*
+		 * When adding auto-terminate for run launch, we notice that on clicking the 
+		 * terminate button, the process exits with exitValue = 1 (due to unexpected
+		 * termination). We just ignore this error message.
+		 * Since we anyways now allow exitValue = 1(previously for app already running)
+		 * for run launch, we shall skip displaying the message.
+		 */
+		
+		int exitValue = getProcessExitValue();
+		
+		if (m_isAIRapp && exitValue == 1)         //ADL Exit Code: Successful invocation of an already running AIR application. ADL exits immediately.
+		{
+			if(!m_isRunLaunch) {
+				e = new AlreadyActiveApplicationException(detailMessage, m_isDebugging);
+			}
+		}
+		else
+		{
+			e = new CommandLineException(detailMessage, getLaunchCommand(), getProcessMessages(), exitValue);
+		}	
+
+		return e;
+	}
+
+	public void setIsRunLaunch(boolean forRunLaunching) {
+		m_isRunLaunch = forRunLaunching;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/ScriptText.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/ScriptText.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/ScriptText.java
new file mode 100644
index 0000000..a1cb4d2
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/ScriptText.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.concrete;
+
+/**
+ * Contains the text contents of a script and is able
+ * to map line numbers to specific regions of the script (i.e. string)
+ */
+public class ScriptText
+{
+	private final String m_text;
+	private int[]  m_lineMap;  // a 2-d array [2i] = startIndex and [2i+1] = endIndex for line i
+
+	public ScriptText(String text)
+	{
+		m_text = text;
+	}
+
+	/* return a string containing the line number requested */
+	public String getLine(int lineNum) 
+	{
+		determineLines();
+
+		int index = lineNum-1;
+		if (index < 0)
+			; // throw 
+
+		/* look into our mapping array */
+		int start = m_lineMap[2*index];
+		int end = m_lineMap[(2*index)+1];
+
+		String s = m_text.substring(start, end);
+		return s;
+	}
+
+	/* line count in module */
+	public int getLineCount()
+	{
+		determineLines();
+		return m_lineMap.length/2;
+	}
+
+	/**
+	 * Build mapping tables based on the line count of 
+	 * the given source string.
+	 * 
+	 * These tables allow us to compute starting and 
+	 * ending locations of each line of the source file.
+	 * 
+	 * The assumption using this technique is that most
+	 * lines of the source files will never be accessed 
+	 * thus we only incur the overhead of 8 bytes 
+	 * (start & end) per line, plus the actual string 
+	 * contents each line a line is requested.
+	 * 
+	 * Thus we need  8 * num_files * num_lines_per_file bytes
+	 * for all these maps.
+	 * 
+	 * For example, say each file is 1000 lines and we have
+	 * 400 source files;  We would consume 3.2MB.  With 
+	 * each request we would allocate an additional 20+
+	 * bytes for the string (assuming a 20B avg line length).
+	 * 
+	 * Allocating each line individually we would consume
+	 * 1000 * 400 * 20 = 8MB.
+	 * 
+	 * It is debatable whether this scheme is more efficient
+	 * than actually builing an array of Strings to contain
+	 * the lines, but gut feel says it is ;)
+	 */
+	private synchronized void determineLines()
+	{
+		// determineLines() is done on demand in order to avoid wasting time
+		// doing this for every file; so check if we've already done it
+		if (m_lineMap != null)
+			return;
+
+		int count = lineCountFor(m_text) + 1; // add 1 to the line count to handle newline on last line
+
+		// allocated our maps (really a 2-d array where [i] = startAt & [i+1] = endAt )
+		m_lineMap = new int[(2*count)+1];
+
+		int i = 0;
+		int lineNum = 0;
+		int startAt = 0;
+		int endAt = 0;
+		int length = m_text.length();
+		char c = '\0';
+		while(i < length)
+		{
+			/* end of line */
+			c = m_text.charAt(i++);
+			if (c == '\n' || c == '\r')
+			{
+				m_lineMap[2*lineNum] = startAt;
+				m_lineMap[(2*lineNum)+1] = endAt;
+				lineNum++;
+
+				/* do we need to chew a CR LF combo */
+				if (c == '\r' && i < length && m_text.charAt(i) == '\n')
+					i++;
+
+				startAt = i;
+				endAt = i;
+			}
+			else 
+				endAt++;
+		}
+
+		/* need to add the last line? */
+		if (startAt != endAt)
+		{
+			/* add the last line if not empty */
+			m_lineMap[2*lineNum] = startAt;
+			m_lineMap[(2*lineNum)+1] = endAt;
+		}
+	}
+ 
+	/**
+	 * Count the number of lines within this string.
+	 */
+	public static int lineCountFor(String s)
+	{
+		int i = 0;
+		int lineNum = 0;
+		int length = s.length();
+		char c = '\0';
+		while(i < length)
+		{
+			/* end of line */
+			c = s.charAt(i++);
+			if (c == '\n' || c == '\r')
+			{
+				lineNum++;
+
+				/* do we need to chew a CR LF combo */
+				if (c == '\r' && i < length && s.charAt(i) == '\n')
+					i++;
+			}
+		}
+		return lineNum;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/StandalonePlayer.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/StandalonePlayer.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/StandalonePlayer.java
new file mode 100644
index 0000000..aa5f423
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/StandalonePlayer.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.concrete;
+
+import java.io.File;
+
+/**
+ * @author mmorearty
+ */
+public class StandalonePlayer extends AbstractPlayer
+{
+	/**
+	 * @param path
+	 */
+	public StandalonePlayer(File path)
+	{
+		super(null, path);
+	}
+
+	/*
+	 * @see flash.tools.debugger.Player#getType()
+	 */
+	public int getType()
+	{
+		return STANDALONE;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/StreamListener.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/StreamListener.java b/modules/fdbworkers/src/flash/tools/debugger/concrete/StreamListener.java
new file mode 100644
index 0000000..bc21ea5
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/StreamListener.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.concrete;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * Reads a stream, and sends the contents somewhere.
+ * @author mmoreart
+ */
+public class StreamListener extends Thread {
+	Reader fIn;
+	Writer fOut;
+
+	/**
+	 * Creates a StreamListener which will copy everything from
+	 * 'in' to 'out'.
+	 * @param in the stream to read
+	 * @param out the stream to write to, or 'null' to discard input
+	 */
+	public StreamListener(Reader in, Writer out)
+	{
+		super("DJAPI StreamListener"); //$NON-NLS-1$
+		setDaemon(true);
+		fIn = in;
+		fOut = out;
+	}
+
+	@Override
+	public void run()
+	{
+		char[] buf = new char[4096];
+		int count;
+
+		try {
+			for (;;) {
+				count = fIn.read(buf);
+				if (count == -1)
+					return; // thread is done
+				if (fOut != null)
+				{
+					try {
+						fOut.write(buf, 0, count);
+					} catch (IOException e) {
+						// the write failed (unlikely), but we still
+						// want to keep reading
+					}
+				}
+			}
+		} catch (IOException e) {
+			// do nothing -- we're done
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseCaminoWindow.txt
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseCaminoWindow.txt b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseCaminoWindow.txt
new file mode 100644
index 0000000..e44f4d1
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseCaminoWindow.txt
@@ -0,0 +1,60 @@
+--------------------------------------------------------------------------------
+--
+--      
+--        Licensed to the Apache Software Foundation (ASF) under one or more
+--        contributor license agreements.  See the NOTICE file distributed with
+--        this work for additional information regarding copyright ownership.
+--        The ASF licenses this file to You under the Apache License, Version 2.0
+--        (the "License"); you may not use this file except in compliance with
+--        the License.  You may obtain a copy of the License at
+--      
+--            http://www.apache.org/licenses/LICENSE-2.0
+--      
+--        Unless required by applicable law or agreed to in writing, software
+--        distributed under the License is distributed on an "AS IS" BASIS,
+--        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+--        See the License for the specific language governing permissions and
+--        limitations under the License.
+--
+--------------------------------------------------------------------------------
+
+-- tell Camino browser to close all windows that have the specified URL
+tell application "Camino"
+	-- 'closed' keeps track of whether we have closed any documents
+	set closed to false
+
+	set done to false
+	repeat until done
+		set done to true
+
+		-- Camino has some hidden windows that are not regular browser
+		-- windows.  Those windows don't have a URL.  We keep count of
+		-- how many windows do have a URL.
+		set countOfWindowsWithURL to 0
+
+		repeat with win in windows
+			if URL of win exists then
+				if URL of win is item 1 of argv then
+					close win
+					set closed to true
+
+					-- since we have closed a document, we must restart the loop
+					set done to false
+					exit repeat
+				else
+					set countOfWindowsWithURL to countOfWindowsWithURL+1
+				end if
+			end if
+		end repeat
+	end repeat
+
+	-- if we closed at least one Safari window, and no more are
+	-- open, then tell Safari to exit
+	if closed and countOfWindowsWithURL is 0 then 
+		quit
+		set closed to "appquit"
+	end if
+
+	-- return true if we closed at least one window, false if not, appquit if told browser to quit
+	closed
+end tell

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseSafariWindow.txt
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseSafariWindow.txt b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseSafariWindow.txt
new file mode 100644
index 0000000..110f4c0
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptCloseSafariWindow.txt
@@ -0,0 +1,54 @@
+--------------------------------------------------------------------------------
+--
+--      
+--        Licensed to the Apache Software Foundation (ASF) under one or more
+--        contributor license agreements.  See the NOTICE file distributed with
+--        this work for additional information regarding copyright ownership.
+--        The ASF licenses this file to You under the Apache License, Version 2.0
+--        (the "License"); you may not use this file except in compliance with
+--        the License.  You may obtain a copy of the License at
+--      
+--            http://www.apache.org/licenses/LICENSE-2.0
+--      
+--        Unless required by applicable law or agreed to in writing, software
+--        distributed under the License is distributed on an "AS IS" BASIS,
+--        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+--        See the License for the specific language governing permissions and
+--        limitations under the License.
+--
+--------------------------------------------------------------------------------
+
+-- tell Safari to close all windows that have the specified URL
+tell application "Safari"
+	-- 'closed' keeps track of whether we have closed any documents
+	set closed to false
+
+	set done to false
+	repeat until done
+		set done to true
+		repeat with w in windows
+			try
+				repeat with t in tabs of w
+					if URL of t is item 1 of argv then
+						close t
+						set closed to true
+
+						-- since we have closed a document, we must restart the loop
+						set done to false
+						exit repeat
+					end if
+				end repeat
+			end try
+		end repeat
+	end repeat
+
+	-- if we closed at least one Safari window, and no more are
+	-- open, then tell Safari to exit
+	if closed and (count of documents) is 0 then		
+		quit
+		set closed to "appquit"
+	end if
+
+	-- return true if we closed at least one window, false if not
+	closed
+end tell

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptGetDefaultBrowserName.txt
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptGetDefaultBrowserName.txt b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptGetDefaultBrowserName.txt
new file mode 100644
index 0000000..e3d84d3
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/appleScriptGetDefaultBrowserName.txt
@@ -0,0 +1,34 @@
+--------------------------------------------------------------------------------
+--
+--      
+--        Licensed to the Apache Software Foundation (ASF) under one or more
+--        contributor license agreements.  See the NOTICE file distributed with
+--        this work for additional information regarding copyright ownership.
+--        The ASF licenses this file to You under the Apache License, Version 2.0
+--        (the "License"); you may not use this file except in compliance with
+--        the License.  You may obtain a copy of the License at
+--      
+--            http://www.apache.org/licenses/LICENSE-2.0
+--      
+--        Unless required by applicable law or agreed to in writing, software
+--        distributed under the License is distributed on an "AS IS" BASIS,
+--        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+--        See the License for the specific language governing permissions and
+--        limitations under the License.
+--
+--------------------------------------------------------------------------------
+
+-- Note, this only works on OSX 10.4 and up
+-- Returns the name of the default browser, e.g. "Safari", "Firefox", "Camino"; or "" if not known
+set p to POSIX path of (path to preferences) & "com.apple.LaunchServices.plist"
+tell application "System Events" to tell property list item "LSHandlerRoleAll" of (property list item 1 of property list item "LSHandlers" of property list file p whose value contains "http") to if exists then
+	set v to value -- now v is, for example, "com.apple.safari"
+	-- "application file id v" returns a file; so we are setting, for example,
+	-- "n" to "Safari.app" and "e" to "app"
+	tell application "Finder" to set {name:n, name extension:e} to application file id v
+	-- strip off the ".app" extension
+	tell (count e) + 1 to return n's text 1 thru -(1 mod it + it)
+end if
+
+-- if we get here, we couldn't find an "http" handler, so we don't know the default browser
+""

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_da.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_da.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_da.properties
new file mode 100644
index 0000000..b7aca59
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_da.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Funktioner i ${fileName}#${fileNumber}
+unknown = ukendt
+empty = <empty>
+processTerminatedWithoutDebuggerConnection = Processen blev afsluttet uden at der blev etableret forbindelse til fejlfinding.
+processTerminatedUnexpectedly = Handlingen blev uventet afbrudt.
+serverSocketNotListening = Serversoklen lytter ikke.
+functionCallsNotSupported = Den valgte afspiller underst\u00f8tter ikke funktionskald
+watchpointsNotSupported = Den valgte afspiller underst\u00f8tter ikke overv\u00e5gningspunkter
+exceptionBreakpointsNotSupported = Den valgte afspiller underst\u00f8tter ikke undtagelsespausepunkter
+operatorNotSupported = Den valgte afspiller underst\u00f8tter ikke operatoren "${operator}"

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_de.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_de.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_de.properties
new file mode 100644
index 0000000..27fc209
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_de.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Funktionen in ${fileName}#${fileNumber}
+unknown = unbekannt
+empty = <leer>
+processTerminatedWithoutDebuggerConnection = Der Vorgang wurde beendet, ohne dass eine Verbindung mit dem Debugger hergestellt wurde.
+processTerminatedUnexpectedly = Der Prozess wurde unerwartet beendet.
+serverSocketNotListening = Server-Socket wartet nicht auf Meldungen.
+functionCallsNotSupported = Zielplayer unterst\u00fctzt keine Funktionsaufrufe
+watchpointsNotSupported = Zielplayer unterst\u00fctzt keine Watchpoints
+exceptionBreakpointsNotSupported = Zielplayer unterst\u00fctzt keine Ausnahme-Haltepunkte
+operatorNotSupported = Zielplayer unterst\u00fctzt nicht den Operator \u201e${operator}\u201c

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_en.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_en.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_en.properties
new file mode 100644
index 0000000..e9e0977
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_en.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Functions in ${fileName}#${fileNumber}
+unknown = unknown
+empty = <empty>
+processTerminatedWithoutDebuggerConnection = Process terminated without establishing connection to debugger.
+processTerminatedUnexpectedly = Process terminated unexpectedly.
+serverSocketNotListening = Server socket not listening.
+functionCallsNotSupported = Target player does not support function calls
+watchpointsNotSupported = Target player does not support watchpoints
+exceptionBreakpointsNotSupported = Target player does not support exception breakpoints
+operatorNotSupported = Target player does not support the "${operator}" operator

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_es.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_es.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_es.properties
new file mode 100644
index 0000000..8b58ad8
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_es.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Funciones en ${fileName}#${fileNumber}
+unknown = desconocido
+empty = <vac\u00edo>
+processTerminatedWithoutDebuggerConnection = Proceso terminado sin establecer conexi\u00f3n con el depurador.
+processTerminatedUnexpectedly = El proceso se ha terminado de forma inesperada.
+serverSocketNotListening = El socket del servidor no est\u00e1 detectando.
+functionCallsNotSupported = El reproductor de destino no admite llamadas de funci\u00f3n
+watchpointsNotSupported = El reproductor de destino no admite puntos de observaci\u00f3n
+exceptionBreakpointsNotSupported = El reproductor de destino no admite puntos de corte de excepciones
+operatorNotSupported = El reproductor de destino no admite el operador "${operator}"

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fi.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fi.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fi.properties
new file mode 100644
index 0000000..9618a65
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fi.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Toiminnot kohteessa ${fileName}#${fileNumber}
+unknown = tuntematon
+empty = <tyhj\u00e4>
+processTerminatedWithoutDebuggerConnection = Prosessi lopetettiin muodostamatta yhteytt\u00e4 virheenkorjaukseen.
+processTerminatedUnexpectedly = Prosessi p\u00e4\u00e4tettiin odottamatta.
+serverSocketNotListening = Palvelimen vastake ei ole kuuntelutilassa.
+functionCallsNotSupported = Kohdesoitin ei tue toimintopuheluita
+watchpointsNotSupported = Kohdesoitin ei tue katselukohtia
+exceptionBreakpointsNotSupported = Kohdesoitin ei tue poikkeuksien keskeytyskohtia
+operatorNotSupported = Kohdesoitin ei tue operaattoria "${operator}"

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fr.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fr.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fr.properties
new file mode 100644
index 0000000..249a5ea
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_fr.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Fonctions de ${fileName}#${fileNumber}
+unknown = Inconnu
+empty = <vide>
+processTerminatedWithoutDebuggerConnection = Le processus s'est termin\u00e9 sans \u00e9tablir de connexion vers le d\u00e9bogueur.
+processTerminatedUnexpectedly = Processus termin\u00e9 de mani\u00e8re inattendue.
+serverSocketNotListening = Le socket du serveur n'est pas en mode d'\u00e9coute.
+functionCallsNotSupported = Le lecteur cible ne prend pas en charge les appels de fonction
+watchpointsNotSupported = Le lecteur cible ne prend pas en charge les points de contr\u00f4le
+exceptionBreakpointsNotSupported = Le lecteur cible ne prend pas en charge les points d'arr\u00eat d'exception.
+operatorNotSupported = Le lecteur cible ne prend pas en charge l'op\u00e9rateur "${operator}"

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_it.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_it.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_it.properties
new file mode 100644
index 0000000..31fa4ec
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_it.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Funzioni in ${fileName}#${fileNumber}
+unknown = sconosciuto
+empty = <vuoto>
+processTerminatedWithoutDebuggerConnection = Processo terminato senza stabilire la connessione con debugger.
+processTerminatedUnexpectedly = Il processo \u00e8 stato interrotto inaspettatamente.
+serverSocketNotListening = Socket del server non in ascolto.
+functionCallsNotSupported = Il Player di destinazione non supporta le chiamate di funzione
+watchpointsNotSupported = Il Player di destinazione non supporta i punti di controllo
+exceptionBreakpointsNotSupported = Il Player di destinazione non supporta i punti di interruzione delle eccezioni
+operatorNotSupported = Il Player di destinazione non supporta l'operatore "${operator}"

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ja.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ja.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ja.properties
new file mode 100644
index 0000000..4aa0269
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ja.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = ${fileName}#${fileNumber} \u5185\u306e\u95a2\u6570
+unknown = \u4e0d\u660e
+empty = <\u7a7a>
+processTerminatedWithoutDebuggerConnection = \u30c7\u30d0\u30c3\u30ac\u30fc\u3078\u306e\u63a5\u7d9a\u304c\u78ba\u7acb\u3055\u308c\u305a\u306b\u30d7\u30ed\u30bb\u30b9\u304c\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002
+processTerminatedUnexpectedly = \u30d7\u30ed\u30bb\u30b9\u304c\u4e88\u671f\u305b\u305a\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002
+serverSocketNotListening = \u30b5\u30fc\u30d0\u30fc\u30bd\u30b1\u30c3\u30c8\u304c\u5f85\u3061\u53d7\u3051\u3057\u3066\u3044\u307e\u305b\u3093\u3002
+functionCallsNotSupported = \u30bf\u30fc\u30b2\u30c3\u30c8\u30d7\u30ec\u30fc\u30e4\u30fc\u3067\u306f\u95a2\u6570\u306e\u547c\u3073\u51fa\u3057\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+watchpointsNotSupported = \u30bf\u30fc\u30b2\u30c3\u30c8\u30d7\u30ec\u30fc\u30e4\u30fc\u3067\u306f\u76e3\u8996\u30dd\u30a4\u30f3\u30c8\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+exceptionBreakpointsNotSupported = \u30bf\u30fc\u30b2\u30c3\u30c8\u30d7\u30ec\u30fc\u30e4\u30fc\u3067\u306f\u4f8b\u5916\u30d6\u30ec\u30fc\u30af\u30dd\u30a4\u30f3\u30c8\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+operatorNotSupported = \u30bf\u30fc\u30b2\u30c3\u30c8\u30d7\u30ec\u30fc\u30e4\u30fc\u3067\u306f "${operator}" \u6f14\u7b97\u5b50\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ko.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ko.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ko.properties
new file mode 100644
index 0000000..7c67001
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_ko.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = ${fileName}#${fileNumber}\uc758 \ud568\uc218
+unknown = \uc54c \uc218 \uc5c6\uc74c
+empty = <\ube44\uc5b4 \uc788\uc74c>
+processTerminatedWithoutDebuggerConnection = \ub514\ubc84\uac70\uc5d0 \ub300\ud55c \uc5f0\uacb0\uc744 \uc124\uc815\ud558\uc9c0 \uc54a\uc740 \uc0c1\ud0dc\uc5d0\uc11c \ud504\ub85c\uc138\uc2a4\uac00 \uc885\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+processTerminatedUnexpectedly = \ud504\ub85c\uc138\uc2a4\uac00 \uc608\uae30\uce58 \uc54a\uac8c \uc885\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+serverSocketNotListening = \uc11c\ubc84 \uc18c\ucf13\uc774 \uc218\uc2e0\ud558\uace0 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+functionCallsNotSupported = \ub300\uc0c1 \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c \ud568\uc218 \ud638\ucd9c\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+watchpointsNotSupported = \ub300\uc0c1 \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c \uac10\uc2dc\uc810\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+exceptionBreakpointsNotSupported = \ub300\uc0c1 \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c \uc608\uc678 \uc911\ub2e8\uc810\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+operatorNotSupported = \ub300\uc0c1 \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c "${operator}" \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nb.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nb.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nb.properties
new file mode 100644
index 0000000..aab7160
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nb.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Funksjoner i ${fileName}#${fileNumber}
+unknown = ukjent
+empty = <tom>
+processTerminatedWithoutDebuggerConnection = Prosessen ble avsluttet uten at den opprettet en tilkobling til feils\u00f8king.
+processTerminatedUnexpectedly = Prosessen ble avbrutt uten forvarsel.
+serverSocketNotListening = Serversocket lytter ikke.
+functionCallsNotSupported = M\u00e5lspilleren st\u00f8tter ikke funksjonskall
+watchpointsNotSupported = M\u00e5lspilleren st\u00f8tter ikke overv\u00e5kningspunkter
+exceptionBreakpointsNotSupported = M\u00e5lspilleren st\u00f8tter ikke unntaksavbruddspunkter
+operatorNotSupported = M\u00e5lspilleren st\u00f8tter ikke operatoren ${operator}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nl.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nl.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nl.properties
new file mode 100644
index 0000000..4b045b8
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_nl.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Functies in ${fileName}#${fileNumber}
+unknown = onbekend
+empty = <leeg>
+processTerminatedWithoutDebuggerConnection = Proces be\u00ebindigd zonder verbinding met foutopsporing tot stand te brengen.
+processTerminatedUnexpectedly = Proces onverwacht afgebroken.
+serverSocketNotListening = Serversocket luistert niet.
+functionCallsNotSupported = Doelspeler ondersteunt geen functieaanroepen
+watchpointsNotSupported = Doelspeler ondersteunt controlepunten niet
+exceptionBreakpointsNotSupported = Doelspeler ondersteunt geen onderbrekingspunten voor uitzonderingen
+operatorNotSupported = Doelspeler ondersteunt de operator "${operator}" niet

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_pt.properties
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_pt.properties b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_pt.properties
new file mode 100644
index 0000000..8f9a89c
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/concrete/djapi_pt.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+functionsInFile = Fun\u00e7\u00f5es em ${fileName}#${fileNumber}
+unknown = desconhecido
+empty = <vazio>
+processTerminatedWithoutDebuggerConnection = O processo terminou sem estabelecer conex\u00e3o com o depurador.
+processTerminatedUnexpectedly = O processo terminou de forma inesperada.
+serverSocketNotListening = O soquete do servidor n\u00e3o est\u00e1 escutando.
+functionCallsNotSupported = O player de destino n\u00e3o oferece suporte a chamadas de fun\u00e7\u00e3o
+watchpointsNotSupported = O player de destino n\u00e3o oferece suporte a pontos de inspe\u00e7\u00e3o
+exceptionBreakpointsNotSupported = O player de destino n\u00e3o oferece suporte a pontos de interrup\u00e7\u00e3o de exce\u00e7\u00e3o
+operatorNotSupported = O player de destino n\u00e3o oferece suporte ao operador "${operator}"