Initial commit
diff --git a/org.eclipse.paho.client.eclipse.view/.classpath b/org.eclipse.paho.client.eclipse.view/.classpath
new file mode 100644
index 0000000..8a8f166
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/.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.6"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/org.eclipse.paho.client.eclipse.view/.project b/org.eclipse.paho.client.eclipse.view/.project
new file mode 100644
index 0000000..846c4ac
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.paho.client.eclipse.view</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/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..05f26a2
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon Jun 07 09:19:25 PDT 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6

+org.eclipse.jdt.core.compiler.compliance=1.6

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.6

diff --git a/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.pde.core.prefs b/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..d52148f
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Tue Aug 03 13:32:53 PDT 2010
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.paho.client.eclipse.view/META-INF/MANIFEST.MF b/org.eclipse.paho.client.eclipse.view/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..04d83cb
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse Paho Client View
+Bundle-SymbolicName: org.eclipse.paho.client.eclipse.view;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.paho.client.eclipse.view.Activator
+Bundle-Vendor: ESF
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.jface.action,
+ org.eclipse.jface.resource,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.window,
+ org.eclipse.paho.client.mqttv3,
+ org.eclipse.swt,
+ org.eclipse.swt.custom,
+ org.eclipse.swt.events,
+ org.eclipse.swt.graphics,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui,
+ org.eclipse.ui.part,
+ org.eclipse.ui.plugin,
+ org.osgi.framework
diff --git a/org.eclipse.paho.client.eclipse.view/README.txt b/org.eclipse.paho.client.eclipse.view/README.txt
new file mode 100644
index 0000000..302d7f0
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/README.txt
@@ -0,0 +1,123 @@
+Project:  Eclipse Paho MQTT Client View
+Version:  1.0.0
+Date:     06-06-2012
+Author:   Eurotech Inc.
+
+
+**************
+** Overview **
+**************
+
+The Eclipse Paho MQTT Client View is an Eclipse plug-in that provides a 
+user interface for managing an MQTT client within Eclipse.  
+
+
+******************
+** Installation **
+******************
+
+The plug-in can be installed using the included update site:
+
+ update_site/update.site.zip
+ 
+1) Unzip the file onto your local machine.  
+
+2) In Eclipse, browse to Help -> Install New Software.
+
+3) Add a new local repository by clicking on the "Add..." button and browsing to the directory
+that you unzipped above (should contain a site.xml file).  Make sure to name the repository
+and then click "Ok".  You should now be able to select the repository in the "Work with:" 
+drop down menu and the plug-in should appear in the list.  
+
+4) Select the plug-in:
+
+ Paho Client Eclipse View Feature
+	
+5) Click "Next" and follow the remaining instructions for installing the plug-in.
+
+
+***********
+** Usage **
+***********
+
+The view can be accessed by navigating to Window -> Show View -> Other..., then expand the 
+"Others" folder and select "Eclipse Paho Client View".  This will open the interface for the 
+Paho MQTT client.  The interface consists of three tabs: Connection, Publish, and Subscribe.
+
+-Connection Tab
+
+This tab is used to connect the MQTT client to a broker.  A connection
+must be established in order to publish and subscribe in the remaining
+tabs.  Here is a brief description of the fields:
+
+Broker Address: (Required) The IP address or URL of the broker
+Broker Port:    (Required) The port number of the broker
+Client ID:      (Required) A unique identifier to connect with.
+Username:       A username, if required by the broker.
+Password:       A password, if required by the broker.
+Keep Alive:     (Required) The number of seconds between keep alive pings sent to the broker.
+Clean Start:    Whether or not to maintain subscriptions across disconnects.
+LWT Enable:     Whether to enable Last Will and Testament (LWT).
+LWT Topic:      The topic that the broker will publish the LWT on.
+LWT Message:    The message that the broker will publish for the LWT.
+LWT QoS:	The quality of service that the LWT will be published on.
+LWT Retain:	Whether to retain the LWT message.
+
+-Publish Tab
+
+Used to publish messages to the broker.  A message may be a string or a File.  Here is a 
+brief description of the fields:
+
+Topic:	 The topic to publish on.
+QoS:     The quality of service to publish on.
+Payload: The payload to publish (if publishing a string).
+File:    The file to publish (if publishing a file).
+
+-Subscribe Tab
+
+Used to subscribe and unsubscribe on topics.  Once the client is subcribed to a topic, all 
+messages recieved will be displayed to the log below.  Here is a brief description of the 
+fields:
+
+Topic: The topic to subscribe on.
+QoS:   The quality of service to subscribe on.
+
+
+**************
+** Building **
+**************
+
+The project requires the Plug-in Development Environment (PDE) in order to build. 
+Information about installing the PDE tools can be found at: 
+
+ www.eclipse.org/pde
+	
+The source for the project itself can be found at:
+
+ http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/
+	
+Once the project is imported into Eclipse, it can be build by rigt clicking on the project
+and navigating to Export -> Plug-in Developement -> Deployable plug-ins and fragments.
+
+
+***************
+** Copyright **
+***************
+
+Copyright (c) 2012 Eurotech Inc. All rights reserved.
+
+
+*************
+** License **
+*************
+
+This project is released under the Eclipse Public License (EPL) version 1.0
+
+
+******************************
+** Additional Documentation **
+******************************
+
+Eclipse Paho:  http://www.eclipse.org/paho/
+MQTT:          http://www.mqtt.org
+
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/Activator.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/Activator.class
new file mode 100644
index 0000000..62cd3b2
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/Activator.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/ClientConstants.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/ClientConstants.class
new file mode 100644
index 0000000..c6dae5a
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/ClientConstants.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$1.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$1.class
new file mode 100644
index 0000000..c62c24f
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$1.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$10.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$10.class
new file mode 100644
index 0000000..6b45fab
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$10.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$11.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$11.class
new file mode 100644
index 0000000..151547c
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$11.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$2.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$2.class
new file mode 100644
index 0000000..cc88085
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$2.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$3.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$3.class
new file mode 100644
index 0000000..ec4899d
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$3.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$4.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$4.class
new file mode 100644
index 0000000..6b7ab6b
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$4.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$5.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$5.class
new file mode 100644
index 0000000..e55f83f
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$5.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$6.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$6.class
new file mode 100644
index 0000000..abd667e
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$6.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$7.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$7.class
new file mode 100644
index 0000000..8cc4b41
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$7.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$8.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$8.class
new file mode 100644
index 0000000..c609f41
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$8.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$9.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$9.class
new file mode 100644
index 0000000..244d4a9
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView$9.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView.class b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView.class
new file mode 100644
index 0000000..a7bf33f
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/bin/org/eclipse/paho/client/eclipse/view/MqttClientView.class
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/build.properties b/org.eclipse.paho.client.eclipse.view/build.properties
new file mode 100644
index 0000000..0d2f5cd
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/build.properties
@@ -0,0 +1,12 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.xml,\

