private void invokeNow(T msg, ResponseImpl<T> response) throws WebServiceException {
    if (log.isLoggable(Level.FINEST)) log.finest("AbstractDispatch.invokeNow(" + msg + ")");

    InputStream in = null;
    OutputStream out = null;

    try {
      String urlSpec = (String) _requestContext.get(ENDPOINT_ADDRESS_PROPERTY);

      if (urlSpec == null) throw new WebServiceException(L.l("Endpoint address not set"));

      URL url = new URL(urlSpec);
      URLConnection connection = url.openConnection();

      if (response != null) connection.setDoInput(true);

      connection.setDoOutput(true);

      // send request
      out = connection.getOutputStream();

      OutputStreamWriter writer = null;

      if (_mode == Service.Mode.PAYLOAD) {
        writer = new OutputStreamWriter(out);

        JAXWSUtil.writeStartSOAPEnvelope(writer, _soapNamespace);
      }

      writeRequest(msg, out);

      if (_mode == Service.Mode.PAYLOAD) JAXWSUtil.writeEndSOAPEnvelope(writer);

      out.flush();

      // read response
      in = connection.getInputStream();

      // XXX for some reason, it seems this is necessary to force the output
      if (response == null) {
        while (in.read() >= 0) {}

        return;
      }

      ByteArrayOutputStream buffer = new ByteArrayOutputStream();

      if (_mode == Service.Mode.PAYLOAD) {
        JAXWSUtil.extractSOAPBody(in, buffer);
      } else {
        // XXX is a copy necessary here or should we expect the client to
        // close the InputStream?
        int ch = -1;

        while ((ch = in.read()) != -1) buffer.write(ch);
      }

      response.set(formatResponse(buffer.toByteArray()));
      response.setContext(connection.getHeaderFields());
    } catch (WebServiceException e) {
      throw e;
    } catch (Exception e) {
      throw new WebServiceException(e);
    } finally {
      try {
        if (out != null) out.close();

        if (in != null) in.close();
      } catch (IOException e) {
        throw new WebServiceException(e);
      }
    }
  }