Merge remote-tracking branch 'origin/R2_0_maintenance'

Change-Id: If130256bcc7453a655d7bf9a2c58734fffc91f30
Signed-off-by: Greg Watson <g.watson@computer.org>
diff --git a/bundles/org.eclipse.remote.console/.project b/bundles/org.eclipse.remote.console/.project
index 0d4f3af..da0bcc4 100644
--- a/bundles/org.eclipse.remote.console/.project
+++ b/bundles/org.eclipse.remote.console/.project
@@ -20,9 +20,15 @@
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.pde.PluginNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
 	</natures>
 </projectDescription>
diff --git a/bundles/org.eclipse.remote.console/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.console/META-INF/MANIFEST.MF
index 5605751..581674f 100644
--- a/bundles/org.eclipse.remote.console/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.console/META-INF/MANIFEST.MF
@@ -2,15 +2,37 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.remote.console;singleton:=true
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 1.1.0.qualifier
 Bundle-Activator: org.eclipse.remote.internal.console.Activator
 Bundle-Localization: plugin
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.remote.core;bundle-version="2.0.0",
- org.eclipse.remote.ui;bundle-version="2.0.0",
- org.eclipse.ui.console;bundle-version="3.6.0",
- org.eclipse.tm.terminal.control;bundle-version="4.0.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %pluginProvider
+Export-Package: org.eclipse.remote.console,
+ org.eclipse.remote.console.actions
+Import-Package: org.eclipse.core.commands,
+ org.eclipse.core.runtime,
+ org.eclipse.core.runtime.jobs,
+ org.eclipse.jface.action,
+ org.eclipse.jface.dialogs,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.ui.widgets,
+ org.eclipse.swt,
+ org.eclipse.swt.events,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.tm.internal.terminal.control,
+ org.eclipse.tm.internal.terminal.provisional.api,
+ org.eclipse.ui,
+ org.eclipse.ui.console,
+ org.eclipse.ui.console.actions,
+ org.eclipse.ui.handlers,
+ org.eclipse.ui.part,
+ org.eclipse.ui.plugin,
+ org.eclipse.ui.progress,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.console/plugin.xml b/bundles/org.eclipse.remote.console/plugin.xml
index 592289c..c016588 100644
--- a/bundles/org.eclipse.remote.console/plugin.xml
+++ b/bundles/org.eclipse.remote.console/plugin.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.4"?>
 <plugin>
+   <extension-point id="org.eclipse.remote.console.toolbar" name="org.eclipse.remote.console.toolbar" schema="schema/consoleToolbar.exsd"/>
    <extension
          point="org.eclipse.ui.console.consoleFactories">
       <consoleFactory
diff --git a/bundles/org.eclipse.remote.console/pom.xml b/bundles/org.eclipse.remote.console/pom.xml
index 68b1b00..0251ef1 100644
--- a/bundles/org.eclipse.remote.console/pom.xml
+++ b/bundles/org.eclipse.remote.console/pom.xml
@@ -11,6 +11,6 @@
   </parent>
 
   <artifactId>org.eclipse.remote.console</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.1.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.remote.console/schema/consoleToolbar.exsd b/bundles/org.eclipse.remote.console/schema/consoleToolbar.exsd