+               icons/

+additional.bundles = org.eclipse.swt,\

+                     org.eclipse.ui,\

+                     org.eclipse.core.runtime,\

+                     org.eclipse.core.boot,\

+                     org.eclipse.core.resources,\

+                     org.eclipse.paho.client.mqttv3

diff --git a/org.eclipse.paho.client.eclipse.view/icons/eurotech.gif b/org.eclipse.paho.client.eclipse.view/icons/eurotech.gif
new file mode 100644
index 0000000..92732e4
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/icons/eurotech.gif
Binary files differ
diff --git a/org.eclipse.paho.client.eclipse.view/plugin.xml b/org.eclipse.paho.client.eclipse.view/plugin.xml
new file mode 100644
index 0000000..b8616b0
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/plugin.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+	<extension point="org.eclipse.ui.views">

+    	<view id="org.eclipse.paho.client.eclipse.view.mqttclientview"

+			name="Eclipse Paho Client View"

+			class="org.eclipse.paho.client.eclipse.view.MqttClientView"

+			icon="icons/eurotech.gif"/>

+	</extension>

+</plugin>
\ No newline at end of file
diff --git a/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/Activator.java b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/Activator.java
new file mode 100644
index 0000000..19d4eda
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/Activator.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 Eurotech Inc. All rights reserved.
+ *
+ * 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:
+ *    Chad Kienle
+ */
+
+package org.eclipse.paho.client.eclipse.view;

+

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "com.esf.eclipse.mqtt.client";

+

+	// The shared instance

+	private static Activator plugin;

+	

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

+	 */

+	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;

+	}

+

+	/**

+	 * Returns an image descriptor for the image file at the given

+	 * plug-in relative path

+	 *

+	 * @param path the path

+	 * @return the image descriptor

+	 */

+	public static ImageDescriptor getImageDescriptor(String path) {

+		return imageDescriptorFromPlugin(PLUGIN_ID, path);

+	}

+}

diff --git a/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/ClientConstants.java b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/ClientConstants.java
new file mode 100644
index 0000000..0da7f4f
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/ClientConstants.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Eurotech Inc. All rights reserved.
+ *
+ * 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:
+ *    Chad Kienle
+ */
+
+package org.eclipse.paho.client.eclipse.view;

+
+/**
+ * Constants for widget sizing defaults
+ */

+public class ClientConstants {

+

+	protected static final int BUTTON_WIDTH = 120;

+	protected static final int BUTTON_HEIGHT = 25;

+}

