public Hashtable runFunc(String function, Vector params) {
    Hashtable h = null;
    Object o = null;
    try {
      System.out.println("RPCClient: running function: " + function);
      o = xmlrpc.execute(function, params);
    } catch (XmlRpcException e) {
      h = new Hashtable();
      h.put("status", "error");
      h.put("error", "Cannot execute XML-RPC query: (" + e.getCause() + ":" + e.toString() + ")");
      return h;
    } catch (IOException e) {
      h = new Hashtable();
      h.put("status", "error");
      h.put("error", "IO Exception executing XML-RPC query: " + e.toString());
      return h;
    }
    if (o == null) {
      h = new Hashtable();
      h.put("status", "error");
      h.put("error", "Object is NULL");
      return h;
    }

    if (!o.getClass().isInstance(new Hashtable())) {
      h = new Hashtable();
      h.put("status", "error");
      h.put("error", "Returned object is not a Hashtable - it is a " + o.getClass().getName());
      return h;
    }
    h = (Hashtable) o;

    if (!h.containsKey("status")) {
      h.put("status", "error");
      h.put("error", "No status in result hash");
      return h;
    }

    String status = (String) h.get("status");
    if (status.equals("error") && !h.containsKey("error")) {
      h.put("error", "Unknown error - no error key found in hash");
    }

    return h;
  }
    @Override
    protected Map dispatch(String method_call, Object[] method_params)
        throws XmlRpcException, XenAPIException {
      if (method_call.equals("session.local_logout")
          || method_call.equals("session.slave_local_login_with_password")
          || method_call.equals("session.logout")) {
        return super.dispatch(method_call, method_params);
      }

      if (method_call.equals("session.login_with_password")) {
        int retries = 0;
        while (retries++ < _retries) {
          try {
            return super.dispatch(method_call, method_params);
          } catch (XmlRpcException e) {
            Throwable cause = e.getCause();
            if (cause == null || !(cause instanceof SocketException)) {
              throw e;
            }
            if (retries >= _retries) {
              throw e;
            }
            s_logger.debug("Unable to login...retrying " + retries);
          }
          try {
            Thread.sleep(_interval);
          } catch (InterruptedException e) {
            s_logger.debug("Man....I was just getting comfortable there....who woke me up?");
          }
        }
      } else {
        int retries = 0;
        while (retries++ < _retries) {
          try {
            return super.dispatch(method_call, method_params);
          } catch (Types.SessionInvalid e) {
            s_logger.debug(
                "Session is invalid for method: "
                    + method_call
                    + " due to "
                    + e.getMessage()
                    + ".  Reconnecting...retry="
                    + retries);
            if (retries >= _retries) {
              removeConnect(_poolUuid);
              throw e;
            }
            loginWithPassword(this, _username, _password, APIVersion.latest().toString());
            method_params[0] = getSessionReference();
          } catch (XmlRpcClientException e) {
            s_logger.debug(
                "XmlRpcClientException for method: " + method_call + " due to " + e.getMessage());
            removeConnect(_poolUuid);
            throw e;
          } catch (XmlRpcException e) {
            s_logger.debug(
                "XmlRpcException for method: "
                    + method_call
                    + " due to "
                    + e.getMessage()
                    + ".  Reconnecting...retry="
                    + retries);
            if (retries >= _retries) {
              removeConnect(_poolUuid);
              throw e;
            }
            Throwable cause = e.getCause();
            if (cause == null || !(cause instanceof SocketException)) {
              removeConnect(_poolUuid);
              throw e;
            }
          } catch (Types.HostIsSlave e) {
            s_logger.debug(
                "HostIsSlave Exception for method: "
                    + method_call
                    + " due to "
                    + e.getMessage()
                    + ".  Reconnecting...retry="
                    + retries);
            removeConnect(_poolUuid);
            throw e;
          }
          try {
            Thread.sleep(_interval);
          } catch (InterruptedException e) {
            s_logger.info("Who woke me from my slumber?");
          }
        }
        assert false : "We should never get here";
        removeConnect(_poolUuid);
      }
      throw new CloudRuntimeException(
          "After " + _retries + " retries, we cannot contact the host ");
    }