docs: private Object exec(HttpURLConnection connection) throws Exception {
  		connection.setConnectTimeout(connectionTimeout);
  		connection.setReadTimeout(readTimeout);
  
  		connection.setRequestMethod(arguments == null ? "GET" : "POST");
  
  		connection.setRequestProperty("User-Agent", "j(s)-lib/1.9.3");
  		connection.setRequestProperty("Accept", "application/json, text/xml, application/octet-stream");
  		connection.setRequestProperty("Pragma", "no-cache");
  		connection.setRequestProperty("Cache", "no-cache");
  
  		// do not set connection close request header in order to let HttpUrlConnection to transparently process persistent
  		// connections, if server request so
  		// note that on HTTP 1.1 all connections are considered persistent unless explicitly declared otherwise
  		// anyway, if js.net.client.android system property is defined, force connection close
  		if (System.getProperty("js.net.client.android") != null) {
  			connection.setRequestProperty("Connection", "close");
  		}
  
  		if (headers != null) {
  			for (Map.Entry<String, String> entry : headers.entrySet()) {
  				connection.setRequestProperty(entry.getKey(), entry.getValue());
  			}
  		}
  
  		String sessionCookie = sessionCookies.get(connection.getURL());
  		if (sessionCookie != null) {
  			connection.setRequestProperty("Cookie", sessionCookie);
  		}
  
  		if (arguments != null) {
  			connection.setDoOutput(true);
  			String contentType = argumentsWriter.getContentType();
  			if (contentType != null) {
  				connection.setRequestProperty("Content-Type", contentType);
  			}
  			argumentsWriter.write(connection.getOutputStream(), arguments);
  		}
  
  		// at this point connection implementation perform the actual HTTP transaction: send request and wait for response,
  		// parse response status code and headers and prepare a stream on response body
  		int statusCode = connection.getResponseCode();
  
  		// current RMI transaction implementation accept as success only 200 or 204 for void remote method
  		if (statusCode != SC_OK && statusCode != SC_NO_CONTENT) {
  			onError(statusCode);
  			// error handler throws exception on any status code
  		}
  
  		String cookies = connection.getHeaderField("Set-Cookie");
  		if (cookies != null) {
  			Matcher matcher = JSESSIONID_PATTERN.matcher(cookies);
  			if (matcher.find()) {
  				sessionCookies.put(connection.getURL(), matcher.group(1));
  			}
  		}
  
  		if (Types.isVoid(returnType)) {
  			return null;
  		}
  		if (!Types.isVoid(returnType) && connection.getContentLength() == 0) {
  			throw new BugError("Invalid HTTP-RMI transaction with |%s|. Expect return value of type |%s| but got empty response.", connection.getURL(), returnType);
  		}
  
  		ValueReader valueReader = ClientEncoders.getInstance().getValueReader(connection);
  		try {
  			return valueReader.read(connection.getInputStream(), returnType);
  		} catch (IOException e) {
  			throw new BugError("Invalid HTTP-RMI transaction with |%s|. Response cannot be parsed to type |%s|. Cause: %s", connection.getURL(), returnType, e);
  		}
  	}