diff --git a/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/MqttClientView.java b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/MqttClientView.java
new file mode 100644
index 0000000..7743003
--- /dev/null
+++ b/org.eclipse.paho.client.eclipse.view/src/org/eclipse/paho/client/eclipse/view/MqttClientView.java
@@ -0,0 +1,837 @@
+/*
+ * Copyright (c) 2012 Eurotech Inc. All rights reserved.
+ *
+ * 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:
+ *    Chad Kienle
+ */
+
+package org.eclipse.paho.client.eclipse.view;

+

+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
+import org.eclipse.paho.client.mqttv3.MqttTopic;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * An MQTT client view.  The top half provides three tabs for Connecting to an MQTT broker, publishing messages,
+ * and subscribing on topics.  The bottom half of the view contains a log of all MQTT connections, publishes, and
+ * subscription events.
+ */

+public class MqttClientView extends ViewPart implements MqttCallback {

+
+	// The display and parent composite

+    private Display display;

+	private Composite parent;

+	
+	// MQTT connection parameters with defaults

+	private static MqttClient mqttClient		= null;

+	private static MqttConnectOptions connOpts	= null;
+	private static String connectAddress 		= "";

+	private static int connectPort 				= 1883;

+	private static String clientId 				= "";

+	private static short keepAlive 				= 30;

+	private static boolean cleanStart 			= true;

+	private static boolean firstConnect 		= true;

+	private static Boolean connected 			= new Boolean(false);

+	private static String tmpMsg 				= null;

+	private static String willTopic 			= "";

+	private static String willMessage 			= "";

+	private static int willQos 					= 0;

+	private static boolean willRetain 			= false;

+	private static String username 				= "";

+	private static String password 				= "";

+	
+	// Current publish parameters with defaults

+	private String publishTopic = null;

+	private int publishQos 		= 0;

+	private boolean retain 		= false;

+	private byte [] payload		= null;

+	private boolean useWill 	= false;

+	
+	// Current subscribe topic and QoS with defaults

+	private String subscribeTopic 	= null;

+	private int subscribeQos 		= 0;

+	
+	// The text boxes to store the values of the MQTT parameters for connecting/publishing/subscribing

+	private Text subscribeTopicValue;

+	private Text publishTopicValue;

+	private Text publishPayloadValue;

+	private Text publishFileName;

+	private Text brokerAddressValue;

+	private Text brokerPortValue;

+	private Text clientIdValue;

+	private Text keepAliveValue;

+	private Text messageLog;

+	private Text willTopicValue;

+	private Text willMessageValue;

+	private Text usernameValue;

+	private Text passwordValue;

+	
+	// The buttons needed to store the state of MQTT parameters for connecting/publishing/subscribing

+	private Button willCheckBox;

+	private Button willRetainCheckBox;

+	private Button cleanStartCheckBox;

+	private Button connectButton;

+	private Button disconnectButton;

+	
+	// The Groups associate with each tab

+	private Group connectionGroup;

+	private Group publishGroup;

+	private Group subscribeGroup;

+	
+	// Quality of Service drop down selection menus

+	private Combo subscribeQosDrop;

+	private Combo publishQosDrop;

+	private Combo willQosDrop;

+
+	/**
+	 *  Constructor
+	 */

+	public MqttClientView() {

+		super();

+	}

+
+	/**
+	 *  Sets the focus
+	 */

+	public void setFocus() {

+	}

+
+	/**
+	 *  Create the control
+	 */

+	public void createPartControl(Composite parent) {

+		// Connection Group

+		this.parent = parent;

+		display = parent.getDisplay();

+		FillLayout masterLayout = new FillLayout();

+		parent.setLayout(masterLayout);

+		
+		// Create composite with rows

+		SashForm sashform = new SashForm(parent, SWT.VERTICAL);

+		

+		final TabFolder tabFolder = new TabFolder(sashform, SWT.V_SCROLL | SWT.H_SCROLL);

+

+	    // Create each tab and set its text, tool tip text, image, and control
+		// Connection tab

+	    TabItem one = new TabItem(tabFolder, SWT.NONE);

+	    one.setText("Connection");

+	    one.setToolTipText("Connect to a Broker");

+	    one.setControl(getConnectionControl(tabFolder));

+
+	    // Publish tab

+	    TabItem two = new TabItem(tabFolder, SWT.NONE);

+	    two.setText("Publish");

+	    two.setToolTipText("Publish messages");

+	    two.setControl(getPublishControl(tabFolder));

+
+	    // Subscribe tab

+	    TabItem three = new TabItem(tabFolder, SWT.NONE);

+	    three.setText("Subscribe");

+	    three.setToolTipText("Subscribe and unsubscribe to topics");

+	    three.setControl(getSubscribeControl(tabFolder));

+		

+		messageLog = new Text(sashform, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);

+	    messageLog.setFont(new Font(display, new FontData("Courier New", 10, SWT.NORMAL)));

+

+		sashform.setWeights(new int[]{2,1});

+	}

+
+	// Listener for LWT enable/disable events

+	private SelectionListener willListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {

+		}

+		public void widgetSelected(SelectionEvent e) {

+			useWill = willCheckBox.getSelection();

+			willTopicValue.setEnabled(useWill);

+			willMessageValue.setEnabled(useWill);

+			willQosDrop.setEnabled(useWill);

+			willRetainCheckBox.setEnabled(useWill);

+		}

+	};

