public void run() {
		final String methodName = "run";
		while (running) {
			try {
				// If no work is currently available, then wait until there is some...
				try {
					synchronized (workAvailable) {
						if (running & messageQueue.isEmpty()
								&& completeQueue.isEmpty()) {
							// @TRACE 704=wait for workAvailable
							log.fine(className, methodName, "704");
							workAvailable.wait();
						}
					}
				} catch (InterruptedException e) {
				}

				if (running) {
					// Check for deliveryComplete callbacks...
					if (!completeQueue.isEmpty()) {
						// First call the delivery arrived callback if needed
						MqttToken token = (MqttToken) completeQueue.elementAt(0);
						handleActionComplete(token);
						completeQueue.removeElementAt(0);
					}
					
					// Check for messageArrived callbacks...
					if (!messageQueue.isEmpty()) {
						// Note, there is a window on connect where a publish
						// could arrive before we've
						// finished the connect logic.
						MqttPublish message = (MqttPublish) messageQueue
								.elementAt(0);

						handleMessage(message);
						messageQueue.removeElementAt(0);
					}
				}

				if (quiescing) {
					clientState.checkQuiesceLock();
				}

				synchronized (spaceAvailable) {
					// Notify the spaceAvailable lock, to say that there's now
					// some space on the queue...

					// @TRACE 706=notify spaceAvailable
					log.fine(className, methodName, "706");
					spaceAvailable.notifyAll();
				}
			} catch (Throwable ex) {
				// Users code could throw an Error or Exception e.g. in the case
				// of class NoClassDefFoundError
				// @TRACE 714=callback threw exception
				log.fine(className, methodName, "714", null, ex);
				running = false;
				clientComms.shutdownConnection(null, new MqttException(ex));
			}
		}
	}