docs: private static Response execute(String method,
  	                                String apiUrl,
  	                                String body,
  	                                Map<String, String> query,
  	                                Map<String, String> headers,
  	                                int connectTimeOut,
  	                                int readTimeOut) throws HttpException {
  
  		HttpURLConnection conn = null;
  		int responseCode = 500;
  
  		try {
  
  			if (query != null && query.size() > 0) {
  				apiUrl = UrlUtils.composeUrl(apiUrl, query);
  			}
  
  			URL url = new URL(apiUrl);
  
  			if (apiUrl.toLowerCase().startsWith("https://")) {
  
  				conn = (HttpsURLConnection) url.openConnection();
  				if (sslFactory != null) {
  					((HttpsURLConnection) conn).setSSLSocketFactory(sslFactory);
  				}
  			}
  			else {
  				conn = (HttpURLConnection) url.openConnection();
  			}
  
  			// time out settings
  			conn.setConnectTimeout(connectTimeOut); // 3s
  			conn.setReadTimeout(readTimeOut); // 5s
  
  			conn.setUseCaches(false);
  			conn.setDoOutput(true);
  			conn.setInstanceFollowRedirects(false);
  			conn.setRequestMethod(method);
  
  			byte[] postData = null;
  			if (body != null) {
  				postData = body.getBytes(StandardCharsets.UTF_8);
  			}
  
  			if (headers != null && headers.size() > 0) {
  
  				// add headers
  				for (String key : headers.keySet()) {
  					conn.setRequestProperty(key, headers.get(key));
  				}
  			}
  
  			if (postData != null) {
  				// turn input on
  				conn.setDoInput(true);
  
  				int postDataLength = postData.length;
  				conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
  
  				OutputStream os = conn.getOutputStream();
  				os.write(postData);
  			}
  
  			// make request ...
  			responseCode = conn.getResponseCode();
  
  			BufferedReader reader = null;
  			if (responseCode < HttpURLConnection.HTTP_BAD_REQUEST) {
  				InputStreamReader inputStream = new InputStreamReader(conn.getInputStream());
  				reader = new BufferedReader(inputStream);
  			} else {  /* error from server */
  				if (conn.getErrorStream() != null) {
  					InputStreamReader inputStream = new InputStreamReader(conn.getErrorStream());
  					reader = new BufferedReader(inputStream);
  				}
  			}
  
  			StringBuilder content = new StringBuilder();
  			if (reader != null) {
  
  				String line;
  				while ((line = reader.readLine()) != null) {
  					content.append(line);
  				}
  			}
  
  			log.debug("Output from request: {} - {}", responseCode, content);
  
  			return new Response(responseCode, content.toString(), conn.getHeaderFields());
  		}
  		catch (Exception e) {
  			log.error("Failed execute request to: {}", apiUrl, e);
  			throw new HttpException(responseCode, e.getMessage());
  		}
  		finally {
  			if (conn != null) {
  				conn.disconnect();
  			}
  		}
  	}