+	
+	// Listener for widget selection events

+	private SelectionListener selectListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {

+		}

+		public void widgetSelected(SelectionEvent e) {

+			cleanStart = cleanStartCheckBox.getSelection();

+			updateInfo();

+		}

+	};

+	
+	// Listener for connect events

+	private SelectionListener connectListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {}

+		public void widgetSelected(SelectionEvent e) {

+			if(e.getSource() == connectButton) {

+				connect();

+			} else if(e.getSource() == disconnectButton) {

+				disconnect();

+			}

+		}

+	};

+	
+	// Listener for publish (text) events

+	private SelectionListener publishListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {}

+		public void widgetSelected(SelectionEvent e) {

+			publishTopic = publishTopicValue.getText();

+			publishQos = Integer.parseInt(publishQosDrop.getText());

+			payload = publishPayloadValue.getText().getBytes();

+			publish();

+		}

+	};

+	
+	// Listener for publish (file) events

+	private SelectionListener publishFileListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {}

+		public void widgetSelected(SelectionEvent e) {

+			publishTopic = publishTopicValue.getText();

+			publishQos = Integer.parseInt(publishQosDrop.getText());

+			String filename = publishFileName.getText();

+			try {

+				payload = getBytesFromFile(new File(filename));

+			} catch (IOException e1) {

+				e1.printStackTrace();

+			}

+			publish();

+		}

+	};

+	
+	// Listener for subscribe events

+	private SelectionListener subscribeListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {}

+		public void widgetSelected(SelectionEvent e) {

+			subscribeTopic = subscribeTopicValue.getText();

+			subscribeQos = Integer.parseInt(subscribeQosDrop.getText());

+			subscribe();

+			publishTopicValue.setText(subscribeTopic);

+		}

+	};

+	
+	// Listener for unsubscribe events

+	private SelectionListener unsubscribeListener = new SelectionListener() {

+		public void widgetDefaultSelected(SelectionEvent e) {}

+		public void widgetSelected(SelectionEvent e) {

+			subscribeTopic = subscribeTopicValue.getText();

+			unsubscribe();

+		}

+	};

+
+	/**
+	 * A parameter's value has changed, update info
+	 */

+	public void valueChanged(Text text) {

+		updateInfo();

+	}

+	
+	/**
+	 * Broker address value has changed, update info
+	 */

+	private void addressValueChanged(Text text) {

+		updateInfo();

+		firstConnect = true;

+	}

+	
+	/**
+	 * Updates the connection information
+	 */

+	private void updateInfo() {

+		connectAddress = brokerAddressValue.getText();

+		willTopic = willTopicValue.getText();

+		willMessage = willMessageValue.getText();

+		clientId = clientIdValue.getText();

+		willQos = Integer.parseInt(willQosDrop.getText());

+		willRetain = willRetainCheckBox.getSelection();

+		username = usernameValue.getText();

+		password = passwordValue.getText();

+		try {

+			connectPort = Integer.parseInt(brokerPortValue.getText());

+		} catch (NumberFormatException e) {

+		}

+		try {

+			keepAlive = Short.parseShort(keepAliveValue.getText());

+		} catch (NumberFormatException e) {

+		}

+	}

+	
+	/**
+	 * Connects to the broker
+	 */

