adjust peripheral integration

Signed-off-by: Ralf Mollik <ramollik@compex-commerce.com>
diff --git a/org.eclipse.osbp.abstractstatemachine.feature/feature.xml b/org.eclipse.osbp.abstractstatemachine.feature/feature.xml
index 347e108..f2f361d 100644
--- a/org.eclipse.osbp.abstractstatemachine.feature/feature.xml
+++ b/org.eclipse.osbp.abstractstatemachine.feature/feature.xml
@@ -4,7 +4,7 @@
         label="%featureName"
         version="0.9.0.qualifier"
         provider-name="%providerName"
-		plugin="org.eclipse.osbp.abstractstatemachine">
+		plugin="org.eclipse.osbp.license">
         
     <description>
         %description
diff --git a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractEventSource.java b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractEventSource.java
index c2bd305..93d2349 100644
--- a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractEventSource.java
+++ b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractEventSource.java
@@ -96,7 +96,7 @@
 		}
 		try {
 			String got = (String) get.invoke(listener);
-			if (got.isEmpty()) {
+			if (got == null || got.isEmpty()) {
 				return;
 			}
 			if (pos > got.length() - 1 || pos < 0) {
diff --git a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractPeripheralService.java b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractPeripheralService.java
index 8f007df..6e9930c 100644
--- a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractPeripheralService.java
+++ b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractPeripheralService.java
@@ -78,13 +78,13 @@
 import jpos.POSPrinterConst;
 import jpos.POSPrinterControl114;
 import jpos.config.JposEntryRegistry;
-import jpos.epson.EpsonPOSPrinterConst;
 import jpos.events.ErrorListener;
 import jpos.events.OutputCompleteEvent;
 import jpos.events.OutputCompleteListener;
 import jpos.events.StatusUpdateEvent;
 import jpos.events.StatusUpdateListener;
 import jpos.loader.simple.SimpleServiceManager;
+import jpos.services.POSPrinterService14;
 import jpos.util.DefaultProperties;
 import jpos.util.JposProperties;
 import jpos.util.JposPropertiesConst;
@@ -95,6 +95,14 @@
  */
 public abstract class AbstractPeripheralService extends AbstractStateMachineParticipant	implements IPeripheral, IPeripheral.Command, 
 								StatusUpdateListener, ErrorListener, OutputCompleteListener, ISignatureListener, ActionListener {
+	private static final String HTTP = "http";
+
+	private static final String APPLICATION_JSON = "application/json";
+
+	private static final String ACCEPT = "Accept";
+
+	private static final String DEVICE_NAME = "deviceName";
+
 	private static final String CASH_DRAWER_CONST = "CashDrawerConst";
 
 	private static final String POS_PRINTER_CONST = "POSPrinterConst";
@@ -152,7 +160,11 @@
 	
 	/** The pos printer fields. */
 	Field[] posPrinterFields = POSPrinterConst.class.getDeclaredFields();
+	
+	private Map<Integer, String> printerBitmaps = new HashMap<>();
 
+    private String esc = ((char)0x1b)+"";
+	
 	@Override
 	public boolean equals(Object obj) {
 		return super.equals(obj);
@@ -188,7 +200,7 @@
 	public void init() {
 		isRemote = statemachine.isJavaPosRemote();
 		if(!isRemote) {
-			LOGGER.debug("Library path=" + System.getProperty("java.library.path"));
+			LOGGER.debug("Library path={}", System.getProperty("java.library.path"));
 			// load all names of configured devices, instantiate and cache it
 			String configFile = ProductConfiguration.getJavaPosConfiguration();
 			if (configFile == null || configFile.length() == 0) {
@@ -216,7 +228,7 @@
 			remoteHost = statemachine.getHostName();
 			remotePort = statemachine.getRemotePort();
 			URIBuilder builder = new URIBuilder();
-			builder.setScheme("http").setHost(remoteHost).setPort(remotePort);
+			builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
 			if(statusPoll == null) {
 				statusPoll = new Timer(1000, this);
 				statusPoll.start();
@@ -233,7 +245,7 @@
 	private String doHttpGet(String path, String paraName1, String para1, String paraName2, String para2) {
 		String responseString = null;
 		URIBuilder builder = new URIBuilder();
-		builder.setScheme("http").setHost(remoteHost).setPort(remotePort);
+		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
 		builder.setPath(path);
 		builder.clearParameters();
 		if(paraName1 != null && para1 != null) {
@@ -244,7 +256,7 @@
 		}
 		try {
 			HttpGet get = new HttpGet(builder.build());
-			get.addHeader("Accept", "application/json");
+			get.addHeader(ACCEPT, APPLICATION_JSON);
 			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 			CloseableHttpResponse response = httpClient.execute(get);
 			responseString = EntityUtils.toString(response.getEntity());
@@ -261,7 +273,7 @@
 	
 	private void doHttpPut(String path, String paraName1, String para1, String paraName2, String para2) {
 		URIBuilder builder = new URIBuilder(); 
-		builder.setScheme("http").setHost(remoteHost).setPort(remotePort);
+		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
 		builder.setPath(path);
 		builder.clearParameters();
 		if(paraName1 != null && para1 != null) {
@@ -272,10 +284,9 @@
 		}
 		try {
 			HttpPut put = new HttpPut(builder.build());
-			put.addHeader("Accept", "application/json");
+			put.addHeader(ACCEPT, APPLICATION_JSON);
 			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
-			CloseableHttpResponse response = httpClient.execute(put);
-			LOGGER.debug(EntityUtils.toString(response.getEntity()));
+			httpClient.execute(put);
 			put.releaseConnection();
 		} catch (URISyntaxException | ParseException | IOException e) {
 			LOGGER.error("{}", e);
@@ -292,11 +303,11 @@
 	
 	private void doHttpPost(String path, String paraName, String para, byte[] image) {
 		URIBuilder builder = new URIBuilder();
-		builder.setScheme("http").setHost(remoteHost).setPort(remotePort);
+		builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
 		builder.setPath(path);
 		try {
 			HttpPost post = new HttpPost(builder.build());
-			post.addHeader("Accept", "application/json");
+			post.addHeader(ACCEPT, APPLICATION_JSON);
 			if(paraName != null && para != null || image != null) {
 				MultipartEntityBuilder mpeBuilder = MultipartEntityBuilder.create();
 				mpeBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
@@ -309,8 +320,7 @@
 				post.setEntity(mpeBuilder.build());
 			}
 			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
-			CloseableHttpResponse response = httpClient.execute(post);
-			LOGGER.debug(EntityUtils.toString(response.getEntity()));
+			httpClient.execute(post);
 			post.releaseConnection();
 		} catch (URISyntaxException | ParseException | IOException e) {
 			LOGGER.error("{}", e);
@@ -346,7 +356,7 @@
 	 */
 	public void setDisplayLine(String deviceName, String displayLine) {
 		if(isRemote) {
-			doHttpPut("/devices/displayLine", "deviceName", deviceName, "displayLine", displayLine);
+			doHttpPut("/devices/displayLine", DEVICE_NAME, deviceName, "displayLine", displayLine);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -373,20 +383,22 @@
 	 *            encodes a pipe separated tuple bitmapNumber, bitmapFilename
 	 */
 	public void setPrinterBitmap(String registerId, String registerBitmapId) {
+		int imgWidth = 200;
+		int imgHeight = 80;
 		if(isRemote) {
+			doHttpPut("/devices/uploadedBitmaps", "uploadedBitmaps", Boolean.toString(ProductConfiguration.hasJavaPosUploadedBitmaps()));
 			byte[] img = statemachine.getBlobService().getByteArrayImage(registerBitmapId, 0);
 			doHttpPost("/devices/printerBitmap", "registerId", registerId, img);
 			return;
-			
 		} else if (!initDone) {
 			return;
 		}
     	// load the image
 		BufferedImage img = statemachine.getBlobService().getBufferedImage(registerBitmapId, 0);
 		// convert it to black/white
-        BufferedImage blackWhite = new BufferedImage(400, 180, BufferedImage.TYPE_BYTE_BINARY);
+        BufferedImage blackWhite = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
         Graphics2D g2d = blackWhite.createGraphics();
-        g2d.drawImage(img, 0, 0, 400, 180, 0, 0, img.getWidth(), img.getHeight(), null);
+        g2d.drawImage(img, 0, 0, imgWidth, imgHeight, 0, 0, img.getWidth(), img.getHeight(), null);
         g2d.dispose();
 		
         // write file in temp dir
@@ -400,13 +412,17 @@
 		}
 		
 		for(BaseControl device:devices.values()) {
-			String deviceName = "";
+			String deviceName = ""; 
 			try {
+				int bitmapIndex = Integer.parseInt(registerId);
+				String path = tempFile.getPath();
 				deviceName = device.getPhysicalDeviceName();
 				if(device instanceof POSPrinter && ((POSPrinterControl114) device).getCapRecBitmap()) {
-					int lineWidth = ((POSPrinterControl114) device).getRecLineWidth();
-					((POSPrinterControl114) device).setBitmap(new Integer(registerId),
-							POSPrinterConst.PTR_S_RECEIPT, tempFile.getPath(), lineWidth / 2, POSPrinterConst.PTR_BM_CENTER);
+					if(ProductConfiguration.hasJavaPosUploadedBitmaps()) {
+						((POSPrinterControl114) device).setBitmap(bitmapIndex,POSPrinterConst.PTR_S_RECEIPT, path, (((POSPrinterControl114) device).getRecLineWidth()/2), POSPrinterConst.PTR_BM_CENTER);
+					} else {
+						printerBitmaps.put(bitmapIndex, path);
+					}
 				}
 			} catch (JposException jex) {
 				LOGGER.error("jpos error setRegisterBitmap for device:{} and:{} ex:{}", deviceName, registerBitmapId, jex);
@@ -426,7 +442,7 @@
 	 */
 	public void setDeviceBrightness(String deviceName, Integer deviceBrightness) {
 		if(isRemote) {
-			doHttpPut("/devices/deviceBrightness", "deviceName", deviceName, "deviceBrightness", deviceBrightness.toString());
+			doHttpPut("/devices/deviceBrightness", DEVICE_NAME, deviceName, "deviceBrightness", deviceBrightness.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -449,7 +465,7 @@
 	 */
 	public void setBlinkRate(String deviceName, Integer blinkRate) {
 		if(isRemote) {
-			doHttpPut("/devices/blinkRate", "deviceName", deviceName, "blinkRate", blinkRate.toString());
+			doHttpPut("/devices/blinkRate", DEVICE_NAME, deviceName, "blinkRate", blinkRate.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -472,7 +488,7 @@
 	 */
 	public void setCursorType(String deviceName, Integer cursorType) {
 		if(isRemote) {
-			doHttpPut("/devices/cursorType", "deviceName", deviceName, "cursorType", cursorType.toString());
+			doHttpPut("/devices/cursorType", DEVICE_NAME, deviceName, "cursorType", cursorType.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -495,7 +511,7 @@
 	 */
 	public void setMarqueeFormat(String deviceName, Integer marqueeFormat) {
 		if(isRemote) {
-			doHttpPut("/devices/marqueeFormat", "deviceName", deviceName, "marqueeFormat", marqueeFormat.toString());
+			doHttpPut("/devices/marqueeFormat", DEVICE_NAME, deviceName, "marqueeFormat", marqueeFormat.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -518,7 +534,7 @@
 	 */
 	public void setMarqueeRepeatWait(String deviceName, Integer marqueeRepeatWait) {
 		if(isRemote) {
-			doHttpPut("/devices/marqueeRepeatWait", "deviceName", deviceName, "marqueeRepeatWait", marqueeRepeatWait.toString());
+			doHttpPut("/devices/marqueeRepeatWait", DEVICE_NAME, deviceName, "marqueeRepeatWait", marqueeRepeatWait.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -541,7 +557,7 @@
 	 */
 	public void setMarqueeType(String deviceName, Integer marqueeType) {
 		if(isRemote) {
-			doHttpPut("/devices/marqueeType", "deviceName", deviceName, "marqueeType", marqueeType.toString());
+			doHttpPut("/devices/marqueeType", DEVICE_NAME, deviceName, "marqueeType", marqueeType.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -564,7 +580,7 @@
 	 */
 	public void setMarqueeUnitWait(String deviceName, Integer marqueeUnitWait) {
 		if(isRemote) {
-			doHttpPut("/devices/marqueeUnitWait", "deviceName", deviceName, "marqueeUnitWait", marqueeUnitWait.toString());
+			doHttpPut("/devices/marqueeUnitWait", DEVICE_NAME, deviceName, "marqueeUnitWait", marqueeUnitWait.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -588,7 +604,7 @@
 	 */
 	public void setCreateWindow(String deviceName, String createWindow) {
 		if(isRemote) {
-			doHttpPut("/devices/createWindow", "deviceName", deviceName, "createWindow", createWindow);
+			doHttpPut("/devices/createWindow", DEVICE_NAME, deviceName, "createWindow", createWindow);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -617,7 +633,7 @@
 	 */
 	public void setDestroyWindow(String deviceName, String destroyWindow) { // NOSONAR
 		if(isRemote) {
-			doHttpPut("/devices/destroyWindow", "deviceName", deviceName, "destroyWindow", destroyWindow);
+			doHttpPut("/devices/destroyWindow", DEVICE_NAME, deviceName, "destroyWindow", destroyWindow);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -643,7 +659,7 @@
 	 */
 	public void setScroll(String deviceName, String scroll) {
 		if(isRemote) {
-			doHttpPut("/devices/scroll", "deviceName", deviceName, "scroll", scroll);
+			doHttpPut("/devices/scroll", DEVICE_NAME, deviceName, "scroll", scroll);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -670,7 +686,7 @@
 	 */
 	public void setInterCharacterWait(String deviceName, Integer interCharacterWait) {
 		if(isRemote) {
-			doHttpPut("/devices/interCharacterWait", "deviceName", deviceName, "interCharacterWait", interCharacterWait.toString());
+			doHttpPut("/devices/interCharacterWait", DEVICE_NAME, deviceName, "interCharacterWait", interCharacterWait.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -694,7 +710,7 @@
 	 */
 	public void setDisplayTextAt(String deviceName, String displayTextAt) {
 		if(isRemote) {
-			doHttpPut("/devices/displayTextAt", "deviceName", deviceName, "displayTextAt", displayTextAt);
+			doHttpPut("/devices/displayTextAt", DEVICE_NAME, deviceName, "displayTextAt", displayTextAt);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -726,7 +742,7 @@
 	 */
 	public void setClearDisplay(String deviceName, String clearDisplay) {
 		if(isRemote) {
-			doHttpPut("/devices/clearDisplay", "deviceName", deviceName, "clearDisplay", clearDisplay);
+			doHttpPut("/devices/clearDisplay", DEVICE_NAME, deviceName, "clearDisplay", clearDisplay);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -753,7 +769,7 @@
 	 */
 	public void setOpenDrawer(String deviceName, Integer openDrawer) { // NOSONAR
 		if(isRemote) {
-			doHttpPut("/devices/openDrawer", "deviceName", deviceName, "openDrawer", openDrawer.toString());
+			doHttpPut("/devices/openDrawer", DEVICE_NAME, deviceName, "openDrawer", openDrawer.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -776,7 +792,7 @@
 	 */
 	public void setPrintNormal(String deviceName, String printNormal) {
 		if(isRemote) {
-			doHttpPut("/devices/printNormal", "deviceName", deviceName, "printNormal", printNormal);
+			doHttpPut("/devices/printNormal", DEVICE_NAME, deviceName, "printNormal", printNormal);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -799,7 +815,7 @@
 	 */
 	public void setPrintCut(String deviceName, String footer) {
 		if(isRemote) {
-			doHttpPut("/devices/printCut", "deviceName", deviceName, "printCut", footer);
+			doHttpPut("/devices/printCut", DEVICE_NAME, deviceName, "printCut", footer);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -809,12 +825,11 @@
 			if (!footer.isEmpty()) {
 				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, footer);
 			}
-			// Feed the receipt to the cutter position automatically,
-			// and cut.
-			((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
-					"\u001b|" + (((POSPrinterControl114) devices.get(deviceName)).getRecLinesToPaperCut()) + "lF");
-			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecPapercut())
-				((POSPrinterControl114) devices.get(deviceName)).cutPaper(100);
+			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecPapercut()) {
+				int linesToPaperCut = ((POSPrinterControl114) devices.get(deviceName)).getRecLinesToPaperCut();
+				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "d" + ((char)(linesToPaperCut+1)));
+				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "i");
+			}
 		} catch (JposException e) {
 			LOGGER.error("jpos error printCut for device:" + deviceName + " {}", e);
 		}
@@ -830,23 +845,19 @@
 	 */
 	public void setPrintBitmap(String deviceName, Integer printBitmap) {
 		if(isRemote) {
-			doHttpPut("/devices/printBitmap", "deviceName", deviceName, "printBitmap", printBitmap.toString());
+			doHttpPut("/devices/printBitmap", DEVICE_NAME, deviceName, "printBitmap", printBitmap.toString());
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
 			return;
 		}
-		String text = String.format("\u001b|%dB", printBitmap);
 		try {
-			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap()) {
-				int[] pram2 = new int[1];
-				pram2[0] = EpsonPOSPrinterConst.PTR_DI_BITMAP_PRINTING_MULTI_TONE;
-				((POSPrinterControl114) devices.get(deviceName))
-						.directIO(EpsonPOSPrinterConst.PTR_DI_SET_BITMAP_PRINTING_TYPE, pram2, "");
-				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, text);
-				pram2[0] = EpsonPOSPrinterConst.PTR_DI_BITMAP_PRINTING_NORMAL;
-				((POSPrinterControl114) devices.get(deviceName))
-						.directIO(EpsonPOSPrinterConst.PTR_DI_SET_BITMAP_PRINTING_TYPE, pram2, "");
+			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap() && printerBitmaps.containsKey(printBitmap)) {
+				if(ProductConfiguration.hasJavaPosUploadedBitmaps()) {
+					((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, esc+"|"+printBitmap.toString()+"B");
+				} else {
+					((POSPrinterControl114) devices.get(deviceName)).printBitmap(POSPrinterConst.PTR_S_RECEIPT, printerBitmaps.get(printBitmap), POSPrinterConst.PTR_BM_ASIS, POSPrinterConst.PTR_BM_CENTER);
+				}
 			}
 		} catch (JposException e) {
 			LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + printBitmap + " {}", e);
@@ -864,7 +875,7 @@
 	 */
 	public void setPrintBarcode(String deviceName, String data) {
 		if(isRemote) {
-			doHttpPut("/devices/printBarcode", "deviceName", deviceName, "printBarcode", data);
+			doHttpPut("/devices/printBarcode", DEVICE_NAME, deviceName, "printBarcode", data);
 			return;
 			
 		} else if (!initDone || !devices.containsKey(deviceName)) {
@@ -872,20 +883,18 @@
 		}
 		String[] parts = data.split("\\|");
 		try {
+			String value = parts[0];
+			int code = Integer.parseInt(parts[1].trim());
+			int height = 0;
+			if(parts.length > 2) {
+				height = Integer.parseInt(parts[2].trim());
+			}
 			if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBarCode()) {
-				// 5mm spaces
-				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
-						"\u001b|500uF");
-				((POSPrinterControl114) devices.get(deviceName)).printBarCode(POSPrinterConst.PTR_S_RECEIPT, parts[0],
-						new Integer(parts[1].trim()), 1000,
-						((POSPrinterControl114) devices.get(deviceName)).getRecLineWidth(),
-						POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW);
-				// 2mm spaces
-				((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
-						"\u001b|200uF");
+				((POSPrinterControl114) devices.get(deviceName)).printBarCode(POSPrinterConst.PTR_S_RECEIPT, value,
+						code, height, ((POSPrinterControl114) devices.get(deviceName)).getRecLineWidth(), POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW);
 			}
 		} catch (JposException e) {
-			LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + data + " {}", e);
+			LOGGER.error("jpos error setPrintBarcode for device:" + deviceName + " and:" + data + " {}", e);
 		}
 	}
 
@@ -898,7 +907,6 @@
 	public void setSlipNotificationsEnabled(boolean slipNotificationsEnabled) {
 		if(isRemote) {
 			doHttpPut("/devices/slipNotificationsEnabled", "slipNotificationsEnabled", Boolean.toString(slipNotificationsEnabled));
-			return;
 		} else {
 			this.slipNotificationsEnabled = slipNotificationsEnabled;
 		}
@@ -927,6 +935,18 @@
 	@Override
 	public void statusUpdateOccurred(StatusUpdateEvent e) { // NOSONAR
 		Object source = e.getSource();
+		if(source instanceof POSPrinterService14) {
+			try {
+				String serviceDescription = ((POSPrinterService14)source).getPhysicalDeviceDescription();
+				if(serviceDescription.contains("Cash Drawer")) {
+					decodeCashDrawerStatus(e.getStatus());
+				} else {
+					decodePOSPrinterStatus(e.getStatus());
+				}
+			} catch (JposException e1) {
+				// NOSONAR
+			}
+		}
 		if (source instanceof CashDrawer) {
 			decodeCashDrawerStatus(e.getStatus());
 		}
@@ -936,152 +956,114 @@
 	}
 
 	private void decodePOSPrinterStatus(int status) {
-		switch (status) {
-		case POSPrinterConst.PTR_SUE_COVER_OPEN:
-			if (statemachine != null) {
+		if (statemachine != null) {
+			switch (status) {
+			case POSPrinterConst.PTR_SUE_COVER_OPEN:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "coverOpen"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_COVER_OK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_COVER_OK:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "coverOpen"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "receiptEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_PAPEROK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_PAPEROK:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "receiptEmpty"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "receiptNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_NEAREMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_NEAREMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "receiptNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_EMPTY:
-			if (statemachine != null && slipNotificationsEnabled) {
-				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_PAPEROK:
-			if (statemachine != null && slipNotificationsEnabled) {
-				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "slipEmpty"));
-				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "slipNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_NEAREMPTY:
-			if (statemachine != null && slipNotificationsEnabled) {
-				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_EMPTY:
+				if (slipNotificationsEnabled) {
+					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipEmpty"));
+				}
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_PAPEROK:
+				if (slipNotificationsEnabled) {
+					statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "slipEmpty"));
+					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "slipNearEmpty"));
+				}
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_NEAREMPTY:
+				if (slipNotificationsEnabled) {
+					statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipNearEmpty"));
+				}
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "journalEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_PAPEROK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_PAPEROK:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "journalEmpty"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "journalNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_NEAREMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_NEAREMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "journalNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGEOPEN, "receiptCartridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_NEAREMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_NEAREMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSOPEN, "receiptCartridgeNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_HEAD_CLEANING:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSOPEN, "receiptHeadCleaning"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_REC_CARTDRIGE_OK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_REC_CARTDRIGE_OK:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGECLOSE, "receiptCartridgeEmpty"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "receiptHeadCleaning"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "receiptCartridgeNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGEOPEN, "slipCartridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_NEAREMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_NEAREMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSOPEN, "slipCartridgeNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_HEAD_CLEANING:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipHeadCleaning"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_SLP_CARTDRIGE_OK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_SLP_CARTDRIGE_OK:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGECLOSE, "slipCartridgeEmpty"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "slipHeadCleaning"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "slipCartridgeNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGEOPEN, "journalCartridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_NEAREMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_NEAREMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSOPEN, "journalCartridgeNearEmpty"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_HEAD_CLEANING:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSOPEN, "journalHeadCleaning"));
-			}
-			break;
-		case POSPrinterConst.PTR_SUE_JRN_CARTDRIGE_OK:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.PTR_SUE_JRN_CARTDRIGE_OK:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.MESSAGECLOSE, "journalCartridgeEmpty"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "journalHeadCleaning"));
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.STATUSCLOSE, "journalCartridgeNearEmpty"));
+				break;
+			default:
+				break;
 			}
-			break;
-		default:
-			break;
 		}
 	}
 
@@ -1111,88 +1093,62 @@
 	 */
 	@Override
 	public void errorOccurred(jpos.events.ErrorEvent e) { // NOSONAR
-		decodePOSPrinterError(e.getErrorCodeExtended());
+		decodePOSPrinterErrorField(e.getErrorCodeExtended());
 	}
 
-	private void decodePOSPrinterError(int error) {
-		switch (error) {
-		case POSPrinterConst.JPOS_EPTR_COVER_OPEN:
-			if (statemachine != null) {
+	private void decodePOSPrinterErrorField(int error) {
+		if (statemachine != null) {
+			switch (error) {
+			case POSPrinterConst.JPOS_EPTR_COVER_OPEN:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorCoverOpen"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_JRN_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_JRN_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_REC_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_REC_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_SLP_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_SLP_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_BADFORMAT:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_BADFORMAT:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorBadFormat"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_EMPTY:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_EMPTY:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipCartdridgeEmpty"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_REMOVED:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_REMOVED:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.ERROR, "errorJournalCartdridgeRemoved"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_REMOVED:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_REMOVED:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeRemoved"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_REMOVED:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_REMOVED:
 				statemachine.processEvent(statemachine,
 						new MessageEvent(EventType.ERROR, "errorSlipCartdridgeRemoved"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_JRN_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_JRN_HEAD_CLEANING:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalHeadCleaning"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_REC_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_REC_HEAD_CLEANING:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptHeadCleaning"));
-			}
-			break;
-		case POSPrinterConst.JPOS_EPTR_SLP_HEAD_CLEANING:
-			if (statemachine != null) {
+				break;
+			case POSPrinterConst.JPOS_EPTR_SLP_HEAD_CLEANING:
 				statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipHeadCleaning"));
+				break;
+			default:
+				break;
 			}
-			break;
-		default:
-			break;
 		}
 	}
 
@@ -1295,7 +1251,9 @@
 	 */
 	public void setPaymentTerminalBalanceRequest(String request) { // NOSONAR
 		if (POSServiceBinder.getPosService() != null) {
-			// zvt.balanceRequest();
+			/**
+			 * zvt.balanceRequest(); 
+			 */
 		}
 	}
 
@@ -1307,7 +1265,9 @@
 	 */
 	public void setPaymentTerminalPrepaidTopUp(Double amount) { // NOSONAR
 		if (POSServiceBinder.getPosService() != null) {
-			// zvt.prepaidTopUp(amount);
+		/**
+		 * zvt.prepaidTopUp(amount);
+		 */
 		}
 	}
 
@@ -1380,36 +1340,33 @@
 	 *            the new prints the report
 	 */
 	public void setPrintReport(String reportParameters, String printService) {
-		if (statemachine.getReportProvider() != null) {
-			String[] parts = reportParameters.split("\\|");
-			String reportName = parts[0];
-			Map<String, String> filterMap = new HashMap<>();
-			// the filter is optional
-			if (parts.length > 1) {
-				String storageKey = parts[1];
-				String filterName = null;
-				String filterValue = null;
-				for (String attribute : statemachine.getStorageAttributes(parts[1])) {
-					if ("filterName".equals(attribute)) {
-						filterName = (String) statemachine.getStorage(storageKey, attribute);
-					}
-					if ("filterValue".equals(attribute)) {
-						filterValue = (String) statemachine.getStorage(storageKey, attribute);
-					}
-					if (filterName != null && filterValue != null) {
-						// TODO: as soon as report supports cube datamarts, the
-						// slicerSingleSelectDecorator must be added
-						filterMap.put(filterName, filterValue);
-						filterName = null;
-						filterValue = null;
-					}
+		String[] parts = reportParameters.split("\\|");
+		String reportName = parts[0];
+		Map<String, String> filterMap = new HashMap<>();
+		// the filter is optional
+		if (parts.length > 1) {
+			String storageKey = parts[1];
+			String filterName = null;
+			String filterValue = null;
+			for (String attribute : statemachine.getStorageAttributes(parts[1])) {
+				if ("filterName".equals(attribute)) {
+					filterName = (String) statemachine.getStorage(storageKey, attribute);
+				} else if ("filterValue".equals(attribute)) {
+					filterValue = (String) statemachine.getStorage(storageKey, attribute);
+				}
+				if (filterName != null && filterValue != null) {
+					filterMap.put(filterName, filterValue);
+					filterName = null;
+					filterValue = null;
 				}
 			}
+		}
+		if (statemachine.getReportProvider() != null) {
 			statemachine.getReportProvider().printReportAsPdf(reportName, statemachine.getEclipseContext(), filterMap, printService);
 		}
 	}
 	
-	public void setSignatureOpen(String dummy) {
+	public void setSignatureOpen(String dummy) {	// NOSONAR
 		if(isRemote) {
 			doHttpPost("/signature/openTablet");
 			if(signatureStatusPoll == null) {
@@ -1418,14 +1375,12 @@
 			} else if(!statusPoll.isRunning()){
 				signatureStatusPoll.restart();
 			}
-		} else if(POSServiceBinder.getSignatureService() != null) {
-			if(POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
-				statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
-			}
+		} else if(POSServiceBinder.getSignatureService() != null && POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
+			statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
 		}
 	}
 
-	public void setSignatureCapture(String dummy) {
+	public void setSignatureCapture(String dummy) {	// NOSONAR
 		if(isRemote) {
 			doHttpPost("/signature/captureTablet");
 		} else if(POSServiceBinder.getSignatureService() != null) {
@@ -1434,7 +1389,7 @@
 		}
 	}
 	
-	public void setSignatureIdle(String dummy) {
+	public void setSignatureIdle(String dummy) {	// NOSONAR
 		if(isRemote) {
 			doHttpPost("/signature/idleTablet");
 		} else if(POSServiceBinder.getSignatureService() != null) {			
@@ -1469,7 +1424,7 @@
 		}
 	}
 	
-	public void setSignatureClose(String dummy) {
+	public void setSignatureClose(String dummy) {	// NOSONAR
 		if(isRemote) {
 			doHttpPost("closeTablet");
 			if(signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
@@ -1498,10 +1453,8 @@
 			statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onSignatureOk"));
 			POSServiceBinder.getSignatureService().idleTablet();
 		}
-		if(event.getButtonId() == 2) {
-			if(POSServiceBinder.getSignatureService() != null) {
-				POSServiceBinder.getSignatureService().clearTablet();
-			}
+		if(event.getButtonId() == 2 && POSServiceBinder.getSignatureService() != null) {
+			POSServiceBinder.getSignatureService().clearTablet();
 		}
 		if(event.getButtonId() == 3) {
 			penData.clear();
@@ -1554,7 +1507,6 @@
 
     public void setSound(String name) { 
     	audio.setSources(statemachine.getThemeResourceService().getThemeResource(name, ThemeResourceType.SOUND));
-//    	audio.setSources(new ExternalResource("http://www.podtrac.com/pts/redirect.mp3?http://piledriver.hipcast.com/deluge/WrestleManiaX7OSWReview55.mp3"));
     	audio.play();
     }
 
@@ -1570,61 +1522,80 @@
 	}
 
 	private void decodeRemoteError(String responseString) {
-		List<String> errors = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
-		for(String error:errors) {
-			if(error.startsWith(POS_PRINTER_CONST)) {
-				for ( Field field : posPrinterFields ) {
-					if(field.getName().equals(error.substring(POS_PRINTER_CONST.length()+1))) {
-						field.setAccessible(true);
-						try {
-							decodePOSPrinterError((int)field.get(error));
-						} catch (IllegalArgumentException | IllegalAccessException e1) {
-							LOGGER.error("{}", e1);
-						}
-						break;
-					}
+		if(responseString != null) {
+			List<String> errors = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
+			for(String error:errors) {
+				if(error.startsWith(POS_PRINTER_CONST)) {
+					decodeRemoteErrorState(error);
 				}
 			}
 		}
 	}
 
+	private void decodeRemoteErrorState(String error) {
+		for ( Field field : posPrinterFields ) {
+			if(field.getName().equals(error.substring(POS_PRINTER_CONST.length()+1))) {
+				field.setAccessible(true);
+				try {
+					decodePOSPrinterErrorField((int)field.get(error));
+				} catch (IllegalArgumentException | IllegalAccessException e1) {
+					LOGGER.error("{}", e1);
+				}
+				break;
+			}
+		}
+	}
+
 	private void decodeRemoteState(String responseString) {
-		List<String> states = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
-		for(String state:states) {
-			if(state.startsWith(CASH_DRAWER_CONST)) {
-				for ( Field field : cashDrawerFields ) {
-				   field.setAccessible(true);
-					if(field.getName().equals(state.substring(CASH_DRAWER_CONST.length()+1))) {
-						field.setAccessible(true);
-						try {
-							decodeCashDrawerStatus((int)field.get(state));
-						} catch (IllegalArgumentException | IllegalAccessException e1) {
-							LOGGER.error("{}", e1);
-						}
-						break;
-					}
-				}
-			} else if(state.startsWith(POS_PRINTER_CONST)) {
-				for ( Field field : posPrinterFields ) {
-					if(field.getName().equals(state.substring(POS_PRINTER_CONST.length()+1))) {
-						field.setAccessible(true);
-						try {
-							decodePOSPrinterStatus((int)field.get(state));
-						} catch (IllegalArgumentException | IllegalAccessException e1) {
-							LOGGER.error("{}", e1);
-						}
-						break;
-					}
+		if(responseString != null) {
+			List<String> states = Arrays
+					.asList(responseString.replace("[", "").replace("]", "").replace("\"", "").split(","));
+			for (String state : states) {
+				if (state.startsWith(CASH_DRAWER_CONST)) {
+					decodeCashDrawerStatusField(state);
+				} else if (state.startsWith(POS_PRINTER_CONST)) {
+					decodePOSPrinterStatusField(state);
 				}
 			}
 		}
 	}
 
+	private void decodePOSPrinterStatusField(String state) {
+		for (Field field : posPrinterFields) {
+			if (field.getName().equals(state.substring(POS_PRINTER_CONST.length() + 1))) {
+				field.setAccessible(true);
+				try {
+					decodePOSPrinterStatus((int) field.get(state));
+				} catch (IllegalArgumentException | IllegalAccessException e1) {
+					LOGGER.error("{}", e1);
+				}
+				break;
+			}
+		}
+	}
+
+	private void decodeCashDrawerStatusField(String state) {
+		for (Field field : cashDrawerFields) {
+			field.setAccessible(true);
+			if (field.getName().equals(state.substring(CASH_DRAWER_CONST.length() + 1))) {
+				field.setAccessible(true);
+				try {
+					decodeCashDrawerStatus((int) field.get(state));
+				} catch (IllegalArgumentException | IllegalAccessException e1) {
+					LOGGER.error("{}", e1);
+				}
+				break;
+			}
+		}
+	}
+
 	private void decodeRemoteSignatureState(String responseString) {
-		List<String> states = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
-		for(String state:states) {
-			if(!state.isEmpty()) {
-				statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, state));
+		if(responseString != null) {
+			List<String> states = Arrays.asList(responseString.replace("[","").replace("]", "").replace("\"", "").split(","));
+			for(String state:states) {
+				if(!state.isEmpty()) {
+					statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, state));
+				}
 			}
 		}
 	}
diff --git a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachine.java b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachine.java
index 274c959..945506e 100644
--- a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachine.java
+++ b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachine.java
@@ -100,9 +100,18 @@
 		{
 			put(KeyCode.TAB, "TAB");
 			put(KeyCode.ENTER, "ENTER");
-			put(KeyCode.ESCAPE, "ESC");
 			put(KeyCode.PAGE_UP, "PGUP");
 			put(KeyCode.PAGE_DOWN, "PGDOWN");
+			put(KeyCode.BACKSPACE, "BACKSPACE");
+			put(KeyCode.INSERT, "INSERT");
+			put(KeyCode.DELETE, "DELETE");
+			put(KeyCode.HOME, "HOME");
+			put(KeyCode.END, "END");
+			put(KeyCode.ARROW_DOWN, "DOWNARROW");
+			put(KeyCode.ARROW_UP, "UPARROW");
+			put(KeyCode.ARROW_LEFT, "LEFTARROW");
+			put(KeyCode.ARROW_RIGHT, "RIGHTARROW");
+			put(KeyCode.ESCAPE, "ESC");
 			put(KeyCode.F1, "F1");
 			put(KeyCode.F2, "F2");
 			put(KeyCode.F3, "F3");
@@ -558,7 +567,7 @@
 	@Override
 	public int getRemotePort() {
 		if(!remotePortOverridden) {
-			if(ProductConfiguration.getJavaPosPortConfiguration() != null) {
+			if(ProductConfiguration.getJavaPosPortConfiguration() != null && !ProductConfiguration.getJavaPosPortConfiguration().isEmpty()) {
 				return Integer.parseInt(ProductConfiguration.getJavaPosPortConfiguration());
 			}
 		}
@@ -871,6 +880,9 @@
 		try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
 			CloseableHttpResponse response = httpClient.execute(get);
 			logger.info(EntityUtils.toString(response.getEntity()));
+			if(response.getEntity().getContentLength()==0) {
+				return false;
+			}
 			return true;
 		} catch (ParseException | IOException e) {
 			// it's ok - we have no remote javapos
diff --git a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachineParticipant.java b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachineParticipant.java
index a84d17c..fc2f87a 100644
--- a/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachineParticipant.java
+++ b/org.eclipse.osbp.abstractstatemachine/src/org/eclipse/osbp/abstractstatemachine/AbstractStateMachineParticipant.java
@@ -37,12 +37,11 @@
 
 public abstract class AbstractStateMachineParticipant implements
 		IStateMachineParticipant {
-	private static final long serialVersionUID = -7670617914357429160L;
 	/** The LOGGER. */
 	protected static final Logger LOGGER = LoggerFactory
 			.getLogger(AbstractStateMachineParticipant.class);
 	protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
-	protected transient IStateMachine statemachine;
+	protected IStateMachine statemachine;
 	protected Locale locale;
 
 	@Override
@@ -169,18 +168,10 @@
 		Object result = get(obj, id);
 		if(result != null) {
 			if(result.getClass().isAssignableFrom(Boolean.class)) {
-				if((Boolean)result) {
-					set(obj, id, false);
-				} else {
-					set(obj, id, true);
-				}
+				set(obj, id, (Boolean)result);
 			}
 			if(result.getClass().isAssignableFrom(boolean.class)) {
-				if((boolean)result) {
-					set(obj, id, false);
-				} else {
-					set(obj, id, true);
-				}
+				set(obj, id, (boolean)result);
 			}
 		} else {
 			set(obj, id, true);
diff --git a/org.eclipse.osbp.bpm b/org.eclipse.osbp.bpm
deleted file mode 160000
index 39e6925..0000000
--- a/org.eclipse.osbp.bpm
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 39e692526b38d4577656d963c5fc313496a7c6e4