public static void testRemoteNode(final ReliabilityAwareProxy proxy, final Map<String, Object> capabilities) {
		executor.execute(new Runnable() {
			
			private int runAttempts = 0;
			
			private void resubmitJob() throws InterruptedException {
				// resubmit job
				executor.submit(this);
				// prevent fast spinning
				Thread.sleep(500);
				runAttempts++;
				return;
			}
			@Override
			public void run() {
				
				if(runAttempts > 10) {
					log.warning("Maximum slot test attempts exceeded - marking as failed. proxy: " + 
							proxy.getId() + " capabilities: " + capabilities);
					proxy.setCapabilityAsBroken(capabilities);
					return;
				}
				
				try {
					while(proxy.getRegistry().getProxyById(proxy.getId()) == null) {
						log.info("Proxy " + proxy.getId() + " not registered yet - deferring test");
						resubmitJob();
						return;
					}
					
					if(100.0 == proxy.getResourceUsageInPercent()) {
						log.info("Proxy " + proxy.getId() + " is busy - deferring test");
						resubmitJob();
						return;
						
					}
					Hub hub = proxy.getRegistry().getHub();
					URL url = new URL(hub.getUrl(), "/grid/admin/" + NodeTestingServlet.class.getSimpleName() + "/session");
					BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", url.toExternalForm());
					
					HashMap<String, Object> transmittedCaps = new HashMap<String, Object>(capabilities);
					transmittedCaps.put("proxyId", proxy.getId());
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("desiredCapabilities", transmittedCaps);
					request.setEntity(new StringEntity(jsonObject.toString()));
					
					HttpClient client = proxy.getHttpClientFactory().getHttpClient();
					HttpHost httpHost = new HttpHost(url.getHost(), url.getPort());
					
					log.info("Hitting node testing servlet at: " + url);
					HttpResponse response = client.execute(httpHost, request);
					
					try {
						int statusCode = response.getStatusLine().getStatusCode();
						
						if(statusCode == HttpStatus.SC_OK) {
							log.info("Node tested OK: " + proxy.getId() + " for caps: " + capabilities);
							proxy.setCapabilityAsWorking(capabilities);
							
						}
						else if(statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
							// older Selenium versions do an HTTP 302 with a location header set
							if(response.getFirstHeader("Location") == null) {
								// this combination is completely unusable
								log.warning("Received and HTTP 302 response without a Location header! Marking proxy as broken: " + proxy.getId());
								proxy.setCapabilityAsBroken(capabilities);
							}
							else {
								log.info("Node tested OK (with old-style HTTP 302): " + proxy.getId() + " for caps: " + capabilities);
								proxy.setCapabilityAsWorking(capabilities);
							}
						}
						else if(statusCode == 429) {
							// test slot is temporarily unavailable - race condition?
							log.warning("Test slot temporarily unavailable on proxy: " + proxy.getId() + " capabilities: " + capabilities);
							resubmitJob();
						}
						else {
							log.warning("Node test failed for node: " + proxy.getId() + " for caps: " + capabilities);
							log.warning("Status code: " + response.getStatusLine().getStatusCode() + " body: " + EntityUtils.toString(response.getEntity()));
							proxy.setCapabilityAsBroken(capabilities);
						}
					}
					finally {
						// make sure we close the response - otherwise we will leak HTTP connections
						response.getEntity().getContent().close();
					}
						
				} catch(Exception e) {
					log.log(Level.WARNING, "Node test caught exception for node: " + proxy.getId() + " for caps: " + capabilities, e);
				}
			}
		});
		
	}