+	private void connect() {
+		// Check if the client is currently connected

+		if (!connected) {
+			// Update connection information

+			updateInfo();
+			// Build connection string

+			String connectString = "tcp://" + connectAddress + ":" + connectPort;

+			if(clientId == null || clientId.length() < 1) {

+				out(getDate() + "Error connecting to " + connectString + ", please enter a valid client ID.");

+				return;

+			}
+			// Instantiate client
+			try {
+				if (firstConnect) {
+					mqttClient = new MqttClient(connectString, clientId);
+					mqttClient.setCallback(this);
+					firstConnect = false;
+				}
+			} catch (MqttException e) {
+				out(getDate() + "Failed to connect to broker: " + e.getMessage());
+				e.printStackTrace();
+			}
+			
+			// Set connection options
+			connOpts = new MqttConnectOptions();
+			connOpts.setCleanSession(cleanStart);
+			connOpts.setConnectionTimeout(30);
+			connOpts.setKeepAliveInterval(keepAlive);
+			if (username.length() > 0 && password.length() > 0) {
+				connOpts.setPassword(password.toCharArray());
+				connOpts.setUserName(username);
+			}
+			if (useWill) {
+				if(willTopic == null || willTopic.equals("")) {
+					out("Error connecting:  Please enter a LWT topic.");
+					return;
+				}
+				connOpts.setWill(mqttClient.getTopic(willTopic), willMessage.getBytes(), willQos, willRetain);
+			}
+			// Attempt to connect
+			try {

+				out(getDate() + "Attempting to connect to broker:  " + connectString);
+				mqttClient.connect(connOpts);

+			

+				connected = true;

+				out(getDate() + "CONNECTED - Client ID: " + clientId);

+			} catch (MqttException e) {

+				out(getDate() + "Failed to connect to broker: " + e.getMessage());

+				e.printStackTrace();

+			}

+		} else {

+			out("Error connecting:  Client is currently connected.");

+		}

+	}

+	
+	/**
+	 * Disconnects from the broker
+	 */

+	private void disconnect() {

+		try {

+			if(connected) {

+				mqttClient.disconnect();

+				out(getDate() + "DISCONNECTED");

+			} else {

+				out(getDate() + "Error disconnecting:  Client was not connected.");

+			}

+		} catch (MqttException e) {

+			out(getDate() + "Error disconnecting:  " + e.getMessage());

+		}

+		connected = false;

+	}

+	
+	/**
+	 * Publishes a message
+	 */

+	private void publish() {

+		

+		if(mqttClient != null) {
+			if(publishTopic == null || publishTopic.equals("")) {
+				out("Error publishing:  Please enter a topic to publish on.");
+				return;
+			}

+			try {
+				MqttTopic topic = mqttClient.getTopic(publishTopic);
+				topic.publish(payload, publishQos, retain);

+				out(getDate() + "PUBLISH");

+				out(" Topic:   \"" + publishTopic + "\"\n" + 

+				    " QOS:     " + publishQos +  "\n" +

+				    " Retain:  " + retain + "\n" +

+				    " Payload: \"" + new String(payload) + "\"");

+			} catch (MqttPersistenceException e) {

+				e.printStackTrace();

+			} catch (NullPointerException e) {

+				e.printStackTrace();

+			} catch (MqttException e) {

+				e.printStackTrace();

+			}

+		}

+	}

+	
+	/**
+	 * Subscribes on a topic
+	 */

+	private void subscribe() {

+		if(mqttClient != null) {

+			try {

+				String [] topicArray = {subscribeTopic};

+				int [] qosArray = {subscribeQos};

+				mqttClient.subscribe(topicArray, qosArray);

+				out(getDate() + "SUBSCRIBE");

+				out(" Topic:   \"" + subscribeTopic + "\"\n" + 

+				    " QOS:     " + subscribeQos);

+			} catch (MqttPersistenceException e) {

+				e.printStackTrace();

+			} catch (NullPointerException e) {

+				e.printStackTrace();

+			} catch (MqttException e) {

+				e.printStackTrace();

+			}

+		}

+	}

+	
+	/**
+	 * Unsubscribes from a topic
+	 */

+	private void unsubscribe() {

+		if(mqttClient != null) {

+			try {

+				String [] topicArray = {subscribeTopic};

+				mqttClient.unsubscribe(topicArray);

+				out(getDate() + "UNSUBSCRIBE");

+				out(" Topic:   \"" + subscribeTopic + "\"");

+			} catch (MqttPersistenceException e) {

+				e.printStackTrace();

+			} catch (NullPointerException e) {

+				e.printStackTrace();

+			} catch (MqttException e) {

+				e.printStackTrace();

+			}

+		}

+	}

+
+	/**
+	 * Logs a message that the broker connection has been lost and attempts to reconnect.
+	 */

+	public void connectionLost(Throwable cause) {

+		connected = false;

+		syncOut(getDate() + "CONNECTION LOST!");

+		String connectString = connectAddress + ":" + connectPort;

+		syncOut(getDate() + "Attempting to reconnect to broker:  " + connectString);

+		try {

+			mqttClient.connect(connOpts);

+		} catch (Exception e) {

+			syncOut(getDate() + "Failed to reconnect.");

+			syncOut(getDate() + "DISCONNECTED");

+		}

+		connected = true;

+		syncOut(getDate() + "CONNECTED - Client ID: " + clientId);

+	}
+
+	/**
+	 * Logs a message that has arrived from the broker
+	 */
+	public void messageArrived(MqttTopic topic, MqttMessage message)
+			throws Exception {
+		syncOut(getDate() + "PUBLISH ARRIVED");
+		syncOut(" Topic:   \"" + topic + "\"");
+		syncOut(" Payload: \"" + new String(message.getPayload()) + "\"");
+	}
+
+	/**
+	 * Logs that a publish has completed (an acknowledgement has been received from the broker
+	 */
+	public void deliveryComplete(MqttDeliveryToken token) {
+		syncOut(getDate() + "PUBLISH COMPLETE");
+	}

