diff -Nurp ./qb.module ../qb/qb.module
--- ./qb.module	2008-09-02 16:17:45.000000000 +0900
+++ ../qb/qb.module	2008-09-02 16:14:09.000000000 +0900
@@ -17,24 +17,62 @@ function qb_perm() {
   return array('administer quickbooks');
 }
 
-function qb_qbxml($root_entity, $elements) {
-  $qbxml = new DOMDocument('1.0');
-  $xml = $qbxml->appendChild($qbxml->createElement($root_entity));
-  foreach ($elements as $name => $value) {
-    _qb_qbxml_node($qbxml, $name, $value, $xml);
+function qb_qbxml($elements, $root = array('QBXML')) {
+  $qbxml = $xml = new DOMDocument('1.0');
+  
+  // Make sure the root is an array so _qb_qbxml_node can process it properly
+  if (!is_array($root)) {
+  	$root = array($root => array());
   }
+
+  // Attach the base/common root of the document
+  $start = _qb_qbxml_node($qbxml, key($root), current($root), $xml);
+
+  // Attach the rest of the document
+  foreach((array)$elements as $key => $element) {
+  	_qb_qbxml_node($qbxml, $key, $element, $start);
+  }
+
   return $qbxml->saveXML();
 }
 
 function _qb_qbxml_node(&$doc, $name, $value, &$parent) {
-  if (is_string($value)) {
+  // Store the elements in the order they were added to the doc
+  static $added;
+
+  if (is_scalar($value)) {
     $element = $doc->createElement($name, $value);
+    $parent->appendChild($element);
   }
   if (is_array($value)) {
-    $element = $doc->createElement($name);
-    foreach ($value as $k => $v) {
-      _qb_qbxml_node($doc, $k, $v, $element);
+    if (is_numeric(key($value))) {
+      for($k=0;$v=$value[$k];$k++) {
+    		_qb_qbxml_node($doc, $name, $v, $parent);
+    	}
+    }
+    else {
+    	$element = $doc->createElement($name);
+      foreach ($value as $k => $v) {
+        // Denote attributes as starting with a _
+        if (is_scalar($v) && strpos($k, '_') === 0) {
+        	$k = substr($k, 1);
+          $attr = $doc->createAttribute($k);
+          $attr->appendChild($doc->createTextNode($v));
+          $element->appendChild($attr);
+        }
+        // Denote processing instructions with a ?
+        else if (is_scalar($v) && strpos($k, '?') === 0) {
+          $k = substr($k, 1);
+        	$doc->appendChild($doc->createProcessingInstruction($k, $v));
+        }
+        else {
+        	_qb_qbxml_node($doc, $k, $v, $element);
+        }
+      }
+      $added[] = $parent->appendChild($element);
     }
   }
-  $parent->appendChild($element);
+
+  // Try and return the last added element (first in the array because of recursion) to help have a more complex "root" as specified in qb_qbxml
+  return reset($added);
 }
diff -Nurp ./qbwc.inc ../qb/qbwc.inc
--- ./qbwc.inc	2008-09-02 16:17:45.000000000 +0900
+++ ../qb/qbwc.inc	2008-09-02 16:12:41.000000000 +0900
@@ -1,30 +1,34 @@
 <?php
 
 class qbwc {
+  // We cannot get back the original Server SOAP object, but we can at least load the right session getting our session variables back
+  // A way to expire these sessions would be nice....
   function _session($ticket) {
-    global $user;
-
-    $session = db_fetch_object(db_query("SELECT * FROM {qbwc_sessions} WHERE ticket = '%s'", $ticket));
-
-    // Session is closed.
-    if ($session->close_ts) {
-      return false;
+    $uid = db_result(db_query('SELECT uid FROM {sessions} WHERE sid = "%s" AND hostname = "%s"', $ticket, $_SERVER['REMOTE_ADDR']));
+    if ($uid && $ticket != session_id()) {
+    	global $user;
+    	$user = user_load(array('uid' => $user));
+
+      session_destroy();
+      session_id($ticket);
+      // Pretend that cookies are enabled so we can get back our session
+      $_COOKIE[session_name()] = true;
+      session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy_sid', 'sess_gc');
+      session_start();
+    }
+    else if (!$uid) {
+    	// Invalid session
+      exit;
     }
-
-    // Switch to the Quickbooks user.
-    if ($user->uid == 0) $user = user_load(array('uid' => $session->uid));
-
-    return $session; ;
   }
 
   function authenticate($params) {
     $name = $params->strUserName;
     $pass = $params->strPassword;
-
     $hostname = ip_address();
 
-    // Generate a ticket to be used for all further communication
-    $ticket = md5(time() . $name);
+    // Use the current session id as the ticket
+    $ticket = session_id();
 
     // Default result: "non-valid user credentials".
     $ret = 'nvu';
@@ -36,30 +40,35 @@ class qbwc {
     // Authenticate as the quickbooks drupal user
     if ($name && ($name == variable_get('qbwc_user', ''))) {
       if ($user = user_authenticate(array('name' => $name, 'pass' => $pass))) {
+        // Set nothing to do until a module decides it has something to do
+        $ret = 'none';
 
-        // Return company file or empty, which means "currently open file".
-        $ret = variable_get('qb_company_file', '');
-
-        if ($theres_nothing_to_do) { // TODO 
-          $ret = 'none';
+        // Let modules return whether they have work to do or not
+        // If no modules return anything, assume no work
+        foreach(module_implements('qbwc_authenticate') as $module) {
+          if (module_invoke($module, 'qbwc_authenticate', $ticket, $user)) {
+            // Return company file or empty, which means "currently open file" when work has been set
+            $ret = variable_get('qb_company_file', '');
+          }
         }
       }
     }
 
-    // Close the session immediately if the authentication failed.
-    $close_ts = ($ret == 'nvu' ) ? time() : 'NULL';
-    db_query("INSERT INTO {qbwc_sessions} ( ticket, hostname, uid, open_ts, close_ts ) VALUES ( '%s', '%s', %d, %d, $close_ts )", $ticket, $hostname, $user->uid, time());
-
     $result = array($ticket, $ret, $next_update, $minimum_wait);
     return (object) array('authenticateResult' => $result);
   }
 
   function closeConnection($params) {
     $ticket = $params->ticket;
+    $this->_session($ticket);
     global $user;
+    
+    // Let modules know we are closing the session
+    module_invoke_all('qbwc_close', $ticket);
 
     // Close the session and log it just like user_logout() sans drupal_goto.
-    watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
+    watchdog('user', t('Session closed for %name.', array('%name' => $user->name)));
+
     // Destroy the current session.
     session_destroy();
     module_invoke_all('user', 'logout', NULL, $user);
@@ -67,12 +76,12 @@ class qbwc {
     // Load the anonymous user.
     $user = drupal_anonymous_user(); 
 
-    db_query("UPDATE {qbwc_sessions} SET close_ts = %d where ticket = '%s'", time(), $ticket);
-
     return (object) array( 'closeConnectionResult' => t('Session closed'));
   }
 
   function connectionError($ticket, $hresult, $message) {
+    // Do not try to reconnect
+    return 'done';
   }
 
   function getLastError($ticket) {
@@ -84,62 +93,140 @@ class qbwc {
   }
 
   function sendRequestXML($params) {
+    static $requestId = 1;
+
     $ticket = $params->ticket;
     $HCPResponse = $params->strHCPResponse;
     $company_file = $params->strCompanyFileName;
     $country = $params->qbXMLCountry;
     $major_version = $params->qbXMLMajorVers;
     $minor_version = $params->qbXMLMinorVers;
-    
-    $session = $this->_session($ticket);
+
+    $this->_session($ticket);
 
     // Default: If the web service has no requests to send, use an empty string.
     $ret = '';
 
     // Decide if we have anything to do and return qbxml.
-    if($requests = module_invoke_all('qbwc_request', $session)) {
-      foreach ( $requests as $r ) {
-        $ret .= qb_qbxml($r['name'], $r['request']);
+    $requests = array();
+    $_SESSION['requestIds'] = $_SESSION['savedData'] = array();
+
+    foreach(module_implements('qbwc_request') as $module) {
+      $request = module_invoke($module, 'qbwc_request');
+
+      // Make sure we have an array of requests instead of just a request
+      if (is_array($request) && !is_numeric(key($request))) {
+      	$request = array($request);
+      }
+
+      foreach((array)$request as $r) {
+        // Set data that module response/request handlers would like to pass between them
+        // during calls to QB
+        if (isset($r['data'])) {
+        	$_SESSION['savedData'][$requestId] = $r['data'];
+        }
+
+        // Attach request ids so we know how to send responses back to the right modules
+        // If modules set it to their own, we'll have to leave it up to them to avoid conflicts for now'
+        if (!isset($r['_requestId'])) {
+          $r['request']['_requestID'] = $requestId;
+          $_SESSION['requestIds'][$requestId++] = $module;
+        }
+
+        if ($r['name']) {
+        	$requests[$r['name']][] = $r['request'];
+        }
       }
     }
 
+    // Formulate the common base XML for all QBWC requests, using QBXML v5.0
+    $top = array(
+      'QBXML' => array(
+        '?qbxml' => 'version="5.0"', // XML processing instruction
+        'QBXMLMsgsRq' => array(
+          '_onError' => 'stopOnError' // XML attribute
+        )
+      )
+    );
+
+    $ret = qb_qbxml($requests, $top);
+
     return (object) array( 'sendRequestXMLResult' => $ret );
   }
 
   function receiveResponseXML($params) {
     $ticket = $params->ticket;
-    $response = $params->response;
+    $response = DOMDocument::loadXML($params->response);
     $hresult = $params->hresult;
     $message = $params->message;
+    $this->_session($ticket);
+    // Get the list of data stored for this response
+    $data = $_SESSION['savedData'];
+
+    // Split out the response elements so they can be sent to the appropriate modules
+    $elements = array();
+    if (is_object($response)) {
+      $top = $response->getElementsByTagName('QBXMLMsgsRs')->item(0);
+      for($i=0;$element = $top->childNodes->item($i); $i++) {
+        if ($element->nodeType == 3) {
+          // Skip #text node types
+        	continue;
+        }
+        $requestId = $element->getAttribute('requestID');
+        if ($module = $_SESSION['requestIds'][$requestId]) {
+          $elements[$module][] = $element;
+          
+          // Set the saved data for this modules requests
+          if ($data[$requestId]) {
+          	$saved[$module][$requestId] = $data[$requestId];
+          }
+        }
+      }
+    }
 
-    $session = $this->_session($ticket);
-
-    /* A positive integer from 1-100 represents the percentage of work 
-      completed, where value of 100 means there is no more work. A negative 
-      value means an error has occurred and Web Connector calls getLastError.
-    */
-    if($responses = module_invoke_all('qbwc_response', $session, $response, $hresult, $message)) {
-      $ret = 0;
-      foreach ($responses as $item) {
-        $ret += $item;
+    $done = 0;
+    $total = 0;
+    foreach(module_implements('qbwc_response') as $module) {
+    	$ret = module_invoke($module, 'qbwc_response', $elements[$module], $hresult, $message, $saved[$module]);
+      // Only count returned values less than 100
+      if (is_numeric($ret) && $ret <= 100) {
+        /* A positive integer from 1-100 represents the percentage of work 
+            completed, where value of 100 means there is no more work. A negative 
+            value means an error has occurred and Web Connector calls getLastError.
+          */
+      	$done += $ret;
+        $total++;
       }
-      $ret = $ret / count($responses);
     }
 
-    if (!isset($ret)) $ret = 100;
+    // Put the accumulation of returned percentages with the total into one total percentage
+    if ($total) {
+    	$done = $done / $total;
+    }
+    else {
+    	$done = 100;
+    }
+
+    // If it runs this long, something is probably wrong...
+    if ($_SESSION['countTimes']++ == 30) {
+    	$done = 100;
+    }
 
-    return (object) array( 'receiveResponseXMLResult' => $ret );
+    return (object) array( 'receiveResponseXMLResult' => $done );
   }
 
-  /* Unimplemented functions
+  // Unimplemented functions
 
   function getInteractiveURL($ticket, $session_id) {
+    $this->_session($ticket);
   }
 
   function interactiveDone($ticket) {
+    $this->_session($ticket);
   }
 
   function interactiveRejected($ticket, $reason) {
+    $this->_session($ticket);
   }
 
 
@@ -147,6 +234,4 @@ class qbwc {
   // the client's version.  It could be used to set a minimum version level.
   function clientVersion($version) {
   }
-
-  */
 }
diff -Nurp ./qbwc.install ../qb/qbwc.install
--- ./qbwc.install	2008-09-02 16:17:45.000000000 +0900
+++ ../qb/qbwc.install	2008-09-02 16:07:42.000000000 +0900
@@ -1,30 +1,16 @@
-<?php // $Id: qbwc.install,v 1.2 2008/06/16 16:12:50 vauxia Exp $
-
-function qbwc_schema() {
-  return array(
-    'qbwc_sessions' => array(
-      'fields' => array(
-        'ticket' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE),
-        'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
-        'hostname' => array('type' => 'varchar', 'length' => 15),
-        'open_ts' => array('type' => 'int', 'not null' => TRUE),
-        'close_ts' => array('type' => 'int', 'default' => 0),
-      ),
-      'indexes' => array(
-        'ticket' => array('ticket'),
-      ),
-    ),
-  );
-}
+<?php 
+// $Id: $
 
 function qbwc_install() {
-  variable_set('qbwc_owner_id', uniqid());
-  variable_set('qbwc_file_id', uniqid());
-  drupal_install_schema('qbwc');
+  // Generate unique IDs for this QWC file
+  $part = array();
+  foreach(array(8,4,4,4,12) as $len) {
+    $part[] = substr(str_pad(base_convert(rand(), 10, 16), $len, "0", STR_PAD_LEFT), 0, $len);
+  }
+
+  variable_set('qbwc_owner_id', implode('-', $part));
 }
 
 function qbwc_uninstall() {
   variable_del('qbwc_owner_id');
-  variable_del('qbwc_file_id');
-  drupal_uninstall_schema('qbwc');
 }
diff -Nurp ./qbwc.module ../qb/qbwc.module
--- ./qbwc.module	2008-09-02 16:17:45.000000000 +0900
+++ ../qb/qbwc.module	2008-09-02 16:15:56.000000000 +0900
@@ -80,10 +80,14 @@ function qbwc_form_alter(&$form, $form_s
 }
 
 function qbwc_qwc() {
-// TODO generate these!
-variable_set('qbwc_file_id', '72832751-65dc-11db-bd13-0800200c9a66');
-variable_set('qbwc_owner_id', '72832751-65dc-11db-bd13-0800200c9a66');
   $elements = array();
+  
+  // Generate a FileID for this application file
+  $part = array();
+  foreach(array(8,4,4,4,12) as $len) {
+    $part[] = substr(str_pad(base_convert(rand(), 10, 16), $len, "0", STR_PAD_LEFT), 0, $len);
+  }
+
   $elements['AppName'] = variable_get('site_name', 'Drupal');
   $elements['AppID'] = '';
   $elements['AppURL'] = variable_get('qbwc_url', '');
@@ -91,27 +95,28 @@ variable_set('qbwc_owner_id', '72832751-
   $elements['AppSupport'] = variable_get('qbwc_url', '') .'/support';
   $elements['UserName'] = variable_get('qbwc_user', '');
   $elements['OwnerID'] = '{' . variable_get('qbwc_owner_id', '') . '}';
-  $elements['FileID'] = '{' . variable_get('qbwc_file_id', '') . '}';
+  $elements['FileID'] = '{' . implode('-', $part) . '}';
   $elements['QBType'] = 'QBFS'; // Used with QB Financial systems, not POS.
   if ($minutes = variable_get('qbwc_scheduler', 0)) {
     $elements['Scheduler'] = array();
     $elements['Scheduler']['RunEveryNMinutes'] = $minutes;
   }
 
-  $xml = qb_qbxml('QBWCXML', $elements);
+  $xml = qb_qbxml($elements, 'QBWCXML');
 
-  header('Content-type: application/force-download');
-  header('Content-Transfer-Encoding: Binary');
-  header('Content-length: ' . strlen($xml));
-  header('Content-disposition: attachment; filename=drupal.qwc');
+  drupal_set_header('Content-type: application/force-download');
+  drupal_set_header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+  drupal_set_header('Content-Transfer-Encoding: Binary');
+  drupal_set_header('Content-length: ' . strlen($xml));
+  drupal_set_header('Content-disposition: attachment; filename=drupal.qwc');
   echo $xml;
+  exit;
 }
 
 function qbwc() {
-  global $base_path;
+  global $base_path, $base_url;
   require_once dirname(__FILE__) . '/qbwc.inc';
-  $wsdl = 'http://developer.intuit.com/uploadedFiles/Support/QBWebConnectorSvc.wsdl';
-  $wsdl = 'https://dev/sites/qb/modules/qb/QBWebConnectorSvc.wsdl?'.time();
+  $wsdl = $base_url .'/'. drupal_get_path('module', 'qbwc') .'/qbwc.wsdl';
   $qbwc = new SoapServer($wsdl, array('uri' => variable_get('qbwc_url', '')));
   $qbwc->setClass('qbwc');
   $qbwc->setPersistence(SOAP_PERSISTENCE_SESSION);
diff -Nurp ./qbwc.wsdl ../qb/qbwc.wsdl
--- ./qbwc.wsdl	1970-01-01 09:00:00.000000000 +0900
+++ ../qb/qbwc.wsdl	2008-09-02 16:07:42.000000000 +0900
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://developer.intuit.com/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://developer.intuit.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+  <wsdl:types>
+    <s:schema elementFormDefault="qualified" targetNamespace="http://developer.intuit.com/">
+      <s:element name="authenticate">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="strUserName" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="strPassword" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="authenticateResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="tns:ArrayOfString" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:complexType name="ArrayOfString">
+        <s:sequence>
+          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
+        </s:sequence>
+      </s:complexType>
+
+<!-- added these two methods -->
+	<s:element name="serverVersion">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="strVersion" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="serverVersionResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="serverVersionResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="clientVersion">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="strVersion" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="clientVersionResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="clientVersionResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+
+
+      <s:element name="sendRequestXML">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="strHCPResponse" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="strCompanyFileName" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="qbXMLCountry" type="s:string" />
+            <s:element minOccurs="1" maxOccurs="1" name="qbXMLMajorVers" type="s:int" />
+            <s:element minOccurs="1" maxOccurs="1" name="qbXMLMinorVers" type="s:int" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="sendRequestXMLResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="sendRequestXMLResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="receiveResponseXML">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="response" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="hresult" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="message" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="receiveResponseXMLResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="1" maxOccurs="1" name="receiveResponseXMLResult" type="s:int" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="connectionError">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="hresult" type="s:string" />
+            <s:element minOccurs="0" maxOccurs="1" name="message" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="connectionErrorResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="connectionErrorResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="getLastError">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="getLastErrorResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="getLastErrorResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="closeConnection">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+      <s:element name="closeConnectionResponse">
+        <s:complexType>
+          <s:sequence>
+            <s:element minOccurs="0" maxOccurs="1" name="closeConnectionResult" type="s:string" />
+          </s:sequence>
+        </s:complexType>
+      </s:element>
+    </s:schema>
+  </wsdl:types>
+
+  <wsdl:message name="authenticateSoapIn">
+    <wsdl:part name="parameters" element="tns:authenticate" />
+  </wsdl:message>
+  <wsdl:message name="authenticateSoapOut">
+    <wsdl:part name="parameters" element="tns:authenticateResponse" />
+  </wsdl:message>
+
+<!-- added this part -->
+  <wsdl:message name="serverVersionSoapIn">
+    <wsdl:part name="parameters" element="tns:serverVersion" />
+  </wsdl:message>
+  <wsdl:message name="serverVersionSoapOut">
+    <wsdl:part name="parameters" element="tns:serverVersionResponse" />
+  </wsdl:message>
+  <wsdl:message name="clientVersionSoapIn">
+    <wsdl:part name="parameters" element="tns:clientVersion" />
+  </wsdl:message>
+  <wsdl:message name="clientVersionSoapOut">
+    <wsdl:part name="parameters" element="tns:clientVersionResponse" />
+  </wsdl:message>
+
+
+  <wsdl:message name="sendRequestXMLSoapIn">
+    <wsdl:part name="parameters" element="tns:sendRequestXML" />
+  </wsdl:message>
+  <wsdl:message name="sendRequestXMLSoapOut">
+    <wsdl:part name="parameters" element="tns:sendRequestXMLResponse" />
+  </wsdl:message>
+  <wsdl:message name="receiveResponseXMLSoapIn">
+    <wsdl:part name="parameters" element="tns:receiveResponseXML" />
+  </wsdl:message>
+  <wsdl:message name="receiveResponseXMLSoapOut">
+    <wsdl:part name="parameters" element="tns:receiveResponseXMLResponse" />
+  </wsdl:message>
+  <wsdl:message name="connectionErrorSoapIn">
+    <wsdl:part name="parameters" element="tns:connectionError" />
+  </wsdl:message>
+  <wsdl:message name="connectionErrorSoapOut">
+    <wsdl:part name="parameters" element="tns:connectionErrorResponse" />
+  </wsdl:message>
+  <wsdl:message name="getLastErrorSoapIn">
+    <wsdl:part name="parameters" element="tns:getLastError" />
+  </wsdl:message>
+  <wsdl:message name="getLastErrorSoapOut">
+    <wsdl:part name="parameters" element="tns:getLastErrorResponse" />
+  </wsdl:message>
+  <wsdl:message name="closeConnectionSoapIn">
+    <wsdl:part name="parameters" element="tns:closeConnection" />
+  </wsdl:message>
+  <wsdl:message name="closeConnectionSoapOut">
+    <wsdl:part name="parameters" element="tns:closeConnectionResponse" />
+  </wsdl:message>
+  <wsdl:portType name="QBWebConnectorSvcSoap">
+	
+	<!-- add this chunk -->
+	<wsdl:operation name="serverVersion">
+      <wsdl:input message="tns:serverVersionSoapIn" />
+      <wsdl:output message="tns:serverVersionSoapOut" />
+    </wsdl:operation>
+	<wsdl:operation name="clientVersion">
+      <wsdl:input message="tns:clientVersionSoapIn" />
+      <wsdl:output message="tns:clientVersionSoapOut" />
+    </wsdl:operation>
+
+
+    <wsdl:operation name="authenticate">
+      <wsdl:input message="tns:authenticateSoapIn" />
+      <wsdl:output message="tns:authenticateSoapOut" />
+    </wsdl:operation>
+    <wsdl:operation name="sendRequestXML">
+      <wsdl:input message="tns:sendRequestXMLSoapIn" />
+      <wsdl:output message="tns:sendRequestXMLSoapOut" />
+    </wsdl:operation>
+    <wsdl:operation name="receiveResponseXML">
+      <wsdl:input message="tns:receiveResponseXMLSoapIn" />
+      <wsdl:output message="tns:receiveResponseXMLSoapOut" />
+    </wsdl:operation>
+    <wsdl:operation name="connectionError">
+      <wsdl:input message="tns:connectionErrorSoapIn" />
+      <wsdl:output message="tns:connectionErrorSoapOut" />
+    </wsdl:operation>
+    <wsdl:operation name="getLastError">
+      <wsdl:input message="tns:getLastErrorSoapIn" />
+      <wsdl:output message="tns:getLastErrorSoapOut" />
+    </wsdl:operation>
+    <wsdl:operation name="closeConnection">
+      <wsdl:input message="tns:closeConnectionSoapIn" />
+      <wsdl:output message="tns:closeConnectionSoapOut" />
+    </wsdl:operation>
+  </wsdl:portType>
+  <wsdl:binding name="QBWebConnectorSvcSoap" type="tns:QBWebConnectorSvcSoap">
+    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
+	<!-- this too was added... -->
+	<wsdl:operation name="serverVersion">
+      <soap:operation soapAction="http://developer.intuit.com/serverVersion" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+	<wsdl:operation name="clientVersion">
+      <soap:operation soapAction="http://developer.intuit.com/clientVersion" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+
+    <wsdl:operation name="authenticate">
+      <soap:operation soapAction="http://developer.intuit.com/authenticate" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="sendRequestXML">
+      <soap:operation soapAction="http://developer.intuit.com/sendRequestXML" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="receiveResponseXML">
+      <soap:operation soapAction="http://developer.intuit.com/receiveResponseXML" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="connectionError">
+      <soap:operation soapAction="http://developer.intuit.com/connectionError" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="getLastError">
+      <soap:operation soapAction="http://developer.intuit.com/getLastError" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="closeConnection">
+      <soap:operation soapAction="http://developer.intuit.com/closeConnection" style="document" />
+      <wsdl:input>
+        <soap:body use="literal" />
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal" />
+      </wsdl:output>
+    </wsdl:operation>
+  </wsdl:binding>
+  <wsdl:service name="QBWebConnectorSvc">
+    <wsdl:port name="QBWebConnectorSvcSoap" binding="tns:QBWebConnectorSvcSoap">
+      <soap:address location="https://idn.vogelfam.net/QBMSDonorSample/QBWebConnectorSvc.asmx" />
+    </wsdl:port>
+  </wsdl:service>
+</wsdl:definitions>
\ No newline at end of file
