public Object execute(XmlRpcClientRequest xmlRpcRequest, XmlRpcTransport transport)
      throws XmlRpcException, XmlRpcClientException, IOException {
    long now = 0;
    Object response = PROCESSING_ERROR_FLAG;

    if (XmlRpc.debug) {
      now = System.currentTimeMillis();
    }

    try {
      byte[] request =
          requestProcessor.encodeRequestBytes(xmlRpcRequest, responseProcessor.getEncoding());
      InputStream is = transport.sendXmlRpc(request);
      response = responseProcessor.decodeResponse(is);
      return response;
    } catch (IOException ioe) {
      throw ioe;
    } catch (XmlRpcClientException xrce) {
      throw xrce;
    } catch (RuntimeException x) {
      if (XmlRpc.debug) {
        x.printStackTrace();
      }
      throw new XmlRpcClientException("Unexpected exception in client processing", x);
    } finally {
      if (XmlRpc.debug) {
        System.out.println(
            "Spent " + (System.currentTimeMillis() - now) + " millis in request/process/response");
      }

      // End the transport's session, handling any problem while
      // avoiding hiding of any earlier exception.
      try {
        transport.endClientRequest();
      } catch (Throwable t) {
        // Don't clobber an earlier exception.
        boolean haveFault = response instanceof XmlRpcException;
        if (haveFault || response == PROCESSING_ERROR_FLAG) {
          System.err.println(
              "Avoiding obscuring previous error "
                  + "by supressing error encountered "
                  + "while ending request: "
                  + t);
          if (haveFault) {
            throw (XmlRpcException) response;
          }
          // else we've already thrown an exception
        } else {
          if (t instanceof XmlRpcException) {
            throw (XmlRpcException) t;
          } else {
            throw new XmlRpcClientException("Unable to end request", t);
          }
        }
      }
    }
  }
 // ### isReusable() would be a better name for this set of methods
 protected boolean canReUse() {
   return responseProcessor.canReUse() && requestProcessor.canReUse();
 }