+	
+	/**
+	 * Synchronously writes a message to the log.
+	 */

+	private void syncOut(String msg) {

+		tmpMsg = msg;

+		parent.getDisplay().syncExec(new Runnable() {

+			public void run(){

+				out(tmpMsg);

+			}

+		});

+	}

+	
+	/**
+	 * Returns a hex string representation of the byte array
+	 */

+	public static String getHexString(byte[] b) {

+		  String result = "";

+		  for (int i=0; i < b.length; i++) {

+		    result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );

+		  }

+		  return result;

+	}

+	
+	/**
+	 * Writes a message to the log
+	 */

+	private void out(String message) {

+		messageLog.append(message + "\n");

+	}

+	
+	/**
+	 * Return the current date as a formatted string.
+	 */

+	private String getDate() {

+		System.currentTimeMillis();

+		SimpleDateFormat formatter = new SimpleDateFormat ("yyyy/MM/dd hh:mm:ss.SS");

+		Date currentTime_1 = new Date();

+		String dateString = formatter.format(currentTime_1);

+		return "[" + dateString + "] ";

+	}

+
+	/**
+	 * Creates the connection composite and populates it with all the widgets needed to establish an MQTT connection
+	 */

+	private Control getConnectionControl(TabFolder tabFolder) {

+		Composite composite = new Composite(tabFolder, SWT.NONE);

+		composite.setLayout(new FillLayout(SWT.VERTICAL));
+		
+		// Connection group

+		connectionGroup = new Group(composite, SWT.NONE);

+	    connectionGroup.setLayout(new GridLayout(2, false));

+	    connectionGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));

+	    connectionGroup.setText("Connection");

+		
+	    // Broker address

+		Label brokerAddressLabel = new Label(connectionGroup, SWT.NULL);

+		brokerAddressLabel.setText("Broker Address: ");

+		brokerAddressValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		brokerAddressValue.setLayoutData(new GridData(120,13));

+		brokerAddressValue.setText(connectAddress);
+		brokerAddressValue.setToolTipText("IP address or URL of the broker");

+		
+		// Broker port

+		Label brokerPortLabel = new Label(connectionGroup, SWT.NULL);

+		brokerPortLabel.setText(   "Broker Port:    ");

+		brokerPortValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		brokerPortValue.setLayoutData(new GridData(30,13));

+		brokerPortValue.setText(Integer.toString(connectPort));
+		brokerPortValue.setToolTipText("Port that the broker is listening on");

+		
+		// Client ID

+		Label clientIdLabel = new Label(connectionGroup, SWT.NULL);

+		clientIdLabel.setText(     "Client ID:      ");

+		clientIdValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		clientIdValue.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));

+		clientIdValue.setText(clientId);
+		clientIdValue.setToolTipText("Client ID to connect with (must be unique)");

+
+		// Username

+		Label usernameLabel = new Label(connectionGroup, SWT.NULL);

+		usernameLabel.setText(     "Username:       ");

+		usernameValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		usernameValue.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));

+		usernameValue.setText(username);
+		usernameValue.setToolTipText("Username to connect with (optional)");

+		
+		// Password

+		Label passwordLabel = new Label(connectionGroup, SWT.NULL);

+		passwordLabel.setText(     "Password:       ");

+		passwordValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		passwordValue.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));

+		passwordValue.setText(password);
+		usernameValue.setToolTipText("Password to connect with (optional)");

+		
+		// Keep alive value in seconds

+		Label keepAliveLabel = new Label(connectionGroup, SWT.NULL);

+		keepAliveLabel.setText(    "Keep Alive:     ");

+		keepAliveValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		keepAliveValue.setLayoutData(new GridData(30,13));

+		keepAliveValue.setText(Short.toString(keepAlive));
+		keepAliveValue.setToolTipText("Number of seconds between keep alive pings with the broker");

+
+		// Clean start

+		Label cleanStartLabel = new Label(connectionGroup, SWT.NULL);

+		cleanStartLabel.setText("Clean Start:  ");

+		cleanStartCheckBox = new Button(connectionGroup, SWT.CHECK);

+		cleanStartCheckBox.setSelection(cleanStart);
+		cleanStartCheckBox.setToolTipText("Select to enable a clean start");

+		
+		// LWT checkbox

+		Label useWillLabel = new Label(connectionGroup, SWT.NULL);

+		useWillLabel.setText("LWT Enable:  ");

+		willCheckBox = new Button(connectionGroup, SWT.CHECK);