new file mode 100644
index 0000000..0b1adee
--- /dev/null
+++ b/bundles/org.eclipse.remote.console/schema/consoleToolbar.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.remote.console" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.remote.console" id="org.eclipse.remote.console.toolbar" name="Terminal Console Toolbar Contributions"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="action" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="action">
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Identifier for this action
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="connectionType" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The connection type this Action applies to
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="actionFactory" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A class implementing IConsoleActionFactory to be called to create the Action
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.remote.console.actions.IConsoleActionFactory"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/TerminalConsoleUtility.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/TerminalConsoleUtility.java
index a9af9f2..ff53269 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/TerminalConsoleUtility.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/TerminalConsoleUtility.java
@@ -17,13 +17,15 @@
 import org.eclipse.ui.console.IConsole;
 
 /**
- * A collection of public API utility methods to open
- * consoles to IRemoteConnection objects
+ * A collection of public API utility methods to open consoles to
+ * IRemoteConnection objects
+ * 
+ * @since 1.1
  */
 public class TerminalConsoleUtility {
 	/**
-	 * Opens a dialog to allow selection of an IRemoteConnection,
-	 * encoding, etc. and then open a console to it.
+	 * Opens a dialog to allow selection of an IRemoteConnection, encoding, etc.
+	 * and then open a console to it.
 	 */
 	public void openConsole() {
 		new TerminalConsoleFactory().openConsole();
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleAction.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/ConsoleAction.java
similarity index 67%
rename from bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleAction.java
rename to bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/ConsoleAction.java
index 9df1416..0b5d60c 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleAction.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/ConsoleAction.java
@@ -8,13 +8,16 @@
  * Contributors:
  * QNX Software Systems - Initial API and implementation
  *******************************************************************************/
-package org.eclipse.remote.internal.console.actions;
+package org.eclipse.remote.console.actions;
 
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.resource.ImageRegistry;
 import org.eclipse.remote.internal.console.Activator;
 
+/**
+ * @since 1.1
+ */
 public abstract class ConsoleAction extends Action {
 	public ConsoleAction(String id) {
 		this(id, 0);
@@ -25,27 +28,20 @@
 		setId(id);
 	}
 
-	protected void setupAction(String text, String tooltip,
-			String image, String enabledImage, String disabledImage,
+	protected void setupAction(String text, String tooltip, String image, String enabledImage, String disabledImage,
 			boolean enabled) {
 		ImageRegistry imageRegistry = Activator.getDefault().getImageRegistry();
 		setupAction(text, tooltip, image, enabledImage, disabledImage, enabled, imageRegistry);
 	}
 
-	protected void setupAction(String text, String tooltip,
-			String hoverImage, String enabledImage, String disabledImage,
-			boolean enabled, ImageRegistry imageRegistry) {
-		setupAction(text,
-				tooltip,
-				imageRegistry.getDescriptor(hoverImage),
-				imageRegistry.getDescriptor(enabledImage),
-				imageRegistry.getDescriptor(disabledImage),
-				enabled);
+	protected void setupAction(String text, String tooltip, String hoverImage, String enabledImage,
+			String disabledImage, boolean enabled, ImageRegistry imageRegistry) {
+		setupAction(text, tooltip, imageRegistry.getDescriptor(hoverImage), imageRegistry.getDescriptor(enabledImage),
+				imageRegistry.getDescriptor(disabledImage), enabled);
 	}
 
-	protected void setupAction(String text, String tooltip,
-			ImageDescriptor hoverImage, ImageDescriptor enabledImage, ImageDescriptor disabledImage,
-			boolean enabled) {
+	protected void setupAction(String text, String tooltip, ImageDescriptor hoverImage, ImageDescriptor enabledImage,
+			ImageDescriptor disabledImage, boolean enabled) {
 		setText(text);
 		setToolTipText(tooltip);
 		setEnabled(enabled);
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/IConsoleActionFactory.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/IConsoleActionFactory.java
new file mode 100644
index 0000000..fff843a
--- /dev/null
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/console/actions/IConsoleActionFactory.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2016 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.remote.console.actions;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * @since 1.1
+ */
+public interface IConsoleActionFactory {
+	public ConsoleAction createAction(String actionId, String connectionType, IAdaptable adapter);
+}
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsole.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsole.java
index 8fdfc7b..011ad72 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsole.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsole.java
@@ -20,7 +20,6 @@
 import org.eclipse.ui.part.IPageBookViewPage;
 import org.eclipse.ui.progress.UIJob;
 
-@SuppressWarnings("restriction")
 public class TerminalConsole extends AbstractConsole {
 	private final String encoding;
 	private final TerminalConsoleConnector terminalConnector;
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsoleExtensionManager.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsoleExtensionManager.java
new file mode 100644
index 0000000..f9cbdb6
--- /dev/null
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsoleExtensionManager.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2016 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.remote.internal.console;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.remote.console.actions.IConsoleActionFactory;
+
+public class TerminalConsoleExtensionManager {
+	private static TerminalConsoleExtensionManager instance;
+	private Map<String, List<String>> actions;
+	private Map<String, IConsoleActionFactory> factories;
+	private Map<String, IConfigurationElement> elements;
+
+	private TerminalConsoleExtensionManager() {
+	}
+
+	public static TerminalConsoleExtensionManager getInstance() {
+		if (instance == null) {
+			instance = new TerminalConsoleExtensionManager();
+		}
+		return instance;
+	}
+
+	public List<String> getActionsForType(String id) {
+		initialize();
+		List<String> list = actions.get(id);
+		return list == null ? new ArrayList<String>() : list;
+	}
+	
+	public IConsoleActionFactory getFactory(String id) {
+		return factories.get(id);
+	}
+
+	private void initialize() {
+		if (actions == null) {
+			actions = new LinkedHashMap<>();
+			elements = new LinkedHashMap<>();
+			factories = new HashMap<>();
+			IExtensionRegistry registry = Platform.getExtensionRegistry();
+			IExtensionPoint point = registry
+					.getExtensionPoint(Activator.getDefault().getBundle().getSymbolicName() + ".toolbar");
+			for (IExtension extension : point.getExtensions()) {
+				for (IConfigurationElement element : extension.getConfigurationElements()) {
+					String id = element.getAttribute("id"); //$NON-NLS-1$
+					if (id != null) {
+						elements.put(id, element);
+						IConsoleActionFactory factory = null;
+						try {
+							factory = (IConsoleActionFactory) element.createExecutableExtension("actionFactory");
+						} catch (CoreException e) {
+							Activator.log(e);
+						}
+						if (factory != null) {
+							String connectionType = element.getAttribute("connectionType");
+							if (connectionType != null) {
+								List<String> actionList = actions.get(connectionType);
+								if (actionList == null) {
+									actionList = new ArrayList<>();
+								}
+								actionList.add(id);
+								actions.put(connectionType, actionList);
+								factories.put(id, factory);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsolePage.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsolePage.java
index c426ecf..4e10ee6 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsolePage.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/TerminalConsolePage.java
@@ -11,7 +11,9 @@
 package org.eclipse.remote.internal.console;
 
 import java.io.UnsupportedEncodingException;
+import java.util.List;
 
+import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
@@ -20,6 +22,9 @@
 import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.osgi.util.NLS;
+import org.eclipse.remote.console.actions.ConsoleAction;
+import org.eclipse.remote.console.actions.IConsoleActionFactory;
+import org.eclipse.remote.core.IRemoteConnection;
 import org.eclipse.remote.internal.console.actions.ConsoleActionConnect;
 import org.eclipse.remote.internal.console.actions.ConsoleActionDisconnect;
 import org.eclipse.remote.internal.console.actions.ConsoleActionScrollLock;
@@ -40,9 +45,9 @@
 import org.eclipse.ui.part.Page;
 import org.eclipse.ui.progress.UIJob;
 
-@SuppressWarnings("restriction")
-public class TerminalConsolePage extends Page {
+public class TerminalConsolePage extends Page implements IAdaptable {
 	public static final String TOOLBAR_GROUP_ID = "org.eclipse.remote.internal.terminal.console.Toolbar"; //$NON-NLS-1$
+	public static final String CONTRIBUTIONS_GROUP_ID = "org.eclipse.remote.internal.terminal.console.Toolbar.contributions"; //$NON-NLS-1$
 
 	private final ConsoleActionConnect connectAction;
 	private final ConsoleActionDisconnect disconnectAction;
@@ -89,10 +94,29 @@
 		super.init(pageSite);
 		IToolBarManager toolBarManager = pageSite.getActionBars().getToolBarManager();
 		toolBarManager.insertBefore(IConsoleConstants.OUTPUT_GROUP, new GroupMarker(TOOLBAR_GROUP_ID));
+
 		toolBarManager.appendToGroup(TOOLBAR_GROUP_ID, connectAction);
 		toolBarManager.appendToGroup(TOOLBAR_GROUP_ID, disconnectAction);
 		toolBarManager.appendToGroup(TOOLBAR_GROUP_ID, new ConsoleActionScrollLock(this));
 		toolBarManager.appendToGroup(TOOLBAR_GROUP_ID, new CloseConsoleAction(terminalConsole));
+		
+		toolBarManager.insertAfter(TOOLBAR_GROUP_ID, new GroupMarker(CONTRIBUTIONS_GROUP_ID));
+		
+		addToolbarContributions(toolBarManager);
+	}
+
+	private void addToolbarContributions(IToolBarManager toolBarManager) {
+		String connectionType = terminalConsole.getConnection().getConnectionType().getId();
+		List<String> actions = TerminalConsoleExtensionManager.getInstance().getActionsForType(connectionType);
+		for (String id : actions) {
+			IConsoleActionFactory factory = TerminalConsoleExtensionManager.getInstance().getFactory(id);
+			if (factory != null) {
+				ConsoleAction action = factory.createAction(id, connectionType, this);
+				if (action != null) {
+					toolBarManager.appendToGroup(CONTRIBUTIONS_GROUP_ID, action);
+				}
+			}
+		}
 	}
 
 	@Override
@@ -175,4 +199,22 @@
 			return Status.OK_STATUS;
 		}
 	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> T getAdapter(Class<T> adapter) {
+		if (adapter.equals(IRemoteConnection.class)) {
+			return (T) terminalConsole.getConnection();
+		}
+		if (adapter.equals(TerminalConsole.class)) {
+			return (T) terminalConsole;
+		}
+		if (adapter.equals(TerminalConsolePage.class)) {
+			return (T) this;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionConnect.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionConnect.java
index e3c97bf..a830e80 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionConnect.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionConnect.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.remote.internal.console.actions;
 
+import org.eclipse.remote.console.actions.ConsoleAction;
 import org.eclipse.remote.internal.console.ImageConsts;
 import org.eclipse.remote.internal.console.TerminalConsole;
 
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionDisconnect.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionDisconnect.java
index b567063..3bece3b 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionDisconnect.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionDisconnect.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.remote.internal.console.actions;
 
+import org.eclipse.remote.console.actions.ConsoleAction;
 import org.eclipse.remote.internal.console.ImageConsts;
 import org.eclipse.remote.internal.console.TerminalConsole;
 
diff --git a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionScrollLock.java b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionScrollLock.java
index 28c7e4a..19c4596 100644
--- a/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionScrollLock.java
+++ b/bundles/org.eclipse.remote.console/src/org/eclipse/remote/internal/console/actions/ConsoleActionScrollLock.java
@@ -11,6 +11,7 @@
 package org.eclipse.remote.internal.console.actions;
 
 import org.eclipse.jface.action.IAction;
+import org.eclipse.remote.console.actions.ConsoleAction;
 import org.eclipse.remote.internal.console.ImageConsts;
 import org.eclipse.remote.internal.console.TerminalConsolePage;
 
diff --git a/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF
index 1fff97f..6938a2c 100644
--- a/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF
@@ -5,11 +5,6 @@
 Bundle-Version: 2.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.internal.core.RemoteCorePlugin
 Bundle-Vendor: %pluginProvider
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
- org.eclipse.core.filesystem,
- org.eclipse.core.resources,
- org.eclipse.core.variables,
- org.eclipse.debug.core
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.remote.core,
  org.eclipse.remote.core.exception,
@@ -18,6 +13,15 @@
  org.eclipse.remote.internal.core.preferences;x-friends:="org.eclipse.remote.ui"
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.equinox.security.storage,
- org.eclipse.cdt.utils.pty,
- org.eclipse.cdt.utils.spawner
+Import-Package: org.eclipse.cdt.utils.pty,
+ org.eclipse.cdt.utils.spawner,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.core.runtime.preferences,
+ org.eclipse.debug.core,
+ org.eclipse.equinox.security.storage,
+ org.eclipse.osgi.service.debug,
+ org.eclipse.osgi.util,
+ org.osgi.framework,
+ org.osgi.service.prefs
diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/RemoteServicesUtils.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/RemoteServicesUtils.java
index 84138f0..0fc43fd 100644
--- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/RemoteServicesUtils.java
+++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/RemoteServicesUtils.java
@@ -40,19 +40,13 @@
 		try {
 			//Use the Mars implementation of Path, see bug 454959
 			return Path.forPosix(path);
-		} catch(NoSuchMethodError e) {
+		} catch (NoSuchMethodError e) {
 			//TODO For older Eclipse, use the fallback below. That code should be
 			//removed when support for Eclipse older than Mars is no longer needed.
-		}
-		/** Constant value indicating if the current platform is Windows */
-		boolean RUNNING_ON_WINDOWS = java.io.File.separatorChar == '\\';
-		if (! RUNNING_ON_WINDOWS) {
-			return new Path(path);
-		} else {
-			return new RemotePath(path);	
+			return RemotePath.forPosix(path);
 		}
 	}
-	
+
 	/**
 	 * Convert a UNC path to a URI
 	 * 
diff --git a/bundles/org.eclipse.remote.doc.isv/.project b/bundles/org.eclipse.remote.doc.isv/.project
new file mode 100644
index 0000000..f25b52a
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/.project
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.remote.doc.isv</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.remote.doc.isv/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.doc.isv/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..176f91b
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse Remote Development documentation plug-in
+Bundle-SymbolicName: org.eclipse.remote.doc.isv;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Eclipse PTP
+Require-Bundle: org.eclipse.remote.console,
+ org.eclipse.remote.core,
+ org.eclipse.remote.jsch.core,
+ org.eclipse.remote.jsch.ui,
+ org.eclipse.remote.serial.core,
+ org.eclipse.remote.serial.ui,
+ org.eclipse.remote.telnet.core,
+ org.eclipse.remote.telnet.ui,
+ org.eclipse.remote.ui
diff --git a/bundles/org.eclipse.remote.doc.isv/build.properties b/bundles/org.eclipse.remote.doc.isv/build.properties
new file mode 100644
index 0000000..3acfefc
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/build.properties
@@ -0,0 +1,5 @@
+bin.includes = plugin.xml,\
+               META-INF/,\
+               html/,\
+               toc*.xml,\
+               css/
diff --git a/bundles/org.eclipse.remote.doc.isv/css/style.css b/bundles/org.eclipse.remote.doc.isv/css/style.css
new file mode 100644
index 0000000..00cc9fb
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/css/style.css
@@ -0,0 +1,17 @@
+code {
+    	color: Crimson;
+    	font-family: monaco,consolas,"courier new",monospace;
+	}
+
+pre {
+	background-color: lightgrey;
+    width: auto;
+    overflow: auto;
+    padding: 25px;
+    border: 1px solid navy;
+    margin: 1em;
+}
+
+p {
+    font: 15px arial, sans-serif;
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.doc.isv/html/.gitignore b/bundles/org.eclipse.remote.doc.isv/html/.gitignore
new file mode 100644
index 0000000..07f4331
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/html/.gitignore
@@ -0,0 +1 @@
+/reference/
diff --git a/bundles/org.eclipse.remote.doc.isv/html/concepts/concepts.html b/bundles/org.eclipse.remote.doc.isv/html/concepts/concepts.html
new file mode 100644
index 0000000..a000aa6
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/html/concepts/concepts.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Concepts</title>
+	<link rel="stylesheet" type="text/css" href="../../css/style.css">
+</style>
+</head>
+
+<body>
+<p>This section describes the main concepts and services implemented by the Eclipse remote framework.</p>
+
+<!--
+ Concepts
+-->
+
+<h1>Concepts</h1>
+
+<p>Some few concepts are needed to understand the framework's services overall. They are described in the next sections.</p>
+
+<h3>Connection type</h3>
+<p>An connection type (<code>IRemoteConnectionType</code>) abstracts a remote protocol to host access. As of version 2.0.1, the framework provides the <b>ssh</b> (implemented through JSch framework), <b>Telnet</b> and <b>Local</b> types.</p> 
+<p>The connection type is obtained from the remote services manager either by passing its scheme ID (Identification) or an URI.</p>
+<p>It has the <code>newConnection</code> method where a new connection of this type is created. It also holds the list of all connections already created that belongs to it.</p>
+
+<h3>Remote connection</h3>
+<p>The remote connection (<code>IRemoteConnection</code>) interface is used to manage a connection to a single remote host. A connection must be established (open) before any other operations are permitted. All operations carried out on remote host should be evoked from its associated services, which are get with <code>getService</code> method.</p>
+<p>Connections are read-only objects. In order to change the attributes of a connection, a working copy (<code>IRemoteConnectionWorkingCopy</code>) must be created. The host attributes getters and setters can also be managed with connection host service (<code>IRemoteConnectionHostService</code>). 
+
+<p>Every remote connection belongs to a connection type.</p>
+
+
+<h3>Remote resource</h3>
+<p>The remote resource interface (<code>IRemoteResource</code>) provides an adapter to a remote resource.</p>
+<p>As of version 2.0.1, there are two types of remote resources: fully remote and synchronized. This interface provides a common mechanism for accessing resource information from either types.</p> 
+
+<h3>Process builder</h3>
+<p>The process builder (<code>IRemoteProcessBuilder</code>) provides process operations on the remote host. This interface is intended to be a drop-in replacement for the Java SE <code>ProcessBuilder</code> class. See the <code>java.lang.ProcessBuilder</code> documentation for a description of the methods.</p>
+<p>It is obtained from the process service (see <code>IRemoteProcessService</code> below) associated with a connection object that holds access information to the remote host.</p>
+
+<h3>Remote process</h3>
+<p>The remote process (<code>IRemoteProcess</code>) represents a process running on the remote host. Use it to manage the process (destroy), get exit status, and input/output/error streams.</p>
+<p>Remote process are created using the <code>IRemoteProcessBuilder</code> interface.</p>
+
+<!--
+ Services
+-->
+
+<h1>Services</h1>
+
+<p>The remote services are implemented as OSGi services. There are available non-UI (core) and UI services.</p>
+
+<p>Any given service can be associated with objects of the model (concepts) or nested to another one. In either case, an service instance is obtained by calling the <code>getService</code> method of its object's provider.</p> 
+
+<p>The main remote services are detailed in the next sections.</p>
+
+<h3>Services manager</h3>
+<p>The services manager (<code>IRemoteServicesManager</code>) interface provides the <b>main entry point</b> for accessing remote services. It can be obtained by calling <code>RemoteServicesUtils.getService(IRemoteServicesManager.class)</code> or using the Plugin's bundle context to access a OSGi service.</p> 
+<p>It provides access to connection types implemented by the framework and any connection already created.</p>
+
+<h3>File Service</h3>
+<p>The file service (<code>IRemoteFileService</code>) provides remote file manipulation operations on a given connection. It is obtained from a remote connection object by calling its <code>getService(IRemoteFileService.class)</code> method.</p>
+
+<p>Using this interface, a path can be translated into an <code>IFileStore</code> object, and then manipulated using any of the normal EFS operations.</p>
+<p>Its UI counterpart service (<code>IRemoteUIFileService</code>) comes with dialog widgets to browse files and directories on remote filesystem. 
+
+<h3>Process Service</h3>
+<p>The process service (<code>IRemoteProcessService</code>) provides services for starting up processes on a remote host. It is obtained from a remote connection object by calling its <code>getService(IRemoteProcessService.class)</code> method.</p>
+<p>It is the entry point to get an <code>IRemoteProcessBuilder</code> object, used to spawn processes on the remote host. Environment variables of remote host are accessed using this service too.</p>
+
+<h3>Connection Service</h3>
+<p>The UI Connection service (<code>IRemoteUIConnectionService</code>) is used for manipulating connections in the UI, such as adding, editing, and opening connections.</p>
+<p>Non-UI connection manipulation should use the <code>IRemoteConnectionType</code> interface (obtained from services manager) and the services related with <code>IRemoteConnection</code> interface.</p> 
+</body>
+</html>
diff --git a/bundles/org.eclipse.remote.doc.isv/html/gettingstarted/intro.html b/bundles/org.eclipse.remote.doc.isv/html/gettingstarted/intro.html
new file mode 100644
index 0000000..ea7b149
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/html/gettingstarted/intro.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Getting started</title>
+	<link rel="stylesheet" type="text/css" href="../../css/style.css">
+</head>
+
+<body>
+<h1>Introduction</h1>
+<p>The purpose of remote services API is to provide a programming interface to remote services that is agnostic to the actual remote services implementation. Currently the only implementation supported of SSH protocol uses JSch(Java Secure Channel) project (<a href="http://www.jcraft.com/jsch/">www.jcraft.com/jsch</a>). An implementation for the local system (where Eclipse is run) and Telnet protocol are also provided.</p>
+<p>The API is generic enough so that it is possible to use it for all remote or local operations. This is useful for situations where both a remote and local mode should be provided, but the programmer wants to avoid two separate code paths.</p> 
+
+<h1>Types of services</h1>
+<p>The API is divided into two types of remote services: UI and non-UI.</p>
+<p>UI services are for activities such as file browsing that require use of the UI. In particular, it provides a main preference page (under "Remote Development > Remote Connections") which allow connections to be created, edited, removed, opened, and closed. </p>
+<p>Non-UI services are purely programmatic, they provides a set of core services for manipulating remote resources. The non-UI services can be used independently of the UI services.</p>
+
+<h1>Remote Services Plugins</h1>
+
+<p>The remote services are divided into two plugins. These plugins should have no dependencies other than the platform.</p>
+<ul>
+  <li>org.eclipse.remote.core - provides non-UI remote services</li>
+  <li>org.eclipse.remote.ui - provides UI remote services</li>
+</ul>
+
+<p>Remote service implementations provide the actual remote functionality using a particular remote protocol. These are supplied as a set of adapter plugins.
+
+<p>As of version 2.0.1, there is currently one implementation of SSH protocol using JSch:</p>
+
+<ul>
+  <li>org.eclipse.remote.jsch.core</li>
+  <li>org.eclipse.remote.jsch.ui</li>
+</ul>
+
+<p>The Telnet protocol implementation and UI widgets are provided by the plugins:</p>
+<ul>
+  <li>org.eclipse.remote.telnet.core</li>
+  <li>org.eclipse.remote.telnet.ui</li>
+</ul>
+ 
+<p>These plugins are dependent on the remote services implementations, but are optional for the remote services API. The API will automatically detect the installed plugins.</p> 
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.doc.isv/html/samples/examples.html b/bundles/org.eclipse.remote.doc.isv/html/samples/examples.html
new file mode 100644
index 0000000..955358e
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/html/samples/examples.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Samples</title>
+	<link rel="stylesheet" type="text/css" href="../../css/style.css">
+</head>
+
+<body>
+<h1>Usage examples</h1>
+<p>This section shows usage examples for using the Eclipse Remote API.</p>
+
+<p>The services manager can be obtained using <code>RemoteServicesUtils</code> (since 2.0.1) helper:</p>
+
+<pre><code class="snippet">
+IRemoteServicesManager servicesManager = RemoteServicesUtils.getService(IRemoteServicesManager.class);
+</code></pre>
+
+<p>An alternative is to use the bundle's context to get the service reference:</p>
+
+<pre><code class="snippet">
+BundleContext context = plugin.getBundle().getBundleContext();
+ServiceReference<T> ref = context.getServiceReference(IRemoteServicesManager.class);
+IRemoteServicesManager servicesManager = context.getService(ref);
+</code></pre>
+
+<p>Once with services manager object, you obtain a connection type by its scheme ID or any URI to the remote host, as in:</p>
+<pre><code class="snippet">
+IRemoteConnectionType connType;
+// Get connection type by Scheme ID
+connType = servicesManager.getConnectionType("ssh");
+// Get connection type by URI
+URI uri = URI.create("ssh://MyConnection/path/to/file");
+connType = servicesManager.getConnectionType(uri);
+</code></pre>
+
+<p>The Telnet connection type can not be obtained by URI, instead you must use its ID:
+<pre><code class="snippet">
+IRemoteConnectionType connType;
+connType = servicesManager.getConnectionType("org.eclipse.remote.telnet.core.connectionType");
+</code></pre>
+
+<p>The remote connection is obtained from connection type object by either name or an URI. For example:
+<pre><code class="snippet">
+IRemoteConnection connection;
+// Get connection by URI
+URI uri = URI.create("ssh://MyConnection/path/to/file");
+connection = connType.getConnection(uri);
+// Get connection by name
+connection = connType.getConnection("MyConnection");
+</code></pre>
+
+<p>If the connection does not exist, it can be created with a connection type (<code>IRemoteConnectionType</code>) instance. Use the connection type object to delete it as well:
+
+<pre><code class="snippet">
+IRemoteConnectionWorkingCopy rcwc; // Writable connection working copy 
+rcwc = connType.newConnection(connectionName); // Create connection of connection type
+IRemoteConnectionHostService hostServices; // Fill connection information through host service
+hostServices = rcwc.getService(IRemoteConnectionHostService.class); // Obtain the service from working copy instance
+hostServices.setHostname(address);
+hostServices.setUsername(username);
+hostServices.setUsePassword(true);
+hostServices.setPassword(passwd);
+IRemoteConnection connection = rcwc.save(); // Finally save the working copy, then get the connection (read-only) object
+
+connType.removeConnection(connection); // Remove connection and all resources associated with it
+</code></pre>
+
+<p>Connections can be opened or closed programmatically. Some operations requires the connection opened:</p>
+<pre><code class="snippet">
+connection.open(monitor); // Open the connection but allow the user to cancel the progress monitor
+connection.close(); // Now close it
+</code></pre>
+
+<p>The file service is obtained from a connection object. Remote resources can be manipulated with <code>IFileStore</code>:</p>
+<pre><code class="snippet">
+IRemoteFileService fileService = connection.getService(IRemoteFileService.class);
+// The remote connection does not need to be open to get the resource
+IFileStore fs = fileService.getResource("/path/to/resource");
+// But the remote connection need to be open to operate on the resource
+if (fs.fetchInfo().exists()) {
+    System.out.println("It exists!");
+}
+</code></pre>
+
+<p>In the other hand, the UI file service is obtained from a connection type rather than the connection. The reason is that it allows user to select the connection in a list. It is also possible to set the connection:</p>
+<pre><code class="snippet">
+IRemoteUIFileService uiFileService = conn.getConnectionType().getService(IRemoteUIFileService.class);
+uiFileService.setConnection(connection); // Set default connection (optional)
+uiFileService.showConnections(true); // Also show list of available connections
+// The return value is the path of the directory selected on the remote system
+String path = uiFileService.browseDirectory(shell, "Browse /home", "/home", IRemoteUIConstants.NONE);
+</code></pre>
+
+<p>Use a connection object to get its associated process service (<code>IRemoteProcessService</code>). Then obtain a process builder (<code>IRemoteProcessBuilder</code>), so that commands can be executed on remote host:</p>
+<pre><code class="snippet">
+IRemoteProcessService ps = connection.getService(IRemoteProcessService.class);
+IRemoteProcessBuilder pb = ps.getProcessBuilder("/bin/ls", "-l");
+IRemoteProcess process = pb.start();
+// Use IRemoteProcess to manage the process. Alternatively, use an adaptor to java.lang.Process
+Process process2 = new RemoteProcessAdapter(process);
+</code></pre>
+
+<p>Use the <code>IRemoteResource</code> adapter to get a location URI of the project (<code>IProject</code>): 
+<pre><code class="snippet">
+IRemoteResource resource = (IRemoteResource)project.getAdapter(IRemoteResource.class);
+URI projectLocation = resource.getActiveLocationURI(); // Get URI to active location
+</code></pre>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.doc.isv/html/toc.html b/bundles/org.eclipse.remote.doc.isv/html/toc.html
new file mode 100644
index 0000000..e589c31
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/html/toc.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Remote Developer's Guide</title>
+</head>
+
+<body>
+<h1>Eclipse Remote Developer's Guide</h1>
+<p>This is the guide of the eclipse remote development framework as of provided by <i>org.eclipse.remote</i> project.</p>
+<h3>Table of Contents</h3>
+<ul style="list-style-type:none">
+ <li><a href="gettingstarted/intro.html">Getting Started</a></li>
+ <li><a href="concepts/concepts.html">Concepts</a></li>
+ <li><a href="samples/examples.html">Usage Examples</a></li>
+ <li><a href="reference/api/index.html">Reference</a></li>
+</ul>
+</body>
+</html>
diff --git a/bundles/org.eclipse.remote.doc.isv/plugin.xml b/bundles/org.eclipse.remote.doc.isv/plugin.xml
new file mode 100644
index 0000000..1f77cc9
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/plugin.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.help.toc">
+      <toc
+            file="toc.xml"
+            primary="true">
+      </toc>
+      <toc
+            file="tocconcepts.xml">
+      </toc>
+      <toc
+            file="tocgettingstarted.xml">
+      </toc>
+      <toc
+            file="tocreference.xml">
+      </toc>
+      <toc
+            file="tocsamples.xml">
+      </toc>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.remote.doc.isv/pom.xml b/bundles/org.eclipse.remote.doc.isv/pom.xml
new file mode 100644
index 0000000..38790c7
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.remote</groupId>
+    <artifactId>remote-parent</artifactId>
+    <version>2.0.2-SNAPSHOT</version>
+    <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>org.eclipse.remote.doc.isv</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho.extras</groupId>
+        <artifactId>tycho-document-bundle-plugin</artifactId>
+        <version>${tycho-extras-version}</version>
+        <configuration>
+           <outputDirectory>${basedir}/html/reference/api</outputDirectory>
+           <!-- TODO: bump tycho-extras version. Excludes option requires >= 0.23
+           <javadocOptions>
+               <excludes>
+                   <exclude>org.eclipse.remote.internal.*</exclude>
+               </excludes>
+           </javadocOptions>
+           -->
+        </configuration>
+        <executions>
+            <execution>
+                <id>javadoc</id>
+                <goals>
+                    <goal>javadoc</goal>
+                </goals>
+            </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/bundles/org.eclipse.remote.doc.isv/toc.xml b/bundles/org.eclipse.remote.doc.isv/toc.xml
new file mode 100644
index 0000000..4a099b6
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/toc.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Eclipse Remote Developer's Guide" topic="html/toc.html">
+   <topic label="Getting Started">
+      <anchor id="gettingstarted"/>
+   </topic>
+   <topic label="Concepts">
+      <anchor id="concepts"/>
+   </topic>
+   <topic label="Reference">
+      <anchor id="reference"/>
+   </topic>
+   <topic label="Samples">
+      <anchor id="samples"/>
+   </topic>
+</toc>
diff --git a/bundles/org.eclipse.remote.doc.isv/tocconcepts.xml b/bundles/org.eclipse.remote.doc.isv/tocconcepts.xml
new file mode 100644
index 0000000..eb382cb
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/tocconcepts.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Concepts" link_to="toc.xml#concepts"> 
+	<topic label="Concepts"  href="html/concepts/concepts.html"> 
+	</topic>
+</toc>
diff --git a/bundles/org.eclipse.remote.doc.isv/tocgettingstarted.xml b/bundles/org.eclipse.remote.doc.isv/tocgettingstarted.xml
new file mode 100644
index 0000000..fb12307
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/tocgettingstarted.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Getting Started" link_to="toc.xml#gettingstarted"> 
+	<topic label="Getting Started"  href="html/gettingstarted/intro.html"> 
+	</topic>
+</toc>
diff --git a/bundles/org.eclipse.remote.doc.isv/tocreference.xml b/bundles/org.eclipse.remote.doc.isv/tocreference.xml
new file mode 100644
index 0000000..e9dc3b6
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/tocreference.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Reference" link_to="toc.xml#reference"> 
+	<topic label="API Reference"  href="html/reference/api/index.html" /> 
+</toc>
diff --git a/bundles/org.eclipse.remote.doc.isv/tocsamples.xml b/bundles/org.eclipse.remote.doc.isv/tocsamples.xml
new file mode 100644
index 0000000..542cbc7
--- /dev/null
+++ b/bundles/org.eclipse.remote.doc.isv/tocsamples.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Samples" link_to="toc.xml#samples"> 
+	<topic label="Samples"  href="html/samples/examples.html"> 
+	</topic>
+</toc>
diff --git a/bundles/org.eclipse.remote.jsch.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.jsch.core/META-INF/MANIFEST.MF
index 76c3b22..95d78a0 100644
--- a/bundles/org.eclipse.remote.jsch.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.jsch.core/META-INF/MANIFEST.MF
@@ -5,14 +5,18 @@
 Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.internal.jsch.core.Activator
 Bundle-Vendor: %pluginProvider
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
- org.eclipse.core.filesystem,
- org.eclipse.remote.core;bundle-version="2.0",
- org.eclipse.jsch.core,
- com.jcraft.jsch,
- org.eclipse.equinox.security
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.remote.internal.jsch.core;x-friends:="org.eclipse.remote.jsch.ui,org.eclipse.remote.jsch.tests",
  org.eclipse.remote.internal.jsch.core.messages;x-internal:=true
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: com.jcraft.jsch,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.filesystem.provider,
+ org.eclipse.core.runtime,
+ org.eclipse.jsch.core,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.internal.core,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java
index 3ea70d3..9095be9 100644
--- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java
+++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java
@@ -80,7 +80,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#getPassphrase()
 		 */
 		@Override
@@ -93,7 +93,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#getPassword()
 		 */
 		@Override
@@ -106,7 +106,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UIKeyboardInteractive#promptKeyboardInteractive(java.lang.String, java.lang.String,
 		 * java.lang.String, java.lang.String[], boolean[])
 		 */
@@ -141,7 +141,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String)
 		 */
 		@Override
@@ -174,7 +174,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String)
 		 */
 		@Override
@@ -203,7 +203,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String)
 		 */
 		@Override
@@ -223,7 +223,7 @@
 
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String)
 		 */
 		@Override
@@ -279,7 +279,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnection.Service#getRemoteConnection()
 	 */
 	@Override
@@ -290,7 +290,7 @@
 	public static class Factory implements IRemoteConnection.Service.Factory {
 		/*
 		 * (non-Javadoc)
-		 * 
+		 *
 		 * @see org.eclipse.remote.core.IRemoteConnection.Service.Factory#getService(org.eclipse.remote.core.IRemoteConnection,
 		 * java.lang.Class)
 		 */
@@ -379,7 +379,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionControlService#close()
 	 */
 	@Override
@@ -406,7 +406,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#forwardLocalPort(int, java.lang.String, int)
 	 */
 	@Override
@@ -423,7 +423,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#forwardLocalPort(java.lang.String, int,
 	 * org.eclipse.core.runtime.IProgressMonitor)
 	 */
@@ -459,7 +459,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#forwardRemotePort(int, java.lang.String, int)
 	 */
 	@Override
@@ -476,7 +476,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#forwardRemotePort(java.lang.String, int,
 	 * org.eclipse.core.runtime.IProgressMonitor)
 	 */
@@ -511,7 +511,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionHostService#getHostname()
 	 */
 	@Override
@@ -536,7 +536,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#getEnv()
 	 */
 	@Override
@@ -546,7 +546,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#getEnv(java.lang.String)
 	 */
 	@Override
@@ -596,7 +596,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionHostService#getPort()
 	 */
 	@Override
@@ -607,7 +607,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#getProcessBuilder(java.util.List)
 	 */
 	@Override
@@ -617,7 +617,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#getProcessBuilder(java.lang.String[])
 	 */
 	@Override
@@ -627,7 +627,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionPropertyService#getProperty(java.lang.String)
 	 */
 	@Override
@@ -637,7 +637,7 @@
 
 	/**
 	 * Get the login shell command if useLoginShell is true
-	 * 
+	 *
 	 * @return login shell command
 	 */
 	public String getLoginShellCommand() {
@@ -731,7 +731,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionHostService#getUsername()
 	 */
 	@Override
@@ -741,7 +741,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#getWorkingDirectory()
 	 */
 	@Override
@@ -775,7 +775,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionControlService#isOpen()
 	 */
 	@Override
@@ -950,7 +950,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnectionControlService#open(org.eclipse.core.runtime.IProgressMonitor)
 	 */
 	@Override
@@ -960,7 +960,7 @@
 
 	/**
 	 * Open ssh connection without full setup (environment, sftp)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteConnection#open()
 	 *
 	 * @param monitor
@@ -992,9 +992,13 @@
 			isFullySetup = true;
 			// getCwd checks the exec channel before checkConfiguration checks the sftp channel
 			fWorkingDir = getCwd(subMon.newChild(10));
-			if (!checkConfiguration(fSessions.get(0), subMon.newChild(20))) {
-				newSession(subMon.newChild(10));
-				loadEnv(subMon.newChild(10));
+			try {
+				if (!checkConfiguration(fSessions.get(0), subMon.newChild(20))) {
+					newSession(subMon.newChild(10));
+					loadEnv(subMon.newChild(10));
+				}
+			} catch (RemoteConnectionException e) {
+				// Do not throw exception now, it will be thrown if FileService is accessed.
 			}
 			loadProperties(subMon.newChild(10));
 			fRemoteConnection.fireConnectionChangeEvent(RemoteConnectionChangeEvent.CONNECTION_OPENED);
@@ -1013,7 +1017,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#removeLocalPortForwarding(int)
 	 */
 	@Override
@@ -1030,7 +1034,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemotePortForwardingService#removeRemotePortForwarding(int)
 	 */
 	@Override
@@ -1047,7 +1051,7 @@
 
 	/*
 	 * (non-Javadoc)
-	 * 
+	 *
 	 * @see org.eclipse.remote.core.IRemoteProcessService#setWorkingDirectory(java.lang.String)
 	 */
 	@Override
diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchFileManager.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchFileManager.java
index 2a6eefe..ded8f10 100644
--- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchFileManager.java
+++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchFileManager.java
@@ -20,12 +20,13 @@
 import org.eclipse.remote.core.IRemoteFileService;
 import org.eclipse.remote.core.IRemoteProcessService;
 import org.eclipse.remote.core.RemoteServicesUtils;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.internal.jsch.core.messages.Messages;
 
 public class JSchFileManager implements IRemoteFileService {
-
 	private final IRemoteConnection fConnection;
 
-	public JSchFileManager(IRemoteConnection connection) {
+	private JSchFileManager(IRemoteConnection connection) {
 		fConnection = connection;
 	}
 
@@ -34,6 +35,13 @@
 		@Override
 		public <T extends Service> T getService(IRemoteConnection remoteConnection, Class<T> service) {
 			if (IRemoteFileService.class.equals(service)) {
+				if (remoteConnection instanceof JSchConnection)
+					try {
+						((JSchConnection) remoteConnection).getSftpCommandChannel();
+					} catch (RemoteConnectionException e) {
+						throw new UnsupportedOperationException(
+								Messages.JSchConnection_Remote_host_does_not_support_sftp);
+					}
 				return (T) new JSchFileManager(remoteConnection);
 			}
 			return null;
@@ -87,5 +95,4 @@
 	public URI toURI(String path) {
 		return toURI(RemoteServicesUtils.posixPath(path));
 	}
-
 }
diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchProcess.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchProcess.java
index 616b4c2..f024b78 100644
--- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchProcess.java
+++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchProcess.java
@@ -21,6 +21,7 @@
 import org.eclipse.remote.core.IRemoteProcessSignalService;
 import org.eclipse.remote.core.IRemoteProcessTerminalService;
 import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.internal.jsch.core.messages.Messages;
 
 import com.jcraft.jsch.Channel;
 import com.jcraft.jsch.ChannelExec;
@@ -162,6 +163,9 @@
 	 */
 	@Override
 	public int exitValue() {
+		if(!isCompleted()) {
+			throw new IllegalThreadStateException(Messages.JSchProcess_exitValue_exception_msg);
+		}
 		return fChannel.getExitStatus();
 	}
 
diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java
index fd288be..dca0d71 100755
--- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java
+++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java
@@ -44,6 +44,7 @@
 	public static String JSchConnectionProxyFactory_ProxyCommandFailed;
 	public static String JSchConnectionProxyFactory_timedOut;
 	public static String JSchConnectionProxyFactory_wasCanceled;
+	public static String JSchProcess_exitValue_exception_msg;
 	public static String JSchProcessBuilder_Connection_is_not_open;
 	public static String JschFileStore_Connection_is_not_open;
 	public static String JschFileStore_File_doesnt_exist;
diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties
index 41b4506..b2e09f3 100755
--- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties
+++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties
@@ -33,6 +33,7 @@
 JSchConnectionProxyFactory_ProxyCommandFailed=Proxy command "{0}" {1} and printed message "{2}"
 JSchConnectionProxyFactory_timedOut=timed out
 JSchConnectionProxyFactory_wasCanceled=was canceled
+JSchProcess_exitValue_exception_msg=process has not exited
 JSchProcessBuilder_Connection_is_not_open=Connection is not open
 JschFileStore_Connection_is_not_open=Connection is not open
 JschFileStore_File_doesnt_exist=File {0} doesn't exist
diff --git a/bundles/org.eclipse.remote.jsch.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.jsch.ui/META-INF/MANIFEST.MF
index 00c083c..1c11522 100644
--- a/bundles/org.eclipse.remote.jsch.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.jsch.ui/META-INF/MANIFEST.MF
@@ -5,20 +5,38 @@
 Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.internal.jsch.ui.Activator
 Bundle-Vendor: %pluginProvider
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
- org.eclipse.core.filesystem,
- org.eclipse.remote.core;bundle-version="2.0",
- org.eclipse.remote.ui,
- org.eclipse.remote.jsch.core,
- org.eclipse.jsch.core,
- org.eclipse.jsch.ui,
- com.jcraft.jsch,
- org.eclipse.ui.forms,
- org.eclipse.ui.ide,
- org.eclipse.ui,
- org.eclipse.jface
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.remote.internal.jsch.ui;x-internal:=true,
  org.eclipse.remote.internal.jsch.ui.messages;x-internal:=true
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: com.jcraft.jsch,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.dialogs,
+ org.eclipse.jface.operation,
+ org.eclipse.jface.preference,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.jface.wizard,
+ org.eclipse.jsch.core,
+ org.eclipse.jsch.ui,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.internal.jsch.core,
+ org.eclipse.remote.ui,
+ org.eclipse.remote.ui.dialogs,
+ org.eclipse.remote.ui.widgets,
+ org.eclipse.swt,
+ org.eclipse.swt.events,
+ org.eclipse.swt.graphics,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui.dialogs,
+ org.eclipse.ui.forms.events,
+ org.eclipse.ui.forms.widgets,
+ org.eclipse.ui.ide.fileSystem,
+ org.eclipse.ui.plugin,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.serial.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.serial.core/META-INF/MANIFEST.MF
index b1ffaa0..302b788 100644
--- a/bundles/org.eclipse.remote.serial.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.serial.core/META-INF/MANIFEST.MF
@@ -5,10 +5,12 @@
 Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.serial.internal.core.Activator
 Bundle-Vendor: %providerName
-Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.remote.core;bundle-version="2.0.0",
- org.eclipse.cdt.native.serial
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.remote.serial.core
 Bundle-Localization: plugin
+Import-Package: org.eclipse.cdt.serial,
+ org.eclipse.core.runtime,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.serial.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.serial.ui/META-INF/MANIFEST.MF
index 7f8de82..c34fe7e 100644
--- a/bundles/org.eclipse.remote.serial.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.serial.ui/META-INF/MANIFEST.MF
@@ -4,13 +4,28 @@
 Bundle-SymbolicName: org.eclipse.remote.serial.ui;singleton:=true
 Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.serial.internal.ui.Activator
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.remote.core;bundle-version="2.0.0",
- org.eclipse.remote.ui;bundle-version="2.0.0",
- org.eclipse.cdt.native.serial;bundle-version="1.0.0",
- org.eclipse.remote.serial.core;bundle-version="1.0.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
+Export-Package: org.eclipse.remote.serial.ui
+Import-Package: org.eclipse.cdt.serial,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.dialogs,
+ org.eclipse.jface.operation,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.jface.wizard,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.serial.core,
+ org.eclipse.remote.ui,
+ org.eclipse.swt,
+ org.eclipse.swt.events,
+ org.eclipse.swt.graphics,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui.plugin,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java
index 0ce8185..c8abdd1 100644
--- a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java
+++ b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java
@@ -20,6 +20,7 @@
 import org.eclipse.remote.core.IRemoteConnectionType;
 import org.eclipse.remote.core.IRemoteConnectionType.Service;
 import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.serial.ui.NewSerialPortConnectionWizard;
 import org.eclipse.remote.ui.AbstractRemoteUIConnectionService;
 import org.eclipse.remote.ui.IRemoteUIConnectionService;
 import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
diff --git a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizard.java b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizard.java
similarity index 88%
rename from bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizard.java
rename to bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizard.java
index dafff96..8f84cf2 100644
--- a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizard.java
+++ b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizard.java
@@ -8,7 +8,7 @@
  * Contributors:
  * QNX Software Systems - initial contribution
  *******************************************************************************/
-package org.eclipse.remote.serial.internal.ui;
+package org.eclipse.remote.serial.ui;
 
 import java.util.Set;
 
@@ -18,6 +18,7 @@
 import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
 import org.eclipse.remote.core.exception.RemoteConnectionException;
 import org.eclipse.remote.serial.core.ISerialPortService;
+import org.eclipse.remote.serial.internal.ui.Activator;
 import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
 import org.eclipse.swt.widgets.Shell;
 
@@ -45,11 +46,11 @@
 			return false;
 		}
 
-		workingCopy.setAttribute(ISerialPortService.PORT_NAME_ATTR, page.portName);
-		workingCopy.setAttribute(ISerialPortService.BAUD_RATE_ATTR, Integer.toString(page.baudRateIndex));
-		workingCopy.setAttribute(ISerialPortService.BYTE_SIZE_ATTR, Integer.toString(page.byteSizeIndex));
-		workingCopy.setAttribute(ISerialPortService.PARITY_ATTR, Integer.toString(page.parityIndex));
-		workingCopy.setAttribute(ISerialPortService.STOP_BITS_ATTR, Integer.toString(page.stopBitsIndex));
+		workingCopy.setAttribute(ISerialPortService.PORT_NAME_ATTR, page.getPortName());
+		workingCopy.setAttribute(ISerialPortService.BAUD_RATE_ATTR, Integer.toString(page.getBaudRateIndex()));
+		workingCopy.setAttribute(ISerialPortService.BYTE_SIZE_ATTR, Integer.toString(page.getByteSizeIndex()));
+		workingCopy.setAttribute(ISerialPortService.PARITY_ATTR, Integer.toString(page.getParityIndex()));
+		workingCopy.setAttribute(ISerialPortService.STOP_BITS_ATTR, Integer.toString(page.getStopBitsIndex()));
 
 		return true;
 	}
@@ -68,7 +69,7 @@
 	public IRemoteConnectionWorkingCopy getConnection() {
 		if (workingCopy == null) {
 			try {
-				workingCopy = connectionType.newConnection(page.name);
+				workingCopy = connectionType.newConnection(page.getName());
 			} catch (RemoteConnectionException e) {
 				Activator.log(e.getStatus());
 			}
diff --git a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizardPage.java b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizardPage.java
similarity index 89%
rename from bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizardPage.java
rename to bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizardPage.java
index cc25f2e..ee80654 100644
--- a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/NewSerialPortConnectionWizardPage.java
+++ b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/ui/NewSerialPortConnectionWizardPage.java
@@ -8,7 +8,7 @@
  * Contributors:
  * QNX Software Systems - initial contribution
  *******************************************************************************/
-package org.eclipse.remote.serial.internal.ui;
+package org.eclipse.remote.serial.ui;
 
 import java.io.IOException;
 
@@ -18,6 +18,8 @@
 import org.eclipse.cdt.serial.SerialPort;
 import org.eclipse.cdt.serial.StopBits;
 import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.remote.serial.internal.ui.Activator;
+import org.eclipse.remote.serial.internal.ui.Messages;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
@@ -32,12 +34,12 @@
 
 public class NewSerialPortConnectionWizardPage extends WizardPage {
 
-	String name;
-	String portName;
-	int baudRateIndex;
-	int byteSizeIndex;
-	int parityIndex;
-	int stopBitsIndex;
+	private String name;
+	private String portName;
+	private int baudRateIndex;
+	private int byteSizeIndex;
+	private int parityIndex;
+	private int stopBitsIndex;
 
 	private String[] portNames;
 
@@ -48,7 +50,7 @@
 	private Combo parityCombo;
 	private Combo stopBitsCombo;
 
-	protected NewSerialPortConnectionWizardPage() {
+	public NewSerialPortConnectionWizardPage() {
 		super(NewSerialPortConnectionWizardPage.class.getName());
 		setDescription(Messages.NewSerialPortConnectionWizardPage_Description);
 		setTitle(Messages.NewSerialPortConnectionWizardPage_Title);
@@ -180,4 +182,28 @@
 		setPageComplete(!name.isEmpty() && portName != null);
 	}
 
+	public String getName() {
+		return name;
+	}
+
+	public String getPortName() {
+		return portName;
+	}
+
+	public int getBaudRateIndex() {
+		return baudRateIndex;
+	}
+
+	public int getByteSizeIndex() {
+		return byteSizeIndex;
+	}
+
+	public int getParityIndex() {
+		return parityIndex;
+	}
+
+	public int getStopBitsIndex() {
+		return stopBitsIndex;
+	}
+
 }
diff --git a/bundles/org.eclipse.remote.telnet.core/.classpath b/bundles/org.eclipse.remote.telnet.core/.classpath
new file mode 100644
index 0000000..098194c
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.remote.telnet.core/.gitignore b/bundles/org.eclipse.remote.telnet.core/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.eclipse.remote.telnet.core/.project b/bundles/org.eclipse.remote.telnet.core/.project
new file mode 100644
index 0000000..cf88212
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.remote.telnet.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.remote.telnet.core/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.remote.telnet.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..f42de36
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/bundles/org.eclipse.remote.telnet.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.telnet.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..358a677
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %bundleName
+Bundle-SymbolicName: org.eclipse.remote.telnet.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.remote.telnet.internal.core.Activator
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.remote.telnet.core,
+ org.eclipse.remote.telnet.internal.core;x-internal:=true
+Bundle-Localization: plugin
+Import-Package: org.eclipse.core.runtime,
+ org.eclipse.osgi.service.debug;version="1.2.0",
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.telnet.core/about.html b/bundles/org.eclipse.remote.telnet.core/about.html
new file mode 100644
index 0000000..3f81093
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/about.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>May 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.telnet.core/about.ini b/bundles/org.eclipse.remote.telnet.core/about.ini
new file mode 100644
index 0000000..5bd1def
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/about.ini
@@ -0,0 +1,27 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=ptp_logo_icon32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+# optional
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
diff --git a/bundles/org.eclipse.remote.telnet.core/about.mappings b/bundles/org.eclipse.remote.telnet.core/about.mappings
new file mode 100644
index 0000000..bddaab4
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+0=@build@
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.telnet.core/about.properties b/bundles/org.eclipse.remote.telnet.core/about.properties
new file mode 100644
index 0000000..ff60b31
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/about.properties
@@ -0,0 +1,22 @@
+###############################################################################
+# Copyright (c) 2015 QNX Software Systems and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     QNX Software Systems - initial API and implementation
+###############################################################################
+
+# NLS_MESSAGEFORMAT_NONE
+# NLS_ENCODING=UTF-8
+
+blurb=Telnet Remote Services\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+Copyright (c) 2015 IBM Corporation, and others.  All rights reserved.\n\
+Visit http://www.eclipse.org/ptp\n
+
diff --git a/bundles/org.eclipse.remote.telnet.core/build.properties b/bundles/org.eclipse.remote.telnet.core/build.properties
new file mode 100644
index 0000000..2b28ace
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/build.properties
@@ -0,0 +1,11 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties,\
+               ptp_logo_icon32.png,\
+               plugin.properties
diff --git a/bundles/org.eclipse.remote.telnet.core/plugin.properties b/bundles/org.eclipse.remote.telnet.core/plugin.properties
new file mode 100644
index 0000000..a8a8ec2
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/plugin.properties
@@ -0,0 +1,2 @@
+bundleName = Remote Serial Port Services
+providerName = Eclipse PTP
diff --git a/bundles/org.eclipse.remote.telnet.core/plugin.xml b/bundles/org.eclipse.remote.telnet.core/plugin.xml
new file mode 100644
index 0000000..0d03a26
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.remote.core.remoteServices">
+      <connectionType
+            id="org.eclipse.remote.telnet.core.connectionType"
+            name="Telnet">
+      </connectionType>
+      <connectionService
+            connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
+            factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
+            service="org.eclipse.remote.core.IRemoteConnectionControlService">
+      </connectionService>
+      <connectionService
+            connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
+            factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
+            service="org.eclipse.remote.core.IRemoteConnectionHostService">
+      </connectionService>
+      <connectionService
+            connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
+            factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
+            service="org.eclipse.remote.core.IRemoteCommandShellService">
+      </connectionService>
+       <connectionService
+            connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
+            factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
+            service="org.eclipse.remote.telnet.core.TelnetConnection">
+      </connectionService>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.remote.telnet.core/pom.xml b/bundles/org.eclipse.remote.telnet.core/pom.xml
new file mode 100644
index 0000000..05580f3
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/pom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.remote</groupId>
+    <artifactId>remote-parent</artifactId>
+    <version>2.0.2-SNAPSHOT</version>
+    <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>org.eclipse.remote.telnet.core</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/bundles/org.eclipse.remote.telnet.core/ptp_logo_icon32.png b/bundles/org.eclipse.remote.telnet.core/ptp_logo_icon32.png
new file mode 100644
index 0000000..e8ec572
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/ptp_logo_icon32.png
Binary files differ
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCodes.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCodes.java
new file mode 100644
index 0000000..3572e91
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCodes.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Fran Litterio (Wind River) - initial API and implementation 
+ * Helmut Haigermoser (Wind River) - repackaged 
+ * Ted Williams (Wind River) - repackaged into org.eclipse namespace 
+ * Michael Scharf (Wind River) - split into core, view and connector plugins 
+ * Martin Oberhuber (Wind River) - fixed copyright headers and beautified
+ * Greg Watson (IBM) - Adapted for org.eclipse.remote
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core;
+
+/**
+ * This interface defines symbolic constants for numeric TELNET protocol command and
+ * option codes.  Any class that needs to use these constants must implement this
+ * interface.  The meanings of these constants are defined in the various TELNET RFCs
+ * (RFC 854 to RFC 861, and others).
+ */
+interface TelnetCodes
+{
+    /** Command code: Subnegotiation End. */
+    static final byte TELNET_SE         = (byte)240;
+
+    /** Command code: No-op. */
+    static final byte TELNET_NOP        = (byte)241;
+
+    /** Command code: Data Mark. */
+    static final byte TELNET_DM         = (byte)242;
+
+    /** Command code: Break. */
+    static final byte TELNET_BREAK      = (byte)243;
+
+    /** Command code: Interrupt Process. */
+    static final byte TELNET_IP         = (byte)244;
+
+    /** Command code: Abort Output. */
+    static final byte TELNET_AO         = (byte)245;
+
+    /** Command code: Are You There. */
+    static final byte TELNET_AYT        = (byte)246;
+
+    /** Command code: Erase Character. */
+    static final byte TELNET_EC         = (byte)247;
+
+    /** Command code: Erase Line. */
+    static final byte TELNET_EL         = (byte)248;
+
+    /** Command code: Go Ahead. */
+    static final byte TELNET_GA         = (byte)249;
+
+    /** Command code: Subnegotiation Begin. */
+    static final byte TELNET_SB         = (byte)250;
+
+    /** Command code: Will. */
+    static final byte TELNET_WILL       = (byte)251;
+
+    /** Command code: Won't. */
+    static final byte TELNET_WONT       = (byte)252;
+
+    /** Command code: Do. */
+    static final byte TELNET_DO         = (byte)253;
+
+    /** Command code: Don't. */
+    static final byte TELNET_DONT       = (byte)254;
+
+    /** Command code: Interpret As Command. */
+    static final byte TELNET_IAC        = (byte)255;
+
+    /** Command code: IS. */
+    static final byte TELNET_IS         = 0;
+
+    /** Command code: SEND. */
+    static final byte TELNET_SEND       = 1;
+
+
+    /** Option code: Transmit Binary option. */
+    static final byte TELNET_OPTION_TRANSMIT_BINARY     = 0;
+
+    /** Option code: Echo option. */
+    static final byte TELNET_OPTION_ECHO                = 1;
+
+    /** Option code: Suppress Go Ahead option. */
+    static final byte TELNET_OPTION_SUPPRESS_GA         = 3;
+
+    /** Option code: Terminal Type */
+    static final byte TELNET_OPTION_TERMINAL_TYPE       = 24;
+
+    /** Option code: Negotitate About Window Size (NAWS) */
+    static final byte TELNET_OPTION_NAWS                = 31;
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCommandShell.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCommandShell.java
new file mode 100644
index 0000000..840d828
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetCommandShell.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+
+import org.eclipse.remote.core.IRemoteConnection;
+import org.eclipse.remote.core.IRemoteConnectionHostService;
+import org.eclipse.remote.core.IRemoteProcess;
+import org.eclipse.remote.core.IRemoteProcessBuilder;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.telnet.internal.core.Logger;
+import org.eclipse.remote.telnet.internal.core.messages.Messages;
+
+public class TelnetCommandShell implements IRemoteProcess {
+	private final TelnetConnection telnetConnection;
+	private TelnetProtocol protocol;
+
+	public TelnetCommandShell(IRemoteConnection remoteConnection, TelnetConnection telnetConnection) {
+		this.telnetConnection = telnetConnection;
+		assert(remoteConnection.getService(IRemoteConnectionHostService.class) != null);
+	}
+
+	@Override
+	public void destroy() {
+		if (protocol != null) {
+			protocol.interrupt();
+		}
+	}
+
+	@Override
+	public int exitValue() {
+		return 0;
+	}
+
+	@Override
+	public InputStream getErrorStream() {
+		return null;
+	}
+
+	@Override
+	public InputStream getInputStream() {
+		if (protocol != null) {
+			PipedOutputStream pipedOutput = new PipedOutputStream();
+			protocol.setClientOutputStream(pipedOutput);
+			try {
+				return new PipedInputStream(pipedOutput);
+			} catch (IOException e) {
+				return null;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public OutputStream getOutputStream() {
+		if (protocol != null) {
+			return protocol.getOutputStream();
+		}
+		return null;
+	}
+
+	@Override
+	public int waitFor() throws InterruptedException {
+		if (protocol != null && protocol.isConnected()) {
+			wait();
+		}
+		return 0;
+	}
+
+	@Override
+	public boolean isCompleted() {
+		return protocol == null || !protocol.isAlive();
+	}
+
+	@Override
+	public IRemoteConnection getRemoteConnection() {
+		return telnetConnection.getRemoteConnection();
+	}
+
+	@Override
+	public <T extends Service> T getService(Class<T> service) {
+		return null;
+	}
+
+	@Override
+	public <T extends Service> boolean hasService(Class<T> service) {
+		return false;
+	}
+
+	@Override
+	public IRemoteProcessBuilder getProcessBuilder() {
+		return null;
+	}
+
+	public void connect() throws RemoteConnectionException {
+		IRemoteConnectionHostService hostSvc = telnetConnection.getRemoteConnection()
+				.getService(IRemoteConnectionHostService.class);
+
+		// Retry the connect after a little pause in case the
+		// remote telnet server isn't ready. ConnectExceptions might
+		// happen if the telnet server process did not initialized itself.
+		// This is seen especially if the telnet server is a process
+		// providing it's input and output via a built in telnet server.
+		int remaining = 10;
+
+		while (remaining >= 0) {
+			// Pause before we re-try if the remaining tries are less than the initial value
+			if (remaining < 10) {
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException e) {
+					/* ignored on purpose */ }
+			}
+
+			try {
+				int nTimeout = hostSvc.getTimeout() * 1000;
+				String strHost = hostSvc.getHostname();
+				int nPort = hostSvc.getPort();
+				InetSocketAddress address = new InetSocketAddress(strHost, nPort);
+				Socket socket = new Socket();
+
+				socket.connect(address, nTimeout);
+
+				// If we get to this point, the connect succeeded and we will
+				// force the remaining counter to be 0.
+				remaining = 0;
+
+				// This next call causes reads on the socket to see TCP urgent data
+				// inline with the rest of the non-urgent data. Without this call, TCP
+				// urgent data is silently dropped by Java. This is required for
+				// TELNET support, because when the TELNET server sends "IAC DM", the
+				// IAC byte is TCP urgent data. If urgent data is silently dropped, we
+				// only see the DM, which looks like an ISO Latin-1 '�' character.
+
+				socket.setOOBInline(true);
+				socket.setKeepAlive(true);
+
+				protocol = new TelnetProtocol(socket, this);
+				protocol.start();
+			} catch (UnknownHostException ex) {
+				// No re-try in case of UnknownHostException, there is no indication that
+				// the DNS will fix itself
+				throw new RemoteConnectionException(Messages.TelnetCommandShell_0 + ex.getMessage());
+			} catch (SocketTimeoutException socketTimeoutException) {
+				// Time out occurred. No re-try in this case either. Time out can
+				// be increased by the user. Multiplying the timeout with the remaining
+				// counter is not desired.
+				throw new RemoteConnectionException(socketTimeoutException.getMessage());
+			} catch (ConnectException connectException) {
+				// In case of a ConnectException, do a re-try. The server could have been
+				// simply not ready yet and the worker would give up to early. If the terminal
+				// control is already closed (disconnected), don't print "Connection refused" errors
+				if (remaining == 0) {
+					throw new RemoteConnectionException(connectException.getMessage());
+				}
+			} catch (Exception exception) {
+				// Any other exception on connect. No re-try in this case either
+				// Log the exception
+				Logger.logException(exception);
+				// And signal failed
+				throw new RemoteConnectionException(exception.getMessage());
+			} finally {
+				remaining--;
+			}
+		}
+	}
+
+	protected void terminated() {
+		telnetConnection.terminated(this);
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetConnection.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetConnection.java
new file mode 100644
index 0000000..c1e3710
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetConnection.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.remote.core.IRemoteCommandShellService;
+import org.eclipse.remote.core.IRemoteConnection;
+import org.eclipse.remote.core.IRemoteConnection.Service;
+import org.eclipse.remote.core.IRemoteConnectionChangeListener;
+import org.eclipse.remote.core.IRemoteConnectionControlService;
+import org.eclipse.remote.core.IRemoteConnectionHostService;
+import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
+import org.eclipse.remote.core.IRemoteProcess;
+import org.eclipse.remote.core.RemoteConnectionChangeEvent;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+
+public class TelnetConnection implements IRemoteConnectionControlService, IRemoteCommandShellService, IRemoteConnectionHostService,
+		IRemoteConnectionChangeListener {
+	public static int DEFAULT_PORT = 23;
+	public static int DEFAULT_TIMEOUT = 0; // Infinite
+
+	public static final String HOSTNAME_ATTR = "telnet.hostname.attr"; //$NON-NLS-1$
+	public static final String USERNAME_ATTR = "telnet.username.attr"; //$NON-NLS-1$
+	public static final String PASSWORD_ATTR = "telnet.password.attr"; //$NON-NLS-1$
+	public static final String PORT_ATTR = "telnet.port.attr"; //$NON-NLS-1$
+	public static final String TIMEOUT_ATTR = "telnet.timeout.attr"; //$NON-NLS-1$
+
+	private final IRemoteConnection remoteConnection;
+	private final List<TelnetCommandShell> shells = Collections.synchronizedList(new ArrayList<TelnetCommandShell>());
+	private boolean isOpen;
+
+	private TelnetConnection(IRemoteConnection remoteConnection) {
+		this.remoteConnection = remoteConnection;
+		remoteConnection.addConnectionChangeListener(this);
+	}
+
+	public static class Factory implements IRemoteConnection.Service.Factory {
+		@SuppressWarnings("unchecked")
+		@Override
+		public <T extends Service> T getService(IRemoteConnection remoteConnection, Class<T> service) {
+			if (TelnetConnection.class.equals(service)) {
+				return (T) new TelnetConnection(remoteConnection);
+			} else if (IRemoteConnectionControlService.class.equals(service) || IRemoteConnectionHostService.class.equals(service)
+					|| IRemoteCommandShellService.class.equals(service)) {
+				return (T) remoteConnection.getService(TelnetConnection.class);
+			}
+			return null;
+		}
+	}
+
+	@Override
+	public IRemoteConnection getRemoteConnection() {
+		return remoteConnection;
+	}
+
+	@Override
+	public IRemoteProcess getCommandShell(int flags) throws IOException {
+		if (isOpen) {
+			TelnetCommandShell shell = new TelnetCommandShell(remoteConnection, this);
+			try {
+				shell.connect();
+			} catch (RemoteConnectionException e) {
+				throw new IOException(e.getMessage());
+			}
+			shells.add(shell);
+			return shell;
+		}
+		return null;
+	}
+
+	@Override
+	public int getPort() {
+		try {
+			String portStr = remoteConnection.getAttribute(PORT_ATTR);
+			return !portStr.isEmpty() ? Integer.parseInt(portStr) : DEFAULT_PORT;
+		} catch (NumberFormatException e) {
+			return -1;
+		}
+	}
+
+	@Override
+	public int getTimeout() {
+		try {
+			String timeoutStr = remoteConnection.getAttribute(TIMEOUT_ATTR);
+			return !timeoutStr.isEmpty() ? Integer.parseInt(timeoutStr) : DEFAULT_TIMEOUT;
+		} catch (NumberFormatException e) {
+			return -1;
+		}
+	}
+
+	@Override
+	public void close() {
+		synchronized (shells) {
+			for (TelnetCommandShell shell : shells) {
+				shell.destroy();
+			}
+		}
+		isOpen = false;
+	}
+
+	@Override
+	public String getHostname() {
+		return remoteConnection.getAttribute(HOSTNAME_ATTR);
+	}
+
+	@Override
+	public boolean useLoginShell() {
+		return true;
+	}
+
+	@Override
+	public String getUsername() {
+		return remoteConnection.getAttribute(USERNAME_ATTR);
+	}
+
+	@Override
+	public void setHostname(String hostname) {
+		if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
+			IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
+			wc.setAttribute(HOSTNAME_ATTR, hostname);
+		}
+	}
+
+	@Override
+	public void setPassphrase(String passphrase) {
+		// Ignore
+	}
+
+	@Override
+	public void setPassword(String password) {
+		if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
+			IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
+			wc.setSecureAttribute(PASSWORD_ATTR, password);
+		}
+	}
+
+	@Override
+	public void setPort(int port) {
+		if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
+			IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
+			wc.setAttribute(PORT_ATTR, Integer.toString(port));
+		}
+	}
+
+	@Override
+	public void setTimeout(int timeout) {
+		if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
+			IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
+			wc.setAttribute(TIMEOUT_ATTR, Integer.toString(timeout));
+		}
+	}
+
+	@Override
+	public void setUseLoginShell(boolean useLogingShell) {
+		// Ignore
+	}
+
+	@Override
+	public void setUsePassword(boolean usePassword) {
+		// Ignore
+	}
+
+	@Override
+	public void setUsername(String username) {
+		if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
+			IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
+			wc.setAttribute(USERNAME_ATTR, username);
+		}
+	}
+
+	@Override
+	public void open(IProgressMonitor monitor) throws RemoteConnectionException {
+		isOpen = true;
+	}
+
+	@Override
+	public boolean isOpen() {
+		return isOpen;
+	}
+
+	@Override
+	public void connectionChanged(RemoteConnectionChangeEvent event) {
+		switch (event.getType()) {
+		case RemoteConnectionChangeEvent.CONNECTION_OPENED:
+			isOpen = true;
+			break;
+
+		case RemoteConnectionChangeEvent.CONNECTION_ABORTED:
+		case RemoteConnectionChangeEvent.CONNECTION_CLOSED:
+			isOpen = false;
+			break;
+		}
+	}
+
+	protected void terminated(TelnetCommandShell shell) {
+		shells.remove(shell);
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetOption.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetOption.java
new file mode 100644
index 0000000..e37b553
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetOption.java
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following Wind River employees contributed to the Terminal component
+ * that contains this file: Chris Thew, Fran Litterio, Stephen Lamb,
+ * Helmut Haigermoser and Ted Williams.
+ *
+ * Contributors:
+ * Michael Scharf (Wind River) - split into core, view and connector plugins
+ * Martin Oberhuber (Wind River) - fixed copyright headers and beautified
+ * Martin Oberhuber (Wind River) - [267181] Fix telnet option negotiation loop
+ * Anton Leherbauer (Wind River) - [453393] Add support for copying wrapped lines without line break
+ * Greg Watson (IBM) - Adapted for org.eclipse.remote
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+
+import org.eclipse.remote.telnet.internal.core.Logger;
+
+/**
+ * This class represents a single TELNET protocol option at one endpoint of a TELNET
+ * connection. This class encapsulates the endpoint associated with the option (local
+ * or remote), the current state of the option (enabled or disabled), the desired state
+ * of the option, the current state of the negotiation, an OutputStream that allows
+ * communication with the remote endpoint, and the number of negotiations that have
+ * started within this connection.
+ * <p>
+ *
+ * In addition to encapsulating the above state, this class performs option negotiation
+ * to attempt to achieve the desired option state. For some options, this class also
+ * performs option sub-negotiation.
+ * <p>
+ *
+ * IMPORTANT: Understanding this code requires understanding the TELNET protocol and
+ * TELNET option processing.
+ * <p>
+ *
+ * @author Fran Litterio (francis.litterio@windriver.com)
+ */
+class TelnetOption implements TelnetCodes {
+	/**
+	 * This array of Strings maps an integer TELNET option code value to the symbolic
+	 * name of the option. Array elements of the form "?" represent unassigned option
+	 * values.
+	 */
+	protected static final String[] optionNames = { "BINARY", // 0 //$NON-NLS-1$
+			"ECHO", // 1 //$NON-NLS-1$
+			"RECONNECTION", // 2 //$NON-NLS-1$
+			"SUPPRESS GO AHEAD", // 3 //$NON-NLS-1$
+			"MSG SIZE NEGOTIATION", // 4 //$NON-NLS-1$
+			"STATUS", // 5 //$NON-NLS-1$
+			"TIMING MARK", // 6 //$NON-NLS-1$
+			"REMOTE CTRL TRANS+ECHO", // 7 //$NON-NLS-1$
+			"OUTPUT LINE WIDTH", // 8 //$NON-NLS-1$
+			"OUTPUT PAGE SIZE", // 9 //$NON-NLS-1$
+			"OUTPUT CR DISPOSITION", // 10 //$NON-NLS-1$
+			"OUTPUT HORIZ TABSTOPS", // 11 //$NON-NLS-1$
+			"OUTPUT HORIZ TAB DISPOSITION", // 12 //$NON-NLS-1$
+			"OUTPUT FORMFEED DISPOSITION", // 13 //$NON-NLS-1$
+			"OUTPUT VERTICAL TABSTOPS", // 14 //$NON-NLS-1$
+			"OUTPUT VT DISPOSITION", // 15 //$NON-NLS-1$
+			"OUTPUT LF DISPOSITION", // 16 //$NON-NLS-1$
+			"EXTENDED ASCII", // 17 //$NON-NLS-1$
+			"LOGOUT", // 18 //$NON-NLS-1$
+			"BYTE MACRO", // 19 //$NON-NLS-1$
+			"DATA ENTRY TERMINAL", // 20 //$NON-NLS-1$
+			"SUPDUP", // 21 //$NON-NLS-1$
+			"SUPDUP OUTPUT", // 22 //$NON-NLS-1$
+			"SEND LOCATION", // 23 //$NON-NLS-1$
+			"TERMINAL TYPE", // 24 //$NON-NLS-1$
+			"END OF RECORD", // 25 //$NON-NLS-1$
+			"TACACS USER IDENTIFICATION", // 26 //$NON-NLS-1$
+			"OUTPUT MARKING", // 27 //$NON-NLS-1$
+			"TERMINAL LOCATION NUMBER", // 28 //$NON-NLS-1$
+			"3270 REGIME", // 29 //$NON-NLS-1$
+			"X.3 PAD", // 30 //$NON-NLS-1$
+			"NEGOTIATE ABOUT WINDOW SIZE", // 31 //$NON-NLS-1$
+			"TERMINAL SPEED", // 32 //$NON-NLS-1$
+			"REMOTE FLOW CONTROL", // 33 //$NON-NLS-1$
+			"LINEMODE", // 34 //$NON-NLS-1$
+			"X DISPLAY LOCATION", // 35 //$NON-NLS-1$
+			"ENVIRONMENT OPTION", // 36 //$NON-NLS-1$
+			"AUTHENTICATION OPTION", // 37 //$NON-NLS-1$
+			"ENCRYPTION OPTION", // 38 //$NON-NLS-1$
+			"NEW ENVIRONMENT OPTION", // 39 //$NON-NLS-1$
+			"TN3270E", // 40 //$NON-NLS-1$
+			"XAUTH", // 41 //$NON-NLS-1$
+			"CHARSET", // 42 //$NON-NLS-1$
+			"REMOTE SERIAL PORT", // 43 //$NON-NLS-1$
+			"COM PORT CONTROL OPTION", // 44 //$NON-NLS-1$
+			"SUPPRESS LOCAL ECHO", // 45 //$NON-NLS-1$
+			"START TLS", // 46 //$NON-NLS-1$
+			"KERMIT", // 47 //$NON-NLS-1$
+			"SEND URL", // 48 //$NON-NLS-1$
+			"FORWARD X", // 49 //$NON-NLS-1$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 50 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+																// ...
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", // ... //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+												// 137
+			"TELOPT PRAGMA LOGON", // 138 //$NON-NLS-1$
+			"TELOPT SSPI LOGON", // 139 //$NON-NLS-1$
+			"TELOPT PRAGMA HEARTBEAT", // 140 //$NON-NLS-1$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 141 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+																// ...
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+			"?", "?", "?", "?", // ... 254 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			"EXTENDED OPTIONS LIST" // 255 //$NON-NLS-1$
+	};
+
+	/**
+	 * Negotiation state: Negotiation not yet started for this option.
+	 * <p>
+	 *
+	 * This constant and the others having similar names represent the states of a
+	 * finite state automaton (FSA) that tracks the negotiation state of this option.
+	 * The initial state is NEGOTIATION_NOT_STARTED. The state machine is as follows
+	 * (with transitions labeled with letters in parentheses):
+	 * <p>
+	 *
+	 * <pre>
+	 *     NEGOTIATION_NOT_STARTED -----> {@link #NEGOTIATION_IN_PROGRESS}
+	 *                         |    (A)      |        ^
+	 *                      (C)|          (B)|        |(D)
+	 *                         |             V        |
+	 *                         +--------> {@link #NEGOTIATION_DONE}
+	 * </pre>
+	 * <p>
+	 *
+	 * Once the FSA leaves state NEGOTIATION_NOT_STARTED, it never returns to that
+	 * state. Transition A happens when the local endpoint sends an option command
+	 * before receiving a command for the same option from the remote endpoint.
+	 * <p>
+	 *
+	 * Transition B happens when the local endpoint receives a reply to an option
+	 * command sent earlier by the local endpoint. Receipt of that reply terminates
+	 * the negotiation.
+	 * <p>
+	 *
+	 * Transition D happens after negotiation is done and "something changes" (see the
+	 * RFCs for the definition of "something changes"). Either endpoint can
+	 * re-negotiate an option after a previous negotiation, but only if some external
+	 * influence (such as the user or the OS) causes it to do so. Re-negotiation must
+	 * start more than {@link #NEGOTIATION_IGNORE_DURATION} milliseconds after the FSA
+	 * enters state NEGOTIATION_DONE or it will be ignored. This is how this client
+	 * prevents negotiation loops.
+	 * <p>
+	 *
+	 * Transition C happens when the local endpoint receives an option command from the
+	 * remote endpoint before sending a command for the same option. In that case, the
+	 * local endpoint replies immediately with an option command and the negotiation
+	 * terminates.
+	 * <p>
+	 *
+	 * Some TELNET servers (e.g., the Solaris server), after sending WILL and receiving
+	 * DONT, will reply with a superfluous WONT. Any such superfluous option command
+	 * received from the remote endpoint while the option's FSA is in state
+	 * {@link #NEGOTIATION_DONE} will be ignored by the local endpoint.
+	 */
+	protected static final int NEGOTIATION_NOT_STARTED = 0;
+
+	/** Negotiation state: Negotiation is in progress for this option. */
+	protected static final int NEGOTIATION_IN_PROGRESS = 1;
+
+	/** Negotiation state: Negotiation has terminated for this option. */
+	protected static final int NEGOTIATION_DONE = 2;
+
+	/**
+	 * The number of milliseconds following the end of negotiation of this option
+	 * before which the remote endpoint can re-negotiate the option. Any option
+	 * command received from the remote endpoint before this time passes is ignored.
+	 * This is used to prevent option negotiation loops.
+	 *
+	 * @see #ignoreNegotiation()
+	 * @see #negotiationCompletionTime
+	 */
+	protected static final int NEGOTIATION_IGNORE_DURATION = 30000;
+
+	/**
+	 * This field holds the current negotiation state for this option.
+	 */
+	protected int negotiationState = NEGOTIATION_NOT_STARTED;
+
+	/**
+	 * This field holds the time when negotiation of this option most recently
+	 * terminated (i.e., entered state {@link #NEGOTIATION_DONE}). This is used to
+	 * determine whether an option command received from the remote endpoint after
+	 * negotiation has terminated for this option is to be ignored or interpreted as
+	 * the start of a new negotiation.
+	 *
+	 * @see #NEGOTIATION_IGNORE_DURATION
+	 */
+	protected Date negotiationCompletionTime = new Date(0);
+
+	/**
+	 * Holds the total number of negotiations that have completed for this option.
+	 */
+	protected int negotiationCount = 0;
+
+	/**
+	 * Holds the integer code representing the option.
+	 */
+	protected byte option = 0;
+
+	/**
+	 * Holds the OutputStream object that allows data to be sent to the remote endpoint
+	 * of the TELNET connection.
+	 */
+	protected OutputStream outputStream;
+
+	/**
+	 * True if this option is for the local endpoint, false for the remote endpoint.
+	 */
+	protected boolean local = true;
+
+	/**
+	 * This field is true if the option is enabled, false if it is disabled. All
+	 * options are initially disabled until they are negotiated to be enabled.
+	 * <p>
+	 */
+	protected boolean enabled = false;
+
+	/**
+	 * This field is true if the client desires the option to be enabled, false if the
+	 * client desires the option to be disabled. This field does not represent the
+	 * remote's endpoints desire (as expressed via WILL and WONT commands) -- it
+	 * represnet the local endpoint's desire.
+	 * <p>
+	 *
+	 * @see #setDesired(boolean)
+	 */
+	protected boolean desired = false;
+
+	/**
+	 * Constructor.
+	 * <p>
+	 *
+	 * @param option
+	 *            The integer code of this option.
+	 * @param desired
+	 *            Whether we desire this option to be enabled.
+	 * @param local
+	 *            Whether this option is for the local or remote endpoint.
+	 * @param serverOutputStream
+	 *            A stream used to negotiate with the remote endpoint.
+	 */
+	TelnetOption(byte option, boolean desired, boolean local, OutputStream outputStream) {
+		this.option = option;
+		this.desired = desired;
+		this.local = local;
+		this.outputStream = outputStream;
+	}
+
+	/**
+	 * @return Returns a String containing the name of the TELNET option specified in
+	 *         parameter <i>option</i>.
+	 */
+	public String optionName() {
+		return optionNames[option & 0xFF];
+	}
+
+	/**
+	 * Returns true if this option is enabled, false if it is disabled.
+	 * <p>
+	 *
+	 * @return Returns true if this option is enabled, false if it is disabled.
+	 */
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	/**
+	 * Enables this option if <i>newValue</i> is true, otherwise disables this
+	 * option.
+	 * <p>
+	 *
+	 * @param newValue
+	 *            True if this option is to be enabled, false otherwise.
+	 */
+	public void setEnabled(boolean newValue) {
+		Logger.log("Enabling " + (local ? "local" : "remote") + " option " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+				optionName());
+		enabled = newValue;
+	}
+
+	/**
+	 * Returns true if the local endpoint desires this option to be enabled, false if
+	 * not. It is not an error for the value returned by this method to differ from
+	 * the value returned by isEnabled(). The value returned by this method can change
+	 * over time, reflecting the local endpoint's changing desire regarding the
+	 * option.
+	 * <p>
+	 *
+	 * NOTE: Even if this option represents a remote endpoint option, the return value
+	 * of this method represents the local endpint's desire regarding the remote
+	 * option.
+	 * <p>
+	 *
+	 * @return Returns true if the local endpoint desires this option to be enabled,
+	 *         false if not.
+	 */
+	public boolean isDesired() {
+		return desired;
+	}
+
+	/**
+	 * Sets our desired value for this option. Note that the option can be desired
+	 * when <i>enabled</i> is false, and the option can be undesired when
+	 * <i>enabled</i> is true, though the latter state should not persist, since either
+	 * endpoint can disable any option at any time.
+	 * <p>
+	 *
+	 * @param newValue
+	 *            True if we desire this option to be enabled, false if
+	 *            we desire this option to be disabled.
+	 */
+	public void setDesired(boolean newValue) {
+		if (newValue) {
+			Logger.log("Setting " + (local ? "local" : "remote") + " option " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+					optionName() + " as desired."); //$NON-NLS-1$
+		}
+
+		desired = newValue;
+	}
+
+	/**
+	 * Call this method to request that negotiation begin for this option. This method
+	 * does nothing if negotiation for this option has already started or is already
+	 * complete. If negotiation has not yet started for this option and the local
+	 * endpoint desires this option to be enabled, then we send a WILL or DO command to
+	 * the remote endpoint.
+	 */
+	public void negotiate() {
+		if (negotiationState == NEGOTIATION_NOT_STARTED && desired) {
+			if (local) {
+				Logger.log("Starting negotiation for local option " + optionName()); //$NON-NLS-1$
+				sendWill();
+			} else {
+				Logger.log("Starting negotiation for remote option " + optionName()); //$NON-NLS-1$
+				sendDo();
+			}
+
+			negotiationState = NEGOTIATION_IN_PROGRESS;
+		}
+	}
+
+	/**
+	 * This method is called whenever we receive a WILL command from the remote
+	 * endpoint.
+	 */
+	public void handleWill() {
+		if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
+			Logger.log("Ignoring superfluous WILL command from remote endpoint."); //$NON-NLS-1$
+			return;
+		}
+
+		if (negotiationState == NEGOTIATION_IN_PROGRESS) {
+			if (desired) {
+				// We sent DO and server replied with WILL. Enable the option, and end
+				// this negotiation.
+
+				enabled = true;
+				Logger.log("Enabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			} else {
+				// This should never happen! We sent DONT and the server replied with
+				// WILL. Bad server. No soup for you. Disable the option, and end
+				// this negotiation.
+
+				Logger.log("Server answered DONT with WILL!"); //$NON-NLS-1$
+				enabled = false;
+				Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			}
+		} else {
+			if (desired) {
+				// Server sent WILL, so we reply with DO. Enable the option, and end
+				// this negotiation.
+
+				sendDo();
+				enabled = true;
+				Logger.log("Enabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			} else {
+				// Server sent WILL, so we reply with DONT. Disable the option, and
+				// end this negotiation.
+
+				sendDont();
+				enabled = false;
+				Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			}
+		}
+	}
+
+	/**
+	 * Handles a WONT command sent by the remote endpoint for this option. The value
+	 * of <i>desired</i> doesn't matter in this method, because the remote endpoint is
+	 * forcing the option to be disabled.
+	 */
+	public void handleWont() {
+		if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
+			Logger.log("Ignoring superfluous WONT command from remote endpoint."); //$NON-NLS-1$
+			return;
+		}
+
+		if (negotiationState == NEGOTIATION_IN_PROGRESS) {
+			// We sent DO or DONT and server replied with WONT. Disable the
+			// option, and end this negotiation.
+
+			enabled = false;
+			Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+			endNegotiation();
+		} else {
+			// Server sent WONT, so we reply with DONT. Disable the option, and
+			// end this negotiation.
+
+			sendDont();
+			enabled = false;
+			Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+			endNegotiation();
+		}
+	}
+
+	/**
+	 * Handles a DO command sent by the remote endpoint for this option.
+	 */
+	public void handleDo() {
+		if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
+			Logger.log("Ignoring superfluous DO command from remote endpoint."); //$NON-NLS-1$
+			return;
+		}
+
+		if (negotiationState == NEGOTIATION_IN_PROGRESS) {
+			if (desired) {
+				// We sent WILL and server replied with DO. Enable the option, and end
+				// this negotiation.
+
+				enabled = true;
+				Logger.log("Enabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			} else {
+				// We sent WONT and server replied with DO. This should never happen!
+				// Bad server. No soup for you. Disable the option, and end this
+				// negotiation.
+
+				Logger.log("Server answered WONT with DO!"); //$NON-NLS-1$
+				enabled = false;
+				Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			}
+		} else {
+			if (desired) {
+				// Server sent DO, so we reply with WILL. Enable the option, and end
+				// this negotiation.
+
+				sendWill();
+				enabled = true;
+				Logger.log("Enabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			} else {
+				// Server sent DO, so we reply with WONT. Disable the option, and end
+				// this negotiation.
+
+				sendWont();
+				enabled = false;
+				Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				endNegotiation();
+			}
+		}
+	}
+
+	/**
+	 * Handles a DONT command sent by the remote endpoint for this option. The value
+	 * of <i>desired</i> doesn't matter in this method, because the remote endpoint is
+	 * forcing the option to be disabled.
+	 */
+	public void handleDont() {
+		if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
+			Logger.log("Ignoring superfluous DONT command from remote endpoint."); //$NON-NLS-1$
+			return;
+		}
+
+		if (negotiationState == NEGOTIATION_IN_PROGRESS) {
+			// We sent WILL or WONT and server replied with DONT. Disable the
+			// option, and end this negotiation.
+
+			enabled = false;
+			Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+			endNegotiation();
+		} else {
+			// Server sent DONT, so we reply with WONT. Disable the option, and end
+			// this negotiation.
+
+			sendWont();
+			enabled = false;
+			Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+			endNegotiation();
+		}
+	}
+
+	/**
+	 * This method handles a subnegotiation command received from the remote endpoint.
+	 * Currently, the only subnegotiation we handle is when the remote endpoint
+	 * commands us to send our terminal type (which is "xterm").
+	 *
+	 * @param subnegotiationData
+	 *            An array of bytes containing a TELNET
+	 *            subnegotiation command received from the
+	 *            remote endpoint.
+	 * @param count
+	 *            The number of bytes in array
+	 *            subnegotiationData to examine.
+	 */
+	public void handleSubnegotiation(byte[] subnegotiationData, int count) {
+		switch (option) {
+		case TELNET_OPTION_TERMINAL_TYPE:
+			if (subnegotiationData[1] != TELNET_SEND) {
+				// This should never happen!
+				Logger.log("Invalid TERMINAL-TYPE subnegotiation command from remote endpoint: " + //$NON-NLS-1$
+						(subnegotiationData[1] & 0xff));
+				break;
+			}
+
+			// Tell the remote endpoint our terminal type is "ansi" using this sequence
+			// of TELNET protocol bytes:
+			//
+			// IAC SB TERMINAL-TYPE IS x t e r m IAC SE
+
+			byte[] terminalTypeData = { TELNET_IAC, TELNET_SB, TELNET_OPTION_TERMINAL_TYPE, TELNET_IS, (byte) 'x', (byte) 't',
+					(byte) 'e', (byte) 'r', (byte) 'm', TELNET_IAC, TELNET_SE };
+
+			try {
+				outputStream.write(terminalTypeData);
+			} catch (IOException ex) {
+				Logger.log("IOException sending TERMINAL-TYPE subnegotiation!"); //$NON-NLS-1$
+				Logger.logException(ex);
+			}
+			break;
+
+		default:
+			// This should never happen!
+			Logger.log("SHOULD NOT BE REACHED: Called for option " + optionName()); //$NON-NLS-1$
+			break;
+		}
+	}
+
+	/**
+	 * This method sends a subnegotiation command to the remote endpoint.
+	 *
+	 * @param subnegotiationData
+	 *            An array of Objects holding data to be used
+	 *            when generating the outbound subnegotiation
+	 *            command.
+	 */
+	public void sendSubnegotiation(Object[] subnegotiationData) {
+		switch (option) {
+		case TELNET_OPTION_NAWS:
+			// Get the width and height of the view and send it to the remote
+			// endpoint using this sequence of TELNET protocol bytes:
+			//
+			// IAC SB NAWS <width-highbyte> <width-lowbyte> <height-highbyte>
+			// <height-lowbyte> IAC SE
+
+			byte[] NAWSData = { TELNET_IAC, TELNET_SB, TELNET_OPTION_NAWS, 0, 0, 0, 0, TELNET_IAC, TELNET_SE };
+			int width = ((Integer) subnegotiationData[0]).intValue();
+			int height = ((Integer) subnegotiationData[1]).intValue();
+
+			NAWSData[3] = (byte) ((width >>> 8) & 0xff); // High order byte of width.
+			NAWSData[4] = (byte) (width & 0xff); // Low order byte of width.
+			NAWSData[5] = (byte) ((height >>> 8) & 0xff); // High order byte of height.
+			NAWSData[6] = (byte) (height & 0xff); // Low order byte of height.
+
+			Logger.log("sending terminal size to remote endpoint: width = " + width + //$NON-NLS-1$
+					", height = " + height + "."); //$NON-NLS-1$ //$NON-NLS-2$
+
+			// This final local variable is a hack to get around the fact that inner
+			// classes cannot reference a non-final local variable in a lexically
+			// enclosing scope.
+
+			final byte[] NAWSDataFinal = NAWSData;
+
+			// Send the NAWS data in a new thread. The current thread is the display
+			// thread, and calls to write() can block, but blocking the display thread
+			// is _bad_ (it hangs the GUI).
+
+			Thread t = new Thread() {
+				@Override
+				public void run() {
+					try {
+						outputStream.write(NAWSDataFinal);
+					} catch (IOException ex) {
+						Logger.log("IOException sending NAWS subnegotiation!"); //$NON-NLS-1$
+						Logger.logException(ex);
+					}
+				}
+			};
+			t.setDaemon(true);
+			t.start();
+			break;
+
+		default:
+			// This should never happen!
+			Logger.log("SHOULD NOT BE REACHED: Called for option " + optionName()); //$NON-NLS-1$
+			break;
+		}
+	}
+
+	/**
+	 * This method returns true if there has not yet been any negotiation of this
+	 * option.
+	 *
+	 * @return Returns true if there has not yet been any negotiation of this option.
+	 */
+	protected boolean notYetNegotiated() {
+		return negotiationState == NEGOTIATION_NOT_STARTED;
+	}
+
+	/**
+	 * This method terminates the current negotiation and records the time at which the
+	 * negotiation terminated.
+	 */
+	protected void endNegotiation() {
+		Logger.log("Ending negotiation #" + negotiationCount + " for " + //$NON-NLS-1$ //$NON-NLS-2$
+				(local ? "local" : "remote") + " option " + optionName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		negotiationState = NEGOTIATION_DONE;
+		negotiationCompletionTime.setTime(System.currentTimeMillis());
+		++negotiationCount;
+	}
+
+	/**
+	 * This method determines whether or not to ignore what appears to be a new
+	 * negotiation initiated by the remote endpoint. This is needed because some
+	 * TELNET servers send superfluous option commands that a naive client might
+	 * interpret as the start of a new negotiation. If the superfluous command is not
+	 * ignored, an option negotiation loop can result (which is bad). For details
+	 * about the superfluous commands sent by some servers, see the documentation for
+	 * {@link #NEGOTIATION_NOT_STARTED}.
+	 * <p>
+	 *
+	 * The current implementation of this method returns true if the new negotiation
+	 * starts within NEGOTIATION_IGNORE_DURATION seconds of the end of the previous
+	 * negotiation of this option.
+	 * <p>
+	 *
+	 * @return Returns true if the new negotiation should be ignored, false if not.
+	 */
+	protected boolean ignoreNegotiation() {
+		return (System.currentTimeMillis() - negotiationCompletionTime.getTime()) < NEGOTIATION_IGNORE_DURATION;
+	}
+
+	/**
+	 * Sends a DO command to the remote endpoint for this option.
+	 */
+	protected void sendDo() {
+		Logger.log("Sending DO " + optionName()); //$NON-NLS-1$
+		sendCommand(TELNET_DO);
+	}
+
+	/**
+	 * Sends a DONT command to the remote endpoint for this option.
+	 */
+	protected void sendDont() {
+		Logger.log("Sending DONT " + optionName()); //$NON-NLS-1$
+		sendCommand(TELNET_DONT);
+	}
+
+	/**
+	 * Sends a WILL command to the remote endpoint for this option.
+	 */
+	protected void sendWill() {
+		Logger.log("Sending WILL " + optionName()); //$NON-NLS-1$
+		sendCommand(TELNET_WILL);
+	}
+
+	/**
+	 * Sends a WONT command to the remote endpoint for this option.
+	 */
+	protected void sendWont() {
+		Logger.log("Sending WONT " + optionName()); //$NON-NLS-1$
+		sendCommand(TELNET_WONT);
+	}
+
+	/**
+	 * This method sends a WILL/WONT/DO/DONT command to the remote endpoint for this
+	 * option.
+	 */
+	protected void sendCommand(byte command) {
+		byte[] data = { TELNET_IAC, 0, 0 };
+
+		data[1] = command;
+		data[2] = option;
+
+		try {
+			outputStream.write(data);
+		} catch (IOException ex) {
+			Logger.log("IOException sending command " + command); //$NON-NLS-1$
+			Logger.logException(ex);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetProtocol.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetProtocol.java
new file mode 100644
index 0000000..f334d4f
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/core/TelnetProtocol.java
@@ -0,0 +1,728 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Fran Litterio (Wind River) - initial API and implementation
+ * Helmut Haigermoser (Wind River) - repackaged
+ * Ted Williams (Wind River) - repackaged into org.eclipse namespace
+ * Michael Scharf (Wind River) - split into core, view and connector plugins
+ * Martin Oberhuber (Wind River) - fixed copyright headers and beautified
+ * Michael Scharf (Wind River) - [209665] Add ability to log byte streams from terminal
+ * Alex Panchenko (Xored) - [277061]  TelnetProtocol.isConnected() should check if socket was not closed
+ * Uwe Stieber (Wind River) - [281329] Telnet connection not handling "SocketException: Connection reset" correct
+ * Nils Hagge (Siemens AG) - [276023] close socket streams after connection is disconnected
+ * Greg Watson (IBM) - Adapted for org.eclipse.remote
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.channels.ReadableByteChannel;
+
+import org.eclipse.remote.telnet.internal.core.Logger;
+import org.eclipse.remote.telnet.internal.core.messages.Messages;
+
+/**
+ * This class encapsulates a TELNET connection to a remote server. It processes
+ * incoming TELNET protocol data and generates outbound TELNET protocol data. It
+ * also manages two sets of TelnetOption objects: one for the local endpoint and
+ * one for the remote endpoint.
+ * <p>
+ *
+ * IMPORTANT: Understanding this code requires understanding the TELNET protocol
+ * and TELNET option processing, as defined in the RFCs listed below.
+ * <p>
+ *
+ * @author Fran Litterio (francis.litterio@windriver.com)
+ *
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc854.txt">RFC 854</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc855.txt">RFC 855</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc856.txt">RFC 856</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc857.txt">RFC 857</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc858.txt">RFC 858</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc859.txt">RFC 859</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc860.txt">RFC 860</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc861.txt">RFC 861</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1091.txt">RFC 1091</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1096.txt">RFC 1096</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1073.txt">RFC 1073</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1079.txt">RFC 1079</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1143.txt">RFC 1143</a>
+ * @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1572.txt">RFC 1572</a>
+ */
+public class TelnetProtocol extends Thread implements TelnetCodes {
+	/**
+	 * TELNET connection state: Initial state.
+	 */
+	protected static final int STATE_INITIAL = 0;
+
+	/**
+	 * TELNET connection state: Last byte processed was IAC code. code.
+	 */
+	protected static final int STATE_IAC_RECEIVED = 1;
+
+	/**
+	 * TELNET connection state: Last byte processed was WILL code. code.
+	 */
+	protected static final int STATE_WILL_RECEIVED = 2;
+
+	/**
+	 * TELNET connection state: Last byte processed was WONT code.
+	 */
+	protected static final int STATE_WONT_RECEIVED = 3;
+
+	/**
+	 * TELNET connection state: Last byte processed was DO code.
+	 */
+	protected static final int STATE_DO_RECEIVED = 4;
+
+	/**
+	 * TELNET connection state: Last byte processed was DONT code.
+	 */
+	protected static final int STATE_DONT_RECEIVED = 5;
+
+	/**
+	 * TELNET connection state: Last byte processed was SB.
+	 */
+	protected static final int STATE_SUBNEGOTIATION_STARTED = 6;
+
+	/**
+	 * TELNET connection state: Currently receiving sub-negotiation data.
+	 */
+	protected static final int STATE_RECEIVING_SUBNEGOTIATION = 7;
+
+	/**
+	 * Size of buffer for processing data received from remote endpoint.
+	 */
+	protected static final int BUFFER_SIZE = 2048;
+
+	/**
+	 * Holds raw bytes received from the remote endpoint, prior to any TELNET
+	 * protocol processing.
+	 */
+	protected ByteBuffer rawBytes = ByteBuffer.allocateDirect(BUFFER_SIZE);
+
+	/**
+	 * Holds incoming network data after the TELNET protocol bytes have been
+	 * processed and removed.
+	 */
+	protected byte[] processedBytes = new byte[BUFFER_SIZE];
+
+	/**
+	 * This field holds a StringBuffer containing text recently received from
+	 * the remote endpoint (after all TELNET protocol bytes have been processed
+	 * and removed).
+	 */
+	protected StringBuffer processedStringBuffer = new StringBuffer(BUFFER_SIZE);
+
+	/**
+	 * Holds the current state of the TELNET protocol processor.
+	 */
+	protected int telnetState = STATE_INITIAL;
+
+	/**
+	 * This field is true if the remote endpoint is a TELNET server, false if
+	 * not. We set this to true if and only if the remote endpoint sends
+	 * recognizable TELNET protocol data. We do not assume that the remote
+	 * endpoint is a TELNET server just because it is listening on port 23. This
+	 * allows us to successfully connect to a TELNET server listening on a port
+	 * other than 23.
+	 * <p>
+	 *
+	 * When this field first changes from false to true, we send all WILL or DO
+	 * commands to the remote endpoint.
+	 * <p>
+	 *
+	 * @see #telnetServerDetected()
+	 */
+	protected boolean remoteIsTelnetServer = false;
+
+	/**
+	 * An array of TelnetOption objects representing the local endpoint's TELNET
+	 * options. The array is indexed by the numeric TELNET option code.
+	 */
+	protected TelnetOption[] localOptions = new TelnetOption[256];
+
+	/**
+	 * An array of TelnetOption objects representing the remote endpoint's
+	 * TELNET options. The array is indexed by the numeric TELNET option code.
+	 */
+	protected TelnetOption[] remoteOptions = new TelnetOption[256];
+
+	/**
+	 * An array of bytes that holds the TELNET subnegotiation command most
+	 * recently received from the remote endpoint. This array does _not_ include
+	 * the leading IAC SB bytes, nor does it include the trailing IAC SE bytes.
+	 * The first byte of this array is always a TELNET option code.
+	 */
+	protected byte[] receivedSubnegotiation = new byte[128];
+
+	/**
+	 * This field holds the index into array {@link #receivedSubnegotiation} of
+	 * the next unused byte. This is used by method
+	 * {@link #processTelnetProtocol(int)} when the state machine is in states
+	 * {@link #STATE_SUBNEGOTIATION_STARTED} and {@link
+	 * #STATE_RECEIVING_SUBNEGOTIATION}.
+	 */
+	protected int nextSubnegotiationByteIndex = 0;
+
+	/**
+	 * This field is true if an error occurs while processing a subnegotiation
+	 * command.
+	 *
+	 * @see #processTelnetProtocol(int)
+	 */
+	protected boolean ignoreSubnegotiation = false;
+
+	/**
+	 * This field holds the width of the Terminal screen in columns.
+	 */
+	protected int width = 0;
+
+	/**
+	 * This field holds the height of the Terminal screen in rows.
+	 */
+	protected int height = 0;
+
+	/**
+	 * This field holds a reference to the {@link TelnetCommandShell}.
+	 */
+	protected TelnetCommandShell shell;
+
+	/**
+	 * This method holds the Socket object for the TELNET connection.
+	 */
+	protected Socket socket;
+
+	/**
+	 * This field holds a reference to an {@link ReadableByteChannel} object used to
+	 * receive data from the remote endpoint.
+	 */
+	protected ReadableByteChannel inputChannel;
+
+	/**
+	 * This field holds a reference to an {@link OutputStream} object used to
+	 * send data to the remote endpoint.
+	 */
+	protected OutputStream serverOutputStream;
+
+	/**
+	 * This field holds a reference to an {@link OutputStream} object used to
+	 * send data to the client.
+	 */
+	protected OutputStream clientOutputStream;
+
+	/**
+	 * UNDER CONSTRUCTION
+	 */
+	protected boolean localEcho = true;
+
+	/**
+	 * This constructor just initializes some internal object state from its
+	 * arguments.
+	 */
+	public TelnetProtocol(Socket socket, TelnetCommandShell shell) throws IOException {
+		super();
+
+		Logger.log("entered"); //$NON-NLS-1$
+
+		this.shell = shell;
+		this.socket = socket;
+
+		// serverInputStream = socket.getInputStream();
+		serverOutputStream = socket.getOutputStream();
+		inputChannel = Channels.newChannel(socket.getInputStream());
+
+		initializeOptions();
+	}
+
+	public OutputStream getOutputStream() {
+		return serverOutputStream;
+	}
+
+	public void setClientOutputStream(OutputStream stream) {
+		clientOutputStream = stream;
+	}
+
+	/**
+	 * Returns true if the TCP connection represented by this object is
+	 * connected, false otherwise.
+	 */
+	public boolean isConnected() {
+		return socket != null && socket.isConnected() && !socket.isClosed();
+	}
+
+	/**
+	 * Returns true if the TCP connection represented by this object is
+	 * connected and the remote endpoint is a TELNET server, false otherwise.
+	 */
+	public boolean isRemoteTelnetServer() {
+		return remoteIsTelnetServer;
+	}
+
+	/**
+	 * This method sets the terminal width and height to the supplied values. If
+	 * either new value differs from the corresponding old value, we initiate a
+	 * NAWS subnegotiation to inform the remote endpoint of the new terminal
+	 * size.
+	 */
+	public void setTerminalSize(int newWidth, int newHeight) {
+		Logger.log("Setting new size: width = " + newWidth + ", height = " + newHeight); //$NON-NLS-1$ //$NON-NLS-2$
+		if (!isConnected() || !isRemoteTelnetServer()) {
+			return;
+		}
+		boolean sizeChanged = false;
+
+		if (newWidth != width || newHeight != height) {
+			sizeChanged = true;
+		}
+
+		width = newWidth;
+		height = newHeight;
+
+		if (sizeChanged && remoteIsTelnetServer && localOptions[TELNET_OPTION_NAWS].isEnabled()) {
+			Integer[] sizeData = { Integer.valueOf(width), Integer.valueOf(height) };
+
+			localOptions[TELNET_OPTION_NAWS].sendSubnegotiation(sizeData);
+		}
+	}
+
+	/**
+	 * Returns true if local echoing is enabled for this TCP connection, false
+	 * otherwise.
+	 */
+	public boolean localEcho() {
+		return localEcho;
+	}
+
+	/**
+	 * This method runs in its own thread. It reads raw bytes from the TELNET
+	 * connection socket, processes any TELNET protocol bytes (and removes
+	 * them), and passes the remaining bytes to a TerminalDisplay object for
+	 * display.
+	 */
+	@Override
+	public void run() {
+		Logger.log("Entered"); //$NON-NLS-1$
+
+		try {
+			while (socket.isConnected()) {
+				rawBytes.clear();
+				int nRawBytes = inputChannel.read(rawBytes);
+				if (nRawBytes == -1) {
+					// End of input on serverInputStream.
+					Logger.log("End of input reading from socket!"); //$NON-NLS-1$
+
+					// Announce to the user that the remote endpoint has closed the
+					// connection.
+					if (clientOutputStream != null) {
+						clientOutputStream.write(Messages.TelnetProtocol_0.getBytes());
+					}
+					break;
+				}
+
+				// Process any TELNET protocol data that we receive. Don't
+				// send any TELNET protocol data until we are sure the remote
+				// endpoint is a TELNET server.
+
+				int nProcessedBytes = processTelnetProtocol(nRawBytes);
+
+				if (nProcessedBytes > 0 && clientOutputStream != null) {
+					clientOutputStream.write(processedBytes, 0, nProcessedBytes);
+					clientOutputStream.flush();
+				}
+			}
+		} catch (ClosedByInterruptException e) {
+			// Handled by finally clause
+		} catch (SocketException ex) {
+			String message = ex.getMessage();
+
+			// A "socket closed" exception is normal here. It's caused by the
+			// user clicking the disconnect button on the Terminal view toolbar.
+
+			if (message != null && !message.equalsIgnoreCase("Socket closed") && !message.equalsIgnoreCase("Connection reset")) { //$NON-NLS-1$ //$NON-NLS-2$
+				Logger.logException(ex);
+			}
+
+		} catch (Exception ex) {
+			Logger.logException(ex);
+		} finally {
+			// Tell the command shell that we have terminated
+			shell.terminated();
+			try {
+				if(inputChannel != null) {
+					inputChannel.close();
+				}
+			} catch (IOException ioe) {
+				/* ignore */
+			}
+			try {
+				if(serverOutputStream != null) {
+					serverOutputStream.close();
+				}
+			} catch (IOException ioe) {
+				/* ignore */
+			}
+			try {
+				if(clientOutputStream != null) {
+					clientOutputStream.close();
+				}
+			} catch (IOException ioe) {
+				/* ignore */
+			}
+		}
+	}
+
+	/**
+	 * This method initializes the localOptions[] and remoteOptions[] arrays so
+	 * that they contain references to TelnetOption objects representing our
+	 * desired state for each option. The goal is to achieve server-side
+	 * echoing, suppression of Go Aheads, and to send the local terminal type
+	 * and size to the remote endpoint.
+	 */
+	protected void initializeOptions() {
+		// First, create all the TelnetOption objects in the "undesired" state.
+
+		for (int i = 0; i < localOptions.length; ++i) {
+			localOptions[i] = new TelnetOption((byte) i, false, true, serverOutputStream);
+		}
+
+		for (int i = 0; i < localOptions.length; ++i) {
+			remoteOptions[i] = new TelnetOption((byte) i, false, false, serverOutputStream);
+		}
+
+		// Next, set some of the options to the "desired" state. The options we
+		// desire to be enabled are as follows:
+		//
+		// TELNET Option Desired for Desired for
+		// Name and Code Local Endpoint Remote Endpoint
+		// --------------------- -------------- ---------------
+		// Echo (1) No Yes
+		// Suppress Go Ahead (3) Yes Yes
+		// Terminal Type (24) Yes Yes
+		// NAWS (31) Yes Yes
+		//
+		// All other options remain in the "undesired" state, and thus will be
+		// disabled (since either endpoint can force any option to be disabled by simply
+		// answering WILL with DONT and DO with WONT).
+
+		localOptions[TELNET_OPTION_ECHO].setDesired(false);
+		remoteOptions[TELNET_OPTION_ECHO].setDesired(true);
+
+		localOptions[TELNET_OPTION_SUPPRESS_GA].setDesired(true);
+		remoteOptions[TELNET_OPTION_SUPPRESS_GA].setDesired(true);
+
+		localOptions[TELNET_OPTION_TERMINAL_TYPE].setDesired(true);
+		remoteOptions[TELNET_OPTION_TERMINAL_TYPE].setDesired(true);
+
+		localOptions[TELNET_OPTION_NAWS].setDesired(true);
+		remoteOptions[TELNET_OPTION_NAWS].setDesired(true);
+	}
+
+	/**
+	 * Process TELNET protocol data contained in the first <i>count</i> bytes
+	 * of <i>rawBytes</i>. This function preserves its state between calls,
+	 * because a multi-byte TELNET command might be split between two (or more)
+	 * calls to this function. The state is preserved in field <i>telnetState</i>.
+	 * This function implements an FSA that recognizes TELNET option codes.
+	 * TELNET option sub-negotiation is delegated to instances of TelnetOption.
+	 *
+	 * @return The number of bytes remaining in the buffer after removing all
+	 *         TELNET protocol bytes.
+	 */
+	// TELNET option state is stored in instances of TelnetOption.
+	protected int processTelnetProtocol(int count) {
+		// This is too noisy to leave on all the time.
+		// Logger.log("Processing " + count + " bytes of data.");
+
+		int nextProcessedByte = 0;
+
+		for (int byteIndex = 0; byteIndex < count; ++byteIndex) {
+			// It is possible for control to flow through the below code such
+			// that nothing happens. This happens when array rawBytes[] contains no
+			// TELNET protocol data.
+
+			byte inputByte = rawBytes.get(byteIndex);
+			int ubyte = inputByte & 0xFF;
+
+			switch (telnetState) {
+			case STATE_INITIAL:
+				if (inputByte == TELNET_IAC) {
+					telnetState = STATE_IAC_RECEIVED;
+				} else {
+					// It's not an IAC code, so just append it to
+					// processedBytes.
+
+					processedBytes[nextProcessedByte++] = inputByte;
+				}
+				break;
+
+			case STATE_IAC_RECEIVED:
+				switch (inputByte) {
+				case TELNET_IAC:
+					// Two IAC bytes in a row are translated into one byte with
+					// the
+					// value 0xff.
+
+					processedBytes[nextProcessedByte++] = (byte) 0xff;
+					telnetState = STATE_INITIAL;
+					break;
+
+				case TELNET_WILL:
+					telnetState = STATE_WILL_RECEIVED;
+					break;
+
+				case TELNET_WONT:
+					telnetState = STATE_WONT_RECEIVED;
+					break;
+
+				case TELNET_DO:
+					telnetState = STATE_DO_RECEIVED;
+					break;
+
+				case TELNET_DONT:
+					telnetState = STATE_DONT_RECEIVED;
+					break;
+
+				case TELNET_SB:
+					telnetState = STATE_SUBNEGOTIATION_STARTED;
+					break;
+
+				// Commands to consume and ignore.
+
+				// Data Mark (DM). This is sent by a TELNET server following an
+				// IAC sent as TCP urgent data. It should cause the client to
+				// skip all not yet processed non-TELNET-protocol data preceding the
+				// DM byte. However, Java 1.4.x has no way to inform clients of
+				// class Socket that urgent data is available, so we simply ignore the
+				// "IAC DM" command. Since the IAC is sent as TCP urgent data,
+				// the Socket must be put into OOB-inline mode via a call to
+				// setOOBInline(true), otherwise the IAC is silently dropped by
+				// Java and only the DM arrives (leaving the user to see a
+				// spurious ISO Latin-1 character).
+				case TELNET_DM:
+
+				case TELNET_NOP: // No-op.
+				case TELNET_GA: // Go Ahead command. Meaningless on a full-duplex link.
+				case TELNET_IP: // Interupt Process command. Server should never send this.
+				case TELNET_AO: // Abort Output command. Server should never send this.
+				case TELNET_AYT: // Are You There command. Server should never send this.
+				case TELNET_EC: // Erase Character command. Server should never send this.
+				case TELNET_EL: // Erase Line command. Server should never send this.
+					telnetState = STATE_INITIAL;
+					break;
+
+				default:
+					// Unrecognized command! This should never happen.
+					Logger.log("processTelnetProtocol: UNRECOGNIZED TELNET PROTOCOL COMMAND: " + //$NON-NLS-1$
+							ubyte);
+					telnetState = STATE_INITIAL;
+					break;
+				}
+				break;
+
+			// For the next four cases, WILL and WONT commands affect the state
+			// of remote options, and DO and DONT commands affect the state of
+			// local options.
+
+			case STATE_WILL_RECEIVED:
+				Logger.log("Received WILL " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				remoteOptions[ubyte].handleWill();
+				telnetState = STATE_INITIAL;
+				telnetServerDetected();
+				break;
+
+			case STATE_WONT_RECEIVED:
+				Logger.log("Received WONT " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				remoteOptions[ubyte].handleWont();
+				telnetState = STATE_INITIAL;
+				telnetServerDetected();
+				break;
+
+			case STATE_DO_RECEIVED:
+				Logger.log("Received DO " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				localOptions[ubyte].handleDo();
+				telnetState = STATE_INITIAL;
+				telnetServerDetected();
+				break;
+
+			case STATE_DONT_RECEIVED:
+				Logger.log("Received DONT " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
+				localOptions[ubyte].handleDont();
+				telnetState = STATE_INITIAL;
+				telnetServerDetected();
+				break;
+
+			case STATE_SUBNEGOTIATION_STARTED:
+				Logger.log("Starting subnegotiation for option " + //$NON-NLS-1$
+						localOptions[ubyte].optionName() + "."); //$NON-NLS-1$
+
+				// First, zero out the array of received subnegotiation butes.
+
+				for (int i = 0; i < receivedSubnegotiation.length; ++i) {
+					receivedSubnegotiation[i] = 0;
+				}
+
+				// Forget about any previous subnegotiation errors.
+
+				ignoreSubnegotiation = false;
+
+				// Then insert this input byte into the array and enter state
+				// STATE_RECEIVING_SUBNEGOTIATION, where we will gather the
+				// remaining subnegotiation bytes.
+
+				nextSubnegotiationByteIndex = 0;
+				receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
+				telnetState = STATE_RECEIVING_SUBNEGOTIATION;
+				break;
+
+			case STATE_RECEIVING_SUBNEGOTIATION:
+				if (inputByte == TELNET_IAC) {
+					// Handle double IAC bytes. From RFC 855: "if parameters
+					// in an option 'subnegotiation' include a byte with a value
+					// of 255, it is necessary to double this byte in accordance
+					// the general TELNET rules."
+
+					if (nextSubnegotiationByteIndex > 0 && receivedSubnegotiation[nextSubnegotiationByteIndex - 1] == TELNET_IAC) {
+						// The last input byte we received in this
+						// subnegotiation was IAC, so this is a double IAC. Leave the previous IAC
+						// in the receivedSubnegotiation[] array and drop the current
+						// one (thus translating a double IAC into a single IAC).
+
+						Logger.log("Double IAC in subnegotiation translated into single IAC."); //$NON-NLS-1$
+						break;
+					}
+
+					// Append the IAC byte to receivedSubnegotiation[]. If there
+					// is no room for the IAC byte, it overwrites the last byte,
+					// because we need to know when the subnegotiation ends, and that is
+					// marked by an "IAC SE" command.
+
+					if (nextSubnegotiationByteIndex < receivedSubnegotiation.length) {
+						receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
+					} else {
+						receivedSubnegotiation[receivedSubnegotiation.length - 1] = inputByte;
+					}
+					break;
+				}
+
+				// Handle an "IAC SE" command, which marks the end of the
+				// subnegotiation. An SE byte by itself might be a legitimate
+				// part of the subnegotiation data, so don't do anything unless the SE
+				// is immediately preceded by an IAC.
+
+				if (inputByte == TELNET_SE && receivedSubnegotiation[nextSubnegotiationByteIndex - 1] == TELNET_IAC) {
+					Logger.log("Found SE code marking end of subnegotiation."); //$NON-NLS-1$
+
+					// We are done receiving the subnegotiation command. Now
+					// process it. We always use the option object stored in array
+					// localOptions[] to process the received subnegotiation.
+					// This is an arbitrary decision, but it is sufficient for handling
+					// options TERMINAL-TYPE and NAWS, which are the only options that
+					// we subnegotiate (presently). If, in the future,subnegotiations
+					// need to be handled by option objects stored in both
+					// localOptions[] and remoteOptions[], then some mechanism
+					// to choose the correct option object must be implemented.
+					//
+					// Also, if ignoreSubnegotiation is true, there was an error
+					// while receiving the subnegotiation, so we must not process the
+					// command, and instead just return to the initial state.
+
+					if (!ignoreSubnegotiation) {
+						// Remove the trailing IAC byte from
+						// receivedSubnegotiation[].
+
+						receivedSubnegotiation[nextSubnegotiationByteIndex - 1] = 0;
+
+						int subnegotiatedOption = receivedSubnegotiation[0] & 0xFF;
+
+						localOptions[subnegotiatedOption].handleSubnegotiation(receivedSubnegotiation, nextSubnegotiationByteIndex);
+					} else {
+						Logger.log("NOT CALLING handleSubnegotiation() BECAUSE OF ERRORS!"); //$NON-NLS-1$
+					}
+
+					// Return to the initial state.
+
+					telnetState = STATE_INITIAL;
+				}
+
+				// Check whether the receivedSubnegotiation[] array is full.
+
+				if (nextSubnegotiationByteIndex >= receivedSubnegotiation.length) {
+					// This should not happen. Array receivedSubnegotiation can
+					// hold 128 bytes, and no TELNET option that we perform
+					// subnegotiation for requires that many bytes in a subnegotiation command.
+					// In the interest of robustness, we handle this case by ignoring all
+					// remaining subnegotiation bytes until we receive the IAC SE
+					// command that ends the subnegotiation. Also, we set
+					// ignoreSubnegotiation to true to prevent a call to
+					// handleSubnegotiation() when the IAC SE command arrives.
+
+					Logger.log("SUBNEGOTIATION BUFFER FULL!"); //$NON-NLS-1$
+					ignoreSubnegotiation = true;
+				} else {
+					Logger.log("Recording subnegotiation byte " + ubyte); //$NON-NLS-1$
+
+					receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
+				}
+				break;
+
+			default:
+				// This should _never_ happen! If it does, it means there is a
+				// bug in this FSA. For robustness, we return to the initial state.
+
+				Logger.log("INVALID TELNET STATE: " + telnetState); //$NON-NLS-1$
+				telnetState = STATE_INITIAL;
+				break;
+			}
+		}
+
+		// Return the number of bytes of processed data (i.e., number of bytes
+		// of raw data minus TELNET control bytes). This value can be zero.
+
+		return nextProcessedByte;
+	}
+
+	/**
+	 * This method is called whenever we receive a valid TELNET protocol command
+	 * from the remote endpoint. When it is called for the first time for this
+	 * connection, we negotiate all options that we desire to be enabled.
+	 * <p>
+	 *
+	 * This method does not negotiate options that we do not desire to be
+	 * enabled, because all options are initially disabled.
+	 * <p>
+	 */
+	protected void telnetServerDetected() {
+		if (!remoteIsTelnetServer) {
+			// This block only executes once per TelnetProtocol instance.
+
+			localEcho = false;
+
+			Logger.log("Detected TELNET server."); //$NON-NLS-1$
+
+			remoteIsTelnetServer = true;
+
+			for (TelnetOption localOption : localOptions) {
+				if (localOption.isDesired()) {
+					localOption.negotiate();
+				}
+			}
+
+			for (TelnetOption remoteOption : remoteOptions) {
+				if (remoteOption.isDesired()) {
+					remoteOption.negotiate();
+				}
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Activator.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Activator.java
new file mode 100644
index 0000000..1d1167e
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Activator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends Plugin {
+	public static final String PLUGIN_ID = "org.eclipse.remote.telnet.core"; //$NON-NLS-1$
+
+	private static Plugin plugin;
+
+	@Override
+	public void start(BundleContext bundleContext) throws Exception {
+		plugin = this;
+		Logger.configure(bundleContext);
+	}
+
+	@Override
+	public void stop(BundleContext bundleContext) throws Exception {
+		plugin = null;
+	}
+
+	public static Plugin getDefault() {
+		return plugin;
+	}
+
+	public static void log(IStatus status) {
+		plugin.getLog().log(status);
+	}
+
+	public static void log(Throwable e) {
+		if (e instanceof CoreException) {
+			log(((CoreException) e).getStatus());
+		} else {
+			log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), IStatus.ERROR, e.getLocalizedMessage(), e));
+		}
+	}
+
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Logger.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Logger.java
new file mode 100644
index 0000000..05c5e46
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/Logger.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Fran Litterio (Wind River) - initial API and implementation
+ * Ted Williams (Wind River) - refactored into org.eclipse namespace
+ * Michael Scharf (Wind River) - split into core, view and connector plugins
+ * Martin Oberhuber (Wind River) - fixed copyright headers and beautified
+ * Greg Watson (IBM) - Adapted for org.eclipse.remote
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.core;
+
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
+import org.osgi.framework.BundleContext;
+
+/**
+ * A simple logger class. Every method in this class is static, so they can be
+ * called from both class and instance methods. To use this class, write code
+ * like this:
+ * <p>
+ *
+ * <pre>
+ * Logger.log(&quot;something has happened&quot;);
+ * Logger.log(&quot;counter is &quot; + counter);
+ * </pre>
+ *
+ * @author Fran Litterio <francis.litterio@windriver.com>
+ * 
+ */
+public final class Logger implements DebugOptionsListener {
+	public static final String TRACE_DEBUG_LOG = "org.eclipse.remote.telnet.core/debug/log"; //$NON-NLS-1$
+	public static final String TRACE_DEBUG_LOG_CHAR = "org.eclipse.remote.telnet.coredebug/log/char"; //$NON-NLS-1$
+	public static final String TRACE_DEBUG_LOG_VT100BACKEND = "org.eclipse.remote.telnet.core/debug/log/VT100Backend"; //$NON-NLS-1$
+
+	private static PrintStream logStream;
+	private static Logger logger;
+
+	private DebugOptions options;
+
+	public static void configure(BundleContext context) {
+		if (logger == null) {
+			logger = new Logger(context);
+		}
+	}
+
+	private Logger(BundleContext context) {
+		Hashtable<String, String> props = new Hashtable<String, String>(2);
+		props.put(DebugOptions.LISTENER_SYMBOLICNAME, Activator.PLUGIN_ID);
+		context.registerService(DebugOptionsListener.class.getName(), this, props);
+	}
+
+	/**
+	 * Encodes a String such that non-printable control characters are
+	 * converted into user-readable escape sequences for logging.
+	 * 
+	 * @param message
+	 *            String to encode
+	 * @return encoded String
+	 */
+	public static final String encode(String message) {
+		boolean encoded = false;
+		StringBuffer buf = new StringBuffer(message.length() + 32);
+		for (int i = 0; i < message.length(); i++) {
+			char c = message.charAt(i);
+			switch (c) {
+			case '\\':
+			case '\'':
+				buf.append('\\');
+				buf.append(c);
+				encoded = true;
+				break;
+			case '\r':
+				buf.append('\\');
+				buf.append('r');
+				encoded = true;
+				break;
+			case '\n':
+				buf.append('\\');
+				buf.append('n');
+				encoded = true;
+				break;
+			case '\t':
+				buf.append('\\');
+				buf.append('t');
+				encoded = true;
+				break;
+			case '\f':
+				buf.append('\\');
+				buf.append('f');
+				encoded = true;
+				break;
+			case '\b':
+				buf.append('\\');
+				buf.append('b');
+				encoded = true;
+				break;
+			default:
+				if (c <= '\u000f') {
+					buf.append('\\');
+					buf.append('x');
+					buf.append('0');
+					buf.append(Integer.toHexString(c));
+					encoded = true;
+				} else if (c >= ' ' && c < '\u007f') {
+					buf.append(c);
+				} else if (c <= '\u00ff') {
+					buf.append('\\');
+					buf.append('x');
+					buf.append(Integer.toHexString(c));
+					encoded = true;
+				} else {
+					buf.append('\\');
+					buf.append('u');
+					if (c <= '\u0fff') {
+						buf.append('0');
+					}
+					buf.append(Integer.toHexString(c));
+					encoded = true;
+				}
+			}
+		}
+		if (encoded) {
+			return buf.toString();
+		}
+		return message;
+	}
+
+	/**
+	 * Checks if logging is enabled.
+	 * 
+	 * @return true if logging is enabled.
+	 */
+	public static final boolean isLogEnabled() {
+		return (logStream != null);
+	}
+
+	/**
+	 * Logs the specified message. Do not append a newline to parameter
+	 * <i>message</i>. This method does that for you.
+	 *
+	 * @param message
+	 *            A String containing the message to log.
+	 */
+	public static final void log(String message) {
+		if (logStream != null) {
+			// Read my own stack to get the class name, method name, and line
+			// number of
+			// where this method was called.
+
+			StackTraceElement caller = new Throwable().getStackTrace()[1];
+			int lineNumber = caller.getLineNumber();
+			String className = caller.getClassName();
+			String methodName = caller.getMethodName();
+			className = className.substring(className.lastIndexOf('.') + 1);
+
+			logStream.println(className + "." + methodName + ":" + lineNumber + ": " + message); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+			logStream.flush();
+		}
+	}
+
+	/**
+	 * Writes a stack trace for an exception to both Standard Error and to the
+	 * log file.
+	 */
+	public static final void logException(Exception ex) {
+		// log in eclipse error log
+		if (Activator.getDefault() != null) {
+			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, ex.getMessage(), ex));
+		} else {
+			ex.printStackTrace();
+		}
+		// Additional Tracing for debug purposes:
+		// Read my own stack to get the class name, method name, and line number
+		// of where this method was called
+		if (logStream != null) {
+			StackTraceElement caller = new Throwable().getStackTrace()[1];
+			int lineNumber = caller.getLineNumber();
+			String className = caller.getClassName();
+			String methodName = caller.getMethodName();
+			className = className.substring(className.lastIndexOf('.') + 1);
+
+			PrintStream tmpStream = System.err;
+
+			if (logStream != null) {
+				tmpStream = logStream;
+			}
+
+			tmpStream.println(className + "." + methodName + ":" + lineNumber + ": " + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					"Caught exception: " + ex); //$NON-NLS-1$
+			ex.printStackTrace(tmpStream);
+		}
+	}
+
+	@Override
+	public void optionsChanged(DebugOptions options) {
+		this.options = options;
+
+		// Any of the three known debugging options turns on the creation of the log file
+		boolean createLogFile = isOptionEnabled(TRACE_DEBUG_LOG) || isOptionEnabled(TRACE_DEBUG_LOG_CHAR)
+				|| isOptionEnabled(TRACE_DEBUG_LOG_VT100BACKEND);
+
+		// Log only if tracing is enabled
+		if (createLogFile && Activator.getDefault() != null) {
+			IPath logFile = Platform.getStateLocation(Activator.getDefault().getBundle());
+			if (logFile != null && logFile.toFile().isDirectory()) {
+				logFile = logFile.append("tmterminal.log"); //$NON-NLS-1$
+				try {
+					logStream = new PrintStream(new FileOutputStream(logFile.toFile(), true));
+				} catch (Exception ex) {
+					logStream = System.err;
+					logStream.println("Exception when opening log file -- logging to stderr!"); //$NON-NLS-1$
+					ex.printStackTrace(logStream);
+				}
+			}
+		}
+	}
+
+	public boolean isOptionEnabled(String option) {
+		if (options == null) {
+			return false;
+		}
+		return options.getBooleanOption(Activator.PLUGIN_ID + option, false);
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/Messages.java b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/Messages.java
new file mode 100644
index 0000000..225cebf
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/Messages.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.core.messages;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.remote.telnet.internal.core.messages.messages"; //$NON-NLS-1$
+
+	public static String TelnetCommandShell_0;
+	public static String TelnetProtocol_0;
+
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/messages.properties b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/messages.properties
new file mode 100644
index 0000000..fcab780
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.core/src/org/eclipse/remote/telnet/internal/core/messages/messages.properties
@@ -0,0 +1,12 @@
+################################################################################
+# Copyright (c) 2015 IBM Corporation, and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial contribution
+################################################################################
+TelnetCommandShell_0=Unknown host: 
+TelnetProtocol_0=Connection closed by foreign host.
diff --git a/bundles/org.eclipse.remote.telnet.ui/.classpath b/bundles/org.eclipse.remote.telnet.ui/.classpath
new file mode 100644
index 0000000..eca7bdb
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.remote.telnet.ui/.gitignore b/bundles/org.eclipse.remote.telnet.ui/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.eclipse.remote.telnet.ui/.project b/bundles/org.eclipse.remote.telnet.ui/.project
new file mode 100644
index 0000000..f2325c7
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.remote.telnet.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.remote.telnet.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.remote.telnet.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/bundles/org.eclipse.remote.telnet.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.telnet.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fe35a44
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %bundleName
+Bundle-SymbolicName: org.eclipse.remote.telnet.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.remote.telnet.internal.ui.Activator
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Import-Package: org.eclipse.core.runtime,
+ org.eclipse.jface.dialogs,
+ org.eclipse.jface.operation,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.jface.wizard,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.telnet.core,
+ org.eclipse.remote.ui,
+ org.eclipse.swt,
+ org.eclipse.swt.events,
+ org.eclipse.swt.graphics,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui.plugin,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.telnet.ui/about.html b/bundles/org.eclipse.remote.telnet.ui/about.html
new file mode 100644
index 0000000..3f81093
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/about.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>May 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.telnet.ui/about.ini b/bundles/org.eclipse.remote.telnet.ui/about.ini
new file mode 100644
index 0000000..5bd1def
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/about.ini
@@ -0,0 +1,27 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=ptp_logo_icon32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+# optional
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
diff --git a/bundles/org.eclipse.remote.telnet.ui/about.mappings b/bundles/org.eclipse.remote.telnet.ui/about.mappings
new file mode 100644
index 0000000..bddaab4
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+0=@build@
\ No newline at end of file
diff --git a/bundles/org.eclipse.remote.telnet.ui/about.properties b/bundles/org.eclipse.remote.telnet.ui/about.properties
new file mode 100644
index 0000000..fbf5048
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/about.properties
@@ -0,0 +1,22 @@
+###############################################################################
+# Copyright (c) 2015 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# NLS_MESSAGEFORMAT_NONE
+# NLS_ENCODING=UTF-8
+
+blurb=Telnet Remote Services\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+Copyright (c) 2015 IBM Corporation, and others.  All rights reserved.\n\
+Visit http://www.eclipse.org/ptp\n
+
diff --git a/bundles/org.eclipse.remote.telnet.ui/build.properties b/bundles/org.eclipse.remote.telnet.ui/build.properties
new file mode 100644
index 0000000..14495ae
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/build.properties
@@ -0,0 +1,12 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties,\
+               ptp_logo_icon32.png,\
+               icons/,\
+               plugin.properties
diff --git a/bundles/org.eclipse.remote.telnet.ui/icons/telnet.png b/bundles/org.eclipse.remote.telnet.ui/icons/telnet.png
new file mode 100644
index 0000000..58bc8da
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/icons/telnet.png
Binary files differ
diff --git a/bundles/org.eclipse.remote.telnet.ui/plugin.properties b/bundles/org.eclipse.remote.telnet.ui/plugin.properties
new file mode 100644
index 0000000..214fce2
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/plugin.properties
@@ -0,0 +1,2 @@
+bundleName = Remote Serial Port Services UI
+providerName = Eclipse PTP
diff --git a/bundles/org.eclipse.remote.telnet.ui/plugin.xml b/bundles/org.eclipse.remote.telnet.ui/plugin.xml
new file mode 100644
index 0000000..d123a9c
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.remote.core.remoteServices">
+      <connectionTypeService
+            connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
+            factory="org.eclipse.remote.telnet.internal.ui.TelnetConnectionsUI$Factory"
+            service="org.eclipse.remote.ui.IRemoteUIConnectionService">
+      </connectionTypeService>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.remote.telnet.ui/pom.xml b/bundles/org.eclipse.remote.telnet.ui/pom.xml
new file mode 100644
index 0000000..1292153
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/pom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.remote</groupId>
+    <artifactId>remote-parent</artifactId>
+    <version>2.0.2-SNAPSHOT</version>
+    <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>org.eclipse.remote.telnet.ui</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/bundles/org.eclipse.remote.telnet.ui/ptp_logo_icon32.png b/bundles/org.eclipse.remote.telnet.ui/ptp_logo_icon32.png
new file mode 100644
index 0000000..e8ec572
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/ptp_logo_icon32.png
Binary files differ
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Activator.java b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Activator.java
new file mode 100644
index 0000000..8daf5aa
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Activator.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.remote.telnet.ui"; //$NON-NLS-1$
+
+	// Image keys
+	public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+		getImageRegistry().put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "/icons/telnet.png")); //$NON-NLS-1$
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	public static void log(IStatus status) {
+		plugin.getLog().log(status);
+	}
+
+	public static void log(Exception e) {
+		if (e instanceof CoreException) {
+			log(((CoreException) e).getStatus());
+		} else {
+			log(new Status(IStatus.ERROR, PLUGIN_ID, e.getLocalizedMessage(), e));
+		}
+	}
+
+	public static <T> T getService(Class<T> service) {
+		BundleContext context = plugin.getBundle().getBundleContext();
+		ServiceReference<T> ref = context.getServiceReference(service);
+		return ref != null ? context.getService(ref) : null;
+	}
+
+}
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Messages.java b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Messages.java
new file mode 100644
index 0000000..707a264
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/Messages.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.remote.telnet.internal.ui.messages"; //$NON-NLS-1$
+	public static String NewSerialPortConnectionWizardPage_BaudRateLabel;
+	public static String NewSerialPortConnectionWizardPage_ByteSizeLabel;
+	public static String NewSerialPortConnectionWizardPage_Description;
+	public static String NewSerialPortConnectionWizardPage_NameLabel;
+	public static String NewSerialPortConnectionWizardPage_ParityLabel;
+	public static String NewSerialPortConnectionWizardPage_PortLabel;
+	public static String NewSerialPortConnectionWizardPage_StopBitsLabel;
+	public static String NewSerialPortConnectionWizardPage_Title;
+	public static String TelnetConnectionWizardPage_0;
+	public static String TelnetConnectionWizardPage_1;
+	public static String TelnetConnectionWizardPage_2;
+	public static String TelnetConnectionWizardPage_3;
+	public static String TelnetConnectionWizardPage_4;
+
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizard.java b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizard.java
new file mode 100644
index 0000000..df2267d
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizard.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.ui;
+
+import java.util.Set;
+
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.remote.core.IRemoteConnection;
+import org.eclipse.remote.core.IRemoteConnectionHostService;
+import org.eclipse.remote.core.IRemoteConnectionType;
+import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
+import org.eclipse.swt.widgets.Shell;
+
+public class TelnetConnectionWizard extends Wizard implements IRemoteUIConnectionWizard {
+
+	private TelnetConnectionWizardPage page;
+	private IRemoteConnectionWorkingCopy workingCopy;
+	private final Shell shell;
+	private final IRemoteConnectionType connectionType;
+
+	public TelnetConnectionWizard(Shell shell, IRemoteConnectionType connectionType) {
+		this.shell = shell;
+		this.connectionType = connectionType;
+	}
+
+	@Override
+	public void addPages() {
+		page = new TelnetConnectionWizardPage();
+		if (workingCopy != null) {
+			IRemoteConnectionHostService hostSvc = workingCopy.getService(IRemoteConnectionHostService.class);
+			if (hostSvc != null) {
+				page.setHost(hostSvc.getHostname());
+				page.setPort(hostSvc.getPort());
+				page.setTimeout(hostSvc.getTimeout());
+			}
+		}
+		addPage(page);
+	}
+
+	@Override
+	public boolean performFinish() {
+		IRemoteConnection conn = getConnection();
+		if (conn != null) {
+			IRemoteConnectionHostService hostSvc = conn.getService(IRemoteConnectionHostService.class);
+			if (hostSvc != null) {
+				hostSvc.setHostname(page.getHost());
+				hostSvc.setPort(page.getPort());
+				hostSvc.setTimeout(page.getTimeout());
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public IRemoteConnectionWorkingCopy open() {
+		WizardDialog dialog = new WizardDialog(shell, this);
+		dialog.setBlockOnOpen(true);
+		if (dialog.open() == WizardDialog.OK) {
+			return getConnection();
+		}
+		return null;
+	}
+
+	@Override
+	public IRemoteConnectionWorkingCopy getConnection() {
+		if (workingCopy == null) {
+			try {
+				workingCopy = connectionType.newConnection(page.getHost());
+			} catch (RemoteConnectionException e) {
+				Activator.log(e.getStatus());
+			}
+		}
+		return workingCopy;
+	}
+
+	@Override
+	public void setConnection(IRemoteConnectionWorkingCopy connection) {
+		workingCopy = connection;
+	}
+
+	@Override
+	public void setConnectionName(String name) {
+		// Ignored
+	}
+
+	@Override
+	public void setInvalidConnectionNames(Set<String> names) {
+		// Ignored
+	}
+
+}
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizardPage.java b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizardPage.java
new file mode 100644
index 0000000..62931ed
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionWizardPage.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.ui;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.remote.telnet.core.TelnetConnection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class TelnetConnectionWizardPage extends WizardPage {
+
+	private String host;
+	private int port = TelnetConnection.DEFAULT_PORT;
+	private int timeout = TelnetConnection.DEFAULT_TIMEOUT;
+
+	private Text hostText;
+	private Text portText;
+	private Text timeoutText;
+
+	protected TelnetConnectionWizardPage() {
+		super(TelnetConnectionWizardPage.class.getName());
+		setDescription(Messages.TelnetConnectionWizardPage_0);
+		setTitle(Messages.TelnetConnectionWizardPage_1);
+	}
+
+	@Override
+	public void createControl(Composite parent) {
+		Composite comp = new Composite(parent, SWT.NONE);
+		comp.setLayout(new GridLayout(2, false));
+
+		Label nameLabel = new Label(comp, SWT.NONE);
+		nameLabel.setText(Messages.TelnetConnectionWizardPage_2);
+
+		hostText = new Text(comp, SWT.BORDER | SWT.SINGLE);
+		hostText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		hostText.setText(host != null ? host : ""); //$NON-NLS-1$
+		hostText.addKeyListener(new KeyListener() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				updateStatus();
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) {
+				// Ignore
+			}
+		});
+
+		Label portLabel = new Label(comp, SWT.NONE);
+		portLabel.setText(Messages.TelnetConnectionWizardPage_3);
+
+		portText = new Text(comp, SWT.BORDER | SWT.SINGLE);
+		portText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		portText.setText(port < 0 ? "" : Integer.toString(port)); //$NON-NLS-1$
+		portText.addKeyListener(new KeyListener() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				updateStatus();
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) {
+				// Ignore
+			}
+		});
+
+		Label timeoutLabel = new Label(comp, SWT.NONE);
+		timeoutLabel.setText(Messages.TelnetConnectionWizardPage_4);
+
+		timeoutText = new Text(comp, SWT.BORDER | SWT.SINGLE);
+		timeoutText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		timeoutText.setText(timeout < 0 ? "" : Integer.toString(timeout)); //$NON-NLS-1$
+		timeoutText.addKeyListener(new KeyListener() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				updateStatus();
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) {
+				// Ignore
+			}
+		});
+
+		setControl(comp);
+		updateStatus();
+	}
+
+	private void updateStatus() {
+		host = hostText.getText();
+		try {
+			port = Integer.parseInt(portText.getText());
+		} catch (NumberFormatException e) {
+			port = -1;
+		}
+		try {
+			timeout = Integer.parseInt(timeoutText.getText());
+		} catch (NumberFormatException e) {
+			timeout = -1;
+		}
+
+		setPageComplete(!host.isEmpty());
+	}
+
+	public String getHost() {
+		return host;
+	}
+
+	public int getPort() {
+		return port;
+	}
+
+	public int getTimeout() {
+		return timeout;
+	}
+
+	public void setHost(String host) {
+		this.host = host;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	public void setTimeout(int timeout) {
+		this.timeout = timeout;
+	}
+}
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionsUI.java b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionsUI.java
new file mode 100644
index 0000000..51b5ed7
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/TelnetConnectionsUI.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2015 QNX Software Systems, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial contribution
+ * Greg Watson (IBM) - Adapted for telnet service
+ *******************************************************************************/
+package org.eclipse.remote.telnet.internal.ui;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.remote.core.IRemoteConnection;
+import org.eclipse.remote.core.IRemoteConnectionType;
+import org.eclipse.remote.core.IRemoteConnectionType.Service;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.ui.AbstractRemoteUIConnectionService;
+import org.eclipse.remote.ui.IRemoteUIConnectionService;
+import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+
+public class TelnetConnectionsUI extends AbstractRemoteUIConnectionService {
+
+	private final IRemoteConnectionType connectionType;
+
+	private TelnetConnectionsUI(IRemoteConnectionType connectionType) {
+		this.connectionType = connectionType;
+	}
+
+	public static class Factory implements IRemoteConnectionType.Service.Factory {
+		@SuppressWarnings("unchecked")
+		@Override
+		public <T extends Service> T getService(IRemoteConnectionType connectionType, Class<T> service) {
+			if (IRemoteUIConnectionService.class.equals(service)) {
+				return (T) new TelnetConnectionsUI(connectionType);
+			}
+			return null;
+		}
+	}
+
+	@Override
+	public IRemoteConnectionType getConnectionType() {
+		return connectionType;
+	}
+
+	@Override
+	public IRemoteUIConnectionWizard getConnectionWizard(Shell shell) {
+		return new TelnetConnectionWizard(shell, connectionType);
+	}
+
+	@Override
+	public void openConnectionWithProgress(Shell shell, IRunnableContext context, final IRemoteConnection connection) {
+		try {
+			IRunnableWithProgress op = new IRunnableWithProgress() {
+				@Override
+				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+					try {
+						connection.open(monitor);
+					} catch (RemoteConnectionException e) {
+						throw new InvocationTargetException(e);
+					}
+					if (monitor.isCanceled()) {
+						throw new InterruptedException();
+					}
+				}
+			};
+			if (context != null) {
+				context.run(true, true, op);
+			} else {
+				new ProgressMonitorDialog(shell).run(true, true, op);
+			}
+		} catch (InvocationTargetException | InterruptedException e) {
+			Activator.log(e);
+		}
+	}
+
+	@Override
+	public ILabelProvider getLabelProvider() {
+		return new DefaultLabelProvider() {
+			@Override
+			public Image getImage(Object element) {
+				return Activator.getDefault().getImageRegistry().get(Activator.IMG_CONNECTION_TYPE);
+			}
+		};
+	}
+
+}
diff --git a/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/messages.properties b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/messages.properties
new file mode 100644
index 0000000..1579353
--- /dev/null
+++ b/bundles/org.eclipse.remote.telnet.ui/src/org/eclipse/remote/telnet/internal/ui/messages.properties
@@ -0,0 +1,23 @@
+################################################################################
+# Copyright (c) 2015 IBM Corporation, and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial contribution
+################################################################################
+NewSerialPortConnectionWizardPage_BaudRateLabel=Baud rate:
+NewSerialPortConnectionWizardPage_ByteSizeLabel=Data size:
+NewSerialPortConnectionWizardPage_Description=New serial port connection settings
+NewSerialPortConnectionWizardPage_NameLabel=Connection name:
+NewSerialPortConnectionWizardPage_ParityLabel=Parity:
+NewSerialPortConnectionWizardPage_PortLabel=Serial port:
+NewSerialPortConnectionWizardPage_StopBitsLabel=Stop bits:
+NewSerialPortConnectionWizardPage_Title=New Serial Port Connection
+TelnetConnectionWizardPage_0=New telnet connection settings
+TelnetConnectionWizardPage_1=New Telnet Connection
+TelnetConnectionWizardPage_2=Host
+TelnetConnectionWizardPage_3=Port:
+TelnetConnectionWizardPage_4=Timeout:
diff --git a/bundles/org.eclipse.remote.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.ui/META-INF/MANIFEST.MF
index 7980f4f..a541a0f 100644
--- a/bundles/org.eclipse.remote.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.remote.ui/META-INF/MANIFEST.MF
@@ -5,16 +5,6 @@
 Bundle-Version: 2.0.0.qualifier
 Bundle-Activator: org.eclipse.remote.internal.ui.RemoteUIPlugin
 Bundle-Vendor: %pluginProvider
-Require-Bundle: org.eclipse.ui,
- org.eclipse.ui.ide,
- org.eclipse.ui.forms,
- org.eclipse.core.runtime;bundle-version="3.8.0",
- org.eclipse.remote.core;bundle-version="2.0",
- org.eclipse.core.filesystem,
- org.eclipse.core.resources,
- org.eclipse.ui.trace,
- org.eclipse.ui.navigator,
- org.eclipse.core.expressions
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.remote.internal.ui;x-internal:=true,
@@ -25,3 +15,37 @@
  org.eclipse.remote.ui.dialogs,
  org.eclipse.remote.ui.widgets
 Bundle-Localization: plugin
+Import-Package: org.eclipse.core.commands,
+ org.eclipse.core.expressions,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.core.runtime.jobs,
+ org.eclipse.core.runtime.preferences;version="3.3.0",
+ org.eclipse.jface.action,
+ org.eclipse.jface.dialogs,
+ org.eclipse.jface.operation,
+ org.eclipse.jface.preference,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.util,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.jface.wizard,
+ org.eclipse.osgi.util,
+ org.eclipse.remote.core,
+ org.eclipse.remote.core.exception,
+ org.eclipse.remote.internal.core.preferences,
+ org.eclipse.remote.ui.widgets,
+ org.eclipse.swt,
+ org.eclipse.swt.events,
+ org.eclipse.swt.graphics,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui,
+ org.eclipse.ui.dialogs,
+ org.eclipse.ui.handlers,
+ org.eclipse.ui.model,
+ org.eclipse.ui.navigator,
+ org.eclipse.ui.plugin,
+ org.eclipse.ui.progress,
+ org.osgi.framework
diff --git a/bundles/org.eclipse.remote.ui/plugin.xml b/bundles/org.eclipse.remote.ui/plugin.xml
index c4985df..69b96ad 100644
--- a/bundles/org.eclipse.remote.ui/plugin.xml
+++ b/bundles/org.eclipse.remote.ui/plugin.xml
@@ -220,9 +220,9 @@
             id="org.eclipse.remote.ui.page.connectionProperties"
             name="%ConnectionProperties.name">
          <enabledWhen>
-            <instanceof
-                  value="org.eclipse.remote.core.IRemoteConnection">
-            </instanceof>
+            <adapt
+                  type="org.eclipse.remote.core.IRemoteConnection">
+            </adapt>
          </enabledWhen>
       </page>
    </extension>
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/Messages.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/Messages.java
index 061ea8f..d9d0a0d 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/Messages.java
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/Messages.java
@@ -114,6 +114,13 @@
 	public static String RemoteUIServicesProxy_1;
 	public static String RemoteUIServicesProxy_2;
 
+	public static String CloseConnectionHandler_0;
+	public static String CloseConnectionHandler_1;
+	public static String DeleteRemoteConnectionHandler_ConfirmDeleteMessage;
+	public static String DeleteRemoteConnectionHandler_DeleteConnectionTitle;
+	public static String OpenConnectionHandler_0;
+	public static String OpenConnectionHandler_1;
+
 	static {
 		// initialize resource bundle
 		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/messages.properties b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/messages.properties
index 27db438..d3e2b92 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/messages.properties
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/messages/messages.properties
@@ -1,4 +1,3 @@
-AbstractRemoteUIConnectionManager_Could_not_open_connection=Could not open connection
 ###############################################################################
 # Copyright (c) 2007 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
@@ -6,6 +5,7 @@
 # which accompanies this distribution, and is available at
 # http://www.eclipse.org/legal/epl-v10.html
 ###############################################################################
+AbstractRemoteUIConnectionManager_Could_not_open_connection=Could not open connection
 AbstractRemoteUIConnectionManager_Connection_Error=Connection Error
 ConnectionsPreferencePage_Add=Add
 ConnectionsPreferencePage_Close=Close
@@ -66,3 +66,9 @@
 RemoteUIServices_Configuring_remote_services=Configuring remote services...
 RemoteUIServicesProxy_1=Missing {0} attribute
 RemoteUIServicesProxy_2=Failed to instantiate factory: {0} in type: {1} in plugin: {2}
+CloseConnectionHandler_0=Closing connections
+CloseConnectionHandler_1=Error closing connections
+DeleteRemoteConnectionHandler_ConfirmDeleteMessage=Delete connection
+DeleteRemoteConnectionHandler_DeleteConnectionTitle=Delete Connection
+OpenConnectionHandler_0=Opening connections
+OpenConnectionHandler_1=Error opening connections
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java
index cd62f1c..8131688 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java
@@ -17,6 +17,7 @@
 import org.eclipse.remote.core.IRemoteConnection;
 import org.eclipse.remote.core.IRemoteConnectionControlService;
 import org.eclipse.remote.internal.ui.RemoteUIPlugin;
+import org.eclipse.remote.internal.ui.messages.Messages;
 import org.eclipse.ui.handlers.HandlerUtil;
 
 public class CloseConnectionHandler extends AbstractHandler {
@@ -38,10 +39,12 @@
 			}
 
 			new Job(Messages.CloseConnectionHandler_0) {
+				@Override
 				protected IStatus run(IProgressMonitor monitor) {
 					List<IStatus> status = new ArrayList<>();
 					for (IRemoteConnection connection : connections) {
-						IRemoteConnectionControlService controlService = connection.getService(IRemoteConnectionControlService.class);
+						IRemoteConnectionControlService controlService = connection
+								.getService(IRemoteConnectionControlService.class);
 						if (controlService != null) {
 							controlService.close();
 						}
@@ -50,7 +53,8 @@
 					if (status.isEmpty()) {
 						return Status.OK_STATUS;
 					} else {
-						return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]), Messages.CloseConnectionHandler_1, null);
+						return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]),
+								Messages.CloseConnectionHandler_1, null);
 					}
 				}
 			}.schedule();
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java
index 8597faa..3ac637c 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java
@@ -25,6 +25,7 @@
 import org.eclipse.remote.core.IRemoteConnectionType;
 import org.eclipse.remote.core.exception.RemoteConnectionException;
 import org.eclipse.remote.internal.ui.RemoteUIPlugin;
+import org.eclipse.remote.internal.ui.messages.Messages;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.handlers.HandlerUtil;
 
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java
deleted file mode 100644
index ed6e6f2..0000000
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.eclipse.remote.internal.ui.views;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-	private static final String BUNDLE_NAME = "org.eclipse.remote.internal.ui.views.messages"; //$NON-NLS-1$
-	public static String CloseConnectionHandler_0;
-	public static String CloseConnectionHandler_1;
-	public static String DeleteRemoteConnectionHandler_ConfirmDeleteMessage;
-	public static String DeleteRemoteConnectionHandler_DeleteConnectionTitle;
-	public static String OpenConnectionHandler_0;
-	public static String OpenConnectionHandler_1;
-	static {
-		// initialize resource bundle
-		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-	}
-
-	private Messages() {
-	}
-}
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java
index 7d56e0b..b772677 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java
@@ -18,6 +18,7 @@
 import org.eclipse.remote.core.IRemoteConnectionControlService;
 import org.eclipse.remote.core.exception.RemoteConnectionException;
 import org.eclipse.remote.internal.ui.RemoteUIPlugin;
+import org.eclipse.remote.internal.ui.messages.Messages;
 import org.eclipse.ui.handlers.HandlerUtil;
 
 public class OpenConnectionHandler extends AbstractHandler {
@@ -39,10 +40,12 @@
 			}
 
 			new Job(Messages.OpenConnectionHandler_0) {
+				@Override
 				protected IStatus run(IProgressMonitor monitor) {
 					List<IStatus> status = new ArrayList<>();
 					for (IRemoteConnection connection : connections) {
-						IRemoteConnectionControlService controlService = connection.getService(IRemoteConnectionControlService.class);
+						IRemoteConnectionControlService controlService = connection
+								.getService(IRemoteConnectionControlService.class);
 						if (controlService != null) {
 							try {
 								controlService.open(monitor);
@@ -55,7 +58,8 @@
 					if (status.isEmpty()) {
 						return Status.OK_STATUS;
 					} else {
-						return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]), Messages.OpenConnectionHandler_1, null);
+						return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]),
+								Messages.OpenConnectionHandler_1, null);
 					}
 				}
 			}.schedule();
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties
deleted file mode 100644
index bfcf04c..0000000
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-CloseConnectionHandler_0=Closing connections
-CloseConnectionHandler_1=Error closing connections
-DeleteRemoteConnectionHandler_ConfirmDeleteMessage=Delete connection
-DeleteRemoteConnectionHandler_DeleteConnectionTitle=Delete Connection
-OpenConnectionHandler_0=Openning connections
-OpenConnectionHandler_1=Error openning connections
diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java
index dca4f19..f047cbb 100644
--- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java
+++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java
@@ -12,6 +12,7 @@
 package org.eclipse.remote.ui.widgets;
 
 import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -314,7 +315,7 @@
 								TreePath treePath = treePaths[0];
 								if (treePath.getLastSegment() instanceof DeferredFileStore) {
 									DeferredFileStore element = ((DeferredFileStore) treePath.getLastSegment());
-									String path = element.getFileStore().toURI().getPath();
+									String path = toPath(element.getFileStore().toURI());
 									String newPath = createNewFolder(path);
 									if (newPath != null) {
 										fTreeViewer.expandToLevel(element, 1);
@@ -332,7 +333,7 @@
 						}
 					} else {
 						DeferredFileStore root = (DeferredFileStore) fTreeViewer.getInput();
-						String path = root.getFileStore().toURI().getPath();
+						String path = toPath(root.getFileStore().toURI());
 						String newPath = createNewFolder(path);
 						if (newPath != null) {
 							fTreeViewer.refresh();
@@ -382,7 +383,7 @@
 						}
 					}
 					if (fResources.size() > 0) {
-						fRemotePathText.setText(fResources.get(0).toURI().getPath());
+						fRemotePathText.setText(toPath(fResources.get(0).toURI()));
 					}
 					updateEnablement();
 					notifySelectionChangedListeners(event);
@@ -433,6 +434,10 @@
 		updateEnablement();
 	}
 
+	private String toPath(URI uri) {
+		return getConnection().getService(IRemoteFileService.class).toPath(uri);
+	}
+
 	/**
 	 * Add a listener that will be notified when the selection is changed.
 	 * 
diff --git a/features/org.eclipse.remote-feature/feature.xml b/features/org.eclipse.remote-feature/feature.xml
index bd2932c..3dfe659 100644
--- a/features/org.eclipse.remote-feature/feature.xml
+++ b/features/org.eclipse.remote-feature/feature.xml
@@ -19,20 +19,6 @@
       %license
    </license>
 
-   <requires>
-      <import plugin="org.eclipse.core.runtime"/>
-      <import plugin="org.eclipse.core.filesystem"/>
-      <import plugin="org.eclipse.core.resources"/>
-      <import plugin="org.eclipse.core.variables"/>
-      <import plugin="org.eclipse.ui"/>
-      <import plugin="org.eclipse.ui.ide"/>
-      <import plugin="org.eclipse.equinox.security"/>
-      <import plugin="org.eclipse.ui.forms"/>
-      <import plugin="org.eclipse.jsch.core"/>
-      <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jface"/>
-   </requires>
-
    <plugin
          id="org.eclipse.remote.core"
          download-size="0"
@@ -48,6 +34,13 @@
          unpack="false"/>
 
    <plugin
+         id="org.eclipse.remote.doc.isv"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
          id="org.eclipse.remote.jsch.core"
          download-size="0"
          install-size="0"
diff --git a/features/org.eclipse.remote-feature/pom.xml b/features/org.eclipse.remote-feature/pom.xml
index 2bfe555..c9d50b9 100644
--- a/features/org.eclipse.remote-feature/pom.xml
+++ b/features/org.eclipse.remote-feature/pom.xml
@@ -15,6 +15,11 @@
       <plugin>
         <groupId>org.eclipse.tycho.extras</groupId>
         <artifactId>tycho-source-feature-plugin</artifactId>
+        <configuration>
+            <excludes>
+                <plugin id="org.eclipse.remote.doc.isv"/>
+            </excludes>
+        </configuration>
         <executions>
           <execution>
             <id>source-feature</id>
diff --git a/features/org.eclipse.remote.console-feature/feature.xml b/features/org.eclipse.remote.console-feature/feature.xml
index 14ed391..49d35e7 100644
--- a/features/org.eclipse.remote.console-feature/feature.xml
+++ b/features/org.eclipse.remote.console-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.remote.console"
       label="%featureName"
-      version="2.0.2.qualifier"
+      version="2.1.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.remote.console-feature/pom.xml b/features/org.eclipse.remote.console-feature/pom.xml
index df3490c..b472f1d 100644
--- a/features/org.eclipse.remote.console-feature/pom.xml
+++ b/features/org.eclipse.remote.console-feature/pom.xml
@@ -12,7 +12,7 @@
 
   <groupId>org.eclipse.remote.features</groupId>
   <artifactId>org.eclipse.remote.console</artifactId>
-  <version>2.0.2-SNAPSHOT</version>
+  <version>2.1.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 
   <build>
diff --git a/features/org.eclipse.remote.telnet-feature/.project b/features/org.eclipse.remote.telnet-feature/.project
new file mode 100644
index 0000000..3951b60
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.remote.telnet-feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.remote.telnet-feature/build.properties b/features/org.eclipse.remote.telnet-feature/build.properties
new file mode 100644
index 0000000..db80add
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+               feature.properties,\
+               epl-v10.html,\
+               eclipse_update_120.jpg
diff --git a/features/org.eclipse.remote.telnet-feature/eclipse_update_120.jpg b/features/org.eclipse.remote.telnet-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.remote.telnet-feature/epl-v10.html b/features/org.eclipse.remote.telnet-feature/epl-v10.html
new file mode 100644
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.remote.telnet-feature/feature.properties b/features/org.eclipse.remote.telnet-feature/feature.properties
new file mode 100644
index 0000000..e952101
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/feature.properties
@@ -0,0 +1,24 @@
+#################################################################################
+# Copyright (c) 2015 IBM Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#################################################################################
+
+# "featureName" property - name of the feature
+featureName=Telnet Remote Services
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse PTP
+
+# "description" property - description of the feature
+description=Provides telnet services for the remote framework
+
+# copyright
+copyright=\
+Copyright (c) 2015 IBM Corporation.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n
diff --git a/features/org.eclipse.remote.telnet-feature/feature.xml b/features/org.eclipse.remote.telnet-feature/feature.xml
new file mode 100644
index 0000000..8aeb185
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/feature.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.remote.telnet"
+      label="%featureName"
+      version="2.0.2.qualifier"
+      provider-name="%providerName"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.remote.telnet.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.remote.telnet.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.remote.telnet-feature/pom.xml b/features/org.eclipse.remote.telnet-feature/pom.xml
new file mode 100644
index 0000000..f6b7629
--- /dev/null
+++ b/features/org.eclipse.remote.telnet-feature/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.remote</groupId>
+    <artifactId>remote-parent</artifactId>
+    <version>2.0.2-SNAPSHOT</version>
+    <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
+  </parent>
+
+  <groupId>org.eclipse.remote.features</groupId>
+  <artifactId>org.eclipse.remote.telnet</artifactId>
+  <version>2.0.2-SNAPSHOT</version>
+  <packaging>eclipse-feature</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho.extras</groupId>
+        <artifactId>tycho-source-feature-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>source-feature</id>
+            <phase>package</phase>
+            <goals>
+              <goal>source-feature</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-p2-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <executions>
+          <execution>
+            <id>attached-p2-metadata</id>
+            <phase>package</phase>
+            <goals>
+              <goal>p2-metadata</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/releng/org.eclipse.remote.build/pom.xml b/releng/org.eclipse.remote.build/pom.xml
index 5910b6d..32e8af4 100644
--- a/releng/org.eclipse.remote.build/pom.xml
+++ b/releng/org.eclipse.remote.build/pom.xml
@@ -15,12 +15,12 @@
 	<name>Remote Parent</name>
 
 	<properties>
-		<remote-release>2.0.2</remote-release>
+		<remote-release>nightly</remote-release>
 		<eclipse-release>luna</eclipse-release>
 		<tycho-version>0.24.0</tycho-version>
 		<tycho-extras-version>${tycho-version}</tycho-extras-version>
 		<tycho.scmUrl>scm:git:git://git.eclipse.org/gitroot/ptp/org.eclipse.remote.git</tycho.scmUrl>
-		<platform-version>4.5milestones</platform-version>
+		<platform-version>4.5</platform-version>
 		<platform-site>http://download.eclipse.org/eclipse/updates/${platform-version}/</platform-site>
 		<license-site>http://download.eclipse.org/cbi/updates/license/</license-site>
 		<tm-site>http://download.eclipse.org/tm/terminal/builds/development/nightly/</tm-site>
@@ -43,6 +43,7 @@
 	</licenses>
 
 	<modules>
+		<module>../../releng/org.eclipse.remote.target</module>
 		<!-- Remote feature -->
 		<module>../../bundles/org.eclipse.remote.core</module>
 		<module>../../bundles/org.eclipse.remote.jsch.core</module>
@@ -57,20 +58,26 @@
 		<module>../../bundles/org.eclipse.remote.serial.core</module>
 		<module>../../bundles/org.eclipse.remote.serial.ui</module>
 		<module>../../features/org.eclipse.remote.serial-feature</module>
+		<!-- Telnet feature -->
+		<module>../../bundles/org.eclipse.remote.telnet.core</module>
+		<module>../../bundles/org.eclipse.remote.telnet.ui</module>
+		<module>../../features/org.eclipse.remote.telnet-feature</module>
+		<!-- Documentation -->
+		<module>../../bundles/org.eclipse.remote.doc.isv</module>
 	</modules>
 
 	<repositories>
-		<repository>
+		<!-- repository>
 			<id>platform-${platform-version}</id>
 			<url>${platform-site}</url>
 			<layout>p2</layout>
-		</repository>
+		</repository-->
 		<repository>
 			<id>license</id>
 			<url>${license-site}</url>
 			<layout>p2</layout>
 		</repository>
-		<repository>
+		<!--repository>
 			<id>tm</id>
 			<url>${tm-site}</url>
 			<layout>p2</layout>
@@ -79,7 +86,7 @@
 			<id>cdt</id>
 			<url>${cdt-site}</url>
 			<layout>p2</layout>
-		</repository>
+		</repository-->
 	</repositories>
 
 	<build>
@@ -124,6 +131,23 @@
 							<arch>x86_64</arch>
 						</environment>
 					</environments>
+					<dependency-resolution>
+						<extraRequirements>
+							<requirement>
+								<type>eclipse-plugin</type>
+								<id>org.eclipse.ui.ide</id>
+								<versionRange>0.0.0</versionRange>
+							</requirement>
+						</extraRequirements>
+		          </dependency-resolution>
+				  <target>
+						<artifact>
+							<groupId>org.eclipse.remote</groupId>
+							<artifactId>org.eclipse.remote.target</artifactId>
+							<version>2.0.2-SNAPSHOT</version>
+							<classifier>mars</classifier>
+						</artifact>
+				  </target>
 				</configuration>
 			</plugin>
 			<plugin>
diff --git a/releng/org.eclipse.remote.repo/category.xml b/releng/org.eclipse.remote.repo/category.xml
index e0568a6..677d810 100644
--- a/releng/org.eclipse.remote.repo/category.xml
+++ b/releng/org.eclipse.remote.repo/category.xml
@@ -18,4 +18,10 @@
    <feature url="features/org.eclipse.remote.console.source_0.0.0.jar" id="org.eclipse.remote.console.source" version="0.0.0">
       <category name="Remote Console SDK"/>
    </feature>
+   <feature url="features/org.eclipse.remote.telnet_0.0.0.jar" id="org.eclipse.remote.telnet" version="0.0.0">
+      <category name="Telnet Protocol Support"/>
+   </feature>
+   <feature url="features/org.eclipse.remote.telnet.source_0.0.0.jar" id="org.eclipse.remote.telnet.source" version="0.0.0">
+      <category name="Telnet Protocol Support SDK"/>
+   </feature>
 </site>
diff --git a/releng/org.eclipse.remote.target/.project b/releng/org.eclipse.remote.target/.project
new file mode 100644
index 0000000..4493f6f
--- /dev/null
+++ b/releng/org.eclipse.remote.target/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.remote.target</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/releng/org.eclipse.remote.build/mars.target b/releng/org.eclipse.remote.target/mars.target
similarity index 91%
rename from releng/org.eclipse.remote.build/mars.target
rename to releng/org.eclipse.remote.target/mars.target
index b047b1d..c848db9 100644
--- a/releng/org.eclipse.remote.build/mars.target
+++ b/releng/org.eclipse.remote.target/mars.target
@@ -3,8 +3,8 @@
 <target name="mars" sequenceNumber="0">
 <locations>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.sdk.ide" version="4.5.0.I20141210-2000"/>
-<repository location="http://download.eclipse.org/eclipse/updates/4.5milestones/"/>
+<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
+<repository location="http://download.eclipse.org/eclipse/updates/4.5/"/>
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.mockito" version="0.0.0"/>
@@ -13,6 +13,7 @@
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.eclipse.cdt.native.serial" version="0.0.0"/>
+<unit id="org.eclipse.cdt.core" version="0.0.0"/>
 <repository location="http://download.eclipse.org/tools/cdt/builds/master/nightly/"/>
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
diff --git a/releng/org.eclipse.remote.target/pom.xml b/releng/org.eclipse.remote.target/pom.xml
new file mode 100644
index 0000000..a2c6a72
--- /dev/null
+++ b/releng/org.eclipse.remote.target/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.eclipse.remote</groupId>
+		<artifactId>remote-parent</artifactId>
+		<version>2.0.2-SNAPSHOT</version>
+		<relativePath>../org.eclipse.remote.build/pom.xml</relativePath>
+	</parent>
+
+	<version>2.0.2-SNAPSHOT</version>
+	<artifactId>org.eclipse.remote.target</artifactId>
+	<packaging>pom</packaging>
+	
+	<build>
+		<plugins>
+			<plugin>
+			<groupId>org.codehaus.mojo</groupId>
+			<artifactId>build-helper-maven-plugin</artifactId>
+			<version>1.9.1</version>
+				<executions>
+					<execution>
+						<id>attach-artifacts</id>
+						<phase>package</phase>
+						<goals>
+							<goal>attach-artifact</goal>
+						</goals>
+						<configuration>
+							<artifacts>
+								<artifact>
+									<file>mars.target</file>
+									<type>target</type>
+									<classifier>mars</classifier>
+								</artifact>
+							</artifacts>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
diff --git a/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/ProcessTests.java b/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/ProcessTests.java
index 001c899..e9cc535 100644
--- a/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/ProcessTests.java
+++ b/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/ProcessTests.java
@@ -19,6 +19,7 @@
 import org.eclipse.remote.core.IRemoteProcessBuilder;
 import org.eclipse.remote.core.IRemoteProcessService;
 import org.eclipse.remote.core.IRemoteServicesManager;
+import org.eclipse.remote.core.RemoteProcessAdapter;
 import org.eclipse.remote.internal.jsch.core.JSchConnection;
 
 public class ProcessTests extends TestCase {
@@ -171,6 +172,28 @@
 		assertEquals("0123456789", result.toString());
 	}
 
+	public void testExitValue() {
+		IRemoteProcessService processService = fRemoteConnection.getService(IRemoteProcessService.class);
+		assertNotNull(processService);
+		IRemoteProcessBuilder builder = processService.getProcessBuilder(new String[]{"sleep","60"}); //$NON-NLS-1$
+		assertNotNull(builder);
+		IRemoteProcess rp = null;
+		try {
+			rp = builder.start();
+		} catch (IOException e) {
+			e.printStackTrace();
+			fail(e.getLocalizedMessage());
+		}
+		assertNotNull(rp);
+		Process p = new RemoteProcessAdapter(rp);
+		try {
+			p.exitValue();
+			fail("Process has not exited. Should throws an IllegalThreadStateException exception");
+		} catch(IllegalThreadStateException e) {
+			e.printStackTrace();
+		}
+	}
+
 	@Override
 	protected void setUp() throws Exception {
 		IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
diff --git a/tests/org.eclipse.remote.telnet.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.remote.telnet.core.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c1a6d04
--- /dev/null
+++ b/tests/org.eclipse.remote.telnet.core.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Remote Telnet tests
+Bundle-SymbolicName: org.eclipse.remote.telnet.core.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.remote.telnet.core.tests.Activator
+Bundle-Vendor: Eclipse PTP
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.remote.telnet.core;bundle-version="1.0.0",
+ org.junit;bundle-version="4.12.0",
+ org.eclipse.remote.core;bundle-version="2.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
diff --git a/tests/org.eclipse.remote.telnet.core.tests/build.properties b/tests/org.eclipse.remote.telnet.core.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/tests/org.eclipse.remote.telnet.core.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/Activator.java b/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/Activator.java
new file mode 100644
index 0000000..bd52832
--- /dev/null
+++ b/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/Activator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wainer dos Santos Moschetta (IBM Corp.) - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core.tests;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class Activator implements BundleActivator {
+
+	private static BundleContext context;
+
+	static BundleContext getContext() {
+		return context;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext bundleContext) throws Exception {
+		Activator.context = bundleContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext bundleContext) throws Exception {
+		Activator.context = null;
+	}
+
+	public static <T> T getService(Class<T> service) {
+		ServiceReference<T> ref = context.getServiceReference(service);
+		return ref != null ? context.getService(ref) : null;
+	}
+}
diff --git a/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/TelnetConnectionTests.java b/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/TelnetConnectionTests.java
new file mode 100644
index 0000000..086c34f
--- /dev/null
+++ b/tests/org.eclipse.remote.telnet.core.tests/src/org/eclipse/remote/telnet/core/tests/TelnetConnectionTests.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2015 IBM Corporation, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wainer dos Santos Moschetta (IBM Corp.) - initial contribution
+ *******************************************************************************/
+package org.eclipse.remote.telnet.core.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.remote.core.IRemoteConnection;
+import org.eclipse.remote.core.IRemoteConnectionHostService;
+import org.eclipse.remote.core.IRemoteConnectionType;
+import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
+import org.eclipse.remote.core.IRemoteProcessBuilder;
+import org.eclipse.remote.core.IRemoteServicesManager;
+import org.eclipse.remote.core.exception.RemoteConnectionException;
+import org.eclipse.remote.telnet.core.TelnetCommandShell;
+import org.eclipse.remote.telnet.core.TelnetConnection;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class TelnetConnectionTests {
+
+	private static final String TELNET_CONN_TYPE_ID = "org.eclipse.remote.telnet.core.connectionType";
+	private static String hostname = "localhost";
+	private static String username = "test";
+	private static String password = "";
+	private static String TEST_CONN_NAME = "NewTelnetConnection";
+	private final String expected_connType_name = "Telnet";
+	private final int expected_telnet_default_port = 23;
+	private final int expected_telnet_default_timeout = 0;
+	private static TelnetConnection telnet;
+
+	@BeforeClass
+	public static void setup() {
+		String host = System.getenv("TEST_HOSTNAME");
+		if(host != null) {
+			hostname = host;
+		}
+		String user = System.getenv("TEST_USERNAME");
+		if(user != null) {
+			username = user;
+		}
+		String passwd = System.getenv("TEST_PASSWORD");
+		if(user != null) {
+			password = passwd;
+		}
+		IRemoteServicesManager services = Activator.getService(IRemoteServicesManager.class);
+		IRemoteConnectionType connType = services.getConnectionType(TELNET_CONN_TYPE_ID);
+		assertNotNull(connType);
+		IRemoteConnectionWorkingCopy workingCopy = null;
+		IRemoteConnection connection = null;
+		try {
+			workingCopy = connType.newConnection(TEST_CONN_NAME);
+			assertNotNull(workingCopy);
+			IRemoteConnectionHostService hostService = workingCopy.getService(IRemoteConnectionHostService.class);
+			hostService.setHostname(hostname);
+			connection = workingCopy.save();
+			assertNotNull(connection);
+		} catch (RemoteConnectionException e) {
+			fail("Failed to create a Telnet connection: " + e.getMessage());
+		}
+		telnet = connection.getService(TelnetConnection.class);
+		assertNotNull(telnet);
+	}
+
+	@Test
+	public void testTelnetConnection() throws RemoteConnectionException {
+		IRemoteConnectionType connType = telnet.getRemoteConnection().getConnectionType();
+		assertEquals("Connection type name", expected_connType_name, connType.getName());
+		assertEquals("Default Telnet over TCP port", expected_telnet_default_port, telnet.getPort());
+		assertEquals("Default connection timeout", expected_telnet_default_timeout, telnet.getTimeout());
+		telnet.open(new NullProgressMonitor());
+		assertTrue("Connection should be open", telnet.isOpen());
+		telnet.close();
+		assertTrue("Connection should be closed", !telnet.isOpen());
+	}
+
+	@Test
+	public void testTelnetCommandShell() {
+		try {
+			telnet.open(new NullProgressMonitor());
+		} catch (RemoteConnectionException e) {
+			e.printStackTrace();
+			fail("Failed to open telnet connection");
+		}
+		TelnetCommandShell commandShell = null;
+		try {
+			commandShell = (TelnetCommandShell) telnet.getCommandShell(IRemoteProcessBuilder.ALLOCATE_PTY);
+		} catch (IOException e) {
+			e.printStackTrace();
+			fail("Failed to get command shell");
+		}
+		try {
+			commandShell.connect();
+		} catch (RemoteConnectionException e) {
+			e.printStackTrace();
+			fail("Unabled to connect with command shell");
+		}
+		OutputStream os = commandShell.getOutputStream();
+		assertNotNull("Command shel output stream", os);
+		InputStream is = commandShell.getInputStream();
+		assertNotNull("Command shel input stream");
+		if(!username.isEmpty() && !password.isEmpty()) {
+			try {
+				// Assume that a login prompt appears
+				readPrompt(is);
+				os.write((username + "\r\n").getBytes());
+				readPrompt(is);
+				os.write((password + "\r\n").getBytes());
+				BufferedReader br = new BufferedReader(new InputStreamReader(is));
+				br.readLine();
+			} catch (IOException e) {
+				e.printStackTrace();
+				fail("Failed to log in");
+			}
+		}
+	}
+
+	@AfterClass
+	public static void tearDown() {
+		IRemoteServicesManager services = Activator.getService(IRemoteServicesManager.class);
+		IRemoteConnectionType connType = services.getConnectionType(TELNET_CONN_TYPE_ID);
+		try {
+			connType.removeConnection(telnet.getRemoteConnection());
+			IRemoteConnection conn = connType.getConnection(TEST_CONN_NAME);
+			assertTrue("Connection should had been deleted", conn == null);
+		} catch (RemoteConnectionException e) {
+			e.printStackTrace();
+			fail("Failed to delete the Telnet connection");
+		}
+	}
+
+	/*
+	 * Consume characters until prompt delimite ":" has been found.
+	 */
+	private void readPrompt(InputStream is) {
+		int v;
+		try {
+			v = is.read();
+			while((v != -1) && (v != ':')) {
+				v = is.read();
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+			fail("Failed to read prompt: " + e.getMessage());
+		}
+	}
+}