+		willCheckBox.setSelection(false);
+		willCheckBox.setToolTipText("Select to enable the Last Will and Testament (LWT)");

+		
+		// LWT topic

+		Label willTopicLabel = new Label(connectionGroup, SWT.NULL);

+		willTopicLabel.setText("LWT Topic: ");

+		willTopicValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		willTopicValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		willTopicValue.setText(willTopic);

+		willTopicValue.setEnabled(useWill);
+		willTopicValue.setToolTipText("Topic that the LWT message is publish on");

+		
+		// LWT message

+		Label willMessageLabel = new Label(connectionGroup, SWT.NULL);

+		willMessageLabel.setText("LWT Message: ");

+		willMessageValue = new Text(connectionGroup, SWT.SINGLE | SWT.BORDER);

+		willMessageValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		willMessageValue.setText(willMessage);

+		willMessageValue.setEnabled(useWill);
+		willMessageValue.setToolTipText("LWT message to publish");

+		
+		// LWT quality of service

+		Label willQosLabel = new Label(connectionGroup, SWT.NULL);

+		willQosLabel.setText("LWT QoS: ");

+		willQosDrop = new Combo(connectionGroup, SWT.DROP_DOWN | SWT.BORDER);

+		willQosDrop.add("0");

+		willQosDrop.add("1");

+		willQosDrop.add("2");

+		willQosDrop.select(0);

+		
+		// LWT retained flag

+		Label willRetainedLabel = new Label(connectionGroup, SWT.NULL);

+		willRetainedLabel.setText("LWT Retain:  ");

+		willRetainCheckBox = new Button(connectionGroup, SWT.CHECK);

+		willRetainCheckBox.setSelection(false);
+		willRetainCheckBox.setToolTipText("Select to retain the last LWT message");

+		
+		// Connect button

+		connectButton = new Button(connectionGroup, SWT.PUSH);

+		connectButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		connectButton.setText("Connect");
+		connectButton.setToolTipText("Press to connect to the broker");

+		
+		// Disconnect button

+		disconnectButton = new Button(connectionGroup, SWT.PUSH);

+		disconnectButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		disconnectButton.setText("Disconnect");
+		disconnectButton.setToolTipText("Press to disconnect from the broker");

+		
+		// A modify listeners for modifications to textual parameters

+		ModifyListener listener = new ModifyListener() {

+			public void modifyText(ModifyEvent e) {
+				valueChanged((Text) e.widget);

+			}

+		};

+		
+		// A modify listener for modification to the broker address

+		ModifyListener addressListener = new ModifyListener() {

+			public void modifyText(ModifyEvent e) {
+				addressValueChanged((Text) e.widget);

+			}

+		};

+		
+		// Set listeners

+		brokerAddressValue.addModifyListener(addressListener);

+		brokerPortValue.addModifyListener(addressListener);

+		clientIdValue.addModifyListener(listener);

+		usernameValue.addModifyListener(listener);

+		passwordValue.addModifyListener(listener);

+		keepAliveValue.addModifyListener(listener);

+		cleanStartCheckBox.addSelectionListener(selectListener);

+		connectButton.addSelectionListener(connectListener);

+		disconnectButton.addSelectionListener(connectListener);

+		willCheckBox.addSelectionListener(willListener);

+		willTopicValue.addModifyListener(listener);

+		willMessageValue.addModifyListener(listener);

+		

+		return composite;

+	}

+

+	/**
+	 * Creates the publish composite and populates it with all the widgets needed to make an MQTT publish.
+	 */

+	private Control getPublishControl(TabFolder tabFolder) {
+		@SuppressWarnings("unused")
+		Label tmpNullLabel;
+		

+		Composite composite = new Composite(tabFolder, SWT.NONE);

+		composite.setLayout(new FillLayout(SWT.VERTICAL));

+		

+		// Publish Group

+		publishGroup = new Group(composite, SWT.NONE);

+		publishGroup.setLayout(new GridLayout(3, false));

+		publishGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));

+		publishGroup.setText("Publish");

+		
+		// Publish topic

+		Label publishTopicLabel = new Label(publishGroup, SWT.NULL);

+		publishTopicLabel.setText("Topic: ");

+		publishTopicValue = new Text(publishGroup, SWT.SINGLE | SWT.BORDER);

+		publishTopicValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		publishTopicValue.setSize(110, 1);

+		

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+		
+		// Publish quality of service

+		Label publishQosLabel = new Label(publishGroup, SWT.NULL);

+		publishQosLabel.setText("QoS: ");

+		publishQosDrop = new Combo(publishGroup, SWT.DROP_DOWN | SWT.BORDER);

+		publishQosDrop.add("0");

+		publishQosDrop.add("1");

+		publishQosDrop.add("2");

+		publishQosDrop.select(0);

+		

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+		
+		// Publish payload (text)

+		Label publishPayloadLabel = new Label(publishGroup, SWT.NULL);

+		publishPayloadLabel.setText("Payload: ");

+		publishPayloadValue = new Text(publishGroup, SWT.SINGLE | SWT.BORDER);

+		publishPayloadValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		publishPayloadValue.setSize(110, 1);

+		

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+		

+		Button publishPayloadButton = new Button(publishGroup, SWT.PUSH);

+		publishPayloadButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		publishPayloadButton.setText("Publish Payload");

+		

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+		
+		// Publish payload (file)

+		Label publishFileLabel = new Label(publishGroup, SWT.NULL);

+		publishFileLabel.setText("File: ");

+		publishFileName = new Text(publishGroup, SWT.SINGLE | SWT.BORDER);

+		publishFileName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		publishFileName.setSize(100, 1);

+
+		// Browse button for selecting a filename

+		Button browseButton = new Button(publishGroup, SWT.PUSH);

+		browseButton.setText("Browse");

+		

+		tmpNullLabel = new Label(publishGroup, SWT.NULL);

+
+		// Publish file button

+		Button publishFileButton = new Button(publishGroup, SWT.PUSH);

+		publishFileButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		publishFileButton.setText("Publish File");

+
+		// Set selection listeners

+		publishPayloadButton.addSelectionListener(publishListener);

+		publishFileButton.addSelectionListener(publishFileListener);

+		browseButton.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				FileDialog dialog = new FileDialog(new Shell(), SWT.NULL);

+				String path = dialog.open();

+				if (path != null) {

+					File file = new File(path);

+					if (file.isFile())

+						displayFiles(new String[] { file.toString()});

+					else

+						displayFiles(file.list());

+

+				}

+			}

+		});

+		

+		return composite;

+	}

+

+	private void displayFiles(String[] files) {

+		for (int i = 0; files != null && i < files.length; i++) {

+			publishFileName.setText(files[i]);

+			publishFileName.setEditable(true);

+		}

+	}

+
+	/**
+	 * Creates the subscribe composite and populates it with all the widgets needed to make an MQTT subscription.
+	 */

+	private Control getSubscribeControl(TabFolder tabFolder) {

+		Composite composite = new Composite(tabFolder, SWT.NONE);

+		composite.setLayout(new FillLayout(SWT.VERTICAL));

+		

+		// Subscribe Group

+		subscribeGroup = new Group(composite, SWT.NONE);

+		subscribeGroup.setLayout(new GridLayout(2, false));

+		subscribeGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		subscribeGroup.setText("Subscribe");

+		
+		// Subscribe topic

+		Label subscribeTopicLabel = new Label(subscribeGroup, SWT.NULL);

+		subscribeTopicLabel.setText("Topic: ");

+		subscribeTopicValue = new Text(subscribeGroup, SWT.SINGLE | SWT.BORDER);

+		subscribeTopicValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));

+		subscribeTopicValue.setSize(80, 1);

+		
+		// Subscribe quality of service

+		Label subscribeQosLabel = new Label(subscribeGroup, SWT.NULL);

+		subscribeQosLabel.setText("QoS: ");

+		subscribeQosDrop = new Combo(subscribeGroup, SWT.DROP_DOWN | SWT.BORDER);

+		subscribeQosDrop.add("0");

+		subscribeQosDrop.add("1");

+		subscribeQosDrop.add("2");

+		subscribeQosDrop.select(0);

+		
+		// Subscribe button

+		Button subscribeButton = new Button(subscribeGroup, SWT.PUSH);

+		subscribeButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		subscribeButton.setText("Subscribe");

+		
+		// Unsubscribe button
+		Button unsubscribeButton = new Button(subscribeGroup, SWT.PUSH);

+		unsubscribeButton.setLayoutData(new GridData(ClientConstants.BUTTON_WIDTH, ClientConstants.BUTTON_HEIGHT));

+		unsubscribeButton.setText("Unsubscribe");
+		
+		// Set selection listeners

+		subscribeButton.addSelectionListener(subscribeListener);

+		unsubscribeButton.addSelectionListener(unsubscribeListener);

+		

+		return composite;

+	}

+	
+	/**
+	 * Return the bytes from a file
+	 */

+	public static byte[] getBytesFromFile(File file) throws IOException {

+		InputStream is = new FileInputStream(file);

+        long length = file.length();

+        byte[] bytes = new byte[(int)length];

+    

+        // Read in file

+        int offset = 0;

+        int numRead = 0;

+        while ((offset < bytes.length) && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {

+        	offset += numRead;

+        }

+    

+        // Close stream

+        is.close();
+        

+        return bytes;

+    }

+}