]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge remote branch 'chat-interface-plugins/msn-plugin' into 1.0.x
authorCraig Andrews <candrews@integralblue.com>
Wed, 18 Aug 2010 16:41:50 +0000 (12:41 -0400)
committerCraig Andrews <candrews@integralblue.com>
Wed, 18 Aug 2010 16:41:50 +0000 (12:41 -0400)
14 files changed:
plugins/Msn/MsnPlugin.php [new file with mode: 0644]
plugins/Msn/README [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/msn.class.php [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/msnbot.php [new file with mode: 0755]
plugins/Msn/extlib/phpmsnclass/soap/.svn/all-wcprops [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/.svn/entries [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_datatypes.xsd.svn-base [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_servicetypes.xsd.svn-base [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_sharingservice.wsdl.svn-base [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd [new file with mode: 0644]
plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl [new file with mode: 0644]
plugins/Msn/msn_waiting_message.php [new file with mode: 0644]
plugins/Msn/msnmanager.php [new file with mode: 0644]

diff --git a/plugins/Msn/MsnPlugin.php b/plugins/Msn/MsnPlugin.php
new file mode 100644 (file)
index 0000000..9db3f77
--- /dev/null
@@ -0,0 +1,216 @@
+<?php\r
+/**\r
+ * StatusNet - the distributed open-source microblogging tool\r
+ * Copyright (C) 2009, StatusNet, Inc.\r
+ *\r
+ * Send and receive notices using the MSN network\r
+ *\r
+ * PHP version 5\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU Affero General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU Affero General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Affero General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ * @category  IM\r
+ * @package   StatusNet\r
+ * @author    Luke Fitzgerald <lw.fitzgerald@googlemail.com>\r
+ * @copyright 2010 StatusNet, Inc.\r
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0\r
+ * @link      http://status.net/\r
+ */\r
+\r
+if (!defined('STATUSNET')) {\r
+    // This check helps protect against security problems;\r
+    // your code file can't be executed directly from the web.\r
+    exit(1);\r
+}\r
+// We bundle the phpmsnclass library...\r
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phpmsnclass');\r
+\r
+/**\r
+ * Plugin for MSN\r
+ *\r
+ * @category  Plugin\r
+ * @package   StatusNet\r
+ * @author    Luke Fitzgerald <lw.fitzgerald@googlemail.com>\r
+ * @copyright 2010 StatusNet, Inc.\r
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0\r
+ * @link      http://status.net/\r
+ */\r
+\r
+class MsnPlugin extends ImPlugin {\r
+    public $user = null;\r
+    public $password = null;\r
+    public $nickname = null;\r
+    public $transport = 'msn';\r
+\r
+    /**\r
+     * Get the internationalized/translated display name of this IM service\r
+     *\r
+     * @return string Name of service\r
+     */\r
+    public function getDisplayName() {\r
+        return _m('MSN');\r
+    }\r
+\r
+    /**\r
+     * Normalize a screenname for comparison\r
+     *\r
+     * @param string $screenname screenname to normalize\r
+     * @return string an equivalent screenname in normalized form\r
+     */\r
+    public function normalize($screenname) {\r
+        $screenname = str_replace(" ","", $screenname);\r
+        return strtolower($screenname);\r
+    }\r
+\r
+    /**\r
+     * Get the screenname of the daemon that sends and receives messages\r
+     *\r
+     * @return string Screenname\r
+     */\r
+    public function daemon_screenname() {\r
+        return $this->user;\r
+    }\r
+\r
+    /**\r
+     * Validate (ensure the validity of) a screenname\r
+     *\r
+     * @param string $screenname screenname to validate\r
+     * @return boolean\r
+     */\r
+    public function validate($screenname) {\r
+        return Validate::email($screenname, common_config('email', 'check_domain'));\r
+    }\r
+\r
+    /**\r
+     * Load related modules when needed\r
+     *\r
+     * @param string $cls Name of the class to be loaded\r
+     * @return boolean hook value; true means continue processing, false means stop.\r
+     */\r
+    public function onAutoload($cls) {\r
+        $dir = dirname(__FILE__);\r
+\r
+        switch ($cls) {\r
+            case 'MSN':\r
+                require_once(INSTALLDIR.'/plugins/Msn/extlib/phpmsnclass/msn.class.php');\r
+                return false;\r
+            case 'MsnManager':\r
+            case 'Msn_waiting_message':\r
+                include_once $dir . '/'.strtolower($cls).'.php';\r
+                return false;\r
+            default:\r
+                return true;\r
+        }\r
+    }\r
+\r
+    /*\r
+     * Start manager on daemon start\r
+     *\r
+     * @return boolean\r
+     */\r
+    public function onStartImDaemonIoManagers(&$classes) {\r
+        parent::onStartImDaemonIoManagers(&$classes);\r
+        $classes[] = new MsnManager($this); // handles sending/receiving\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Ensure the database table is present\r
+    *\r
+    */\r
+    public function onCheckSchema() {\r
+        $schema = Schema::get();\r
+\r
+        // For storing messages while sessions become ready\r
+        $schema->ensureTable('msn_waiting_message',\r
+                             array(new ColumnDef('id', 'integer', null,\r
+                                                 false, 'PRI', null, null, true),\r
+                                   new ColumnDef('screenname', 'varchar', 255, false),\r
+                                   new ColumnDef('message', 'text', null, false),\r
+                                   new ColumnDef('created', 'datetime', null, false),\r
+                                   new ColumnDef('claimed', 'datetime')));\r
+\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Get a microid URI for the given screenname\r
+    *\r
+    * @param string $screenname\r
+    * @return string microid URI\r
+    */\r
+    public function microiduri($screenname) {\r
+        return 'msnim:' . $screenname;\r
+    }\r
+\r
+    /**\r
+     * Send a message to a given screenname\r
+     *\r
+     * @param string $screenname Screenname to send to\r
+     * @param string $body Text to send\r
+     * @return boolean success value\r
+     */\r
+    public function send_message($screenname, $body) {\r
+        $this->enqueue_outgoing_raw(array('to' => $screenname, 'message' => $body));\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Accept a queued input message.\r
+     *\r
+     * @param array $data Data\r
+     * @return true if processing completed, false if message should be reprocessed\r
+     */\r
+    public function receive_raw_message($data) {\r
+        $this->handle_incoming($data['sender'], $data['message']);\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Initialize plugin\r
+    *\r
+    * @return boolean\r
+    */\r
+    public function initialize() {\r
+        if (!isset($this->user)) {\r
+            throw new Exception("Must specify a user");\r
+        }\r
+        if (!isset($this->password)) {\r
+            throw new Exception("Must specify a password");\r
+        }\r
+        if (!isset($this->nickname)) {\r
+            throw new Exception("Must specify a nickname");\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Get plugin information\r
+     *\r
+     * @param array $versions array to insert information into\r
+     * @return void\r
+     */\r
+    public function onPluginVersion(&$versions) {\r
+        $versions[] = array(\r
+            'name' => 'MSN',\r
+            'version' => STATUSNET_VERSION,\r
+            'author' => 'Luke Fitzgerald',\r
+            'homepage' => 'http://status.net/wiki/Plugin:MSN',\r
+            'rawdescription' =>\r
+            _m('The MSN plugin allows users to send and receive notices over the MSN network.')\r
+        );\r
+        return true;\r
+    }\r
+}\r
diff --git a/plugins/Msn/README b/plugins/Msn/README
new file mode 100644 (file)
index 0000000..fa7bc2f
--- /dev/null
@@ -0,0 +1,32 @@
+The MSN plugin allows users to send and receive notices over the MSN network.
+
+Required PHP extensions:
+curl pcre mhash mcrypt bcmath
+
+Installation
+============
+add "addPlugin('msn',
+    array('setting'=>'value', 'setting2'=>'value2', ...);"
+to the bottom of your config.php
+
+scripts/imdaemon.php included with StatusNet must be running. It will be started by
+the plugin along with their other daemons when you run scripts/startdaemons.sh.
+See the StatusNet README for more about queuing and daemons.
+
+Settings
+========
+user*: username (screenname) to use when logging into MSN
+password*: password for that user
+nickname*: nickname for the bot
+
+* required
+default values are in (parenthesis)
+
+Example
+=======
+addPlugin('msn', array(
+    'user' => '...',
+    'password' => '...',
+    'nickname' => '...'
+));
+
diff --git a/plugins/Msn/extlib/phpmsnclass/msn.class.php b/plugins/Msn/extlib/phpmsnclass/msn.class.php
new file mode 100644 (file)
index 0000000..9abdce1
--- /dev/null
@@ -0,0 +1,3183 @@
+<?php\r
+/*\r
+\r
+phpmsnclass ver 2.0s\r
+Luke Fitzgerald <lw.fitzgerald@googlemail.com>\r
+\r
+Based on MSN class ver 2.0 by Tommy Wu, Ricky Su\r
+License: GPL\r
+\r
+Documentation on the MSN protocol can be found at: http://msnpiki.msnfanatic.com/index.php/Main_Page\r
+\r
+This class uses MSNP15.\r
+\r
+In addition to PHP5, the additional php modules required are:\r
+curl pcre mhash mcrypt bcmath\r
+\r
+*/\r
+\r
+class MSN {\r
+    const PROTOCOL = 'MSNP15';\r
+    const PASSPORT_URL = 'https://login.live.com/RST.srf';\r
+    const BUILDVER = '8.1.0178';\r
+    const PROD_KEY = 'PK}_A_0N_K%O?A9S';\r
+    const PROD_ID = 'PROD0114ES4Z%Q5W';\r
+    const LOGIN_METHOD = 'SSO';\r
+\r
+    const OIM_SEND_URL = 'https://ows.messenger.msn.com/OimWS/oim.asmx';\r
+    const OIM_SEND_SOAP = 'http://messenger.live.com/ws/2006/09/oim/Store2';\r
+\r
+    const OIM_MAILDATA_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    const OIM_MAILDATA_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata';\r
+    const OIM_READ_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    const OIM_READ_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMessage';\r
+    const OIM_DEL_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    const OIM_DEL_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/DeleteMessages';\r
+\r
+    const MEMBERSHIP_URL = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    const MEMBERSHIP_SOAP = 'http://www.msn.com/webservices/AddressBook/FindMembership';\r
+\r
+    const ADDMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    const ADDMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/AddMember';\r
+\r
+    const DELMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    const DELMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/DeleteMember';\r
+\r
+    // the message length (include header) is limited (maybe since WLM 8.5 released)\r
+    // for WLM: 1664 bytes\r
+    // for YIM: 518 bytes\r
+    const MAX_MSN_MESSAGE_LEN = 1664;\r
+    const MAX_YAHOO_MESSAGE_LEN = 518;\r
+\r
+    private $debug;\r
+    private $timeout;\r
+\r
+    private $id;\r
+    private $ticket;\r
+    private $user = '';\r
+    private $password = '';\r
+    private $NSfp = false;\r
+    private $passport_policy = '';\r
+    private $alias;\r
+    private $psm;\r
+    private $retry_wait;\r
+    private $update_pending;\r
+    private $PhotoStickerFile = false;\r
+    private $Emotions = false;\r
+    private $XFRReqTimeout = 60;\r
+    private $SBStreamTimeout = 2;\r
+    private $MsnObjArray = array();\r
+    private $MsnObjMap = array();\r
+    private $ABAuthHeader;\r
+    private $ABService;\r
+    private $Contacts;\r
+\r
+    private $server = 'messenger.hotmail.com';\r
+    private $port = 1863;\r
+\r
+    private $clientid = '';\r
+\r
+    private $error = '';\r
+\r
+    private $authed = false;\r
+\r
+    private $oim_try = 3;\r
+\r
+    private $font_fn = 'Arial';\r
+    private $font_co = '333333';\r
+    private $font_ef = '';\r
+\r
+    // Begin added for StatusNet\r
+\r
+    private $aContactList = array();\r
+    private $aADL = array();\r
+\r
+    /**\r
+    * Holds session information indexed by screenname if\r
+    * session has no socket or socket if socket present\r
+    *\r
+    * @var array\r
+    */\r
+    private $switchBoardSessions = array();\r
+\r
+    /**\r
+    * Holds sockets indexed by screenname\r
+    *\r
+    * @var array\r
+    */\r
+    private $switchBoardSessionLookup = array();\r
+\r
+    /**\r
+    * Holds references to sessions waiting for XFR\r
+    *\r
+    * @var array\r
+    */\r
+    private $waitingForXFR = array();\r
+\r
+    /**\r
+    * Event Handler Functions\r
+    */\r
+    private $myEventHandlers = array();\r
+\r
+    // End added for StatusNet\r
+\r
+    /**\r
+    * Constructor method\r
+    *\r
+    * @param array $Configs Array of configuration options\r
+    *                       'user'           - Username\r
+    *                       'password'       - Password\r
+    *                       'alias'          - Bot nickname\r
+    *                       'psm'            - Bot personal status message\r
+    *                       'retry_wait'     - Time to wait before trying to reconnect\r
+    *                       'update_pending' - Whether to update pending contacts\r
+    *                       'PhotoSticker'   - Photo file to use (?)\r
+    *                       'debug'          - Enable/Disable debugging mode\r
+    * @param integer $timeout Connection timeout\r
+    * @param integer $client_id Client id (hexadecimal)\r
+    * @return MSN\r
+    */\r
+    public function __construct ($Configs = array(), $timeout = 15, $client_id = 0x7000800C) {\r
+        $this->user = $Configs['user'];\r
+        $this->password = $Configs['password'];\r
+        $this->alias = isset($Configs['alias']) ? $Configs['alias'] : '';\r
+        $this->psm = isset($Configs['psm']) ? $Configs['psm'] : '';\r
+        $this->retry_wait = isset($Configs['retry_wait']) ? $Configs['retry_wait'] : 30;\r
+        $this->update_pending = isset($Configs['update_pending']) ? $Configs['update_pending'] : true;\r
+        $this->PhotoStickerFile=isset($Configs['PhotoSticker']) ? $Configs['PhotoSticker'] : false;\r
+\r
+        if ($this->Emotions = isset($Configs['Emotions']) ? $Configs['Emotions']:false) {\r
+            foreach($this->Emotions as $EmotionFilePath)\r
+                $this->MsnObj($EmotionFilePath,$Type=2);\r
+        }\r
+        $this->debug = isset($Configs['debug']) ? $Configs['debug'] : false;\r
+        $this->timeout = $timeout;\r
+\r
+        // Check support\r
+        if (!function_exists('curl_init')) throw new Exception("curl module not found!\n");\r
+        if (!function_exists('preg_match')) throw new Exception("pcre module not found!\n");\r
+        if (!function_exists('mhash')) throw new Exception("mhash module not found!\n");\r
+        if (!function_exists('mcrypt_cbc')) throw new Exception("mcrypt module not found!\n");\r
+        if (!function_exists('bcmod')) throw new Exception("bcmath module not found!\n");\r
+\r
+        /*\r
+         http://msnpiki.msnfanatic.com/index.php/Client_ID\r
+         Client ID for MSN:\r
+         normal MSN 8.1 clientid is:\r
+         01110110 01001100 11000000 00101100\r
+         = 0x764CC02C\r
+\r
+         we just use following:\r
+         * 0x04: Your client can send/receive Ink (GIF format)\r
+         * 0x08: Your client can send/recieve Ink (ISF format)\r
+         * 0x8000: This means you support Winks receiving (If not set the official Client will warn with 'contact has an older client and is not capable of receiving Winks')\r
+         * 0x70000000: This is the value for MSNC7 (WL Msgr 8.1)\r
+         = 0x7000800C;\r
+         */\r
+        $this->clientid = $client_id;\r
+        $this->ABService = new SoapClient(realpath(dirname(__FILE__)).'/soap/msnab_sharingservice.wsdl', array('trace' => 1));\r
+    }\r
+\r
+    /**\r
+     * Signon methods\r
+     */\r
+\r
+    /**\r
+     * Connect to the NS server\r
+     *\r
+     * @param String $user Username\r
+     * @param String $password Password\r
+     * @param String $redirect_server Redirect server\r
+     * @param Integer $redirect_port Redirect port\r
+     * @return Boolean Returns true if successful\r
+     */\r
+    private function connect($user, $password, $redirect_server = '', $redirect_port = 1863) {\r
+        $this->id = 1;\r
+        if ($redirect_server === '') {\r
+            $this->NSfp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);\r
+            if (!$this->NSfp) {\r
+                $this->error = "!!! Could not connect to $this->server:$this->port, error => $errno, $errstr";\r
+                return false;\r
+            }\r
+        }\r
+        else {\r
+            $this->NSfp = @fsockopen($redirect_server, $redirect_port, $errno, $errstr, $this->timeout);\r
+            if (!$this->NSfp) {\r
+                $this->error = "!!! Could not connect to $redirect_server:$redirect_port, error => $errno, $errstr";\r
+                return false;\r
+            }\r
+        }\r
+        $this->authed = false;\r
+        // MSNP9\r
+        // NS: >> VER {id} MSNP9 CVR0\r
+        // MSNP15\r
+        // NS: >>> VER {id} MSNP15 CVR0\r
+        $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0');\r
+\r
+        $start_tm = time();\r
+        while (!self::socketcheck($this->NSfp)) {\r
+            $data = $this->ns_readln();\r
+            // no data?\r
+            if ($data === false) {\r
+                // logout now\r
+                // NS: >>> OUT\r
+                $this->ns_writeln("OUT");\r
+                @fclose($this->NSfp);\r
+                $this->error = 'Timeout, maybe protocol changed!';\r
+                return false;\r
+            }\r
+\r
+            $code = substr($data, 0, 3);\r
+            $start_tm = time();\r
+\r
+            switch ($code) {\r
+                case 'VER':\r
+                    // MSNP9\r
+                    // NS: <<< VER {id} MSNP9 CVR0\r
+                    // NS: >>> CVR {id} 0x0409 winnt 5.1 i386 MSMSGS 6.0.0602 msmsgs {user}\r
+                    // MSNP15\r
+                    // NS: <<< VER {id} MSNP15 CVR0\r
+                    // NS: >>> CVR {id} 0x0409 winnt 5.1 i386 MSMSGS 8.1.0178 msmsgs {user}\r
+                    $this->ns_writeln("CVR $this->id 0x0409 winnt 5.1 i386 MSMSGS ".self::BUILDVER." msmsgs $user");\r
+                    break;\r
+\r
+                case 'CVR':\r
+                    // MSNP9\r
+                    // NS: <<< CVR {id} {ver_list} {download_serve} ....\r
+                    // NS: >>> USR {id} TWN I {user}\r
+                    // MSNP15\r
+                    // NS: <<< CVR {id} {ver_list} {download_serve} ....\r
+                    // NS: >>> USR {id} SSO I {user}\r
+                    $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." I $user");\r
+                    break;\r
+\r
+                case 'USR':\r
+                    // already login for passport site, finish the login process now.\r
+                    // NS: <<< USR {id} OK {user} {verify} 0\r
+                    if ($this->authed) return true;\r
+                    // max. 16 digits for password\r
+                    if (strlen($password) > 16)\r
+                    $password = substr($password, 0, 16);\r
+\r
+                    $this->user = $user;\r
+                    $this->password = $password;\r
+                    // NS: <<< USR {id} SSO S {policy} {nonce}\r
+                    @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce) = @explode(' ', $data);\r
+\r
+                    $this->passport_policy = $policy;\r
+                    $aTickets = $this->get_passport_ticket();\r
+                    if (!$aTickets || !is_array($aTickets)) {\r
+                        // logout now\r
+                        // NS: >>> OUT\r
+                        $this->ns_writeln("OUT");\r
+                        @fclose($this->NSfp);\r
+                        $this->error = 'Passport authentication failed!';\r
+                        return false;\r
+                    }\r
+\r
+                    $ticket = $aTickets['ticket'];\r
+                    $secret = $aTickets['secret'];\r
+                    $this->ticket = $aTickets;\r
+                    $login_code = $this->generateLoginBLOB($secret, $nonce);\r
+\r
+                    // NS: >>> USR {id} SSO S {ticket} {login_code}\r
+                    $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." S $ticket $login_code");\r
+                    $this->authed = true;\r
+                    break;\r
+\r
+                case 'XFR':\r
+                    // main login server will redirect to anther NS after USR command\r
+                    // MSNP9\r
+                    // NS: <<< XFR {id} NS {server} 0 {server}\r
+                    // MSNP15\r
+                    // NS: <<< XFR {id} NS {server} U D\r
+                    @list(/* XFR */, /* id */, $Type, $server) = @explode(' ', $data);\r
+                    if ($Type!='NS') break;\r
+                    @list($ip, $port) = @explode(':', $server);\r
+                    // this connection will close after XFR\r
+                    @fclose($this->NSfp);\r
+\r
+                    $this->NSfp = @fsockopen($ip, $port, $errno, $errstr, $this->timeout);\r
+                    if (!$this->NSfp) {\r
+                        $this->error = "Can't connect to $ip:$port, error => $errno, $errstr";\r
+                        return false;\r
+                    }\r
+\r
+                    // MSNP9\r
+                    // NS: >> VER {id} MSNP9 CVR0\r
+                    // MSNP15\r
+                    // NS: >>> VER {id} MSNP15 CVR0\r
+                    $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0');\r
+                    break;\r
+\r
+                case 'GCF':\r
+                    // return some policy data after 'USR {id} SSO I {user}' command\r
+                    // NS: <<< GCF 0 {size}\r
+                    @list(/* GCF */, /* 0 */, $size) = @explode(' ', $data);\r
+                    // we don't need the data, just read it and drop\r
+                    if (is_numeric($size) && $size > 0)\r
+                        $this->ns_readdata($size);\r
+                    break;\r
+\r
+                default:\r
+                    // we'll quit if got any error\r
+                    if (is_numeric($code)) {\r
+                        // logout now\r
+                        // NS: >>> OUT\r
+                        $this->ns_writeln("OUT");\r
+                        @fclose($this->NSfp);\r
+                        $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
+                        return false;\r
+                    }\r
+                    // unknown response from server, just ignore it\r
+                    break;\r
+            }\r
+        }\r
+        // never goto here\r
+    }\r
+\r
+    /**\r
+     * Sign onto the NS server and retrieve the address book\r
+     *\r
+     * @return void\r
+     */\r
+    public function signon() {\r
+        /* FIXME Don't implement the signon as a loop or we could hang\r
+        *        the queue handler! */\r
+        $this->debug_message('*** Trying to connect to MSN network');\r
+\r
+        // Remove any remaining switchboard sessions\r
+        $this->switchBoardSessions = array();\r
+        $this->switchBoardSessionLookup = array();\r
+\r
+        while (true) {\r
+            // Connect\r
+            if (!$this->connect($this->user, $this->password)) {\r
+                $this->signonFailure("!!! Could not connect to server: $this->error");\r
+                continue;\r
+            }\r
+\r
+            // Update contacts\r
+            if ($this->UpdateContacts() === false) {\r
+                $this->signonFailure('');\r
+                continue;\r
+            }\r
+\r
+            // Get membership lists\r
+            if (($this->aContactList = $this->getMembershipList()) === false) {\r
+                $this->signonFailure('!!! Get membership list failed');\r
+                continue;\r
+            }\r
+\r
+            if ($this->update_pending) {\r
+                if (is_array($this->aContactList)) {\r
+                    $pending = 'Pending';\r
+                    foreach ($this->aContactList as $u_domain => $aUserList) {\r
+                        foreach ($aUserList as $u_name => $aNetworks) {\r
+                            foreach ($aNetworks as $network => $aData) {\r
+                                if (isset($aData[$pending])) {\r
+                                    // pending list\r
+                                    $cnt = 0;\r
+                                    foreach (array('Allow', 'Reverse') as $list) {\r
+                                        if (isset($aData[$list]))\r
+                                            $cnt++;\r
+                                        else {\r
+                                            if ($this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
+                                                $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
+                                                $cnt++;\r
+                                            }\r
+                                        }\r
+                                    }\r
+                                    if ($cnt >= 2) {\r
+                                        $id = $aData[$pending];\r
+                                        // we can delete it from pending now\r
+                                        if ($this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $pending))\r
+                                            unset($this->aContactList[$u_domain][$u_name][$network][$pending]);\r
+                                    }\r
+                                }\r
+                                else {\r
+                                    // sync list\r
+                                    foreach (array('Allow', 'Reverse') as $list) {\r
+                                        if (!isset($aData[$list])) {\r
+                                            if ($this->addMemberToList($u_name.'@'.$u_domain, $network, $list))\r
+                                                $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
+                                        }\r
+                                    }\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            $n = 0;\r
+            $sList = '';\r
+            $len = 0;\r
+            if (is_array($this->aContactList)) {\r
+                foreach ($this->aContactList as $u_domain => $aUserList) {\r
+                    $str = '<d n="'.$u_domain.'">';\r
+                    $len += strlen($str);\r
+                    if ($len > 7400) {\r
+                        $this->aADL[$n] = '<ml l="1">'.$sList.'</ml>';\r
+                        $n++;\r
+                        $sList = '';\r
+                        $len = strlen($str);\r
+                    }\r
+                    $sList .= $str;\r
+                    foreach ($aUserList as $u_name => $aNetworks) {\r
+                        foreach ($aNetworks as $network => $status) {\r
+                            $str = '<c n="'.$u_name.'" l="3" t="'.$network.'" />';\r
+                            $len += strlen($str);\r
+                            // max: 7500, but <ml l="1"></d></ml> is 19,\r
+                            // so we use 7475\r
+                            if ($len > 7475) {\r
+                                $sList .= '</d>';\r
+                                $this->aADL[$n] = '<ml l="1">'.$sList.'</ml>';\r
+                                $n++;\r
+                                $sList = '<d n="'.$u_domain.'">'.$str;\r
+                                $len = strlen($sList);\r
+                            }\r
+                            else\r
+                                $sList .= $str;\r
+                        }\r
+                    }\r
+                    $sList .= '</d>';\r
+                }\r
+            }\r
+            $this->aADL[$n] = '<ml l="1">'.$sList.'</ml>';\r
+            // NS: >>> BLP {id} BL\r
+            $this->ns_writeln("BLP $this->id BL");\r
+            foreach ($this->aADL as $str) {\r
+                $len = strlen($str);\r
+                // NS: >>> ADL {id} {size}\r
+                $this->ns_writeln("ADL $this->id $len");\r
+                $this->ns_writedata($str);\r
+            }\r
+            // NS: >>> PRP {id} MFN name\r
+            if ($this->alias == '') $this->alias = $user;\r
+            $aliasname = rawurlencode($this->alias);\r
+            $this->ns_writeln("PRP $this->id MFN $aliasname");\r
+            //設定個人大頭貼\r
+            //$MsnObj=$this->PhotoStckObj();\r
+            // NS: >>> CHG {id} {status} {clientid} {msnobj}\r
+            $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
+            if ($this->PhotoStickerFile !== false)\r
+                $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
+            // NS: >>> UUX {id} length\r
+            $str = '<Data><PSM>'.htmlspecialchars($this->psm).'</PSM><CurrentMedia></CurrentMedia><MachineGuid></MachineGuid></Data>';\r
+            $len = strlen($str);\r
+            $this->ns_writeln("UUX $this->id $len");\r
+            $this->ns_writedata($str);\r
+            if (!self::socketcheck($this->NSfp)) {\r
+                $this->debug_message('*** Connected, waiting for commands');\r
+                break;\r
+            } else {\r
+                $this->NSRetryWait($this->retry_wait);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+    * Called if there is an error during signon\r
+    *\r
+    * @param string $message Error message to log\r
+    * @return void\r
+    */\r
+    private function signonFailure($message) {\r
+        if(!empty($message)) {\r
+            $this->debug_message($message);\r
+        }\r
+        $this->callHandler('ConnectFailed');\r
+        $this->NSRetryWait($this->retry_wait);\r
+    }\r
+\r
+    /**\r
+    * Log out and close the NS connection\r
+    *\r
+    * @return void\r
+    */\r
+    private function nsLogout() {\r
+        if (is_resource($this->NSfp) && !feof($this->NSfp)) {\r
+            // logout now\r
+            // NS: >>> OUT\r
+            $this->ns_writeln("OUT");\r
+            fclose($this->NSfp);\r
+            $this->NSfp = false;\r
+            $this->debug_message("*** Logged out");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * NS and SB command handling methods\r
+     */\r
+\r
+    /**\r
+     * Read and handle incoming command from NS\r
+     *\r
+     * @return void\r
+     */\r
+    private function nsReceive() {\r
+        // Sign in again if not signed in or socket failed\r
+        if (!is_resource($this->NSfp) || self::socketcheck($this->NSfp)) {\r
+            $this->callHandler('Reconnect');\r
+            $this->NSRetryWait($this->retry_wait);\r
+            $this->signon();\r
+            return;\r
+        }\r
+\r
+        $data = $this->ns_readln();\r
+        if ($data === false) {\r
+            // There was no data / an error when reading from the socket so reconnect\r
+            $this->callHandler('Reconnect');\r
+            $this->NSRetryWait($this->retry_wait);\r
+            $this->signon();\r
+            return;\r
+        }\r
+\r
+        switch (substr($data, 0, 3)) {\r
+            case 'SBS':\r
+                // after 'USR {id} OK {user} {verify} 0' response, the server will send SBS and profile to us\r
+                // NS: <<< SBS 0 null\r
+                break;\r
+\r
+            case 'RFS':\r
+                // FIXME:\r
+                // NS: <<< RFS ???\r
+                // refresh ADL, so we re-send it again\r
+                if (is_array($this->aADL)) {\r
+                    foreach ($this->aADL as $str) {\r
+                        $len = strlen($str);\r
+                        // NS: >>> ADL {id} {size}\r
+                        $this->ns_writeln("ADL $this->id $len");\r
+                        $this->ns_writedata($str);\r
+                    }\r
+                }\r
+                break;\r
+\r
+            case 'LST':\r
+                // NS: <<< LST {email} {alias} 11 0\r
+                @list(/* LST */, $email) = @explode(' ', $data);\r
+                @list($u_name, $u_domain) = @explode('@', $email);\r
+                if (!isset($this->aContactList[$u_domain][$u_name][1])) {\r
+                    $this->aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow';\r
+                    $this->debug_message("*** Added to contact list: $u_name@$u_domain");\r
+                }\r
+                break;\r
+\r
+            case 'ADL':\r
+                // randomly, we get ADL command, someone add us to their contact list for MSNP15\r
+                // NS: <<< ADL 0 {size}\r
+                @list(/* ADL */, /* 0 */, $size) = @explode(' ', $data);\r
+                if (is_numeric($size) && $size > 0) {\r
+                    $data = $this->ns_readdata($size);\r
+                    preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
+                    if (is_array($matches) && count($matches) > 0) {\r
+                        $u_domain = $matches[1];\r
+                        $u_name = $matches[2];\r
+                        $network = $matches[4];\r
+                        if (isset($this->aContactList[$u_domain][$u_name][$network]))\r
+                            $this->debug_message("*** Someone (network: $network) added us to their list (but already in our list): $u_name@$u_domain");\r
+                        else {\r
+                            $re_login = false;\r
+                            $cnt = 0;\r
+                            foreach (array('Allow', 'Reverse') as $list) {\r
+                                if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
+                                    if ($re_login) {\r
+                                        $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+                                        continue;\r
+                                    }\r
+                                    $aTickets = $this->get_passport_ticket();\r
+                                    if (!$aTickets || !is_array($aTickets)) {\r
+                                        // failed to login? ignore it\r
+                                        $this->debug_message("*** Could not re-login, something wrong here");\r
+                                        $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+                                        continue;\r
+                                    }\r
+                                    $re_login = true;\r
+                                    $this->ticket = $aTickets;\r
+                                    $this->debug_message("**** Got new ticket, trying again");\r
+                                    if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
+                                        $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+                                        continue;\r
+                                    }\r
+                                }\r
+                                $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
+                                $cnt++;\r
+                            }\r
+                            $this->debug_message("*** Someone (network: $network) added us to their list: $u_name@$u_domain");\r
+                        }\r
+                        $str = '<ml l="1"><d n="'.$u_domain.'"><c n="'.$u_name.'" l="3" t="'.$network.'" /></d></ml>';\r
+                        $len = strlen($str);\r
+\r
+                        $this->callHandler('AddedToList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
+                    }\r
+                    else\r
+                        $this->debug_message("*** Someone added us to their list: $data");\r
+                }\r
+                break;\r
+\r
+            case 'RML':\r
+                // randomly, we get RML command, someome remove us to their contact list for MSNP15\r
+                // NS: <<< RML 0 {size}\r
+                @list(/* RML */, /* 0 */, $size) = @explode(' ', $data);\r
+                if (is_numeric($size) && $size > 0) {\r
+                    $data = $this->ns_readdata($size);\r
+                    preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
+                    if (is_array($matches) && count($matches) > 0) {\r
+                        $u_domain = $matches[1];\r
+                        $u_name = $matches[2];\r
+                        $network = $matches[4];\r
+                        if (isset($this->aContactList[$u_domain][$u_name][$network])) {\r
+                            $aData = $this->aContactList[$u_domain][$u_name][$network];\r
+\r
+                            foreach ($aData as $list => $id)\r
+                                $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list);\r
+\r
+                            unset($this->aContactList[$u_domain][$u_name][$network]);\r
+                            $this->debug_message("*** Someone (network: $network) removed us from their list: $u_name@$u_domain");\r
+                        }\r
+                        else\r
+                            $this->debug_message("*** Someone (network: $network) removed us from their list (but not in our list): $u_name@$u_domain");\r
+\r
+                        $this->callHandler('RemovedFromList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
+                    }\r
+                    else\r
+                        $this->debug_message("*** Someone removed us from their list: $data");\r
+                }\r
+                break;\r
+\r
+            case 'MSG':\r
+                // randomly, we get MSG notification from server\r
+                // NS: <<< MSG Hotmail Hotmail {size}\r
+                @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size) = @explode(' ', $data);\r
+                if (is_numeric($size) && $size > 0) {\r
+                    $data = $this->ns_readdata($size);\r
+                    $aLines = @explode("\n", $data);\r
+                    $header = true;\r
+                    $ignore = false;\r
+                    $maildata = '';\r
+                    foreach ($aLines as $line) {\r
+                        $line = rtrim($line);\r
+                        if ($header) {\r
+                            if ($line === '') {\r
+                                $header = false;\r
+                                continue;\r
+                            }\r
+                            if (strncasecmp($line, 'Content-Type:', 13) == 0) {\r
+                                if (strpos($line, 'text/x-msmsgsinitialmdatanotification') === false && strpos($line, 'text/x-msmsgsoimnotification') === false) {\r
+                                    // we just need text/x-msmsgsinitialmdatanotification\r
+                                    // or text/x-msmsgsoimnotification\r
+                                    $ignore = true;\r
+                                    break;\r
+                                }\r
+                            }\r
+                            continue;\r
+                        }\r
+                        if (strncasecmp($line, 'Mail-Data:', 10) == 0) {\r
+                            $maildata = trim(substr($line, 10));\r
+                            break;\r
+                        }\r
+                    }\r
+                    if ($ignore) {\r
+                        $this->debug_message("*** Ignoring MSG for: $line");\r
+                        break;\r
+                    }\r
+                    if ($maildata == '') {\r
+                        $this->debug_message("*** Ignoring MSG not for OIM");\r
+                        break;\r
+                    }\r
+                    $re_login = false;\r
+                    if (strcasecmp($maildata, 'too-large') == 0) {\r
+                        $this->debug_message("*** Large mail-data, need to get the data via SOAP");\r
+                        $maildata = $this->getOIM_maildata();\r
+                        if ($maildata === false) {\r
+                            $this->debug_message("*** Could not get mail-data via SOAP");\r
+\r
+                            // maybe we need to re-login again\r
+                            $aTickets = $this->get_passport_ticket();\r
+                            if (!$aTickets || !is_array($aTickets)) {\r
+                                // failed to login? ignore it\r
+                                $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
+                                break;\r
+                            }\r
+                            $re_login = true;\r
+                            $this->ticket = $aTickets;\r
+                            $this->debug_message("*** Got new ticket, trying again");\r
+                            $maildata = $this->getOIM_maildata();\r
+                            if ($maildata === false) {\r
+                                $this->debug_message("*** Could not get mail-data via SOAP, and re-login already attempted, ignoring this OIM");\r
+                                break;\r
+                            }\r
+                        }\r
+                    }\r
+                    // could be a lots of <M>...</M>, so we can't use preg_match here\r
+                    $p = $maildata;\r
+                    $aOIMs = array();\r
+                    while (1) {\r
+                        $start = strpos($p, '<M>');\r
+                        $end = strpos($p, '</M>');\r
+                        if ($start === false || $end === false || $start > $end) break;\r
+                        $end += 4;\r
+                        $sOIM = substr($p, $start, $end - $start);\r
+                        $aOIMs[] = $sOIM;\r
+                        $p = substr($p, $end);\r
+                    }\r
+                    if (count($aOIMs) == 0) {\r
+                        $this->debug_message("*** Ignoring empty OIM");\r
+                        break;\r
+                    }\r
+                    foreach ($aOIMs as $maildata) {\r
+                        // T: 11 for MSN, 13 for Yahoo\r
+                        // S: 6 for MSN, 7 for Yahoo\r
+                        // RT: the datetime received by server\r
+                        // RS: already read or not\r
+                        // SZ: size of message\r
+                        // E: sender\r
+                        // I: msgid\r
+                        // F: always 00000000-0000-0000-0000-000000000009\r
+                        // N: sender alias\r
+                        preg_match('#<T>(.*)</T>#', $maildata, $matches);\r
+                        if (count($matches) == 0) {\r
+                            $this->debug_message("*** Ignoring OIM maildata without <T>type</T>");\r
+                            continue;\r
+                        }\r
+                        $oim_type = $matches[1];\r
+                        if ($oim_type = 13)\r
+                            $network = 32;\r
+                        else\r
+                            $network = 1;\r
+                        preg_match('#<E>(.*)</E>#', $maildata, $matches);\r
+                        if (count($matches) == 0) {\r
+                            $this->debug_message("*** Ignoring OIM maildata without <E>sender</E>");\r
+                            continue;\r
+                        }\r
+                        $oim_sender = $matches[1];\r
+                        preg_match('#<I>(.*)</I>#', $maildata, $matches);\r
+                        if (count($matches) == 0) {\r
+                            $this->debug_message("*** Ignoring OIM maildata without <I>msgid</I>");\r
+                            continue;\r
+                        }\r
+                        $oim_msgid = $matches[1];\r
+                        preg_match('#<SZ>(.*)</SZ>#', $maildata, $matches);\r
+                        $oim_size = (count($matches) == 0) ? 0 : $matches[1];\r
+                        preg_match('#<RT>(.*)</RT>#', $maildata, $matches);\r
+                        $oim_time = (count($matches) == 0) ? 0 : $matches[1];\r
+                        $this->debug_message("*** OIM received from $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size");\r
+                        $sMsg = $this->getOIM_message($oim_msgid);\r
+                        if ($sMsg === false) {\r
+                            $this->debug_message("*** Could not get OIM, msgid = $oim_msgid");\r
+                            if ($re_login) {\r
+                                $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
+                                continue;\r
+                            }\r
+                            $aTickets = $this->get_passport_ticket();\r
+                            if (!$aTickets || !is_array($aTickets)) {\r
+                                // failed to login? ignore it\r
+                                $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
+                                continue;\r
+                            }\r
+                            $re_login = true;\r
+                            $this->ticket = $aTickets;\r
+                            $this->debug_message("*** get new ticket, try it again");\r
+                            $sMsg = $this->getOIM_message($oim_msgid);\r
+                            if ($sMsg === false) {\r
+                                $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
+                                continue;\r
+                            }\r
+                        }\r
+                        $this->debug_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg");\r
+                        $this->callHandler('IMin', array('sender' => $oim_sender, 'message' => $sMsg, 'network' => $network, 'offline' => true));\r
+                    }\r
+                }\r
+                break;\r
+\r
+            case 'UBM':\r
+                // randomly, we get UBM, this is the message from other network, like Yahoo!\r
+                // NS: <<< UBM {email} $network $type {size}\r
+                @list(/* UBM */, $from_email, $network, $type, $size) = @explode(' ', $data);\r
+                if (is_numeric($size) && $size > 0) {\r
+                    $data = $this->ns_readdata($size);\r
+                    $aLines = @explode("\n", $data);\r
+                    $header = true;\r
+                    $ignore = false;\r
+                    $sMsg = '';\r
+                    foreach ($aLines as $line) {\r
+                        $line = rtrim($line);\r
+                        if ($header) {\r
+                            if ($line === '') {\r
+                                $header = false;\r
+                                continue;\r
+                            }\r
+                            if (strncasecmp($line, 'TypingUser:', 11) == 0) {\r
+                                $ignore = true;\r
+                                break;\r
+                            }\r
+                            continue;\r
+                        }\r
+                        $aSubLines = @explode("\r", $line);\r
+                        foreach ($aSubLines as $str) {\r
+                            if ($sMsg !== '')\r
+                            $sMsg .= "\n";\r
+                            $sMsg .= $str;\r
+                        }\r
+                    }\r
+                    if ($ignore) {\r
+                        $this->debug_message("*** Ignoring message from $from_email: $line");\r
+                        break;\r
+                    }\r
+                    $this->debug_message("*** MSG from $from_email (network: $network): $sMsg");\r
+                    $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false));\r
+                }\r
+                break;\r
+\r
+            case 'UBX':\r
+                // randomly, we get UBX notification from server\r
+                // NS: <<< UBX email {network} {size}\r
+                @list(/* UBX */, /* email */, /* network */, $size) = @explode(' ', $data);\r
+                // we don't need the notification data, so just ignore it\r
+                if (is_numeric($size) && $size > 0)\r
+                    $this->ns_readdata($size);\r
+                break;\r
+\r
+            case 'CHL':\r
+                // randomly, we'll get challenge from server\r
+                // NS: <<< CHL 0 {code}\r
+                @list(/* CHL */, /* 0 */, $chl_code) = @explode(' ', $data);\r
+                $fingerprint = $this->getChallenge($chl_code);\r
+                // NS: >>> QRY {id} {product_id} 32\r
+                // NS: >>> fingerprint\r
+                $this->ns_writeln("QRY $this->id ".self::PROD_ID.' 32');\r
+                $this->ns_writedata($fingerprint);\r
+                $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
+                if ($this->PhotoStickerFile !== false)\r
+                    $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
+                break;\r
+            case 'CHG':\r
+                // NS: <<< CHG {id} {status} {code}\r
+                // ignore it\r
+                // change our status to online first\r
+                break;\r
+\r
+            case 'XFR':\r
+                // sometimes, NS will redirect to another NS\r
+                // MSNP9\r
+                // NS: <<< XFR {id} NS {server} 0 {server}\r
+                // MSNP15\r
+                // NS: <<< XFR {id} NS {server} U D\r
+                // for normal switchboard XFR\r
+                // NS: <<< XFR {id} SB {server} CKI {cki} U messenger.msn.com 0\r
+                @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code) = @explode(' ', $data);\r
+                @list($ip, $port) = @explode(':', $server);\r
+                if ($server_type != 'SB') {\r
+                    // maybe exit?\r
+                    // this connection will close after XFR\r
+                    $this->nsLogout();\r
+                    continue;\r
+                }\r
+\r
+                $this->debug_message("NS: <<< XFR SB");\r
+                $session = array_shift($this->waitingForXFR);\r
+                $this->connectToSBSession('Active', $ip, $port, $session['to'], array('cki' => $cki_code));\r
+                break;\r
+            case 'QNG':\r
+                // NS: <<< QNG {time}\r
+                @list(/* QNG */, $ping_wait) = @explode(' ', $data);\r
+                $this->callHandler('Pong', $ping_wait);\r
+                break;\r
+\r
+            case 'RNG':\r
+                if ($this->PhotoStickerFile !== false)\r
+                    $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
+                else\r
+                    $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
+                // someone is trying to talk to us\r
+                // NS: <<< RNG {session_id} {server} {auth_type} {ticket} {email} {alias} U {client} 0\r
+                $this->debug_message("NS: <<< RNG $data");\r
+                @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name) = @explode(' ', $data);\r
+                @list($sb_ip, $sb_port) = @explode(':', $server);\r
+                $this->debug_message("*** RING from $email, $sb_ip:$sb_port");\r
+                $this->addContact($email, 1, $email, true);\r
+                $this->connectToSBSession('Passive', $sb_ip, $sb_port, $email, array('sid' => $sid, 'ticket' => $ticket));\r
+                break;\r
+\r
+            case 'NLN':\r
+                // NS: <<< NLN {status} {email} {networkid} {nickname} {clientid} {dpobj}\r
+                @list(/* NLN */, $status, $email, $network, $nickname) = @explode(' ', $data);\r
+                $this->callHandler('StatusChange', array('screenname' => $email, 'status' => $status, 'network' => $network, 'nickname' => $nickname));\r
+                break;\r
+\r
+            case 'OUT':\r
+                // force logout from NS\r
+                // NS: <<< OUT xxx\r
+                $this->debug_message("*** LOGOUT from NS");\r
+                return $this->nsLogout();\r
+\r
+            default:\r
+                $code = substr($data,0,3);\r
+                if (is_numeric($code)) {\r
+                    $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
+                    $this->debug_message("*** NS: $this->error");\r
+\r
+                    return $this->nsLogout();\r
+                }\r
+                break;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Read and handle incoming command/message from\r
+     * a switchboard session socket\r
+     */\r
+    private function sbReceive($socket) {\r
+        $intsocket = (int) $socket;\r
+        $session = &$this->switchBoardSessions[$intsocket];\r
+\r
+        if (feof($socket)) {\r
+            // Unset session lookup value\r
+            unset($this->switchBoardSessionLookup[$session['to']]);\r
+\r
+            // Unset session itself\r
+            unset($this->switchBoardSessions[$intsocket]);\r
+            return;\r
+        }\r
+\r
+        $id = &$session['id'];\r
+\r
+        $data = $this->sb_readln($socket);\r
+        $code = substr($data, 0, 3);\r
+        switch($code) {\r
+            case 'IRO':\r
+                // SB: <<< IRO {id} {rooster} {roostercount} {email} {alias} {clientid}\r
+                @list(/* IRO */, /* id */, $cur_num, $total, $email, $alias, $clientid) = @explode(' ', $data);\r
+                $this->debug_message("*** $email joined session");\r
+                if ($email == $session['to']) {\r
+                    $session['joined'] = true;\r
+                    $this->callHandler('SessionReady', array('to' => $email));\r
+                }\r
+                break;\r
+            case 'BYE':\r
+                $this->debug_message("*** Quit for BYE");\r
+                $this->endSBSession($socket);\r
+                break;\r
+            case 'USR':\r
+                // SB: <<< USR {id} OK {user} {alias}\r
+                // we don't need the data, just ignore it\r
+                // request user to join this switchboard\r
+                // SB: >>> CAL {id} {user}\r
+                $this->sb_writeln($socket, $id, "CAL $id ".$session['to']);\r
+                break;\r
+            case 'CAL':\r
+                // SB: <<< CAL {id} RINGING {?}\r
+                // we don't need this, just ignore, and wait for other response\r
+                $session['id']++;\r
+                break;\r
+            case 'JOI':\r
+                // SB: <<< JOI {user} {alias} {clientid?}\r
+                // someone join us\r
+                @list(/* JOI */, $email) = @explode(' ', $data);\r
+                if ($email == $session['to']) {\r
+                    $session['joined'] = true;\r
+                    $this->callHandler('SessionReady', array('to' => $email));\r
+                }\r
+                break;\r
+            case 'MSG':\r
+                // SB: <<< MSG {email} {alias} {len}\r
+                @list(/* MSG */, $from_email, /* alias */, $len) = @explode(' ', $data);\r
+                $len = trim($len);\r
+                $data = $this->sb_readdata($socket, $len);\r
+                $aLines = @explode("\n", $data);\r
+                $header = true;\r
+                $ignore = false;\r
+                $is_p2p = false;\r
+                $sMsg = '';\r
+                foreach ($aLines as $line) {\r
+                    $line = rtrim($line);\r
+                    if ($header) {\r
+                        if ($line === '') {\r
+                            $header = false;\r
+                            continue;\r
+                        }\r
+                        if (strncasecmp($line, 'TypingUser:', 11) == 0) {\r
+                            // typing notification, just ignore\r
+                            $ignore = true;\r
+                            break;\r
+                        }\r
+                        if (strncasecmp($line, 'Chunk:', 6) == 0) {\r
+                            // we don't handle any split message, just ignore\r
+                            $ignore = true;\r
+                            break;\r
+                        }\r
+                        if (strncasecmp($line, 'Content-Type: application/x-msnmsgrp2p', 38) == 0) {\r
+                            // p2p message, ignore it, but we need to send acknowledgement for it...\r
+                            $is_p2p = true;\r
+                            $p = strstr($data, "\n\n");\r
+                            $sMsg = '';\r
+                            if ($p === false) {\r
+                                $p = strstr($data, "\r\n\r\n");\r
+                                if ($p !== false)\r
+                                $sMsg = substr($p, 4);\r
+                            }\r
+                            else\r
+                            $sMsg = substr($p, 2);\r
+                            break;\r
+                        }\r
+                        if (strncasecmp($line, 'Content-Type: application/x-', 28) == 0) {\r
+                            // ignore all application/x-... message\r
+                            // for example:\r
+                            //      application/x-ms-ink        => ink message\r
+                            $ignore = true;\r
+                            break;\r
+                        }\r
+                        if (strncasecmp($line, 'Content-Type: text/x-', 21) == 0) {\r
+                            // ignore all text/x-... message\r
+                            // for example:\r
+                            //      text/x-msnmsgr-datacast         => nudge, voice clip....\r
+                            //      text/x-mms-animemoticon         => customized animemotion word\r
+                            $ignore = true;\r
+                            break;\r
+                        }\r
+                        continue;\r
+                    }\r
+                    if ($sMsg !== '')\r
+                        $sMsg .= "\n";\r
+                    $sMsg .= $line;\r
+                }\r
+                if ($ignore) {\r
+                    $this->debug_message("*** Ignoring SB data from $from_email: $line");\r
+                    break;\r
+                }\r
+                if ($is_p2p) {\r
+                    // we will ignore any p2p message after sending acknowledgement\r
+                    $ignore = true;\r
+                    $len = strlen($sMsg);\r
+                    $this->debug_message("*** p2p message from $from_email, size $len");\r
+                    // header = 48 bytes\r
+                    // content >= 0 bytes\r
+                    // footer = 4 bytes\r
+                    // so it need to >= 52 bytes\r
+                    /*if ($len < 52) {\r
+                        $this->debug_message("*** p2p: size error, less than 52!");\r
+                        break;\r
+                    }*/\r
+                    $aDwords = @unpack("V12dword", $sMsg);\r
+                    if (!is_array($aDwords)) {\r
+                        $this->debug_message("*** p2p: header unpack error!");\r
+                        break;\r
+                    }\r
+                    $this->debug_message("*** p2p: dump received message:\n".$this->dump_binary($sMsg));\r
+                    $hdr_SessionID = $aDwords['dword1'];\r
+                    $hdr_Identifier = $aDwords['dword2'];\r
+                    $hdr_DataOffsetLow = $aDwords['dword3'];\r
+                    $hdr_DataOffsetHigh = $aDwords['dword4'];\r
+                    $hdr_TotalDataSizeLow = $aDwords['dword5'];\r
+                    $hdr_TotalDataSizeHigh = $aDwords['dword6'];\r
+                    $hdr_MessageLength = $aDwords['dword7'];\r
+                    $hdr_Flag = $aDwords['dword8'];\r
+                    $hdr_AckID = $aDwords['dword9'];\r
+                    $hdr_AckUID = $aDwords['dword10'];\r
+                    $hdr_AckSizeLow = $aDwords['dword11'];\r
+                    $hdr_AckSizeHigh = $aDwords['dword12'];\r
+                    $this->debug_message("*** p2p: header SessionID = $hdr_SessionID");\r
+                    $this->debug_message("*** p2p: header Inentifier = $hdr_Identifier");\r
+                    $this->debug_message("*** p2p: header Data Offset Low = $hdr_DataOffsetLow");\r
+                    $this->debug_message("*** p2p: header Data Offset High = $hdr_DataOffsetHigh");\r
+                    $this->debug_message("*** p2p: header Total Data Size Low = $hdr_TotalDataSizeLow");\r
+                    $this->debug_message("*** p2p: header Total Data Size High = $hdr_TotalDataSizeHigh");\r
+                    $this->debug_message("*** p2p: header MessageLength = $hdr_MessageLength");\r
+                    $this->debug_message("*** p2p: header Flag = $hdr_Flag");\r
+                    $this->debug_message("*** p2p: header AckID = $hdr_AckID");\r
+                    $this->debug_message("*** p2p: header AckUID = $hdr_AckUID");\r
+                    $this->debug_message("*** p2p: header AckSize Low = $hdr_AckSizeLow");\r
+                    $this->debug_message("*** p2p: header AckSize High = $hdr_AckSizeHigh");\r
+                    if ($hdr_Flag == 2) {\r
+                        //This is an ACK from SB ignore....\r
+                        $this->debug_message("*** p2p: //This is an ACK from SB ignore....:\n");\r
+                        break;\r
+                    }\r
+                    $MsgBody = $this->linetoArray(substr($sMsg, 48, -4));\r
+                    $this->debug_message("*** p2p: body".print_r($MsgBody, true));\r
+                    if (($MsgBody['EUF-GUID']=='{A4268EEC-FEC5-49E5-95C3-F126696BDBF6}')&&($PictureFilePath=$this->GetPictureFilePath($MsgBody['Context']))) {\r
+                        while (true) {\r
+                            if ($this->sb_readln($socket) === false) break;\r
+                        }\r
+                        $this->debug_message("*** p2p: Inv hdr:\n".$this->dump_binary(substr($sMsg, 0, 48)));\r
+                        preg_match('/{([0-9A-F\-]*)}/i', $MsgBody['Via'], $Matches);\r
+                        $BranchGUID = $Matches[1];\r
+                        //it's an invite to send a display picture.\r
+                        $new_id = ~$hdr_Identifier;\r
+                        $hdr = pack(\r
+                            "LLLLLLLLLLLL", $hdr_SessionID,\r
+                            $new_id,\r
+                            0, 0,\r
+                            $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh,\r
+                            0,\r
+                            2,\r
+                            $hdr_Identifier,\r
+                            $hdr_AckID,\r
+                            $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh\r
+                        );\r
+                        $footer = pack("L", 0);\r
+                        $message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer";\r
+                        $len = strlen($message);\r
+                        $this->sb_writeln($socket, $id, "MSG $id D $len");\r
+                        $this->sb_writedata($socket, $message);\r
+                        $this->debug_message("*** p2p: send display picture acknowledgement for $hdr_SessionID");\r
+                        $this->debug_message("*** p2p: Invite ACK message:\n".$this->dump_binary($message));\r
+                        $this->sb_readln($socket); // Read ACK;\r
+                        $this->debug_message("*** p2p: Invite ACK Hdr:\n".$this->dump_binary($hdr));\r
+                        $new_id -= 3;\r
+                        //Send 200 OK message\r
+                        $MessageContent="SessionID: ".$MsgBody['SessionID']."\r\n\r\n".pack("C", 0);\r
+                        $MessagePayload=\r
+                            "MSNSLP/1.0 200 OK\r\n".\r
+                            "To: <msnmsgr:".$from_email.">\r\n".\r
+                            "From: <msnmsgr:".$this->user.">\r\n".\r
+                            "Via: ".$MsgBody['Via']."\r\n".\r
+                            "CSeq: ".($MsgBody['CSeq']+1)."\r\n".\r
+                            "Call-ID: ".$MsgBody['Call-ID']."\r\n".\r
+                            "Max-Forwards: 0\r\n".\r
+                            "Content-Type: application/x-msnmsgr-sessionreqbody\r\n".\r
+                            "Content-Length: ".strlen($MessageContent)."\r\n\r\n".\r
+                        $MessageContent;\r
+                        $hdr_TotalDataSizeLow=strlen($MessagePayload);\r
+                        $hdr_TotalDataSizeHigh=0;\r
+                        $hdr = pack(\r
+                            "LLLLLLLLLLLL", $hdr_SessionID,\r
+                            $new_id,\r
+                            0, 0,\r
+                            $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh,\r
+                            strlen($MessagePayload),\r
+                            0,\r
+                            rand(),\r
+                            0,\r
+                            0, 0\r
+                        );\r
+\r
+                        $message =\r
+                            "MIME-Version: 1.0\r\n".\r
+                            "Content-Type: application/x-msnmsgrp2p\r\n".\r
+                            "P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer";\r
+                        $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
+                        $this->sb_writedata($socket, $message);\r
+                        $this->debug_message("*** p2p: dump 200 ok message:\n".$this->dump_binary($message));\r
+                        $this->sb_readln($socket); // Read ACK;\r
+\r
+                        $this->debug_message("*** p2p: 200 ok:\n".$this->dump_binary($hdr));\r
+                        // send data preparation message\r
+                        // send 4 null bytes as data\r
+                        $hdr_TotalDataSizeLow = 4;\r
+                        $hdr_TotalDataSizeHigh = 0 ;\r
+                        $new_id++;\r
+                        $hdr = pack(\r
+                            "LLLLLLLLLLLL",\r
+                            $MsgBody['SessionID'],\r
+                            $new_id,\r
+                            0, 0,\r
+                            $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh,\r
+                            $hdr_TotalDataSizeLow,\r
+                            0,\r
+                            rand(),\r
+                            0,\r
+                            0, 0\r
+                        );\r
+                        $message =\r
+                            "MIME-Version: 1.0\r\n".\r
+                            "Content-Type: application/x-msnmsgrp2p\r\n".\r
+                            "P2P-Dest: $from_email\r\n\r\n$hdr".pack('L', 0)."$footer";\r
+                        $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
+                        $this->sb_writedata($socket, $message);\r
+                        $this->debug_message("*** p2p: dump send Data preparation message:\n".$this->dump_binary($message));\r
+                        $this->debug_message("*** p2p: Data Prepare Hdr:\n".$this->dump_binary($hdr));\r
+                        $this->sb_readln($socket); // Read ACK;\r
+\r
+                        // send Data Content..\r
+                        $footer=pack('N',1);\r
+                        $new_id++;\r
+                        $FileSize=filesize($PictureFilePath);\r
+                        if ($hTitle=fopen($PictureFilePath,'rb')) {\r
+                            $Offset = 0;\r
+                            //$new_id++;\r
+                            while (!feof($hTitle)) {\r
+                                $FileContent = fread($hTitle, 1024);\r
+                                $FileContentSize = strlen($FileContent);\r
+                                $hdr = pack(\r
+                                    "LLLLLLLLLLLL",\r
+                                    $MsgBody['SessionID'],\r
+                                    $new_id,\r
+                                    $Offset, 0,\r
+                                    $FileSize, 0,\r
+                                    $FileContentSize,\r
+                                    0x20,\r
+                                    rand(),\r
+                                    0,\r
+                                    0, 0\r
+                                );\r
+                                $message =\r
+                                    "MIME-Version: 1.0\r\n".\r
+                                    "Content-Type: application/x-msnmsgrp2p\r\n".\r
+                                    "P2P-Dest: $from_email\r\n\r\n$hdr$FileContent$footer";\r
+                                $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
+                                $this->sb_writedata($socket, $message);\r
+                                $this->debug_message("*** p2p: dump send Data Content message  $Offset / $FileSize :\n".$this->dump_binary($message));\r
+                                $this->debug_message("*** p2p: Data Content Hdr:\n".$this->dump_binary($hdr));\r
+                                //$this->SB_readln($socket);//Read ACK;\r
+                                $Offset += $FileContentSize;\r
+                            }\r
+                        }\r
+                        //Send Bye\r
+                        /*\r
+                        $MessageContent="\r\n".pack("C", 0);\r
+                        $MessagePayload=\r
+                            "BYE MSNMSGR:MSNSLP/1.0\r\n".\r
+                            "To: <msnmsgr:$from_email>\r\n".\r
+                            "From: <msnmsgr:".$this->user.">\r\n".\r
+                            "Via: MSNSLP/1.0/TLP ;branch={".$BranchGUID."}\r\n".\r
+                            "CSeq: 0\r\n".\r
+                            "Call-ID: ".$MsgBody['Call-ID']."\r\n".\r
+                            "Max-Forwards: 0\r\n".\r
+                            "Content-Type: application/x-msnmsgr-sessionclosebody\r\n".\r
+                            "Content-Length: ".strlen($MessageContent)."\r\n\r\n".$MessageContent;\r
+                        $footer=pack('N',0);\r
+                        $hdr_TotalDataSizeLow=strlen($MessagePayload);\r
+                        $hdr_TotalDataSizeHigh=0;\r
+                        $new_id++;\r
+                        $hdr = pack("LLLLLLLLLLLL",\r
+                        0,\r
+                        $new_id,\r
+                        0, 0,\r
+                        $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh,\r
+                        0,\r
+                        0,\r
+                        rand(),\r
+                        0,\r
+                        0,0);\r
+                        $message =\r
+                                    "MIME-Version: 1.0\r\n".\r
+                                    "Content-Type: application/x-msnmsgrp2p\r\n".\r
+                                    "P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer";\r
+                        $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
+                        $id++;\r
+                        $this->sb_writedata($socket, $message);\r
+                        $this->debug_message("*** p2p: dump send BYE message :\n".$this->dump_binary($message));\r
+                        */\r
+                        break;\r
+                    }\r
+                    //TODO:\r
+                    //if ($hdr_Flag == 2) {\r
+                    // just send ACK...\r
+                    //    $this->sb_writeln($socket, $id, "ACK $id");\r
+                    //    break;\r
+                    //}\r
+                    if ($hdr_SessionID == 4) {\r
+                        // ignore?\r
+                        $this->debug_message("*** p2p: ignore flag 4");\r
+                        break;\r
+                    }\r
+                    $finished = false;\r
+                    if ($hdr_TotalDataSizeHigh == 0) {\r
+                        // only 32 bites size\r
+                        if (($hdr_MessageLength + $hdr_DataOffsetLow) == $hdr_TotalDataSizeLow)\r
+                        $finished = true;\r
+                    }\r
+                    else {\r
+                        // we won't accept any file transfer\r
+                        // so I think we won't get any message size need to use 64 bits\r
+                        // 64 bits size here, can't count directly...\r
+                        $totalsize = base_convert(sprintf("%X%08X", $hdr_TotalDataSizeHigh, $hdr_TotalDataSizeLow), 16, 10);\r
+                        $dataoffset = base_convert(sprintf("%X%08X", $hdr_DataOffsetHigh, $hdr_DataOffsetLow), 16, 10);\r
+                        $messagelength = base_convert(sprintf("%X", $hdr_MessageLength), 16, 10);\r
+                        $now_size = bcadd($dataoffset, $messagelength);\r
+                        if (bccomp($now_size, $totalsize) >= 0)\r
+                        $finished = true;\r
+                    }\r
+                    if (!$finished) {\r
+                        // ignore not finished split packet\r
+                        $this->debug_message("*** p2p: ignore split packet, not finished");\r
+                        break;\r
+                    }\r
+                    //$new_id = ~$hdr_Identifier;\r
+                    /*\r
+                     $new_id++;\r
+                     $hdr = pack("LLLLLLLLLLLL", $hdr_SessionID,\r
+                     $new_id,\r
+                     0, 0,\r
+                     $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh,\r
+                     0,\r
+                     2,\r
+                     $hdr_Identifier,\r
+                     $hdr_AckID,\r
+                     $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh);\r
+                     $footer = pack("L", 0);\r
+                     $message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer";\r
+                     $len = strlen($message);\r
+                     $this->sb_writeln($socket, $id, "MSG $id D $len");\r
+                     $id++;\r
+                     $this->sb_writedata($socket, $message);\r
+                     $this->debug_message("*** p2p: send acknowledgement for $hdr_SessionID");\r
+                     $this->debug_message("*** p2p: dump sent message:\n".$this->dump_binary($hdr.$footer));\r
+                     */\r
+                    break;\r
+                }\r
+                $this->debug_message("*** MSG from $from_email: $sMsg");\r
+                $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => 1, 'offline' => false));\r
+                break;\r
+            case '217':\r
+                $this->debug_message('*** User '.$session['to'].' is offline. Trying OIM.');\r
+                $session['offline'] = true;\r
+                break;\r
+            default:\r
+                if (is_numeric($code)) {\r
+                    $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
+                    $this->debug_message("*** SB: $this->error");\r
+                }\r
+                break;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Checks for new data and calls appropriate methods\r
+     *\r
+     * This method is usually called in an infinite loop to keep checking for new data\r
+     *\r
+     * @return void\r
+     */\r
+    public function receive() {\r
+        // First, get an array of sockets that have data that is ready to be read\r
+        $ready = array();\r
+        $ready = $this->getSockets();\r
+        $numrdy = stream_select($ready, $w = NULL, $x = NULL, NULL);\r
+\r
+        // Now that we've waited for something, go through the $ready\r
+        // array and read appropriately\r
+\r
+        foreach ($ready as $socket) {\r
+            if ($socket == $this->NSfp) {\r
+                $this->nsReceive();\r
+            } else {\r
+                $this->sbReceive($socket);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Switchboard related methods\r
+     */\r
+\r
+    /**\r
+     * Send a request for a switchboard session\r
+     *\r
+     * @param string $to Target email for switchboard session\r
+     */\r
+    private function reqSBSession($to) {\r
+        $this->debug_message("*** Request SB for $to");\r
+        $this->ns_writeln("XFR $this->id SB");\r
+\r
+        // Add to the queue of those waiting for a switchboard session reponse\r
+        $this->switchBoardSessions[$to] = array(\r
+            'to' => $to,\r
+            'socket' => NULL,\r
+            'id' => 1,\r
+            'joined' => false,\r
+            'offline' => false,\r
+            'XFRReqTime' => time()\r
+        );\r
+        $this->waitingForXFR[$to] = &$this->switchBoardSessions[$to];\r
+    }\r
+\r
+    /**\r
+     * Following an XFR or RNG, connect to the switchboard session\r
+     *\r
+     * @param string $mode Mode, either 'Active' (in the case of XFR) or 'Passive' (in the case of RNG)\r
+     * @param string $ip IP of Switchboard\r
+     * @param integer $port Port of Switchboard\r
+     * @param string $to User on other end of Switchboard\r
+     * @param array $param Array of parameters - 'cki', 'ticket', 'sid'\r
+     * @return boolean true if successful\r
+     */\r
+    private function connectToSBSession($mode, $ip, $port, $to, $param) {\r
+        $this->debug_message("*** SB: Trying to connect to switchboard server $ip:$port");\r
+\r
+        $socket = @fsockopen($ip, $port, $errno, $errstr, $this->timeout);\r
+        if (!$socket) {\r
+            $this->debug_message("*** SB: Can't connect to $ip:$port, error => $errno, $errstr");\r
+            return false;\r
+        }\r
+\r
+        // Store the socket in the lookup array\r
+        $this->switchBoardSessionLookup[$to] = $socket;\r
+\r
+        // Store the socket in the sessions array\r
+        $this->switchBoardSessions[$to] = array(\r
+            'to' => $to,\r
+            'socket' => $socket,\r
+            'id' => 1,\r
+            'joined' => false,\r
+            'offline' => false,\r
+            'XFRReqTime' => time()\r
+        );\r
+\r
+        // Change the index of the session to the socket\r
+        $intsocket = (int) $socket;\r
+        $this->switchBoardSessions[$intsocket] = $this->switchBoardSessions[$to];\r
+        unset($this->switchBoardSessions[$to]);\r
+\r
+        $id = &$this->switchBoardSessions[$intsocket]['id'];\r
+\r
+        if ($mode == 'Active') {\r
+            $cki_code = $param['cki'];\r
+\r
+            // SB: >>> USR {id} {user} {cki}\r
+            $this->sb_writeln($socket, $id, "USR $id $this->user $cki_code");\r
+        } else {\r
+            // Passive\r
+            $ticket = $param['ticket'];\r
+            $sid = $param['sid'];\r
+\r
+            // SB: >>> ANS {id} {user} {ticket} {session_id}\r
+            $this->sb_writeln($socket, $id, "ANS $id $this->user $ticket $sid");\r
+        }\r
+    }\r
+\r
+    /**\r
+    * Called when we want to end a switchboard session\r
+    * or a switchboard session ends\r
+    *\r
+    * @param resource $socket Socket\r
+    * @param boolean $killsession Whether to delete the session\r
+    * @return void\r
+    */\r
+    private function endSBSession($socket) {\r
+        if (!self::socketcheck($socket)) {\r
+            $this->sb_writeln($socket, $fake = 0, 'OUT');\r
+        }\r
+        @fclose($socket);\r
+\r
+        // Unset session lookup value\r
+        $intsocket = (int) $socket;\r
+        unset($this->switchBoardSessionLookup[$this->switchBoardSessions[$intsocket]['to']]);\r
+\r
+        // Unset session itself\r
+        unset($this->switchBoardSessions[$intsocket]);\r
+    }\r
+\r
+    /**\r
+     * Send a message via an existing SB session\r
+     *\r
+     * @param string $to Recipient for message\r
+     * @param string $message Message\r
+     * @return boolean true on success\r
+     */\r
+    private function sendMessageViaSB($to, $message) {\r
+        $socket = $this->switchBoardSessionLookup[$to];\r
+        if (self::socketcheck($socket)) {\r
+            return false;\r
+        }\r
+\r
+        $id = &$this->switchBoardSessions[(int) $socket]['id'];\r
+\r
+        $aMessage = $this->getMessage($message);\r
+        // CheckEmotion...\r
+        $MsnObjDefine = $this->GetMsnObjDefine($aMessage);\r
+        if ($MsnObjDefine !== '') {\r
+            $SendString = "MIME-Version: 1.0\r\nContent-Type: text/x-mms-emoticon\r\n\r\n$MsnObjDefine";\r
+            $len = strlen($SendString);\r
+\r
+            if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||\r
+                $this->sb_writedata($socket, $SendString) === false) {\r
+                    $this->endSBSession($socket);\r
+                    return false;\r
+                }\r
+        }\r
+        $len = strlen($aMessage);\r
+\r
+        if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||\r
+            $this->sb_writedata($socket, $aMessage) === false) {\r
+                $this->endSBSession($socket);\r
+                return false;\r
+            }\r
+\r
+        // Don't close the SB session, we might as well leave it open\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Send a message to a user on another network\r
+     *\r
+     * @param string $to Intended recipient\r
+     * @param string $message Message\r
+     * @param integer $network Network\r
+     * @return void\r
+     */\r
+    private function sendOtherNetworkMessage($to, $message, $network) {\r
+        $message = $this->getMessage($message, $network);\r
+        $len = strlen($message);\r
+        if ($this->ns_writeln("UUM $this->id $to $network 1 $len") === false ||\r
+            $this->ns_writedata($Message) === false) {\r
+            return false;\r
+        }\r
+        $this->debug_message("*** Sent to $to (network: $network):\n$Message");\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Send a message\r
+     *\r
+     * @param string $to To address in form user@host.com(@network)\r
+     *                   where network is 1 for MSN, 32 for Yahoo\r
+     *                   and 'Offline' for offline messages\r
+     * @param string $message Message\r
+     * @param boolean &$waitForSession Boolean passed by reference,\r
+     *                                 if set to true on return, message\r
+     *                                 did not fail to send but is\r
+     *                                 waiting for a valid session\r
+     *\r
+     * @return boolean true on success\r
+     */\r
+    public function sendMessage($to, $message, &$waitForSession) {\r
+        if ($message != '') {\r
+            $toParts = explode('@', $to);\r
+            if(count($toParts) < 3) {\r
+                list($name, $host) = $toParts;\r
+                $network = 1;\r
+            } else {\r
+                list($name, $host, $network) = $toParts;\r
+            }\r
+\r
+            $recipient = $name.'@'.$host;\r
+\r
+            if ($network === 1) {\r
+                if (!isset($this->switchBoardSessionLookup[$recipient])) {\r
+                    if (!isset($this->switchBoardSessions[$recipient]) || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout) {\r
+                        $this->debug_message("*** No existing SB session or request has timed out");\r
+                        $this->reqSBSession($recipient);\r
+                    }\r
+\r
+                    $waitForSession = true;\r
+                    return false;\r
+                } else {\r
+                    $socket = $this->switchBoardSessionLookup[$recipient];\r
+                    $intsocket = (int) $socket;\r
+                    if ($this->switchBoardSessions[$intsocket]['offline']) {\r
+                        $this->debug_message("*** Contact ($recipient) offline, sending OIM");\r
+                        $this->endSBSession($socket);\r
+                        $waitForSession = false;\r
+                        return $this->sendMessage($recipient.'@Offline', $message);\r
+                    } else {\r
+                        if ($this->switchBoardSessions[$intsocket]['joined'] !== true) {\r
+                            $this->debug_message("*** Recipient has not joined session, returning false");\r
+                            $waitForSession = true;\r
+                            return false;\r
+                        }\r
+\r
+                        $this->debug_message("*** Attempting to send message to $recipient using existing SB session");\r
+\r
+                        if ($this->sendMessageViaSB($recipient, $message)) {\r
+                            $this->debug_message('*** Message sent successfully');\r
+                            return true;\r
+                        }\r
+\r
+                        $waitForSession = false;\r
+                        return false;\r
+                    }\r
+                }\r
+            } elseif ($network == 'Offline') {\r
+                //Send OIM\r
+                //FIXME: ä¿®æ­£Send OIM\r
+                $lockkey = '';\r
+                $re_login = false;\r
+                for ($i = 0; $i < $this->oim_try; $i++) {\r
+                    if (($oim_result = $this->sendOIM($recipient, $message, $lockkey)) === true) break;\r
+                    if (is_array($oim_result) && $oim_result['challenge'] !== false) {\r
+                        // need challenge lockkey\r
+                        $this->debug_message("*** Need challenge code for ".$oim_result['challenge']);\r
+                        $lockkey = $this->getChallenge($oim_result['challenge']);\r
+                        continue;\r
+                    }\r
+                    if ($oim_result === false || $oim_result['auth_policy'] !== false) {\r
+                        if ($re_login) {\r
+                            $this->debug_message("*** Can't send OIM, but we already re-logged-in again, so returning false");\r
+                            return false;\r
+                        }\r
+                        $this->debug_message("*** Can't send OIM, maybe ticket expired, trying to login again");\r
+\r
+                        // Maybe we need to re-login again\r
+                        if (!$this->get_passport_ticket()) {\r
+                            $this->debug_message("*** Can't re-login, something went wrong here, returning false");\r
+                            return false;\r
+                        }\r
+                        $this->debug_message("*** Getting new ticket and trying again");\r
+                        continue;\r
+                    }\r
+                }\r
+                return true;\r
+            } else {\r
+                // Other network\r
+                return $this->sendOtherNetworkMessage($recipient, $message, $network);\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * OIM methods\r
+     */\r
+\r
+    /**\r
+    * Get OIM mail data\r
+    *\r
+    * @return string mail data or false on failure\r
+    */\r
+    function getOIM_maildata() {\r
+        preg_match('#t=(.*)&p=(.*)#', $this->ticket['web_ticket'], $matches);\r
+        if (count($matches) == 0) {\r
+            $this->debug_message('*** No web ticket?');\r
+            return false;\r
+        }\r
+        $t = htmlspecialchars($matches[1]);\r
+        $p = htmlspecialchars($matches[2]);\r
+        $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\r
+<soap:Header>\r
+  <PassportCookie xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">\r
+    <t>'.$t.'</t>\r
+    <p>'.$p.'</p>\r
+  </PassportCookie>\r
+</soap:Header>\r
+<soap:Body>\r
+  <GetMetadata xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi" />\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.self::OIM_MAILDATA_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::OIM_MAILDATA_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::OIM_MAILDATA_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) {\r
+            $this->debug_message("*** Could not get OIM maildata! http code: $http_code");\r
+            return false;\r
+        }\r
+\r
+        // <GetMetadataResponse xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">See #XML_Data</GetMetadataResponse>\r
+        preg_match('#<GetMetadataResponse([^>]*)>(.*)</GetMetadataResponse>#', $data, $matches);\r
+        if (count($matches) == 0) {\r
+            $this->debug_message('*** Could not get OIM maildata');\r
+            return false;\r
+        }\r
+        return $matches[2];\r
+    }\r
+\r
+    /**\r
+    * Fetch OIM message with given id\r
+    *\r
+    * @param string $msgid\r
+    * @return string Message or false on failure\r
+    */\r
+    function getOIM_message($msgid) {\r
+        preg_match('#t=(.*)&p=(.*)#', $this->ticket['web_ticket'], $matches);\r
+        if (count($matches) == 0) {\r
+            $this->debug_message('*** No web ticket?');\r
+            return false;\r
+        }\r
+        $t = htmlspecialchars($matches[1]);\r
+        $p = htmlspecialchars($matches[2]);\r
+\r
+        // read OIM\r
+        $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\r
+<soap:Header>\r
+  <PassportCookie xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">\r
+    <t>'.$t.'</t>\r
+    <p>'.$p.'</p>\r
+  </PassportCookie>\r
+</soap:Header>\r
+<soap:Body>\r
+  <GetMessage xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">\r
+    <messageId>'.$msgid.'</messageId>\r
+    <alsoMarkAsRead>false</alsoMarkAsRead>\r
+  </GetMessage>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.self::OIM_READ_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::OIM_READ_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::OIM_READ_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) {\r
+            $this->debug_message("*** Can't get OIM: $msgid, http code = $http_code");\r
+            return false;\r
+        }\r
+\r
+        // why can't use preg_match('#<GetMessageResult>(.*)</GetMessageResult>#', $data, $matches)?\r
+        // multi-lines?\r
+        $start = strpos($data, '<GetMessageResult>');\r
+        $end = strpos($data, '</GetMessageResult>');\r
+        if ($start === false || $end === false || $start > $end) {\r
+            $this->debug_message("*** Can't get OIM: $msgid");\r
+            return false;\r
+        }\r
+        $lines = substr($data, $start + 18, $end - $start);\r
+        $aLines = @explode("\n", $lines);\r
+        $header = true;\r
+        $ignore = false;\r
+        $sOIM = '';\r
+        foreach ($aLines as $line) {\r
+            $line = rtrim($line);\r
+            if ($header) {\r
+                if ($line === '') {\r
+                    $header = false;\r
+                    continue;\r
+                }\r
+                continue;\r
+            }\r
+            // stop at empty lines\r
+            if ($line === '') break;\r
+            $sOIM .= $line;\r
+        }\r
+        $sMsg = base64_decode($sOIM);\r
+        //$this->debug_message("*** we get OIM ($msgid): $sMsg");\r
+\r
+        // delete OIM\r
+        $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\r
+<soap:Header>\r
+  <PassportCookie xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">\r
+    <t>'.$t.'</t>\r
+    <p>'.$p.'</p>\r
+  </PassportCookie>\r
+</soap:Header>\r
+<soap:Body>\r
+  <DeleteMessages xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi">\r
+    <messageIds>\r
+      <messageId>'.$msgid.'</messageId>\r
+    </messageIds>\r
+  </DeleteMessages>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.self::OIM_DEL_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::OIM_DEL_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::OIM_DEL_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200)\r
+            $this->debug_message("*** Could not delete OIM: $msgid, http code = $http_code");\r
+        else\r
+            $this->debug_message("*** OIM ($msgid) deleted");\r
+        return $sMsg;\r
+    }\r
+\r
+    /**\r
+     * Send offline message\r
+     *\r
+     * @param string $to Intended recipient\r
+     * @param string $sMessage Message\r
+     * @param string $lockkey Lock key\r
+     * @return mixed true on success or error data\r
+     */\r
+    private function sendOIM($to, $sMessage, $lockkey) {\r
+        $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\r
+<soap:Header>\r
+  <From memberName="'.$this->user.'"\r
+        friendlyName="=?utf-8?B?'.base64_encode($this->user).'?="\r
+        xml:lang="zh-TW"\r
+        proxy="MSNMSGR"\r
+        xmlns="http://messenger.msn.com/ws/2004/09/oim/"\r
+        msnpVer="'.self::PROTOCOL.'"\r
+        buildVer="'.self::BUILDVER.'"/>\r
+  <To memberName="'.$to.'" xmlns="http://messenger.msn.com/ws/2004/09/oim/"/>\r
+  <Ticket passport="'.htmlspecialchars($this->ticket['oim_ticket']).'"\r
+          appid="'.self::PROD_ID.'"\r
+          lockkey="'.$lockkey.'"\r
+          xmlns="http://messenger.msn.com/ws/2004/09/oim/"/>\r
+  <Sequence xmlns="http://schemas.xmlsoap.org/ws/2003/03/rm">\r
+    <Identifier xmlns="http://schemas.xmlsoap.org/ws/2002/07/utility">http://messenger.msn.com</Identifier>\r
+    <MessageNumber>1</MessageNumber>\r
+  </Sequence>\r
+</soap:Header>\r
+<soap:Body>\r
+  <MessageType xmlns="http://messenger.msn.com/ws/2004/09/oim/">text</MessageType>\r
+  <Content xmlns="http://messenger.msn.com/ws/2004/09/oim/">MIME-Version: 1.0\r
+Content-Type: text/plain; charset=UTF-8\r
+Content-Transfer-Encoding: base64\r
+X-OIM-Message-Type: OfflineMessage\r
+X-OIM-Run-Id: {DAB68CFA-38C9-449B-945E-38AFA51E50A7}\r
+X-OIM-Sequence-Num: 1\r
+\r
+'.chunk_split(base64_encode($sMessage)).'\r
+  </Content>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.self::OIM_SEND_SOAP,\r
+            'Content-Type: text/xml',\r
+            'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::OIM_SEND_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::OIM_SEND_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code == 200) {\r
+            $this->debug_message("*** OIM sent for $to");\r
+            return true;\r
+        }\r
+\r
+        $challenge = false;\r
+        $auth_policy = false;\r
+        // the lockkey is invalid, authenticated fail, we need challenge it again\r
+        // <LockKeyChallenge xmlns="http://messenger.msn.com/ws/2004/09/oim/">364763969</LockKeyChallenge>\r
+        preg_match("#<LockKeyChallenge (.*)>(.*)</LockKeyChallenge>#", $data, $matches);\r
+        if (count($matches) != 0) {\r
+            // yes, we get new LockKeyChallenge\r
+            $challenge = $matches[2];\r
+            $this->debug_message("*** OIM need new challenge ($challenge) for $to");\r
+        }\r
+        // auth policy error\r
+        // <RequiredAuthPolicy xmlns="http://messenger.msn.com/ws/2004/09/oim/">MBI_SSL</RequiredAuthPolicy>\r
+        preg_match("#<RequiredAuthPolicy (.*)>(.*)</RequiredAuthPolicy>#", $data, $matches);\r
+        if (count($matches) != 0) {\r
+            $auth_policy = $matches[2];\r
+            $this->debug_message("*** OIM need new auth policy ($auth_policy) for $to");\r
+        }\r
+        if ($auth_policy === false && $challenge === false) {\r
+            //<faultcode xmlns:q0="http://messenger.msn.com/ws/2004/09/oim/">q0:AuthenticationFailed</faultcode>\r
+            preg_match("#<faultcode (.*)>(.*)</faultcode>#", $data, $matches);\r
+            if (count($matches) == 0) {\r
+                // no error, we assume the OIM is sent\r
+                $this->debug_message("*** OIM sent for $to");\r
+                return true;\r
+            }\r
+            $err_code = $matches[2];\r
+            //<faultstring>Exception of type 'System.Web.Services.Protocols.SoapException' was thrown.</faultstring>\r
+            preg_match("#<faultstring>(.*)</faultstring>#", $data, $matches);\r
+            if (count($matches) > 0)\r
+                $err_msg = $matches[1];\r
+            else\r
+                $err_msg = '';\r
+            $this->debug_message("*** OIM failed for $to");\r
+            $this->debug_message("*** OIM Error code: $err_code");\r
+            $this->debug_message("*** OIM Error Message: $err_msg");\r
+            return false;\r
+        }\r
+        return array('challenge' => $challenge, 'auth_policy' => $auth_policy);\r
+    }\r
+\r
+    /**\r
+     * Contact / Membership list methods\r
+     */\r
+\r
+    /**\r
+    * Fetch contact list\r
+    *\r
+    * @return boolean true on success\r
+    */\r
+    private function UpdateContacts() {\r
+        $ABApplicationHeaderArray = array(\r
+            'ABApplicationHeader' => array(\r
+                ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'),\r
+                'ApplicationId' => 'CFE80F9D-180F-4399-82AB-413F33A1FA11',\r
+                'IsMigration' => false,\r
+                'PartnerScenario' => 'ContactSave'\r
+             )\r
+        );\r
+\r
+        $ABApplicationHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABApplicationHeader', $this->Array2SoapVar($ABApplicationHeaderArray));\r
+        $ABFindAllArray = array(\r
+            'ABFindAll' => array(\r
+                ':' => array('xmlns'=>'http://www.msn.com/webservices/AddressBook'),\r
+                'abId' => '00000000-0000-0000-0000-000000000000',\r
+                'abView' => 'Full',\r
+                'lastChange' => '0001-01-01T00:00:00.0000000-08:00',\r
+            )\r
+        );\r
+        $ABFindAll = new SoapParam($this->Array2SoapVar($ABFindAllArray), 'ABFindAll');\r
+        $this->ABService->__setSoapHeaders(array($ABApplicationHeader, $this->ABAuthHeader));\r
+        $this->Contacts = array();\r
+        try {\r
+            $this->debug_message('*** Updating Contacts...');\r
+            $Result = $this->ABService->ABFindAll($ABFindAll);\r
+            $this->debug_message("*** Result:\n".print_r($Result, true)."\n".$this->ABService->__getLastResponse());\r
+            foreach($Result->ABFindAllResult->contacts->Contact as $Contact)\r
+                $this->Contacts[$Contact->contactInfo->passportName] = $Contact;\r
+        } catch(Exception $e) {\r
+            $this->debug_message("*** Update Contacts Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage());\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Add contact\r
+    *\r
+    * @param string $email\r
+    * @param integer $network\r
+    * @param string $display\r
+    * @param boolean $sendADL\r
+    * @return boolean true on success\r
+    */\r
+    private function addContact($email, $network, $display = '', $sendADL = false) {\r
+        if ($network != 1) return true;\r
+        if (isset($this->Contacts[$email])) return true;\r
+\r
+        $ABContactAddArray = array(\r
+            'ABContactAdd' => array(\r
+                ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'),\r
+                'abId' => '00000000-0000-0000-0000-000000000000',\r
+                'contacts' => array(\r
+                    'Contact' => array(\r
+                        ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'),\r
+                        'contactInfo' => array(\r
+                            'contactType' => 'LivePending',\r
+                            'passportName' => $email,\r
+                            'isMessengerUser' => true,\r
+                            'MessengerMemberInfo' => array(\r
+                                'DisplayName' => $email\r
+                            )\r
+                        )\r
+                    )\r
+                ),\r
+                'options' => array(\r
+                    'EnableAllowListManagement' => true\r
+                )\r
+            )\r
+        );\r
+        $ABContactAdd = new SoapParam($this->Array2SoapVar($ABContactAddArray), 'ABContactAdd');\r
+        try {\r
+            $this->debug_message("*** Adding Contact $email...");\r
+            $this->ABService->ABContactAdd($ABContactAdd);\r
+        } catch(Exception $e) {\r
+            $this->debug_message("*** Add Contact Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage());\r
+            return false;\r
+        }\r
+        if ($sendADL && !feof($this->NSfp)) {\r
+            @list($u_name, $u_domain) = @explode('@', $email);\r
+            foreach (array('1', '2') as $l) {\r
+                $str = '<ml l="1"><d n="'.$u_domain.'"><c n="'.$u_name.'" l="'.$l.'" t="'.$network.'" /></d></ml>';\r
+                $len = strlen($str);\r
+                // NS: >>> ADL {id} {size}\r
+                $this->ns_writeln("ADL $this->id $len");\r
+                $this->ns_writedata($str);\r
+            }\r
+        }\r
+        $this->UpdateContacts();\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Remove contact from list\r
+    *\r
+    * @param integer $memberID\r
+    * @param string $email\r
+    * @param integer $network\r
+    * @param string $list\r
+    */\r
+    function delMemberFromList($memberID, $email, $network, $list) {\r
+        if ($network != 1 && $network != 32) return true;\r
+        if ($memberID === false) return true;\r
+        $user = $email;\r
+        $ticket = htmlspecialchars($this->ticket['contact_ticket']);\r
+        if ($network == 1)\r
+            $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"\r
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">\r
+<soap:Header>\r
+    <ABApplicationHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ApplicationId>996CDE1E-AA53-4477-B943-2BE802EA6166</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>ContactMsgrAPI</PartnerScenario>\r
+    </ABApplicationHeader>\r
+    <ABAuthHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ManagedGroupRequest>false</ManagedGroupRequest>\r
+        <TicketToken>'.$ticket.'</TicketToken>\r
+    </ABAuthHeader>\r
+</soap:Header>\r
+<soap:Body>\r
+    <DeleteMember xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <serviceHandle>\r
+            <Id>0</Id>\r
+            <Type>Messenger</Type>\r
+            <ForeignId></ForeignId>\r
+        </serviceHandle>\r
+        <memberships>\r
+            <Membership>\r
+                <MemberRole>'.$list.'</MemberRole>\r
+                <Members>\r
+                    <Member xsi:type="PassportMember" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+                        <Type>Passport</Type>\r
+                        <MembershipId>'.$memberID.'</MembershipId>\r
+                        <State>Accepted</State>\r
+                    </Member>\r
+                </Members>\r
+            </Membership>\r
+        </memberships>\r
+    </DeleteMember>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+        else\r
+            $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"\r
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">\r
+<soap:Header>\r
+    <ABApplicationHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ApplicationId>996CDE1E-AA53-4477-B943-2BE802EA6166</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>ContactMsgrAPI</PartnerScenario>\r
+    </ABApplicationHeader>\r
+    <ABAuthHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ManagedGroupRequest>false</ManagedGroupRequest>\r
+        <TicketToken>'.$ticket.'</TicketToken>\r
+    </ABAuthHeader>\r
+</soap:Header>\r
+<soap:Body>\r
+    <DeleteMember xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <serviceHandle>\r
+            <Id>0</Id>\r
+            <Type>Messenger</Type>\r
+            <ForeignId></ForeignId>\r
+        </serviceHandle>\r
+        <memberships>\r
+            <Membership>\r
+                <MemberRole>'.$list.'</MemberRole>\r
+                <Members>\r
+                    <Member xsi:type="EmailMember" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+                        <Type>Email</Type>\r
+                        <MembershipId>'.$memberID.'</MembershipId>\r
+                        <State>Accepted</State>\r
+                    </Member>\r
+                </Members>\r
+            </Membership>\r
+        </memberships>\r
+    </DeleteMember>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.self::DELMEMBER_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::DELMEMBER_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::DELMEMBER_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) {\r
+            preg_match('#<faultcode>(.*)</faultcode><faultstring>(.*)</faultstring>#', $data, $matches);\r
+            if (count($matches) == 0) {\r
+                $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list");\r
+                return false;\r
+            }\r
+            $faultcode = trim($matches[1]);\r
+            $faultstring = trim($matches[2]);\r
+            if (strcasecmp($faultcode, 'soap:Client') || stripos($faultstring, 'Member does not exist') === false) {\r
+                $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list, error code: $faultcode, $faultstring");\r
+                return false;\r
+            }\r
+            $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list, not present in list");\r
+            return true;\r
+        }\r
+        $this->debug_message("*** Member successfully deleted (network: $network) $email ($memberID) from $list list");\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Add contact to list\r
+    *\r
+    * @param string $email\r
+    * @param integer $network\r
+    * @param string $list\r
+    */\r
+    function addMemberToList($email, $network, $list) {\r
+        if ($network != 1 && $network != 32) return true;\r
+        $ticket = htmlspecialchars($this->ticket['contact_ticket']);\r
+        $user = $email;\r
+\r
+        if ($network == 1)\r
+            $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"\r
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">\r
+<soap:Header>\r
+    <ABApplicationHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ApplicationId>996CDE1E-AA53-4477-B943-2BE802EA6166</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>ContactMsgrAPI</PartnerScenario>\r
+    </ABApplicationHeader>\r
+    <ABAuthHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ManagedGroupRequest>false</ManagedGroupRequest>\r
+        <TicketToken>'.$ticket.'</TicketToken>\r
+    </ABAuthHeader>\r
+</soap:Header>\r
+<soap:Body>\r
+    <AddMember xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <serviceHandle>\r
+            <Id>0</Id>\r
+            <Type>Messenger</Type>\r
+            <ForeignId></ForeignId>\r
+        </serviceHandle>\r
+        <memberships>\r
+            <Membership>\r
+                <MemberRole>'.$list.'</MemberRole>\r
+                <Members>\r
+                    <Member xsi:type="PassportMember" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+                        <Type>Passport</Type>\r
+                        <State>Accepted</State>\r
+                        <PassportName>'.$user.'</PassportName>\r
+                    </Member>\r
+                </Members>\r
+            </Membership>\r
+        </memberships>\r
+    </AddMember>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+        else\r
+            $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"\r
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">\r
+<soap:Header>\r
+    <ABApplicationHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ApplicationId>996CDE1E-AA53-4477-B943-2BE802EA6166</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>ContactMsgrAPI</PartnerScenario>\r
+    </ABApplicationHeader>\r
+    <ABAuthHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ManagedGroupRequest>false</ManagedGroupRequest>\r
+        <TicketToken>'.$ticket.'</TicketToken>\r
+    </ABAuthHeader>\r
+</soap:Header>\r
+<soap:Body>\r
+    <AddMember xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <serviceHandle>\r
+            <Id>0</Id>\r
+            <Type>Messenger</Type>\r
+            <ForeignId></ForeignId>\r
+        </serviceHandle>\r
+        <memberships>\r
+            <Membership>\r
+                <MemberRole>'.$list.'</MemberRole>\r
+                <Members>\r
+                    <Member xsi:type="EmailMember" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+                        <Type>Email</Type>\r
+                        <State>Accepted</State>\r
+                        <Email>'.$user.'</Email>\r
+                        <Annotations>\r
+                            <Annotation>\r
+                                <Name>MSN.IM.BuddyType</Name>\r
+                                <Value>32:YAHOO</Value>\r
+                            </Annotation>\r
+                        </Annotations>\r
+                    </Member>\r
+                </Members>\r
+            </Membership>\r
+        </memberships>\r
+    </AddMember>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+        $header_array = array(\r
+            'SOAPAction: '.self::ADDMEMBER_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
+        );\r
+\r
+        $this->debug_message('*** URL: '.self::ADDMEMBER_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::ADDMEMBER_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) {\r
+            preg_match('#<faultcode>(.*)</faultcode><faultstring>(.*)</faultstring>#', $data, $matches);\r
+            if (count($matches) == 0) {\r
+                $this->debug_message("*** Could not add member (network: $network) $email to $list list");\r
+                return false;\r
+            }\r
+            $faultcode = trim($matches[1]);\r
+            $faultstring = trim($matches[2]);\r
+            if (strcasecmp($faultcode, 'soap:Client') || stripos($faultstring, 'Member already exists') === false) {\r
+                $this->debug_message("*** Could not add member (network: $network) $email to $list list, error code: $faultcode, $faultstring");\r
+                return false;\r
+            }\r
+            $this->debug_message("*** Could not add member (network: $network) $email to $list list, already present");\r
+            return true;\r
+        }\r
+        $this->debug_message("*** Member successfully added (network: $network) $email to $list list");\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Get membership lists\r
+    *\r
+    * @param mixed $returnData Membership list or false on failure\r
+    */\r
+    function getMembershipList($returnData = false) {\r
+        $ticket = htmlspecialchars($this->ticket['contact_ticket']);\r
+        $XML = '<?xml version="1.0" encoding="utf-8"?>\r
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"\r
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+               xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">\r
+<soap:Header>\r
+    <ABApplicationHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ApplicationId>996CDE1E-AA53-4477-B943-2BE802EA6166</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>Initial</PartnerScenario>\r
+    </ABApplicationHeader>\r
+    <ABAuthHeader xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <ManagedGroupRequest>false</ManagedGroupRequest>\r
+        <TicketToken>'.$ticket.'</TicketToken>\r
+    </ABAuthHeader>\r
+</soap:Header>\r
+<soap:Body>\r
+    <FindMembership xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <serviceFilter>\r
+            <Types>\r
+                <ServiceType>Messenger</ServiceType>\r
+                <ServiceType>Invitation</ServiceType>\r
+                <ServiceType>SocialNetwork</ServiceType>\r
+                <ServiceType>Space</ServiceType>\r
+                <ServiceType>Profile</ServiceType>\r
+            </Types>\r
+        </serviceFilter>\r
+    </FindMembership>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+        $header_array = array(\r
+            'SOAPAction: '.self::MEMBERSHIP_SOAP,\r
+            'Content-Type: text/xml; charset=utf-8',\r
+            'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
+        );\r
+        $this->debug_message('*** URL: '.self::MEMBERSHIP_URL);\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, self::MEMBERSHIP_URL);\r
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) return false;\r
+        $p = $data;\r
+        $aMemberships = array();\r
+        while (1) {\r
+            //$this->debug_message("search p = $p");\r
+            $start = strpos($p, '<Membership>');\r
+            $end = strpos($p, '</Membership>');\r
+            if ($start === false || $end === false || $start > $end) break;\r
+            //$this->debug_message("start = $start, end = $end");\r
+            $end += 13;\r
+            $sMembership = substr($p, $start, $end - $start);\r
+            $aMemberships[] = $sMembership;\r
+            //$this->debug_message("add sMembership = $sMembership");\r
+            $p = substr($p, $end);\r
+        }\r
+        //$this->debug_message("aMemberships = ".var_export($aMemberships, true));\r
+\r
+        $aContactList = array();\r
+        foreach ($aMemberships as $sMembership) {\r
+            //$this->debug_message("sMembership = $sMembership");\r
+            if (isset($matches)) unset($matches);\r
+            preg_match('#<MemberRole>(.*)</MemberRole>#', $sMembership, $matches);\r
+            if (count($matches) == 0) continue;\r
+            $sMemberRole = $matches[1];\r
+            //$this->debug_message("MemberRole = $sMemberRole");\r
+            if ($sMemberRole != 'Allow' && $sMemberRole != 'Reverse' && $sMemberRole != 'Pending') continue;\r
+            $p = $sMembership;\r
+            if (isset($aMembers)) unset($aMembers);\r
+            $aMembers = array();\r
+            while (1) {\r
+                //$this->debug_message("search p = $p");\r
+                $start = strpos($p, '<Member xsi:type="');\r
+                $end = strpos($p, '</Member>');\r
+                if ($start === false || $end === false || $start > $end) break;\r
+                //$this->debug_message("start = $start, end = $end");\r
+                $end += 9;\r
+                $sMember = substr($p, $start, $end - $start);\r
+                $aMembers[] = $sMember;\r
+                //$this->debug_message("add sMember = $sMember");\r
+                $p = substr($p, $end);\r
+            }\r
+            //$this->debug_message("aMembers = ".var_export($aMembers, true));\r
+            foreach ($aMembers as $sMember) {\r
+                //$this->debug_message("sMember = $sMember");\r
+                if (isset($matches)) unset($matches);\r
+                preg_match('#<Member xsi\:type="([^"]*)">#', $sMember, $matches);\r
+                if (count($matches) == 0) continue;\r
+                $sMemberType = $matches[1];\r
+                //$this->debug_message("MemberType = $sMemberType");\r
+                $network = -1;\r
+                preg_match('#<MembershipId>(.*)</MembershipId>#', $sMember, $matches);\r
+                if (count($matches) == 0) continue;\r
+                $id = $matches[1];\r
+                if ($sMemberType == 'PassportMember') {\r
+                    if (strpos($sMember, '<Type>Passport</Type>') === false) continue;\r
+                    $network = 1;\r
+                    preg_match('#<PassportName>(.*)</PassportName>#', $sMember, $matches);\r
+                }\r
+                else if ($sMemberType == 'EmailMember') {\r
+                    if (strpos($sMember, '<Type>Email</Type>') === false) continue;\r
+                    // Value is 32: or 32:YAHOO\r
+                    preg_match('#<Annotation><Name>MSN.IM.BuddyType</Name><Value>(.*):(.*)</Value></Annotation>#', $sMember, $matches);\r
+                    if (count($matches) == 0) continue;\r
+                    if ($matches[1] != 32) continue;\r
+                    $network = 32;\r
+                    preg_match('#<Email>(.*)</Email>#', $sMember, $matches);\r
+                }\r
+                if ($network == -1) continue;\r
+                if (count($matches) > 0) {\r
+                    $email = $matches[1];\r
+                    @list($u_name, $u_domain) = @explode('@', $email);\r
+                    if ($u_domain == NULL) continue;\r
+                    $aContactList[$u_domain][$u_name][$network][$sMemberRole] = $id;\r
+                    $this->debug_message("*** Adding new contact (network: $network, status: $sMemberRole): $u_name@$u_domain ($id)");\r
+                }\r
+            }\r
+        }\r
+        return $aContactList;\r
+    }\r
+\r
+    /**\r
+     * MsnObj related methods\r
+     */\r
+\r
+    /**\r
+     *\r
+     * @param $FilePath åœ–檔路徑\r
+     * @param $Type     æª”案類型 3=>大頭貼,2表情圖案\r
+     * @return array\r
+     */\r
+    private function MsnObj($FilePath, $Type = 3) {\r
+        if (!($FileSize=filesize($FilePath))) return '';\r
+        $Location = md5($FilePath);\r
+        $Friendly = md5($FilePath.$Type);\r
+        if (isset($this->MsnObjMap[$Location])) return $this->MsnObjMap[$Location];\r
+        $sha1d = base64_encode(sha1(file_get_contents($FilePath), true));\r
+        $sha1c = base64_encode(sha1("Creator".$this->user."Size$FileSize"."Type$Type"."Location$Location"."Friendly".$Friendly."SHA1D$sha1d", true));\r
+        $this->MsnObjArray[$Location] = $FilePath;\r
+        $MsnObj = '<msnobj Creator="'.$this->user.'" Size="'.$FileSize.'" Type="'.$Type.'" Location="'.$Location.'" Friendly="'.$Friendly.'" SHA1D="'.$sha1d.'" SHA1C="'.$sha1c.'"/>';\r
+        $this->MsnObjMap[$Location] = $MsnObj;\r
+        $this->debug_message("*** p2p: addMsnObj $FilePath::$MsnObj\n");\r
+        return $MsnObj;\r
+    }\r
+\r
+    private function GetPictureFilePath($Context) {\r
+        $MsnObj = base64_decode($Context);\r
+        if (preg_match('/location="(.*?)"/i', $MsnObj, $Match))\r
+            $location = $Match[1];\r
+        $this->debug_message("*** p2p: PictureFile[$location] ::All".print_r($this->MsnObjArray,true)."\n");\r
+        if ($location && isset($this->MsnObjArray[$location]))\r
+            return $this->MsnObjArray[$location];\r
+        return false;\r
+    }\r
+\r
+    private function GetMsnObjDefine($Message) {\r
+        $DefineString = '';\r
+        if (is_array($this->Emotions))\r
+            foreach ($this->Emotions as $Pattern => $FilePath) {\r
+                if (strpos($Message, $Pattern) !== false)\r
+                $DefineString .= "$Pattern\t".$this->MsnObj($FilePath, 2)."\t";\r
+            }\r
+        return $DefineString;\r
+    }\r
+\r
+    /**\r
+     * Socket methods\r
+     */\r
+\r
+    /**\r
+     * Read data of specified size from NS socket\r
+     *\r
+     * @param integer $size Size to read\r
+     * @return string Data read\r
+     */\r
+    private function ns_readdata($size) {\r
+        $data = '';\r
+        $count = 0;\r
+        while (!feof($this->NSfp)) {\r
+            $buf = @fread($this->NSfp, $size - $count);\r
+            $data .= $buf;\r
+            $count += strlen($buf);\r
+            if ($count >= $size) break;\r
+        }\r
+        $this->debug_message("NS: data ($size/$count) <<<\n$data");\r
+        return $data;\r
+    }\r
+\r
+    /**\r
+     * Read line from the NS socket\r
+     *\r
+     * @return string Data read\r
+     */\r
+    private function ns_readln() {\r
+        $data = @fgets($this->NSfp, 4096);\r
+        if ($data !== false) {\r
+            $data = trim($data);\r
+            $this->debug_message("NS: <<< $data");\r
+        }\r
+        return $data;\r
+    }\r
+\r
+    /**\r
+     * Write line to NS socket\r
+     *\r
+     * Also increments id\r
+     *\r
+     * @param string $data Line to write to socket\r
+     * @return mixed Bytes written or false on failure\r
+     */\r
+    private function ns_writeln($data) {\r
+        $result = @fwrite($this->NSfp, $data."\r\n");\r
+        if ($result !== false) {\r
+            $this->debug_message("NS: >>> $data");\r
+            $this->id++;\r
+        }\r
+        return $result;\r
+    }\r
+\r
+    /**\r
+     * Write data to NS socket\r
+     *\r
+     * @param string $data Data to write to socket\r
+     * @return mixed Bytes written or false on failure\r
+     */\r
+    private function ns_writedata($data) {\r
+        $result = @fwrite($this->NSfp, $data);\r
+        if ($result !== false) {\r
+            $this->debug_message("NS: >>> $data");\r
+        }\r
+        return $result;\r
+    }\r
+\r
+    /**\r
+     * Read data of specified size from given SB socket\r
+     *\r
+     * @param resource $socket SB socket\r
+     * @param integer $size Size to read\r
+     * @return string Data read\r
+     */\r
+    private function sb_readdata($socket, $size) {\r
+        $data = '';\r
+        $count = 0;\r
+        while (!feof($socket)) {\r
+            $buf = @fread($socket, $size - $count);\r
+            $data .= $buf;\r
+            $count += strlen($buf);\r
+            if ($count >= $size) break;\r
+        }\r
+        $this->debug_message("SB: data ($size/$count) <<<\n$data");\r
+        return $data;\r
+    }\r
+\r
+    /**\r
+     * Read line from given SB socket\r
+     *\r
+     * @param resource $socket SB Socket\r
+     * @return string Line read\r
+     */\r
+    private function sb_readln($socket) {\r
+        $data = @fgets($socket, 4096);\r
+        if ($data !== false) {\r
+            $data = trim($data);\r
+            $this->debug_message("SB: <<< $data");\r
+        }\r
+        return $data;\r
+    }\r
+\r
+    /**\r
+     * Write line to given SB socket\r
+     *\r
+     * Also increments id\r
+     *\r
+     * @param resource $socket SB socket\r
+     * @param integer $id Reference to SB id\r
+     * @param string $data Line to write\r
+     * @return mixed Bytes written or false on error\r
+     */\r
+    private function sb_writeln($socket, &$id, $data) {\r
+        $result = @fwrite($socket, $data."\r\n");\r
+        if ($result !== false) {\r
+            $this->debug_message("SB: >>> $data");\r
+            $id++;\r
+        }\r
+        return $result;\r
+    }\r
+\r
+    /**\r
+     * Write data to given SB socket\r
+     *\r
+     * @param resource $socket SB socket\r
+     * @param $data Data to write to socket\r
+     * @return mixed Bytes written or false on error\r
+     */\r
+    private function sb_writedata($socket, $data) {\r
+        $result = @fwrite($socket, $data);\r
+        if ($result !== false) {\r
+            $this->debug_message("SB: >>> $data");\r
+        }\r
+        return $result;\r
+    }\r
+\r
+    /**\r
+     * Get all the sockets currently in use\r
+     *\r
+     * @return array Array of socket resources\r
+     */\r
+    public function getSockets() {\r
+        return array_merge(array($this->NSfp), $this->switchBoardSessionLookup);\r
+    }\r
+\r
+    /**\r
+     * Checks socket for end of file\r
+     *\r
+     * @param resource $socket Socket to check\r
+     * @return boolean true if end of file (socket)\r
+     */\r
+    private static function socketcheck($socket){\r
+        $info = stream_get_meta_data($socket);\r
+        return $info['eof'];\r
+    }\r
+\r
+    /**\r
+     * Key generation methods\r
+     */\r
+\r
+    private function derive_key($key, $magic) {\r
+        $hash1 = mhash(MHASH_SHA1, $magic, $key);\r
+        $hash2 = mhash(MHASH_SHA1, $hash1.$magic, $key);\r
+        $hash3 = mhash(MHASH_SHA1, $hash1, $key);\r
+        $hash4 = mhash(MHASH_SHA1, $hash3.$magic, $key);\r
+        return $hash2.substr($hash4, 0, 4);\r
+    }\r
+\r
+    private function generateLoginBLOB($key, $challenge) {\r
+        $key1 = base64_decode($key);\r
+        $key2 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY HASH');\r
+        $key3 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY ENCRYPTION');\r
+\r
+        // get hash of challenge using key2\r
+        $hash = mhash(MHASH_SHA1, $challenge, $key2);\r
+\r
+        // get 8 bytes random data\r
+        $iv = substr(base64_encode(rand(1000,9999).rand(1000,9999)), 2, 8);\r
+\r
+        $cipher = mcrypt_cbc(MCRYPT_3DES, $key3, $challenge."\x08\x08\x08\x08\x08\x08\x08\x08", MCRYPT_ENCRYPT, $iv);\r
+\r
+        $blob = pack('LLLLLLL', 28, 1, 0x6603, 0x8004, 8, 20, 72);\r
+        $blob .= $iv;\r
+        $blob .= $hash;\r
+        $blob .= $cipher;\r
+\r
+        return base64_encode($blob);\r
+    }\r
+\r
+    /**\r
+    * Generate challenge response\r
+    *\r
+    * @param string $code\r
+    * @return string challenge response code\r
+    */\r
+    private function getChallenge($code) {\r
+        // MSNP15\r
+        // http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges\r
+        // Step 1: The MD5 Hash\r
+        $md5Hash = md5($code.self::PROD_KEY);\r
+        $aMD5 = @explode("\0", chunk_split($md5Hash, 8, "\0"));\r
+        for ($i = 0; $i < 4; $i++) {\r
+            $aMD5[$i] = implode('', array_reverse(@explode("\0", chunk_split($aMD5[$i], 2, "\0"))));\r
+            $aMD5[$i] = (0 + base_convert($aMD5[$i], 16, 10)) & 0x7FFFFFFF;\r
+        }\r
+\r
+        // Step 2: A new string\r
+        $chl_id = $code.self::PROD_ID;\r
+        $chl_id .= str_repeat('0', 8 - (strlen($chl_id) % 8));\r
+\r
+        $aID = @explode("\0", substr(chunk_split($chl_id, 4, "\0"), 0, -1));\r
+        for ($i = 0; $i < count($aID); $i++) {\r
+            $aID[$i] = implode('', array_reverse(@explode("\0", chunk_split($aID[$i], 1, "\0"))));\r
+            $aID[$i] = 0 + base_convert(bin2hex($aID[$i]), 16, 10);\r
+        }\r
+\r
+        // Step 3: The 64 bit key\r
+        $magic_num = 0x0E79A9C1;\r
+        $str7f = 0x7FFFFFFF;\r
+        $high = 0;\r
+        $low = 0;\r
+        for ($i = 0; $i < count($aID); $i += 2) {\r
+            $temp = $aID[$i];\r
+            $temp = bcmod(bcmul($magic_num, $temp), $str7f);\r
+            $temp = bcadd($temp, $high);\r
+            $temp = bcadd(bcmul($aMD5[0], $temp), $aMD5[1]);\r
+            $temp = bcmod($temp, $str7f);\r
+\r
+            $high = $aID[$i+1];\r
+            $high = bcmod(bcadd($high, $temp), $str7f);\r
+            $high = bcadd(bcmul($aMD5[2], $high), $aMD5[3]);\r
+            $high = bcmod($high, $str7f);\r
+\r
+            $low = bcadd(bcadd($low, $high), $temp);\r
+        }\r
+\r
+        $high = bcmod(bcadd($high, $aMD5[1]), $str7f);\r
+        $low = bcmod(bcadd($low, $aMD5[3]), $str7f);\r
+\r
+        $new_high = bcmul($high & 0xFF, 0x1000000);\r
+        $new_high = bcadd($new_high, bcmul($high & 0xFF00, 0x100));\r
+        $new_high = bcadd($new_high, bcdiv($high & 0xFF0000, 0x100));\r
+        $new_high = bcadd($new_high, bcdiv($high & 0xFF000000, 0x1000000));\r
+        // we need integer here\r
+        $high = 0+$new_high;\r
+\r
+        $new_low = bcmul($low & 0xFF, 0x1000000);\r
+        $new_low = bcadd($new_low, bcmul($low & 0xFF00, 0x100));\r
+        $new_low = bcadd($new_low, bcdiv($low & 0xFF0000, 0x100));\r
+        $new_low = bcadd($new_low, bcdiv($low & 0xFF000000, 0x1000000));\r
+        // we need integer here\r
+        $low = 0+$new_low;\r
+\r
+        // we just use 32 bits integer, don't need the key, just high/low\r
+        // $key = bcadd(bcmul($high, 0x100000000), $low);\r
+\r
+        // Step 4: Using the key\r
+        $md5Hash = md5($code.self::PROD_KEY);\r
+        $aHash = @explode("\0", chunk_split($md5Hash, 8, "\0"));\r
+\r
+        $hash = '';\r
+        $hash .= sprintf("%08x", (0 + base_convert($aHash[0], 16, 10)) ^ $high);\r
+        $hash .= sprintf("%08x", (0 + base_convert($aHash[1], 16, 10)) ^ $low);\r
+        $hash .= sprintf("%08x", (0 + base_convert($aHash[2], 16, 10)) ^ $high);\r
+        $hash .= sprintf("%08x", (0 + base_convert($aHash[3], 16, 10)) ^ $low);\r
+\r
+        return $hash;\r
+    }\r
+\r
+    /**\r
+     * Utility methods\r
+     */\r
+\r
+    private function Array2SoapVar($Array, $ReturnSoapVarObj = true, $TypeName = null, $TypeNameSpace = null) {\r
+        $ArrayString = '';\r
+        foreach($Array as $Key => $Val) {\r
+            if ($Key{0} == ':') continue;\r
+            $Attrib = '';\r
+            if (is_array($Val[':'])) {\r
+                foreach ($Val[':'] as $AttribName => $AttribVal)\r
+                    $Attrib .= " $AttribName = '$AttribVal'";\r
+            }\r
+            if ($Key{0} == '!') {\r
+                //List Type Define\r
+                $Key = substr($Key,1);\r
+                foreach ($Val as $ListKey => $ListVal) {\r
+                    if ($ListKey{0} == ':') continue;\r
+                    if (is_array($ListVal)) $ListVal = $this->Array2SoapVar($ListVal, false);\r
+                    elseif (is_bool($ListVal)) $ListVal = $ListVal ? 'true' : 'false';\r
+                    $ArrayString .= "<$Key$Attrib>$ListVal</$Key>";\r
+                }\r
+                continue;\r
+            }\r
+            if (is_array($Val)) $Val = $this->Array2SoapVar($Val, false);\r
+            elseif (is_bool($Val)) $Val = $Val ? 'true' : 'false';\r
+            $ArrayString .= "<$Key$Attrib>$Val</$Key>";\r
+        }\r
+        if ($ReturnSoapVarObj) return new SoapVar($ArrayString, XSD_ANYXML, $TypeName, $TypeNameSpace);\r
+        return $ArrayString;\r
+    }\r
+\r
+    private function linetoArray($lines) {\r
+        $lines = str_replace("\r", '', $lines);\r
+        $lines = explode("\n", $lines);\r
+        foreach ($lines as $line) {\r
+            if (!isset($line{3})) continue;\r
+            list($Key, $Val) = explode(':', $line);\r
+            $Data[trim($Key)] = trim($Val);\r
+        }\r
+        return $Data;\r
+    }\r
+\r
+    /**\r
+    * Get Passport ticket\r
+    *\r
+    * @param string $url URL string (Optional)\r
+    * @return mixed Array of tickets or false on failure\r
+    */\r
+    private function get_passport_ticket($url = '') {\r
+        $user = $this->user;\r
+        $password = htmlspecialchars($this->password);\r
+\r
+        if ($url === '')\r
+            $passport_url = self::PASSPORT_URL;\r
+        else\r
+            $passport_url = $url;\r
+\r
+        $XML = '<?xml version="1.0" encoding="UTF-8"?>\r
+<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"\r
+          xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"\r
+          xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"\r
+          xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"\r
+          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"\r
+          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"\r
+          xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc"\r
+          xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">\r
+<Header>\r
+  <ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">\r
+    <ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>\r
+    <ps:BinaryVersion>4</ps:BinaryVersion>\r
+    <ps:UIVersion>1</ps:UIVersion>\r
+    <ps:Cookies></ps:Cookies>\r
+    <ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>\r
+  </ps:AuthInfo>\r
+  <wsse:Security>\r
+    <wsse:UsernameToken Id="user">\r
+      <wsse:Username>'.$user.'</wsse:Username>\r
+      <wsse:Password>'.$password.'</wsse:Password>\r
+    </wsse:UsernameToken>\r
+  </wsse:Security>\r
+</Header>\r
+<Body>\r
+  <ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">\r
+    <wst:RequestSecurityToken Id="RST0">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>http://Passport.NET/tb</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST1">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>messengerclear.live.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="'.$this->passport_policy.'"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST2">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>messenger.msn.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="?id=507"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST3">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>contacts.msn.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST4">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>messengersecure.live.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="MBI_SSL"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST5">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>spaces.live.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+    <wst:RequestSecurityToken Id="RST6">\r
+      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>\r
+      <wsp:AppliesTo>\r
+        <wsa:EndpointReference>\r
+          <wsa:Address>storage.msn.com</wsa:Address>\r
+        </wsa:EndpointReference>\r
+      </wsp:AppliesTo>\r
+      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>\r
+    </wst:RequestSecurityToken>\r
+  </ps:RequestMultipleSecurityTokens>\r
+</Body>\r
+</Envelope>';\r
+\r
+        $this->debug_message("*** URL: $passport_url");\r
+        $this->debug_message("*** Sending SOAP:\n$XML");\r
+        $curl = curl_init();\r
+        curl_setopt($curl, CURLOPT_URL, $passport_url);\r
+        if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1);\r
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);\r
+        curl_setopt($curl, CURLOPT_POST, 1);\r
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);\r
+        $data = curl_exec($curl);\r
+        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
+        curl_close($curl);\r
+        $this->debug_message("*** Get Result:\n$data");\r
+\r
+        if ($http_code != 200) {\r
+            // sometimes, redirect to another URL\r
+            // MSNP15\r
+            //<faultcode>psf:Redirect</faultcode>\r
+            //<psf:redirectUrl>https://msnia.login.live.com/pp450/RST.srf</psf:redirectUrl>\r
+            //<faultstring>Authentication Failure</faultstring>\r
+            if (strpos($data, '<faultcode>psf:Redirect</faultcode>') === false) {\r
+                $this->debug_message("*** Could not get passport ticket! http code = $http_code");\r
+                return false;\r
+            }\r
+            preg_match("#<psf\:redirectUrl>(.*)</psf\:redirectUrl>#", $data, $matches);\r
+            if (count($matches) == 0) {\r
+                $this->debug_message('*** Redirected, but could not get redirect URL!');\r
+                return false;\r
+            }\r
+            $redirect_url = $matches[1];\r
+            if ($redirect_url == $passport_url) {\r
+                $this->debug_message('*** Redirected, but to same URL!');\r
+                return false;\r
+            }\r
+            $this->debug_message("*** Redirected to $redirect_url");\r
+            return $this->get_passport_ticket($redirect_url);\r
+        }\r
+\r
+        // sometimes, redirect to another URL, also return 200\r
+        // MSNP15\r
+        //<faultcode>psf:Redirect</faultcode>\r
+        //<psf:redirectUrl>https://msnia.login.live.com/pp450/RST.srf</psf:redirectUrl>\r
+        //<faultstring>Authentication Failure</faultstring>\r
+        if (strpos($data, '<faultcode>psf:Redirect</faultcode>') !== false) {\r
+            preg_match("#<psf\:redirectUrl>(.*)</psf\:redirectUrl>#", $data, $matches);\r
+            if (count($matches) != 0) {\r
+                $redirect_url = $matches[1];\r
+                if ($redirect_url == $passport_url) {\r
+                    $this->debug_message('*** Redirected, but to same URL!');\r
+                    return false;\r
+                }\r
+                $this->debug_message("*** Redirected to $redirect_url");\r
+                return $this->get_passport_ticket($redirect_url);\r
+            }\r
+        }\r
+\r
+        // no Redurect faultcode or URL\r
+        // we should get the ticket here\r
+\r
+        // we need ticket and secret code\r
+        // RST1: messengerclear.live.com\r
+        // <wsse:BinarySecurityToken Id="Compact1">t=tick&p=</wsse:BinarySecurityToken>\r
+        // <wst:BinarySecret>binary secret</wst:BinarySecret>\r
+        // RST2: messenger.msn.com\r
+        // <wsse:BinarySecurityToken Id="PPToken2">t=tick</wsse:BinarySecurityToken>\r
+        // RST3: contacts.msn.com\r
+        // <wsse:BinarySecurityToken Id="Compact3">t=tick&p=</wsse:BinarySecurityToken>\r
+        // RST4: messengersecure.live.com\r
+        // <wsse:BinarySecurityToken Id="Compact4">t=tick&p=</wsse:BinarySecurityToken>\r
+        // RST5: spaces.live.com\r
+        // <wsse:BinarySecurityToken Id="Compact5">t=tick&p=</wsse:BinarySecurityToken>\r
+        // RST6: storage.msn.com\r
+        // <wsse:BinarySecurityToken Id="Compact6">t=tick&p=</wsse:BinarySecurityToken>\r
+        preg_match("#".\r
+            "<wsse\:BinarySecurityToken Id=\"Compact1\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "<wst\:BinarySecret>(.*)</wst\:BinarySecret>(.*)".\r
+            "<wsse\:BinarySecurityToken Id=\"PPToken2\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "<wsse\:BinarySecurityToken Id=\"Compact3\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "<wsse\:BinarySecurityToken Id=\"Compact4\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "<wsse\:BinarySecurityToken Id=\"Compact5\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "<wsse\:BinarySecurityToken Id=\"Compact6\">(.*)</wsse\:BinarySecurityToken>(.*)".\r
+            "#",\r
+        $data, $matches);\r
+\r
+        // no ticket found!\r
+        if (count($matches) == 0) {\r
+            $this->debug_message('*** Could not get passport ticket!');\r
+            return false;\r
+        }\r
+\r
+        //$this->debug_message(var_export($matches, true));\r
+        // matches[0]: all data\r
+        // matches[1]: RST1 (messengerclear.live.com) ticket\r
+        // matches[2]: ...\r
+        // matches[3]: RST1 (messengerclear.live.com) binary secret\r
+        // matches[4]: ...\r
+        // matches[5]: RST2 (messenger.msn.com) ticket\r
+        // matches[6]: ...\r
+        // matches[7]: RST3 (contacts.msn.com) ticket\r
+        // matches[8]: ...\r
+        // matches[9]: RST4 (messengersecure.live.com) ticket\r
+        // matches[10]: ...\r
+        // matches[11]: RST5 (spaces.live.com) ticket\r
+        // matches[12]: ...\r
+        // matches[13]: RST6 (storage.live.com) ticket\r
+        // matches[14]: ...\r
+\r
+        // so\r
+        // ticket => $matches[1]\r
+        // secret => $matches[3]\r
+        // web_ticket => $matches[5]\r
+        // contact_ticket => $matches[7]\r
+        // oim_ticket => $matches[9]\r
+        // space_ticket => $matches[11]\r
+        // storage_ticket => $matches[13]\r
+\r
+        // yes, we get ticket\r
+        $aTickets = array(\r
+            'ticket' => html_entity_decode($matches[1]),\r
+            'secret' => html_entity_decode($matches[3]),\r
+            'web_ticket' => html_entity_decode($matches[5]),\r
+            'contact_ticket' => html_entity_decode($matches[7]),\r
+            'oim_ticket' => html_entity_decode($matches[9]),\r
+            'space_ticket' => html_entity_decode($matches[11]),\r
+            'storage_ticket' => html_entity_decode($matches[13])\r
+        );\r
+        $this->ticket = $aTickets;\r
+        //$this->debug_message(var_export($aTickets, true));\r
+        $ABAuthHeaderArray = array(\r
+            'ABAuthHeader' => array(\r
+                ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'),\r
+                'ManagedGroupRequest' => false,\r
+                'TicketToken' => htmlspecialchars($this->ticket['contact_ticket']),\r
+            )\r
+        );\r
+        $this->ABAuthHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABAuthHeader', $this->Array2SoapVar($ABAuthHeaderArray));\r
+        return $aTickets;\r
+    }\r
+\r
+    /**\r
+    * Generate the data to send a message\r
+    *\r
+    * @param string $sMessage Message\r
+    * @param integer $network Network\r
+    * @return string Message data\r
+    */\r
+    private function getMessage($sMessage, $network = 1) {\r
+        $msg_header = "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\nX-MMS-IM-Format: FN=$this->font_fn; EF=$this->font_ef; CO=$this->font_co; CS=0; PF=22\r\n\r\n";\r
+        $msg_header_len = strlen($msg_header);\r
+        if ($network == 1)\r
+            $maxlen = self::MAX_MSN_MESSAGE_LEN - $msg_header_len;\r
+        else\r
+            $maxlen = self::MAX_YAHOO_MESSAGE_LEN - $msg_header_len;\r
+        $sMessage = str_replace("\r", '', $sMessage);\r
+        $msg = substr($sMessage, 0, $maxlen);\r
+        return $msg_header.$msg;\r
+    }\r
+\r
+    /**\r
+    * Sleep for the given number of seconds\r
+    *\r
+    * @param integer $wait Number of seconds to sleep for\r
+    */\r
+    private function NSRetryWait($wait) {\r
+        $this->debug_message("*** Sleeping for $wait seconds before retrying");\r
+        sleep($wait);\r
+    }\r
+\r
+    /**\r
+     * Sends a ping command\r
+     *\r
+     * Should be called about every 50 seconds\r
+     *\r
+     * @return void\r
+     */\r
+    public function sendPing() {\r
+        // NS: >>> PNG\r
+        $this->ns_writeln("PNG");\r
+    }\r
+\r
+    /**\r
+    * Methods to add / call callbacks\r
+    */\r
+\r
+    /**\r
+     * Calls User Handler\r
+     *\r
+     * Calls registered handler for a specific event.\r
+     *\r
+     * @param string $event Command (event) name (Rvous etc)\r
+     * @param array $data Data\r
+     * @see registerHandler\r
+     * @return void\r
+     */\r
+    private function callHandler($event, $data = NULL) {\r
+        if (isset($this->myEventHandlers[$event])) {\r
+            if ($data !== NULL) {\r
+                call_user_func($this->myEventHandlers[$event], $data);\r
+            } else {\r
+                call_user_func($this->myEventHandlers[$event]);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Registers a user handler\r
+     *\r
+     * Handler List\r
+     * IMIn, SessionReady, Pong, ConnectFailed, Reconnect,\r
+     * AddedToList, RemovedFromList, StatusChange\r
+     *\r
+     * @param string $event Event name\r
+     * @param string $handler User function to call\r
+     * @see callHandler\r
+     * @return boolean true if successful\r
+     */\r
+    public function registerHandler($event, $handler) {\r
+        if (is_callable($handler)) {\r
+            $this->myEventHandlers[$event] = $handler;\r
+            return true;\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Debugging methods\r
+     */\r
+\r
+    /**\r
+     * Print message if debugging is enabled\r
+     *\r
+     * @param string $str Message to print\r
+     */\r
+    private function debug_message($str) {\r
+        if (!$this->debug) return;\r
+        echo $str."\n";\r
+    }\r
+\r
+    /**\r
+     * Dump binary data\r
+     *\r
+     * @param string $str Data string\r
+     * @return Binary data\r
+     */\r
+    private function dump_binary($str) {\r
+        $buf = '';\r
+        $a_str = '';\r
+        $h_str = '';\r
+        $len = strlen($str);\r
+        for ($i = 0; $i < $len; $i++) {\r
+            if (($i % 16) == 0) {\r
+                if ($buf !== '') {\r
+                    $buf .= "$h_str $a_str\n";\r
+                }\r
+                $buf .= sprintf("%04X:", $i);\r
+                $a_str = '';\r
+                $h_str = '';\r
+            }\r
+            $ch = ord($str[$i]);\r
+            if ($ch < 32)\r
+            $a_str .= '.';\r
+            else\r
+            $a_str .= chr($ch);\r
+            $h_str .= sprintf(" %02X", $ch);\r
+        }\r
+        if ($h_str !== '')\r
+        $buf .= "$h_str $a_str\n";\r
+        return $buf;\r
+    }\r
+}\r
diff --git a/plugins/Msn/extlib/phpmsnclass/msnbot.php b/plugins/Msn/extlib/phpmsnclass/msnbot.php
new file mode 100755 (executable)
index 0000000..7a9f66c
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/php
+<?php
+global $msn;
+function ChildSignalFunction($signal)
+{
+       global $msn;    
+       switch($signal)
+       {
+               case SIGTRAP:
+               case SIGTERM:
+               case SIGHUP:                    
+                       if(is_object($msn))     $msn->End();
+                       return;
+       }
+}
+
+// network:
+//      1: WLM/MSN
+//      2: LCS
+//      4: Mobile Phones
+//     32: Yahoo!
+function getNetworkName($network)
+{
+       switch ($network)
+       {
+               case 1:
+                       return 'WLM/MSN';
+               case 2:
+                       return 'LCS';
+               case 4:
+                       return 'Mobile Phones';
+               case 32:
+                       return 'Yahoo!';
+       }
+       return "Unknown ($network)";
+}
+
+
+require_once('config.php');
+include_once('msn.class.php');
+
+$msn = new MSN(array(
+                'user' => 'xxx@hotmail.com',
+                'password' => 'mypassword',
+                'alias' => 'myalias',
+                'psm' => 'psm',
+//                'PhotoSticker' => 'msntitle.jpg',
+                'debug'=> true,
+/*                'Emotions' => array(
+                   'aaa' =>  'emotion.gif'
+                 ),*/
+));
+
+$fp=fopen(MSN_CLASS_LOG_DIR.DIRECTORY_SEPARATOR.'msnbot.pid', 'wt');
+if($fp)
+{
+       fputs($fp,posix_getpid());
+       fclose($fp);
+}
+declare(ticks = 1);
+$msn->Run();
+$msn->log_message("done!");
+@unlink(dirname($_SERVER['argv'][0]).DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR.'msnbot.pid');
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/.svn/all-wcprops b/plugins/Msn/extlib/phpmsnclass/soap/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..0e73537
--- /dev/null
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 41
+/svn/!svn/ver/39/trunk/phpmsnclassv2/soap
+END
+msnab_servicetypes.xsd
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/!svn/ver/39/trunk/phpmsnclassv2/soap/msnab_servicetypes.xsd
+END
+msnab_sharingservice.wsdl
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/!svn/ver/39/trunk/phpmsnclassv2/soap/msnab_sharingservice.wsdl
+END
+msnab_datatypes.xsd
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/!svn/ver/39/trunk/phpmsnclassv2/soap/msnab_datatypes.xsd
+END
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/.svn/entries b/plugins/Msn/extlib/phpmsnclass/soap/.svn/entries
new file mode 100644 (file)
index 0000000..062f5cb
--- /dev/null
@@ -0,0 +1,130 @@
+10
+
+dir
+46
+http://phpmsnclass.googlecode.com/svn/trunk/phpmsnclassv2/soap
+http://phpmsnclass.googlecode.com/svn
+
+
+
+2009-07-27T06:16:08.380493Z
+39
+ricky@ez2.us
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+d71849f3-712d-0410-a681-1795f7bea18a
+\f
+msnab_servicetypes.xsd
+file
+
+
+
+
+2010-06-08T18:29:30.506015Z
+096c0222d82879fa2b4bd47fa45f4aaf
+2009-07-27T06:16:08.380493Z
+39
+ricky@ez2.us
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+27903
+\f
+msnab_sharingservice.wsdl
+file
+
+
+
+
+2010-06-08T18:29:30.506015Z
+40f2d65d6cf6245c064defb02bd62705
+2009-07-27T06:16:08.380493Z
+39
+ricky@ez2.us
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+27625
+\f
+msnab_datatypes.xsd
+file
+
+
+
+
+2010-06-08T18:29:30.506015Z
+6a376c90de444594c1c75970586f99f8
+2009-07-27T06:16:08.380493Z
+39
+ricky@ez2.us
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+42170
+\f
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_datatypes.xsd.svn-base b/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_datatypes.xsd.svn-base
new file mode 100644 (file)
index 0000000..46fc23f
--- /dev/null
@@ -0,0 +1,832 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<xsd:schema xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://www.msn.com/webservices/AddressBook" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">\r
+    <xsd:complexType name="abInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="ownerPuid" type="xsd:string"/>\r
+            <xsd:element name="OwnerCID" type="xsd:integer" minOccurs="0"/>\r
+            <xsd:element name="ownerEmail" type="xsd:string"/>\r
+            <xsd:element name="fDefault" type="xsd:boolean"/>\r
+            <xsd:element name="joinedNamespace" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsBot" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsParentManaged" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="SubscribeExternalPartner" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="NotifyExternalPartner" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="AddressBookType" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="MessengerApplicationServiceCreated" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsBetaMigrated" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="HandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="xsd:integer"/>\r
+            <xsd:element name="Type" type="xsd:string" default="Messenger"/>\r
+            <xsd:element name="ForeignId" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ServiceType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Memberships" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Info" type="msnab:InfoType"/>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+            <xsd:element name="LastChange" type="xsd:dateTime" default="0001-01-01T00:00:00"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean" default="false"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="Membership">\r
+        <xsd:sequence>\r
+            <xsd:element name="MemberRole" type="xsd:string"/>\r
+            <xsd:element name="Members">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Member" type="msnab:BaseMember" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="MembershipIsComplete" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="BaseMember">\r
+        <xsd:sequence>\r
+            <xsd:element name="MembershipId" type="xsd:positiveInteger" minOccurs="0"/>\r
+            <xsd:element name="Type" type="xsd:string"/>\r
+            <xsd:element name="Location" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Id" type="msnab:Guid"/>\r
+                        <xsd:element name="IsPassportNameHidden" type="xsd:boolean"/>\r
+                        <xsd:element name="CID" type="xsd:long"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="State" type="msnab:MemberState"/>\r
+            <xsd:element name="Annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Deleted" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="JoinedDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="ExpirationDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="CircleId" type="msnab:Guid"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PassportMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="PassportName" type="xsd:string"/>\r
+                    <xsd:element name="IsPassportNameHidden" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="PassportId" type="xsd:int" minOccurs="0"/>\r
+                    <xsd:element name="CID" type="xsd:long" minOccurs="0"/>\r
+                    <xsd:element name="PassportChanges" type="xsd:string" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="EmailMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Email" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PhoneMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="PhoneNumber" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RoleMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                    <xsd:element name="DefiningService">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Id" type="xsd:integer"/>\r
+                                <xsd:element name="Type" type="xsd:string"/>\r
+                                <xsd:element name="ForeignId" type="xsd:string"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                    <xsd:element name="MaxRoleRecursionDepth" type="xsd:integer"/>\r
+                    <xsd:element name="MaxDegreesSeparation" type="xsd:integer"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ServiceMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Service" type="msnab:HandleType"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="DomainMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="DomainName" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="EveryoneMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember"/>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="GroupMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="msnab:Guid"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="Guid">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:element name="MemberType">\r
+        <xsd:simpleType>\r
+            <xsd:restriction base="xsd:string">\r
+                <xsd:enumeration value="Allow"/>\r
+            </xsd:restriction>\r
+        </xsd:simpleType>\r
+    </xsd:element>\r
+    <xsd:simpleType name="MemberState">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="Accepted"/>\r
+            <xsd:enumeration value="Pending"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="Annotation">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="Value" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactId" type="msnab:Guid" minOccurs="0"/>\r
+            <xsd:element name="contactInfo" type="msnab:contactInfoType" minOccurs="0"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            A space (ASCII #32) separated list of properties that\r
+            have changed as part of an update request. The property\r
+            names don't always match the name of the associated\r
+            element.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="fDeleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastModifiedBy" type="xsd:integer" minOccurs="0"/>\r
+            <xsd:element name="CreatedBy" type="xsd:integer" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactIdType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactId" type="msnab:Guid" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="emails" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactEmail" type="msnab:contactEmailType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="phones" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactPhone" type="msnab:contactPhoneType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="locations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactLocation" type="msnab:contactLocationType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="webSites" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactWebSite" type="msnab:contactWebSiteType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupIds" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupIdsDeleted" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="contactType" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="quickName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="firstName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="MiddleName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="lastName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="Suffix" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="NameTitle" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="passportName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsPassportNameHidden" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="displayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="puid" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="CID" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="BrandIdList" type="xsd:anyType" minOccurs="0"/>\r
+            <xsd:element name="comment" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isMobileIMEnabled" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isMessengerUser" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isFavorite" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isSmtp" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="hasSpace" type="xsd:boolean" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            Indicates whether the contact has a Windows Live\r
+            Space or not.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="spotWatchState" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="birthdate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="primaryEmailType" type="msnab:ContactEmailTypeType" minOccurs="0"/>\r
+            <xsd:element name="PrimaryLocation" type="msnab:ContactLocationTypeType" minOccurs="0"/>\r
+            <xsd:element name="PrimaryPhone" type="msnab:ContactPhoneTypeType" minOccurs="0"/>\r
+            <xsd:element name="IsPrivate" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="Anniversary" type="xsd:string" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            Seen is YYYY/MM/DD format.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="Gender" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="TimeZone" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="NetworkInfoList" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="NetworkInfo" type="msnab:NetworkInfoType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="PublicDisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsAutoUpdateDisabled" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="MessengerMemberInfo" type="msnab:MessengerMemberInfo" minOccurs="0"/>\r
+            <xsd:element name="PropertiesChanged" type="xsd:anyType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactEmailType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactEmailType" type="msnab:ContactEmailTypeType"/>\r
+            <xsd:element name="email" type="xsd:string"/>\r
+            <xsd:element name="isMessengerEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="Capability" type="xsd:integer"/>\r
+            <xsd:element name="MessengerEnabledExternally" type="xsd:boolean"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactEmailTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactEmailPersonal"/>\r
+            <xsd:enumeration value="ContactEmailBusiness"/>\r
+            <xsd:enumeration value="ContactEmailOther"/>\r
+            <xsd:enumeration value="ContactEmailMessenger"/>\r
+            <xsd:enumeration value="Messenger2"/>\r
+            <xsd:enumeration value="Messenger3"/>\r
+            <xsd:enumeration value="Messenger4"/>\r
+            <xsd:enumeration value="Passport"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactPhoneType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactPhoneType" type="msnab:ContactPhoneTypeType"/>\r
+            <xsd:element name="number" type="xsd:string"/>\r
+            <xsd:element name="isMessengerEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactPhoneTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactPhonePersonal"/>\r
+            <xsd:enumeration value="ContactPhoneBusiness"/>\r
+            <xsd:enumeration value="ContactPhoneMobile"/>\r
+            <xsd:enumeration value="ContactPhonePager"/>\r
+            <xsd:enumeration value="ContactPhoneOther"/>\r
+            <xsd:enumeration value="ContactPhoneFax"/>\r
+            <xsd:enumeration value="Personal2"/>\r
+            <xsd:enumeration value="Business2"/>\r
+            <xsd:enumeration value="BusinessFax"/>\r
+            <xsd:enumeration value="BusinessMobile"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactLocationType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactLocationType" type="msnab:ContactLocationTypeType"/>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="street" type="xsd:string"/>\r
+            <xsd:element name="city" type="xsd:string"/>\r
+            <xsd:element name="state" type="xsd:string"/>\r
+            <xsd:element name="country" type="xsd:string"/>\r
+            <xsd:element name="postalCode" type="xsd:string"/>\r
+            <xsd:element name="Department" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactLocationTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactLocationPersonal"/>\r
+            <xsd:enumeration value="ContactLocationBusiness"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactWebSiteType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactWebSiteType" type="msnab:ContactWebSiteTypeType"/>\r
+            <xsd:element name="webURL" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactWebSiteTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactWebSitePersonal"/>\r
+            <xsd:enumeration value="ContactWebSiteBusiness"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="GroupType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groupId" type="msnab:Guid"/>\r
+            <xsd:element name="groupInfo" type="msnab:groupInfoType"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            A space (ASCII #32) separated list of properties that\r
+            have changed as part of an update request. The property\r
+            names don't always match the name of the associated\r
+            element.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="fDeleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="groupInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupType" type="msnab:Guid" default="C8529CE2-6EAD-434d-881F-341E17DB3FF8" minOccurs="0"/>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsPrivate" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsFavorite" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="fMessenger" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="groupFilterType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groupIds">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="InvalidPassportUser">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="errorcode" type="xsd:string"/>\r
+                <xsd:element name="errorstring" type="xsd:string"/>\r
+                <xsd:element name="additionalDetails">\r
+                    <xsd:complexType>\r
+                        <xsd:sequence>\r
+                            <xsd:element name="originalExceptionErrorMessage" type="xsd:string"/>\r
+                        </xsd:sequence>\r
+                    </xsd:complexType>\r
+                </xsd:element>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:complexType name="MessengerMemberInfo">\r
+        <xsd:sequence>\r
+            <xsd:element name="PendingAnnotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="InfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Handle" type="msnab:HandleType"/>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="InverseRequired" type="xsd:boolean" default="false"/>\r
+            <xsd:element name="AuthorizationCriteria" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RSSUrl" type="xsd:anyURI" minOccurs="0"/>\r
+            <xsd:element name="IsBot" type="xsd:boolean" default="false"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NotificationDataType">\r
+        <xsd:sequence>\r
+            <xsd:element name="StoreService" type="msnab:ServiceType"/>\r
+            <xsd:element name="Status" type="xsd:string"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="Gleam" type="xsd:boolean" default="false"/>\r
+            <xsd:element name="InstanceId" type="xsd:string" default="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="BaseDynamicItemType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Type" type="xsd:string"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Notifications" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="NotificationData" type="msnab:NotificationDataType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleDynamicItem" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseDynamicItemType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PassportDynamicItem" block="" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseDynamicItemType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="CID" type="xsd:string" minOccurs="0"/>\r
+                    <xsd:element name="PassportName" type="xsd:string"/>\r
+                    <xsd:element name="PassportId" type="xsd:string" minOccurs="0"/>\r
+                    <xsd:element name="SpaceStatus" type="xsd:string"/>\r
+                    <xsd:element name="SpaceLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="SpaceLastViewed" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="SpaceGleam" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="ProfileLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ProfileLastView" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ProfileStatus" type="xsd:string"/>\r
+                    <xsd:element name="ProfileGleam" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="ContactProfileStatus" type="xsd:string"/>\r
+                    <xsd:element name="ContactProfileLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ContactProfileLastViewed" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="LiveContactLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="abType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid"/>\r
+            <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+            <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="createDate" type="xsd:dateTime"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:anyType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Circles" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="CircleInverseInfo" type="msnab:CircleInverseInfoType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleTicket" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NetworkInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="DomainId" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="DomainTag" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="UserTileURL" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="ProfileURL" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RelationshipType" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="RelationshipState" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="RelationshipStateDate" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RelationshipRole" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="NDRCount" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="InviterCID" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="PropertiesChanged" type="xsd:anyType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactFilterType">\r
+        <xsd:sequence>\r
+            <xsd:element name="IncludeHiddenContacts" type="xsd:boolean"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="filterOptionsType">\r
+        <xsd:sequence>\r
+            <xsd:element name="DeltasOnly" type="xsd:boolean"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="ContactFilter" type="msnab:ContactFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="entityHandle">\r
+        <xsd:sequence>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NotationType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="Value" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ListTemplateVariableItemType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Values">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Value" type="msnab:SimpleTemplateVariableBaseType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TemplateVariableBaseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="SimpleTemplateVariableBaseType">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Value" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PublisherIdTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                    <xsd:element name="NameHint" type="xsd:string" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TargetIdTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:PublisherIdTemplateVariable">\r
+                <xsd:sequence>\r
+                    <xsd:element name="IdOwner" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TextTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType"/>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="HlinkTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Text" type="xsd:string"/>\r
+                    <xsd:element name="Notations">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Notation" type="msnab:NotationType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ListTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Items">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="ListTemplateVariableItem" type="msnab:ListTemplateVariableItemType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ImageTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Href" type="xsd:anyURI"/>\r
+                    <xsd:element name="Notations">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Notation" type="msnab:NotationType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ActivityDetailsType">\r
+        <xsd:sequence>\r
+            <xsd:element name="OwnerCID" type="xsd:string"/>\r
+            <xsd:element name="ObjectId" type="xsd:string"/>\r
+            <xsd:element name="ApplicationId" type="xsd:string"/>\r
+            <xsd:element name="ChangeType" type="xsd:string"/>\r
+            <xsd:element name="PublishDate" type="xsd:dateTime"/>\r
+            <xsd:element name="TemplateVariables">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="TemplateVariable" type="msnab:TemplateVariableBaseType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RecentActivityTemplateType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Cardinality" type="xsd:string"/>\r
+            <xsd:element name="Data" type="xsd:string"/>\r
+            <xsd:element name="Title" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RequestedLocalesType">\r
+        <xsd:sequence>\r
+            <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RecentActivityTemplateContainerType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ApplicationId" type="xsd:string"/>\r
+            <xsd:element name="ApplicationName" type="xsd:string"/>\r
+            <xsd:element name="ChangeType" type="xsd:integer"/>\r
+            <xsd:element name="Locale" type="xsd:string"/>\r
+            <xsd:element name="RequestedLocales" type="msnab:RequestedLocalesType"/>\r
+            <xsd:element name="TemplateRevision" type="xsd:integer"/>\r
+            <xsd:element name="Templates">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="RecentActivityTemplate" type="msnab:RecentActivityTemplateType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CollapseCondition" type="msnab:CollapseConditionType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CollapseConditionType">\r
+        <xsd:sequence>\r
+            <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CirclePersonalMembershipType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Role" type="xsd:string"/>\r
+            <xsd:element name="State" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="abHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ABId" type="xsd:string"/>\r
+            <xsd:element name="Puid" type="xsd:long"/>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Email" type="xsd:string"/>\r
+            <xsd:element name="Puid" type="xsd:long"/>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+            <xsd:element name="CircleId" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="MembershipInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="CirclePersonalMembership" type="msnab:CirclePersonalMembershipType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PersonalInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="MembershipInfo" type="msnab:MembershipInfoType"/>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean"/>\r
+            <xsd:element name="IsFavorite" type="xsd:boolean"/>\r
+            <xsd:element name="IsFamily" type="xsd:boolean"/>\r
+            <xsd:element name="Changes" type="xsd:anyType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Domain" type="xsd:int"/>\r
+            <xsd:element name="HostedDomain" type="xsd:string"/>\r
+            <xsd:element name="Type" type="xsd:int"/>\r
+            <xsd:element name="MembershipAccess" type="xsd:int"/>\r
+            <xsd:element name="IsPresenceEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="RequestMembershipOption" type="xsd:int"/>\r
+            <xsd:element name="DisplayName" type="xsd:string"/>\r
+            <xsd:element name="ProfileLastUpdated" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:anyType" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Handle" type="msnab:ContentHandleType"/>\r
+            <xsd:element name="Info" type="msnab:ContentInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleInverseInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Content" type="msnab:ContentType"/>\r
+            <xsd:element name="PersonalInfo" type="msnab:PersonalInfoType"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="callerInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="PublicDisplayName" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+</xsd:schema>\r
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_servicetypes.xsd.svn-base b/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_servicetypes.xsd.svn-base
new file mode 100644 (file)
index 0000000..3fa9798
--- /dev/null
@@ -0,0 +1,567 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<xsd:schema xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.msn.com/webservices/AddressBook" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">\r
+    <xsd:include schemaLocation="msnab_datatypes.xsd"/>\r
+    <xsd:element name="ABApplicationHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ApplicationId" type="msnab:Guid" fixed="09607671-1C32-421F-A6A6-CBFAA51AB5F4"/>\r
+                <xsd:element name="IsMigration" type="xsd:boolean" default="false"/>\r
+                <xsd:element name="PartnerScenario" type="xsd:string" default="Initial"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="BrandId" type="xsd:string" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABAuthHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ManagedGroupRequest" type="xsd:boolean" default="false"/>\r
+                <xsd:element name="TicketToken" type="xsd:string"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ServiceHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="Version" type="xsd:token"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="CacheKeyChanged" type="xsd:boolean" minOccurs="0"/>\r
+                <xsd:element name="PreferredHostName" type="xsd:string" minOccurs="0"/>\r
+                <xsd:element name="SessionId" type="msnab:Guid" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="FindMembership" type="msnab:FindMembershipRequestType"/>\r
+    <xsd:complexType name="FindMembershipRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceFilter">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Types">\r
+                            <xsd:complexType>\r
+                                <xsd:sequence>\r
+                                    <xsd:element name="ServiceType" type="xsd:string" maxOccurs="unbounded"/>\r
+                                </xsd:sequence>\r
+                            </xsd:complexType>\r
+                        </xsd:element>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="View" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="deltasOnly" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="FindMembershipResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Services">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Service" type="msnab:ServiceType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="OwnerNamespace">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Info">\r
+                            <xsd:complexType>\r
+                                <xsd:sequence>\r
+                                    <xsd:element name="Handle">\r
+                                        <xsd:complexType>\r
+                                            <xsd:sequence>\r
+                                                <xsd:element name="Id" type="xsd:string"/>\r
+                                                <xsd:element name="IsPassportNameHidden" type="xsd:boolean"/>\r
+                                                <xsd:element name="CID" type="xsd:integer"/>\r
+                                            </xsd:sequence>\r
+                                        </xsd:complexType>\r
+                                    </xsd:element>\r
+                                    <xsd:element name="CreatorPuid" type="xsd:integer"/>\r
+                                    <xsd:element name="CreatorCID" type="xsd:integer"/>\r
+                                    <xsd:element name="CreatorPassportName" type="xsd:string"/>\r
+                                    <xsd:element name="CircleAttributes">\r
+                                        <xsd:complexType>\r
+                                            <xsd:sequence>\r
+                                                <xsd:element name="IsPresenceEnabled" type="xsd:boolean"/>\r
+                                                <xsd:element name="IsEvent" type="xsd:boolean" minOccurs="0"/>\r
+                                                <xsd:element name="Domain" type="xsd:string"/>\r
+                                            </xsd:sequence>\r
+                                        </xsd:complexType>\r
+                                    </xsd:element>\r
+                                    <xsd:element name="MessengerApplicationServiceCreated" type="xsd:boolean" minOccurs="0"/>\r
+                                </xsd:sequence>\r
+                            </xsd:complexType>\r
+                        </xsd:element>\r
+                        <xsd:element name="Changes" type="xsd:string"/>\r
+                        <xsd:element name="CreateDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="LastChange" type="xsd:dateTime"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="FindMembershipResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="FindMembershipResult" type="msnab:FindMembershipResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABFindAll" type="msnab:ABFindAllRequestType"/>\r
+    <xsd:complexType name="ABFindAllRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="abView" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="deltasOnly" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+            <xsd:element name="dynamicItemView" type="xsd:string" fixed="Gleam" minOccurs="0"/>\r
+            <xsd:element name="dynamicItemLastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABFindAllResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groups" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DynamicItems" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="DynamicItem" type="msnab:BaseDynamicItemType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleResult">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="CircleTicket" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="ab">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="abId" type="msnab:Guid"/>\r
+                        <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+                        <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+                        <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="createDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABFindAllResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABFindAllResult" type="msnab:ABFindAllResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactAdd" type="msnab:ABContactAddRequestType"/>\r
+    <xsd:complexType name="ABContactAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="options" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="EnableAllowListManagement" type="xsd:boolean"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABContactAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABContactAddResult" type="msnab:ABContactAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactDelete" type="msnab:ABContactDeleteRequestType"/>\r
+    <xsd:complexType name="ABContactDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactIdType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactDeleteResponse"/>\r
+    <xsd:element name="ABGroupContactAdd" type="msnab:ABGroupContactAddRequestType"/>\r
+    <xsd:complexType name="ABGroupContactAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupContactAddOptions" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="fGenerateMissingQuickName" type="xsd:boolean" minOccurs="0"/>\r
+                        <xsd:element name="EnableAllowListManagement" type="xsd:boolean" minOccurs="0"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABGroupContactAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupContactAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABGroupContactAddResult" type="msnab:ABGroupContactAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupAdd" type="msnab:ABGroupAddRequestType"/>\r
+    <xsd:complexType name="ABGroupAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupAddOptions">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="fRenameOnMsgrConflict" type="xsd:boolean" minOccurs="0"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupInfo">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="GroupInfo" type="msnab:groupInfoType"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABGroupAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABGroupAddResult" type="msnab:ABGroupAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupUpdate" type="msnab:ABGroupUpdateRequestType"/>\r
+    <xsd:complexType name="ABGroupUpdateRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groups">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupUpdateResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupDelete" type="msnab:ABGroupDeleteRequestType"/>\r
+    <xsd:complexType name="ABGroupDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupDeleteResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactUpdate" type="msnab:ABContactUpdateRequestType"/>\r
+    <xsd:complexType name="ABContactUpdateRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactUpdateResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupContactDelete" type="msnab:ABGroupContactDeleteRequestType"/>\r
+    <xsd:complexType name="ABGroupContactDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupContactDeleteResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="AddMember" type="msnab:AddMemberRequestType"/>\r
+    <xsd:complexType name="AddMemberRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceHandle" type="msnab:HandleType"/>\r
+            <xsd:element name="memberships">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="AddMemberResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="DeleteMember" type="msnab:DeleteMemberRequestType"/>\r
+    <xsd:complexType name="DeleteMemberRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceHandle" type="msnab:HandleType"/>\r
+            <xsd:element name="memberships">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="nsHandle" type="msnab:ContentHandleType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="DeleteMemberResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:complexType name="ABAddResponseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ABAddResult" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABAddResponse" type="msnab:ABAddResponseType"/>\r
+    <xsd:element name="ABAdd" type="msnab:ABAddRequestType"/>\r
+    <xsd:complexType name="ABAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="UpdateDynamicItemRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="xsd:string"/>\r
+            <xsd:element name="dynamicItems">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="DynamicItem" type="msnab:BaseDynamicItemType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="UpdateDynamicItem" type="msnab:UpdateDynamicItemRequestType"/>\r
+    <xsd:element name="UpdateDynamicItemResponse"/>\r
+    <xsd:element name="ABFindContactsPaged" type="msnab:ABFindContactsPagedRequestType"/>\r
+    <xsd:complexType name="ABFindContactsPagedRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="filterOptions" type="msnab:filterOptionsType"/>\r
+            <xsd:element name="abView" type="xsd:string"/>\r
+            <xsd:element name="extendedContent" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABFindContactsPagedResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Groups" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleResult" type="msnab:CircleResultType"/>\r
+            <xsd:element name="Ab">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="abId" type="msnab:Guid"/>\r
+                        <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+                        <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+                        <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="createDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABFindContactsPagedResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABFindContactsPagedResult" type="msnab:ABFindContactsPagedResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNApplicationHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ApplicationId" type="msnab:Guid"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNAuthHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="TicketToken" type="xsd:string"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNServiceHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="Version" type="xsd:token"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="CacheKeyChanged" type="xsd:boolean" minOccurs="0"/>\r
+                <xsd:element name="PreferredHostName" type="xsd:string" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="GetContactsRecentActivity" type="msnab:GetContactsRecentActivityRequestType"/>\r
+    <xsd:complexType name="GetContactsRecentActivityRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="entityHandle" type="msnab:entityHandle"/>\r
+            <xsd:element name="locales">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="count" type="xsd:int"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="GetContactsRecentActivityResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="GetContactsRecentActivityResult" type="msnab:GetContactsRecentActivityResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:complexType name="GetContactsRecentActivityResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Activities">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ActivityDetails" type="msnab:ActivityDetailsType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Templates">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="RecentActivityTemplateContainer" type="msnab:RecentActivityTemplateContainerType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="FeedUrl" type="xsd:anyURI"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ManageWLConnection" type="msnab:ManageWLConnectionRequestType"/>\r
+    <xsd:complexType name="ManageWLConnectionRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abHandle" type="msnab:abHandleType"/>\r
+            <xsd:element name="contactId" type="xsd:string"/>\r
+            <xsd:element name="connection" type="xsd:boolean"/>\r
+            <xsd:element name="presence" type="xsd:boolean"/>\r
+            <xsd:element name="action" type="xsd:integer"/>\r
+            <xsd:element name="relationshipType" type="xsd:int"/>\r
+            <xsd:element name="relationshipRole" type="xsd:int"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ManageWLConnectionResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ManageWLConnectionResult" type="msnab:ContactType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="CreateContact" type="msnab:CreateContactType"/>\r
+    <xsd:complexType name="CreateContactType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abHandle" type="msnab:abHandleType"/>\r
+            <xsd:element name="contactHandle" type="msnab:contactHandleType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="CreateContactResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="CreateContactResult" type="msnab:ContactType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="CreateCircle" type="msnab:CreateCircleRequestType"/>\r
+    <xsd:complexType name="CreateCircleRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="properties" type="msnab:ContentInfoType"/>\r
+            <xsd:element name="callerInfo" type="msnab:callerInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CreateCircleResponseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="CreateCircleResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="CreateCircleResult" type="msnab:CreateCircleResponseType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+</xsd:schema>\r
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_sharingservice.wsdl.svn-base b/plugins/Msn/extlib/phpmsnclass/soap/.svn/text-base/msnab_sharingservice.wsdl.svn-base
new file mode 100644 (file)
index 0000000..7ec87f9
--- /dev/null
@@ -0,0 +1,532 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<definitions xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.msn.com/webservices/AddressBook">\r
+    <types>\r
+        <ns:schema xmlns="http://www.w3.org/2001/XMLSchema">\r
+            <ns:import schemaLocation="msnab_servicetypes.xsd" namespace="http://www.msn.com/webservices/AddressBook"/>\r
+        </ns:schema>\r
+    </types>\r
+    <message name="ABHeader">\r
+        <part name="ApplicationHeader" element="msnab:ABApplicationHeader"/>\r
+        <part name="AuthHeader" element="msnab:ABAuthHeader"/>\r
+    </message>\r
+    <message name="FindMembershipMessage">\r
+        <part name="FindMembershipRequest" element="msnab:FindMembership"/>\r
+    </message>\r
+    <message name="ABFindAllMessage">\r
+        <part name="ABFindAllRequest" element="msnab:ABFindAll"/>\r
+    </message>\r
+    <message name="ABContactAddMessage">\r
+        <part name="ABContactAddRequest" element="msnab:ABContactAdd"/>\r
+    </message>\r
+    <message name="ABContactDeleteMessage">\r
+        <part name="ABContactDeleteRequest" element="msnab:ABContactDelete"/>\r
+    </message>\r
+    <message name="ABGroupContactAddMessage">\r
+        <part name="ABGroupContactAddRequest" element="msnab:ABGroupContactAdd"/>\r
+    </message>\r
+    <message name="ABGroupAddMessage">\r
+        <part name="ABGroupAddRequest" element="msnab:ABGroupAdd"/>\r
+    </message>\r
+    <message name="ABGroupUpdateMessage">\r
+        <part name="ABGroupUpdateRequest" element="msnab:ABGroupUpdate"/>\r
+    </message>\r
+    <message name="ABGroupDeleteMessage">\r
+        <part name="ABGroupDeleteRequest" element="msnab:ABGroupDelete"/>\r
+    </message>\r
+    <message name="ABGroupContactDeleteMessage">\r
+        <part name="ABGroupContactDeleteRequest" element="msnab:ABGroupContactDelete"/>\r
+    </message>\r
+    <message name="ABContactUpdateMessage">\r
+        <part name="ABContactUpdateRequest" element="msnab:ABContactUpdate"/>\r
+    </message>\r
+    <message name="AddMemberMessage">\r
+        <part name="AddMemberRequest" element="msnab:AddMember"/>\r
+    </message>\r
+    <message name="DeleteMemberMessage">\r
+        <part name="DeleteMemberRequest" element="msnab:DeleteMember"/>\r
+    </message>\r
+    <message name="ServiceHeader">\r
+        <part name="ServiceHeader" element="msnab:ServiceHeader"/>\r
+    </message>\r
+    <message name="FindMembershipResponseMessage">\r
+        <part name="FindMembershipResponse" element="msnab:FindMembershipResponse"/>\r
+    </message>\r
+    <message name="ABFindAllResponseMessage">\r
+        <part name="ABFindAllResponse" element="msnab:ABFindAllResponse"/>\r
+    </message>\r
+    <message name="ABContactAddResponseMessage">\r
+        <part name="ABContactAddResponse" element="msnab:ABContactAddResponse"/>\r
+    </message>\r
+    <message name="ABContactDeleteResponseMessage">\r
+        <part name="ABContactDeleteResponse" element="msnab:ABContactDeleteResponse"/>\r
+    </message>\r
+    <message name="ABGroupContactAddResponseMessage">\r
+        <part name="ABGroupContactAddResponse" element="msnab:ABGroupContactAddResponse"/>\r
+    </message>\r
+    <message name="ABGroupAddResponseMessage">\r
+        <part name="ABGroupAddResponse" element="msnab:ABGroupAddResponse"/>\r
+    </message>\r
+    <message name="ABGroupUpdateResponseMessage">\r
+        <part name="ABGroupUpdateResponse" element="msnab:ABGroupUpdateResponse"/>\r
+    </message>\r
+    <message name="ABGroupDeleteResponseMessage">\r
+        <part name="ABGroupDeleteResponse" element="msnab:ABGroupDeleteResponse"/>\r
+    </message>\r
+    <message name="ABGroupContactDeleteResponseMessage">\r
+        <part name="ABGroupContactDeleteResponse" element="msnab:ABGroupContactDeleteResponse"/>\r
+    </message>\r
+    <message name="ABContactUpdateResponseMessage">\r
+        <part name="ABContactUpdateResponse" element="msnab:ABContactUpdateResponse"/>\r
+    </message>\r
+    <message name="AddMemberResponseMessage">\r
+        <part name="AddMemberResponse" element="msnab:AddMemberResponse"/>\r
+    </message>\r
+    <message name="DeleteMemberResponseMessage">\r
+        <part name="DeleteMemberResponse" element="msnab:DeleteMemberResponse"/>\r
+    </message>\r
+    <message name="InvalidPassportUserMessage">\r
+        <part name="fault" element="msnab:InvalidPassportUser"/>\r
+    </message>\r
+    <message name="ABAddMessage">\r
+        <part name="ABAddRequest" element="msnab:ABAdd"/>\r
+    </message>\r
+    <message name="ABAddResponseMessage">\r
+        <part name="ABAddResponse" element="msnab:ABAddResponse"/>\r
+    </message>\r
+    <message name="UpdateDynamicItemMessage">\r
+        <part name="UpdateDynamicItem" element="msnab:UpdateDynamicItem"/>\r
+    </message>\r
+    <message name="UpdateDynamicItemResponseMessage">\r
+        <part name="UpdateDynamicItemResponse" element="msnab:UpdateDynamicItemResponse"/>\r
+    </message>\r
+    <message name="ABFindContactsPagedMessage">\r
+        <part name="ABFindContactsPagedRequest" element="msnab:ABFindContactsPaged"/>\r
+    </message>\r
+    <message name="ABFindContactsPagedResponseMessage">\r
+        <part name="ABFindContactsPagedResponse" element="msnab:ABFindContactsPagedResponse"/>\r
+    </message>\r
+    <message name="GetContactsRecentActivityMessage">\r
+        <part name="GetContactsRecentActivityRequest" element="msnab:GetContactsRecentActivity"/>\r
+    </message>\r
+    <message name="GetContactsRecentActivityResponseMessage">\r
+        <part name="GetContactsRecentActivityResponse" element="msnab:GetContactsRecentActivityResponse"/>\r
+    </message>\r
+    <message name="WNHeader">\r
+        <part name="WNApplicationHeader" element="msnab:WNApplicationHeader"/>\r
+        <part name="WNAuthHeader" element="msnab:WNAuthHeader"/>\r
+        <part name="WNServiceHeader" element="msnab:WNServiceHeader"/>\r
+    </message>\r
+    <message name="CreateCircleMessage">\r
+        <part name="CreateCircleRequest" element="msnab:CreateCircle"/>\r
+    </message>\r
+    <message name="CreateCircleResponseMessage">\r
+        <part name="CreateCircleResponse" element="msnab:CreateCircleResponse"/>\r
+    </message>\r
+    <message name="CreateContactMessage">\r
+        <part name="CreateContactRequest" element="msnab:CreateContact"/>\r
+    </message>\r
+    <message name="CreateContactResponseMessage">\r
+        <part name="CreateContactResponse" element="msnab:CreateContactResponse"/>\r
+    </message>\r
+    <message name="ManageWLConnectionMessage">\r
+        <part name="ManageWLConnection" element="msnab:ManageWLConnection"/>\r
+    </message>\r
+    <message name="ManageWLConnectionResponseMessage">\r
+        <part name="ManageWLConnectionResponse" element="msnab:ManageWLConnectionResponse"/>\r
+    </message>\r
+    <portType name="SharingServicePortType">\r
+        <operation name="FindMembership">\r
+            <input message="msnab:FindMembershipMessage"/>\r
+            <output message="msnab:FindMembershipResponseMessage"/>\r
+        </operation>\r
+        <operation name="AddMember">\r
+            <input message="msnab:AddMemberMessage"/>\r
+            <output message="msnab:AddMemberResponseMessage"/>\r
+        </operation>\r
+        <operation name="DeleteMember">\r
+            <input message="msnab:DeleteMemberMessage"/>\r
+            <output message="msnab:DeleteMemberResponseMessage"/>\r
+        </operation>\r
+        <operation name="CreateCircle">\r
+            <input message="msnab:CreateCircleMessage"/>\r
+            <output message="msnab:CreateCircleResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <portType name="ABServicePortType">\r
+        <operation name="ABFindAll">\r
+            <input message="msnab:ABFindAllMessage"/>\r
+            <output message="msnab:ABFindAllResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABContactAdd">\r
+            <input message="msnab:ABContactAddMessage"/>\r
+            <output message="msnab:ABContactAddResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABContactDelete">\r
+            <input message="msnab:ABContactDeleteMessage"/>\r
+            <output message="msnab:ABContactDeleteResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupContactAdd">\r
+            <input message="msnab:ABGroupContactAddMessage"/>\r
+            <output message="msnab:ABGroupContactAddResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupAdd">\r
+            <input message="msnab:ABGroupAddMessage"/>\r
+            <output message="msnab:ABGroupAddResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupUpdate">\r
+            <input message="msnab:ABGroupUpdateMessage"/>\r
+            <output message="msnab:ABGroupUpdateResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupDelete">\r
+            <input message="msnab:ABGroupDeleteMessage"/>\r
+            <output message="msnab:ABGroupDeleteResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupContactDelete">\r
+            <input message="msnab:ABGroupContactDeleteMessage"/>\r
+            <output message="msnab:ABGroupContactDeleteResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABContactUpdate">\r
+            <input message="msnab:ABContactUpdateMessage"/>\r
+            <output message="msnab:ABContactUpdateResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABAdd">\r
+            <input message="msnab:ABAddMessage"/>\r
+            <output message="msnab:ABAddResponseMessage"/>\r
+        </operation>\r
+        <operation name="UpdateDynamicItem">\r
+            <input message="msnab:UpdateDynamicItemMessage"/>\r
+            <output message="msnab:UpdateDynamicItemResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABFindContactsPaged">\r
+            <input message="msnab:ABFindContactsPagedMessage"/>\r
+            <output message="msnab:ABFindContactsPagedResponseMessage"/>\r
+        </operation>\r
+        <operation name="CreateContact">\r
+            <input message="msnab:CreateContactMessage"/>\r
+            <output message="msnab:CreateContactResponseMessage"/>\r
+        </operation>\r
+        <operation name="ManageWLConnection">\r
+            <input message="msnab:ManageWLConnectionMessage"/>\r
+            <output message="msnab:ManageWLConnectionResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <portType name="WhatsUpServicePortType">\r
+        <operation name="GetContactsRecentActivity">\r
+            <input message="msnab:GetContactsRecentActivityMessage"/>\r
+            <output message="msnab:GetContactsRecentActivityResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <binding name="SharingServiceBinding" type="msnab:SharingServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="FindMembership">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/FindMembership"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="AddMember">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/AddMember"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="DeleteMember">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/DeleteMember"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="CreateCircle">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/CreateCircle"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <binding name="ABServiceBinding" type="msnab:ABServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="ABFindAll">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABFindAll"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABContactAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABContactDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABGroupContactAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupContactAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABGroupAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupUpdate">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupUpdate"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupContactDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupContactDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABContactUpdate">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactUpdate"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABAdd"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="UpdateDynamicItem">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/UpdateDynamicItem"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABFindContactsPaged">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABFindContactsPaged"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="CreateContact">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/CreateContact"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ManageWLConnection">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ManageWLConnection"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <binding name="WhatsUpServiceBinding" type="msnab:WhatsUpServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="GetContactsRecentActivity">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/GetContactsRecentActivity"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNAuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <service name="SharingService">\r
+        <port name="FindMembershipPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="AddMemberPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="DeleteMemberPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="CreateCirclePort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+    </service>\r
+    <service name="ABService">\r
+        <port name="ABFindAllPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupContactAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupUpdatePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupContactDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactUpdatePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="UpdateDynamicItemPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABFindContactsPagedPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="CreateContactPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ManageWLConnectionPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+    </service>\r
+    <service name="WhatsUpService">\r
+        <port name="GetContactsRecentActivityPort" binding="msnab:WhatsUpServiceBinding">\r
+            <soap:address location="http://sup.live.com/whatsnew/whatsnewservice.asmx"/>\r
+        </port>\r
+    </service>\r
+</definitions>\r
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd b/plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd
new file mode 100644 (file)
index 0000000..46fc23f
--- /dev/null
@@ -0,0 +1,832 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<xsd:schema xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://www.msn.com/webservices/AddressBook" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">\r
+    <xsd:complexType name="abInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="ownerPuid" type="xsd:string"/>\r
+            <xsd:element name="OwnerCID" type="xsd:integer" minOccurs="0"/>\r
+            <xsd:element name="ownerEmail" type="xsd:string"/>\r
+            <xsd:element name="fDefault" type="xsd:boolean"/>\r
+            <xsd:element name="joinedNamespace" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsBot" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsParentManaged" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="SubscribeExternalPartner" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="NotifyExternalPartner" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="AddressBookType" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="MessengerApplicationServiceCreated" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsBetaMigrated" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="HandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="xsd:integer"/>\r
+            <xsd:element name="Type" type="xsd:string" default="Messenger"/>\r
+            <xsd:element name="ForeignId" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ServiceType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Memberships" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Info" type="msnab:InfoType"/>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+            <xsd:element name="LastChange" type="xsd:dateTime" default="0001-01-01T00:00:00"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean" default="false"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="Membership">\r
+        <xsd:sequence>\r
+            <xsd:element name="MemberRole" type="xsd:string"/>\r
+            <xsd:element name="Members">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Member" type="msnab:BaseMember" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="MembershipIsComplete" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="BaseMember">\r
+        <xsd:sequence>\r
+            <xsd:element name="MembershipId" type="xsd:positiveInteger" minOccurs="0"/>\r
+            <xsd:element name="Type" type="xsd:string"/>\r
+            <xsd:element name="Location" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Id" type="msnab:Guid"/>\r
+                        <xsd:element name="IsPassportNameHidden" type="xsd:boolean"/>\r
+                        <xsd:element name="CID" type="xsd:long"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="State" type="msnab:MemberState"/>\r
+            <xsd:element name="Annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Deleted" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="JoinedDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="ExpirationDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="CircleId" type="msnab:Guid"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PassportMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="PassportName" type="xsd:string"/>\r
+                    <xsd:element name="IsPassportNameHidden" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="PassportId" type="xsd:int" minOccurs="0"/>\r
+                    <xsd:element name="CID" type="xsd:long" minOccurs="0"/>\r
+                    <xsd:element name="PassportChanges" type="xsd:string" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="EmailMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Email" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PhoneMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="PhoneNumber" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RoleMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                    <xsd:element name="DefiningService">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Id" type="xsd:integer"/>\r
+                                <xsd:element name="Type" type="xsd:string"/>\r
+                                <xsd:element name="ForeignId" type="xsd:string"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                    <xsd:element name="MaxRoleRecursionDepth" type="xsd:integer"/>\r
+                    <xsd:element name="MaxDegreesSeparation" type="xsd:integer"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ServiceMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Service" type="msnab:HandleType"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="DomainMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="DomainName" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="EveryoneMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember"/>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="GroupMember" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseMember">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="msnab:Guid"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="Guid">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:element name="MemberType">\r
+        <xsd:simpleType>\r
+            <xsd:restriction base="xsd:string">\r
+                <xsd:enumeration value="Allow"/>\r
+            </xsd:restriction>\r
+        </xsd:simpleType>\r
+    </xsd:element>\r
+    <xsd:simpleType name="MemberState">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="Accepted"/>\r
+            <xsd:enumeration value="Pending"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="Annotation">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="Value" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactId" type="msnab:Guid" minOccurs="0"/>\r
+            <xsd:element name="contactInfo" type="msnab:contactInfoType" minOccurs="0"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            A space (ASCII #32) separated list of properties that\r
+            have changed as part of an update request. The property\r
+            names don't always match the name of the associated\r
+            element.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="fDeleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastModifiedBy" type="xsd:integer" minOccurs="0"/>\r
+            <xsd:element name="CreatedBy" type="xsd:integer" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactIdType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactId" type="msnab:Guid" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="emails" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactEmail" type="msnab:contactEmailType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="phones" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactPhone" type="msnab:contactPhoneType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="locations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactLocation" type="msnab:contactLocationType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="webSites" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ContactWebSite" type="msnab:contactWebSiteType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupIds" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupIdsDeleted" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="contactType" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="quickName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="firstName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="MiddleName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="lastName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="Suffix" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="NameTitle" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="passportName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsPassportNameHidden" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="displayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="puid" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="CID" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="BrandIdList" type="xsd:anyType" minOccurs="0"/>\r
+            <xsd:element name="comment" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isMobileIMEnabled" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isMessengerUser" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isFavorite" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="isSmtp" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="hasSpace" type="xsd:boolean" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            Indicates whether the contact has a Windows Live\r
+            Space or not.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="spotWatchState" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="birthdate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="primaryEmailType" type="msnab:ContactEmailTypeType" minOccurs="0"/>\r
+            <xsd:element name="PrimaryLocation" type="msnab:ContactLocationTypeType" minOccurs="0"/>\r
+            <xsd:element name="PrimaryPhone" type="msnab:ContactPhoneTypeType" minOccurs="0"/>\r
+            <xsd:element name="IsPrivate" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="Anniversary" type="xsd:string" minOccurs="0">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            Seen is YYYY/MM/DD format.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="Gender" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="TimeZone" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="NetworkInfoList" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="NetworkInfo" type="msnab:NetworkInfoType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="PublicDisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsAutoUpdateDisabled" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="MessengerMemberInfo" type="msnab:MessengerMemberInfo" minOccurs="0"/>\r
+            <xsd:element name="PropertiesChanged" type="xsd:anyType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactEmailType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactEmailType" type="msnab:ContactEmailTypeType"/>\r
+            <xsd:element name="email" type="xsd:string"/>\r
+            <xsd:element name="isMessengerEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="Capability" type="xsd:integer"/>\r
+            <xsd:element name="MessengerEnabledExternally" type="xsd:boolean"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactEmailTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactEmailPersonal"/>\r
+            <xsd:enumeration value="ContactEmailBusiness"/>\r
+            <xsd:enumeration value="ContactEmailOther"/>\r
+            <xsd:enumeration value="ContactEmailMessenger"/>\r
+            <xsd:enumeration value="Messenger2"/>\r
+            <xsd:enumeration value="Messenger3"/>\r
+            <xsd:enumeration value="Messenger4"/>\r
+            <xsd:enumeration value="Passport"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactPhoneType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactPhoneType" type="msnab:ContactPhoneTypeType"/>\r
+            <xsd:element name="number" type="xsd:string"/>\r
+            <xsd:element name="isMessengerEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactPhoneTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactPhonePersonal"/>\r
+            <xsd:enumeration value="ContactPhoneBusiness"/>\r
+            <xsd:enumeration value="ContactPhoneMobile"/>\r
+            <xsd:enumeration value="ContactPhonePager"/>\r
+            <xsd:enumeration value="ContactPhoneOther"/>\r
+            <xsd:enumeration value="ContactPhoneFax"/>\r
+            <xsd:enumeration value="Personal2"/>\r
+            <xsd:enumeration value="Business2"/>\r
+            <xsd:enumeration value="BusinessFax"/>\r
+            <xsd:enumeration value="BusinessMobile"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactLocationType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactLocationType" type="msnab:ContactLocationTypeType"/>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="street" type="xsd:string"/>\r
+            <xsd:element name="city" type="xsd:string"/>\r
+            <xsd:element name="state" type="xsd:string"/>\r
+            <xsd:element name="country" type="xsd:string"/>\r
+            <xsd:element name="postalCode" type="xsd:string"/>\r
+            <xsd:element name="Department" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactLocationTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactLocationPersonal"/>\r
+            <xsd:enumeration value="ContactLocationBusiness"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="contactWebSiteType">\r
+        <xsd:sequence>\r
+            <xsd:element name="contactWebSiteType" type="msnab:ContactWebSiteTypeType"/>\r
+            <xsd:element name="webURL" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:simpleType name="ContactWebSiteTypeType">\r
+        <xsd:restriction base="xsd:string">\r
+            <xsd:enumeration value="ContactWebSitePersonal"/>\r
+            <xsd:enumeration value="ContactWebSiteBusiness"/>\r
+        </xsd:restriction>\r
+    </xsd:simpleType>\r
+    <xsd:complexType name="GroupType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groupId" type="msnab:Guid"/>\r
+            <xsd:element name="groupInfo" type="msnab:groupInfoType"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:string">\r
+                <xsd:annotation>\r
+                    <xsd:documentation>\r
+            A space (ASCII #32) separated list of properties that\r
+            have changed as part of an update request. The property\r
+            names don't always match the name of the associated\r
+            element.\r
+          </xsd:documentation>\r
+                </xsd:annotation>\r
+            </xsd:element>\r
+            <xsd:element name="fDeleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="groupInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="annotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupType" type="msnab:Guid" default="C8529CE2-6EAD-434d-881F-341E17DB3FF8" minOccurs="0"/>\r
+            <xsd:element name="name" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsPrivate" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="IsFavorite" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="fMessenger" type="xsd:boolean" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="groupFilterType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groupIds">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="guid" type="msnab:Guid" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="InvalidPassportUser">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="errorcode" type="xsd:string"/>\r
+                <xsd:element name="errorstring" type="xsd:string"/>\r
+                <xsd:element name="additionalDetails">\r
+                    <xsd:complexType>\r
+                        <xsd:sequence>\r
+                            <xsd:element name="originalExceptionErrorMessage" type="xsd:string"/>\r
+                        </xsd:sequence>\r
+                    </xsd:complexType>\r
+                </xsd:element>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:complexType name="MessengerMemberInfo">\r
+        <xsd:sequence>\r
+            <xsd:element name="PendingAnnotations" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Annotation" type="msnab:Annotation" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="InfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Handle" type="msnab:HandleType"/>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="InverseRequired" type="xsd:boolean" default="false"/>\r
+            <xsd:element name="AuthorizationCriteria" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RSSUrl" type="xsd:anyURI" minOccurs="0"/>\r
+            <xsd:element name="IsBot" type="xsd:boolean" default="false"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NotificationDataType">\r
+        <xsd:sequence>\r
+            <xsd:element name="StoreService" type="msnab:ServiceType"/>\r
+            <xsd:element name="Status" type="xsd:string"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="Gleam" type="xsd:boolean" default="false"/>\r
+            <xsd:element name="InstanceId" type="xsd:string" default="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="BaseDynamicItemType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Type" type="xsd:string"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Notifications" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="NotificationData" type="msnab:NotificationDataType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Changes" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleDynamicItem" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseDynamicItemType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PassportDynamicItem" block="" mixed="false">\r
+        <xsd:complexContent mixed="false">\r
+            <xsd:extension base="msnab:BaseDynamicItemType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="CID" type="xsd:string" minOccurs="0"/>\r
+                    <xsd:element name="PassportName" type="xsd:string"/>\r
+                    <xsd:element name="PassportId" type="xsd:string" minOccurs="0"/>\r
+                    <xsd:element name="SpaceStatus" type="xsd:string"/>\r
+                    <xsd:element name="SpaceLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="SpaceLastViewed" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="SpaceGleam" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="ProfileLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ProfileLastView" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ProfileStatus" type="xsd:string"/>\r
+                    <xsd:element name="ProfileGleam" type="xsd:boolean" minOccurs="0"/>\r
+                    <xsd:element name="ContactProfileStatus" type="xsd:string"/>\r
+                    <xsd:element name="ContactProfileLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="ContactProfileLastViewed" type="xsd:dateTime" minOccurs="0"/>\r
+                    <xsd:element name="LiveContactLastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="abType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid"/>\r
+            <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+            <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+            <xsd:element name="createDate" type="xsd:dateTime"/>\r
+            <xsd:element name="propertiesChanged" type="xsd:anyType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Circles" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="CircleInverseInfo" type="msnab:CircleInverseInfoType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleTicket" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NetworkInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="DomainId" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="DomainTag" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="UserTileURL" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="ProfileURL" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RelationshipType" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="RelationshipState" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="RelationshipStateDate" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="RelationshipRole" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="NDRCount" type="xsd:int" minOccurs="0"/>\r
+            <xsd:element name="InviterCID" type="xsd:long" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="PropertiesChanged" type="xsd:anyType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContactFilterType">\r
+        <xsd:sequence>\r
+            <xsd:element name="IncludeHiddenContacts" type="xsd:boolean"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="filterOptionsType">\r
+        <xsd:sequence>\r
+            <xsd:element name="DeltasOnly" type="xsd:boolean"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="ContactFilter" type="msnab:ContactFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="entityHandle">\r
+        <xsd:sequence>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="NotationType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="Value" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ListTemplateVariableItemType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Values">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Value" type="msnab:SimpleTemplateVariableBaseType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TemplateVariableBaseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="SimpleTemplateVariableBaseType">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Value" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PublisherIdTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Id" type="xsd:string"/>\r
+                    <xsd:element name="NameHint" type="xsd:string" minOccurs="0"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TargetIdTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:PublisherIdTemplateVariable">\r
+                <xsd:sequence>\r
+                    <xsd:element name="IdOwner" type="xsd:string"/>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="TextTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType"/>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="HlinkTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Text" type="xsd:string"/>\r
+                    <xsd:element name="Notations">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Notation" type="msnab:NotationType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ListTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:TemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Items">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="ListTemplateVariableItem" type="msnab:ListTemplateVariableItemType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ImageTemplateVariable">\r
+        <xsd:complexContent>\r
+            <xsd:extension base="msnab:SimpleTemplateVariableBaseType">\r
+                <xsd:sequence>\r
+                    <xsd:element name="Href" type="xsd:anyURI"/>\r
+                    <xsd:element name="Notations">\r
+                        <xsd:complexType>\r
+                            <xsd:sequence>\r
+                                <xsd:element name="Notation" type="msnab:NotationType" maxOccurs="unbounded"/>\r
+                            </xsd:sequence>\r
+                        </xsd:complexType>\r
+                    </xsd:element>\r
+                </xsd:sequence>\r
+            </xsd:extension>\r
+        </xsd:complexContent>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ActivityDetailsType">\r
+        <xsd:sequence>\r
+            <xsd:element name="OwnerCID" type="xsd:string"/>\r
+            <xsd:element name="ObjectId" type="xsd:string"/>\r
+            <xsd:element name="ApplicationId" type="xsd:string"/>\r
+            <xsd:element name="ChangeType" type="xsd:string"/>\r
+            <xsd:element name="PublishDate" type="xsd:dateTime"/>\r
+            <xsd:element name="TemplateVariables">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="TemplateVariable" type="msnab:TemplateVariableBaseType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RecentActivityTemplateType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Cardinality" type="xsd:string"/>\r
+            <xsd:element name="Data" type="xsd:string"/>\r
+            <xsd:element name="Title" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RequestedLocalesType">\r
+        <xsd:sequence>\r
+            <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="RecentActivityTemplateContainerType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ApplicationId" type="xsd:string"/>\r
+            <xsd:element name="ApplicationName" type="xsd:string"/>\r
+            <xsd:element name="ChangeType" type="xsd:integer"/>\r
+            <xsd:element name="Locale" type="xsd:string"/>\r
+            <xsd:element name="RequestedLocales" type="msnab:RequestedLocalesType"/>\r
+            <xsd:element name="TemplateRevision" type="xsd:integer"/>\r
+            <xsd:element name="Templates">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="RecentActivityTemplate" type="msnab:RecentActivityTemplateType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CollapseCondition" type="msnab:CollapseConditionType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CollapseConditionType">\r
+        <xsd:sequence>\r
+            <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CirclePersonalMembershipType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Role" type="xsd:string"/>\r
+            <xsd:element name="State" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="abHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ABId" type="xsd:string"/>\r
+            <xsd:element name="Puid" type="xsd:long"/>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="contactHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Email" type="xsd:string"/>\r
+            <xsd:element name="Puid" type="xsd:long"/>\r
+            <xsd:element name="Cid" type="xsd:long"/>\r
+            <xsd:element name="CircleId" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="MembershipInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="CirclePersonalMembership" type="msnab:CirclePersonalMembershipType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="PersonalInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="MembershipInfo" type="msnab:MembershipInfoType"/>\r
+            <xsd:element name="Name" type="xsd:string"/>\r
+            <xsd:element name="IsNotMobileVisible" type="xsd:boolean"/>\r
+            <xsd:element name="IsFavorite" type="xsd:boolean"/>\r
+            <xsd:element name="IsFamily" type="xsd:boolean"/>\r
+            <xsd:element name="Changes" type="xsd:anyType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Domain" type="xsd:int"/>\r
+            <xsd:element name="HostedDomain" type="xsd:string"/>\r
+            <xsd:element name="Type" type="xsd:int"/>\r
+            <xsd:element name="MembershipAccess" type="xsd:int"/>\r
+            <xsd:element name="IsPresenceEnabled" type="xsd:boolean"/>\r
+            <xsd:element name="RequestMembershipOption" type="xsd:int"/>\r
+            <xsd:element name="DisplayName" type="xsd:string"/>\r
+            <xsd:element name="ProfileLastUpdated" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="Changes" type="xsd:anyType" minOccurs="0"/>\r
+            <xsd:element name="CreateDate" type="xsd:dateTime" minOccurs="0"/>\r
+            <xsd:element name="LastChanged" type="xsd:dateTime" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentHandleType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ContentType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Handle" type="msnab:ContentHandleType"/>\r
+            <xsd:element name="Info" type="msnab:ContentInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CircleInverseInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Content" type="msnab:ContentType"/>\r
+            <xsd:element name="PersonalInfo" type="msnab:PersonalInfoType"/>\r
+            <xsd:element name="Deleted" type="xsd:boolean"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="callerInfoType">\r
+        <xsd:sequence>\r
+            <xsd:element name="PublicDisplayName" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+</xsd:schema>\r
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd b/plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd
new file mode 100644 (file)
index 0000000..3fa9798
--- /dev/null
@@ -0,0 +1,567 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<xsd:schema xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.msn.com/webservices/AddressBook" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">\r
+    <xsd:include schemaLocation="msnab_datatypes.xsd"/>\r
+    <xsd:element name="ABApplicationHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ApplicationId" type="msnab:Guid" fixed="09607671-1C32-421F-A6A6-CBFAA51AB5F4"/>\r
+                <xsd:element name="IsMigration" type="xsd:boolean" default="false"/>\r
+                <xsd:element name="PartnerScenario" type="xsd:string" default="Initial"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="BrandId" type="xsd:string" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABAuthHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ManagedGroupRequest" type="xsd:boolean" default="false"/>\r
+                <xsd:element name="TicketToken" type="xsd:string"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ServiceHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="Version" type="xsd:token"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="CacheKeyChanged" type="xsd:boolean" minOccurs="0"/>\r
+                <xsd:element name="PreferredHostName" type="xsd:string" minOccurs="0"/>\r
+                <xsd:element name="SessionId" type="msnab:Guid" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="FindMembership" type="msnab:FindMembershipRequestType"/>\r
+    <xsd:complexType name="FindMembershipRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceFilter">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Types">\r
+                            <xsd:complexType>\r
+                                <xsd:sequence>\r
+                                    <xsd:element name="ServiceType" type="xsd:string" maxOccurs="unbounded"/>\r
+                                </xsd:sequence>\r
+                            </xsd:complexType>\r
+                        </xsd:element>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="View" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="deltasOnly" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="FindMembershipResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Services">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Service" type="msnab:ServiceType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="OwnerNamespace">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Info">\r
+                            <xsd:complexType>\r
+                                <xsd:sequence>\r
+                                    <xsd:element name="Handle">\r
+                                        <xsd:complexType>\r
+                                            <xsd:sequence>\r
+                                                <xsd:element name="Id" type="xsd:string"/>\r
+                                                <xsd:element name="IsPassportNameHidden" type="xsd:boolean"/>\r
+                                                <xsd:element name="CID" type="xsd:integer"/>\r
+                                            </xsd:sequence>\r
+                                        </xsd:complexType>\r
+                                    </xsd:element>\r
+                                    <xsd:element name="CreatorPuid" type="xsd:integer"/>\r
+                                    <xsd:element name="CreatorCID" type="xsd:integer"/>\r
+                                    <xsd:element name="CreatorPassportName" type="xsd:string"/>\r
+                                    <xsd:element name="CircleAttributes">\r
+                                        <xsd:complexType>\r
+                                            <xsd:sequence>\r
+                                                <xsd:element name="IsPresenceEnabled" type="xsd:boolean"/>\r
+                                                <xsd:element name="IsEvent" type="xsd:boolean" minOccurs="0"/>\r
+                                                <xsd:element name="Domain" type="xsd:string"/>\r
+                                            </xsd:sequence>\r
+                                        </xsd:complexType>\r
+                                    </xsd:element>\r
+                                    <xsd:element name="MessengerApplicationServiceCreated" type="xsd:boolean" minOccurs="0"/>\r
+                                </xsd:sequence>\r
+                            </xsd:complexType>\r
+                        </xsd:element>\r
+                        <xsd:element name="Changes" type="xsd:string"/>\r
+                        <xsd:element name="CreateDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="LastChange" type="xsd:dateTime"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="FindMembershipResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="FindMembershipResult" type="msnab:FindMembershipResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABFindAll" type="msnab:ABFindAllRequestType"/>\r
+    <xsd:complexType name="ABFindAllRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="abView" type="xsd:string" minOccurs="0"/>\r
+            <xsd:element name="deltasOnly" type="xsd:boolean" default="false" minOccurs="0"/>\r
+            <xsd:element name="lastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+            <xsd:element name="dynamicItemView" type="xsd:string" fixed="Gleam" minOccurs="0"/>\r
+            <xsd:element name="dynamicItemLastChange" type="xsd:dateTime" default="0001-01-01T00:00:00.0000000-08:00" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABFindAllResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="groups" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="DynamicItems" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="DynamicItem" type="msnab:BaseDynamicItemType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleResult">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="CircleTicket" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="ab">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="abId" type="msnab:Guid"/>\r
+                        <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+                        <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+                        <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="createDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABFindAllResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABFindAllResult" type="msnab:ABFindAllResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactAdd" type="msnab:ABContactAddRequestType"/>\r
+    <xsd:complexType name="ABContactAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="options" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="EnableAllowListManagement" type="xsd:boolean"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABContactAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABContactAddResult" type="msnab:ABContactAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactDelete" type="msnab:ABContactDeleteRequestType"/>\r
+    <xsd:complexType name="ABContactDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactIdType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactDeleteResponse"/>\r
+    <xsd:element name="ABGroupContactAdd" type="msnab:ABGroupContactAddRequestType"/>\r
+    <xsd:complexType name="ABGroupContactAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupContactAddOptions" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="fGenerateMissingQuickName" type="xsd:boolean" minOccurs="0"/>\r
+                        <xsd:element name="EnableAllowListManagement" type="xsd:boolean" minOccurs="0"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABGroupContactAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupContactAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABGroupContactAddResult" type="msnab:ABGroupContactAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupAdd" type="msnab:ABGroupAddRequestType"/>\r
+    <xsd:complexType name="ABGroupAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupAddOptions">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="fRenameOnMsgrConflict" type="xsd:boolean" minOccurs="0"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupInfo">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="GroupInfo" type="msnab:groupInfoType"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABGroupAddResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="guid" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupAddResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABGroupAddResult" type="msnab:ABGroupAddResultType" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupUpdate" type="msnab:ABGroupUpdateRequestType"/>\r
+    <xsd:complexType name="ABGroupUpdateRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groups">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupUpdateResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupDelete" type="msnab:ABGroupDeleteRequestType"/>\r
+    <xsd:complexType name="ABGroupDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupDeleteResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABContactUpdate" type="msnab:ABContactUpdateRequestType"/>\r
+    <xsd:complexType name="ABContactUpdateRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABContactUpdateResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="ABGroupContactDelete" type="msnab:ABGroupContactDeleteRequestType"/>\r
+    <xsd:complexType name="ABGroupContactDeleteRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="msnab:Guid" fixed="00000000-0000-0000-0000-000000000000"/>\r
+            <xsd:element name="contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="groupFilter" type="msnab:groupFilterType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABGroupContactDeleteResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="AddMember" type="msnab:AddMemberRequestType"/>\r
+    <xsd:complexType name="AddMemberRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceHandle" type="msnab:HandleType"/>\r
+            <xsd:element name="memberships">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="AddMemberResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:element name="DeleteMember" type="msnab:DeleteMemberRequestType"/>\r
+    <xsd:complexType name="DeleteMemberRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="serviceHandle" type="msnab:HandleType"/>\r
+            <xsd:element name="memberships">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Membership" type="msnab:Membership" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="nsHandle" type="msnab:ContentHandleType" minOccurs="0"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="DeleteMemberResponse">\r
+        <xsd:complexType/>\r
+    </xsd:element>\r
+    <xsd:complexType name="ABAddResponseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="ABAddResult" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABAddResponse" type="msnab:ABAddResponseType"/>\r
+    <xsd:element name="ABAdd" type="msnab:ABAddRequestType"/>\r
+    <xsd:complexType name="ABAddRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="UpdateDynamicItemRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abId" type="xsd:string"/>\r
+            <xsd:element name="dynamicItems">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="DynamicItem" type="msnab:BaseDynamicItemType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="UpdateDynamicItem" type="msnab:UpdateDynamicItemRequestType"/>\r
+    <xsd:element name="UpdateDynamicItemResponse"/>\r
+    <xsd:element name="ABFindContactsPaged" type="msnab:ABFindContactsPagedRequestType"/>\r
+    <xsd:complexType name="ABFindContactsPagedRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="filterOptions" type="msnab:filterOptionsType"/>\r
+            <xsd:element name="abView" type="xsd:string"/>\r
+            <xsd:element name="extendedContent" type="xsd:string"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="ABFindContactsPagedResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Groups" minOccurs="0">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Group" type="msnab:GroupType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Contacts">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="Contact" type="msnab:ContactType" minOccurs="0" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="CircleResult" type="msnab:CircleResultType"/>\r
+            <xsd:element name="Ab">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="abId" type="msnab:Guid"/>\r
+                        <xsd:element name="abInfo" type="msnab:abInfoType"/>\r
+                        <xsd:element name="lastChange" type="xsd:dateTime"/>\r
+                        <xsd:element name="DynamicItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="RecentActivityItemLastChanged" type="xsd:dateTime"/>\r
+                        <xsd:element name="createDate" type="xsd:dateTime"/>\r
+                        <xsd:element name="propertiesChanged" type="xsd:string"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ABFindContactsPagedResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ABFindContactsPagedResult" type="msnab:ABFindContactsPagedResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNApplicationHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ApplicationId" type="msnab:Guid"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNAuthHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="TicketToken" type="xsd:string"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="WNServiceHeader">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="Version" type="xsd:token"/>\r
+                <xsd:element name="CacheKey" type="xsd:token" minOccurs="0"/>\r
+                <xsd:element name="CacheKeyChanged" type="xsd:boolean" minOccurs="0"/>\r
+                <xsd:element name="PreferredHostName" type="xsd:string" minOccurs="0"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="GetContactsRecentActivity" type="msnab:GetContactsRecentActivityRequestType"/>\r
+    <xsd:complexType name="GetContactsRecentActivityRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="entityHandle" type="msnab:entityHandle"/>\r
+            <xsd:element name="locales">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="string" type="xsd:string" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="count" type="xsd:int"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="GetContactsRecentActivityResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="GetContactsRecentActivityResult" type="msnab:GetContactsRecentActivityResultType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:complexType name="GetContactsRecentActivityResultType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Activities">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="ActivityDetails" type="msnab:ActivityDetailsType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="Templates">\r
+                <xsd:complexType>\r
+                    <xsd:sequence>\r
+                        <xsd:element name="RecentActivityTemplateContainer" type="msnab:RecentActivityTemplateContainerType" maxOccurs="unbounded"/>\r
+                    </xsd:sequence>\r
+                </xsd:complexType>\r
+            </xsd:element>\r
+            <xsd:element name="FeedUrl" type="xsd:anyURI"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ManageWLConnection" type="msnab:ManageWLConnectionRequestType"/>\r
+    <xsd:complexType name="ManageWLConnectionRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abHandle" type="msnab:abHandleType"/>\r
+            <xsd:element name="contactId" type="xsd:string"/>\r
+            <xsd:element name="connection" type="xsd:boolean"/>\r
+            <xsd:element name="presence" type="xsd:boolean"/>\r
+            <xsd:element name="action" type="xsd:integer"/>\r
+            <xsd:element name="relationshipType" type="xsd:int"/>\r
+            <xsd:element name="relationshipRole" type="xsd:int"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="ManageWLConnectionResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="ManageWLConnectionResult" type="msnab:ContactType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="CreateContact" type="msnab:CreateContactType"/>\r
+    <xsd:complexType name="CreateContactType">\r
+        <xsd:sequence>\r
+            <xsd:element name="abHandle" type="msnab:abHandleType"/>\r
+            <xsd:element name="contactHandle" type="msnab:contactHandleType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="CreateContactResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="CreateContactResult" type="msnab:ContactType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+    <xsd:element name="CreateCircle" type="msnab:CreateCircleRequestType"/>\r
+    <xsd:complexType name="CreateCircleRequestType">\r
+        <xsd:sequence>\r
+            <xsd:element name="properties" type="msnab:ContentInfoType"/>\r
+            <xsd:element name="callerInfo" type="msnab:callerInfoType"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:complexType name="CreateCircleResponseType">\r
+        <xsd:sequence>\r
+            <xsd:element name="Id" type="msnab:Guid"/>\r
+        </xsd:sequence>\r
+    </xsd:complexType>\r
+    <xsd:element name="CreateCircleResponse">\r
+        <xsd:complexType>\r
+            <xsd:sequence>\r
+                <xsd:element name="CreateCircleResult" type="msnab:CreateCircleResponseType"/>\r
+            </xsd:sequence>\r
+        </xsd:complexType>\r
+    </xsd:element>\r
+</xsd:schema>\r
diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl b/plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl
new file mode 100644 (file)
index 0000000..7ec87f9
--- /dev/null
@@ -0,0 +1,532 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- edited with XMLSpy v2008 sp1 (http://www.altova.com) by wp (freezingsoft) -->\r
+<definitions xmlns:msnab="http://www.msn.com/webservices/AddressBook" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.msn.com/webservices/AddressBook">\r
+    <types>\r
+        <ns:schema xmlns="http://www.w3.org/2001/XMLSchema">\r
+            <ns:import schemaLocation="msnab_servicetypes.xsd" namespace="http://www.msn.com/webservices/AddressBook"/>\r
+        </ns:schema>\r
+    </types>\r
+    <message name="ABHeader">\r
+        <part name="ApplicationHeader" element="msnab:ABApplicationHeader"/>\r
+        <part name="AuthHeader" element="msnab:ABAuthHeader"/>\r
+    </message>\r
+    <message name="FindMembershipMessage">\r
+        <part name="FindMembershipRequest" element="msnab:FindMembership"/>\r
+    </message>\r
+    <message name="ABFindAllMessage">\r
+        <part name="ABFindAllRequest" element="msnab:ABFindAll"/>\r
+    </message>\r
+    <message name="ABContactAddMessage">\r
+        <part name="ABContactAddRequest" element="msnab:ABContactAdd"/>\r
+    </message>\r
+    <message name="ABContactDeleteMessage">\r
+        <part name="ABContactDeleteRequest" element="msnab:ABContactDelete"/>\r
+    </message>\r
+    <message name="ABGroupContactAddMessage">\r
+        <part name="ABGroupContactAddRequest" element="msnab:ABGroupContactAdd"/>\r
+    </message>\r
+    <message name="ABGroupAddMessage">\r
+        <part name="ABGroupAddRequest" element="msnab:ABGroupAdd"/>\r
+    </message>\r
+    <message name="ABGroupUpdateMessage">\r
+        <part name="ABGroupUpdateRequest" element="msnab:ABGroupUpdate"/>\r
+    </message>\r
+    <message name="ABGroupDeleteMessage">\r
+        <part name="ABGroupDeleteRequest" element="msnab:ABGroupDelete"/>\r
+    </message>\r
+    <message name="ABGroupContactDeleteMessage">\r
+        <part name="ABGroupContactDeleteRequest" element="msnab:ABGroupContactDelete"/>\r
+    </message>\r
+    <message name="ABContactUpdateMessage">\r
+        <part name="ABContactUpdateRequest" element="msnab:ABContactUpdate"/>\r
+    </message>\r
+    <message name="AddMemberMessage">\r
+        <part name="AddMemberRequest" element="msnab:AddMember"/>\r
+    </message>\r
+    <message name="DeleteMemberMessage">\r
+        <part name="DeleteMemberRequest" element="msnab:DeleteMember"/>\r
+    </message>\r
+    <message name="ServiceHeader">\r
+        <part name="ServiceHeader" element="msnab:ServiceHeader"/>\r
+    </message>\r
+    <message name="FindMembershipResponseMessage">\r
+        <part name="FindMembershipResponse" element="msnab:FindMembershipResponse"/>\r
+    </message>\r
+    <message name="ABFindAllResponseMessage">\r
+        <part name="ABFindAllResponse" element="msnab:ABFindAllResponse"/>\r
+    </message>\r
+    <message name="ABContactAddResponseMessage">\r
+        <part name="ABContactAddResponse" element="msnab:ABContactAddResponse"/>\r
+    </message>\r
+    <message name="ABContactDeleteResponseMessage">\r
+        <part name="ABContactDeleteResponse" element="msnab:ABContactDeleteResponse"/>\r
+    </message>\r
+    <message name="ABGroupContactAddResponseMessage">\r
+        <part name="ABGroupContactAddResponse" element="msnab:ABGroupContactAddResponse"/>\r
+    </message>\r
+    <message name="ABGroupAddResponseMessage">\r
+        <part name="ABGroupAddResponse" element="msnab:ABGroupAddResponse"/>\r
+    </message>\r
+    <message name="ABGroupUpdateResponseMessage">\r
+        <part name="ABGroupUpdateResponse" element="msnab:ABGroupUpdateResponse"/>\r
+    </message>\r
+    <message name="ABGroupDeleteResponseMessage">\r
+        <part name="ABGroupDeleteResponse" element="msnab:ABGroupDeleteResponse"/>\r
+    </message>\r
+    <message name="ABGroupContactDeleteResponseMessage">\r
+        <part name="ABGroupContactDeleteResponse" element="msnab:ABGroupContactDeleteResponse"/>\r
+    </message>\r
+    <message name="ABContactUpdateResponseMessage">\r
+        <part name="ABContactUpdateResponse" element="msnab:ABContactUpdateResponse"/>\r
+    </message>\r
+    <message name="AddMemberResponseMessage">\r
+        <part name="AddMemberResponse" element="msnab:AddMemberResponse"/>\r
+    </message>\r
+    <message name="DeleteMemberResponseMessage">\r
+        <part name="DeleteMemberResponse" element="msnab:DeleteMemberResponse"/>\r
+    </message>\r
+    <message name="InvalidPassportUserMessage">\r
+        <part name="fault" element="msnab:InvalidPassportUser"/>\r
+    </message>\r
+    <message name="ABAddMessage">\r
+        <part name="ABAddRequest" element="msnab:ABAdd"/>\r
+    </message>\r
+    <message name="ABAddResponseMessage">\r
+        <part name="ABAddResponse" element="msnab:ABAddResponse"/>\r
+    </message>\r
+    <message name="UpdateDynamicItemMessage">\r
+        <part name="UpdateDynamicItem" element="msnab:UpdateDynamicItem"/>\r
+    </message>\r
+    <message name="UpdateDynamicItemResponseMessage">\r
+        <part name="UpdateDynamicItemResponse" element="msnab:UpdateDynamicItemResponse"/>\r
+    </message>\r
+    <message name="ABFindContactsPagedMessage">\r
+        <part name="ABFindContactsPagedRequest" element="msnab:ABFindContactsPaged"/>\r
+    </message>\r
+    <message name="ABFindContactsPagedResponseMessage">\r
+        <part name="ABFindContactsPagedResponse" element="msnab:ABFindContactsPagedResponse"/>\r
+    </message>\r
+    <message name="GetContactsRecentActivityMessage">\r
+        <part name="GetContactsRecentActivityRequest" element="msnab:GetContactsRecentActivity"/>\r
+    </message>\r
+    <message name="GetContactsRecentActivityResponseMessage">\r
+        <part name="GetContactsRecentActivityResponse" element="msnab:GetContactsRecentActivityResponse"/>\r
+    </message>\r
+    <message name="WNHeader">\r
+        <part name="WNApplicationHeader" element="msnab:WNApplicationHeader"/>\r
+        <part name="WNAuthHeader" element="msnab:WNAuthHeader"/>\r
+        <part name="WNServiceHeader" element="msnab:WNServiceHeader"/>\r
+    </message>\r
+    <message name="CreateCircleMessage">\r
+        <part name="CreateCircleRequest" element="msnab:CreateCircle"/>\r
+    </message>\r
+    <message name="CreateCircleResponseMessage">\r
+        <part name="CreateCircleResponse" element="msnab:CreateCircleResponse"/>\r
+    </message>\r
+    <message name="CreateContactMessage">\r
+        <part name="CreateContactRequest" element="msnab:CreateContact"/>\r
+    </message>\r
+    <message name="CreateContactResponseMessage">\r
+        <part name="CreateContactResponse" element="msnab:CreateContactResponse"/>\r
+    </message>\r
+    <message name="ManageWLConnectionMessage">\r
+        <part name="ManageWLConnection" element="msnab:ManageWLConnection"/>\r
+    </message>\r
+    <message name="ManageWLConnectionResponseMessage">\r
+        <part name="ManageWLConnectionResponse" element="msnab:ManageWLConnectionResponse"/>\r
+    </message>\r
+    <portType name="SharingServicePortType">\r
+        <operation name="FindMembership">\r
+            <input message="msnab:FindMembershipMessage"/>\r
+            <output message="msnab:FindMembershipResponseMessage"/>\r
+        </operation>\r
+        <operation name="AddMember">\r
+            <input message="msnab:AddMemberMessage"/>\r
+            <output message="msnab:AddMemberResponseMessage"/>\r
+        </operation>\r
+        <operation name="DeleteMember">\r
+            <input message="msnab:DeleteMemberMessage"/>\r
+            <output message="msnab:DeleteMemberResponseMessage"/>\r
+        </operation>\r
+        <operation name="CreateCircle">\r
+            <input message="msnab:CreateCircleMessage"/>\r
+            <output message="msnab:CreateCircleResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <portType name="ABServicePortType">\r
+        <operation name="ABFindAll">\r
+            <input message="msnab:ABFindAllMessage"/>\r
+            <output message="msnab:ABFindAllResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABContactAdd">\r
+            <input message="msnab:ABContactAddMessage"/>\r
+            <output message="msnab:ABContactAddResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABContactDelete">\r
+            <input message="msnab:ABContactDeleteMessage"/>\r
+            <output message="msnab:ABContactDeleteResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupContactAdd">\r
+            <input message="msnab:ABGroupContactAddMessage"/>\r
+            <output message="msnab:ABGroupContactAddResponseMessage"/>\r
+            <fault name="InvalidPassportUserException" message="msnab:InvalidPassportUserMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupAdd">\r
+            <input message="msnab:ABGroupAddMessage"/>\r
+            <output message="msnab:ABGroupAddResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupUpdate">\r
+            <input message="msnab:ABGroupUpdateMessage"/>\r
+            <output message="msnab:ABGroupUpdateResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupDelete">\r
+            <input message="msnab:ABGroupDeleteMessage"/>\r
+            <output message="msnab:ABGroupDeleteResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABGroupContactDelete">\r
+            <input message="msnab:ABGroupContactDeleteMessage"/>\r
+            <output message="msnab:ABGroupContactDeleteResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABContactUpdate">\r
+            <input message="msnab:ABContactUpdateMessage"/>\r
+            <output message="msnab:ABContactUpdateResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABAdd">\r
+            <input message="msnab:ABAddMessage"/>\r
+            <output message="msnab:ABAddResponseMessage"/>\r
+        </operation>\r
+        <operation name="UpdateDynamicItem">\r
+            <input message="msnab:UpdateDynamicItemMessage"/>\r
+            <output message="msnab:UpdateDynamicItemResponseMessage"/>\r
+        </operation>\r
+        <operation name="ABFindContactsPaged">\r
+            <input message="msnab:ABFindContactsPagedMessage"/>\r
+            <output message="msnab:ABFindContactsPagedResponseMessage"/>\r
+        </operation>\r
+        <operation name="CreateContact">\r
+            <input message="msnab:CreateContactMessage"/>\r
+            <output message="msnab:CreateContactResponseMessage"/>\r
+        </operation>\r
+        <operation name="ManageWLConnection">\r
+            <input message="msnab:ManageWLConnectionMessage"/>\r
+            <output message="msnab:ManageWLConnectionResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <portType name="WhatsUpServicePortType">\r
+        <operation name="GetContactsRecentActivity">\r
+            <input message="msnab:GetContactsRecentActivityMessage"/>\r
+            <output message="msnab:GetContactsRecentActivityResponseMessage"/>\r
+        </operation>\r
+    </portType>\r
+    <binding name="SharingServiceBinding" type="msnab:SharingServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="FindMembership">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/FindMembership"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="AddMember">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/AddMember"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="DeleteMember">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/DeleteMember"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="CreateCircle">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/CreateCircle"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <binding name="ABServiceBinding" type="msnab:ABServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="ABFindAll">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABFindAll"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABContactAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABContactDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABGroupContactAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupContactAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+            <fault name="InvalidPassportUserException">\r
+                <soap:fault name="InvalidPassportUserException" use="literal"/>\r
+            </fault>\r
+        </operation>\r
+        <operation name="ABGroupAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupAdd"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupUpdate">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupUpdate"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABGroupContactDelete">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABGroupContactDelete"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABContactUpdate">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABContactUpdate"/>\r
+            <input>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+                <soap:body use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABAdd">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABAdd"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="UpdateDynamicItem">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/UpdateDynamicItem"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ABFindContactsPaged">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ABFindContactsPaged"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="CreateContact">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/CreateContact"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+        <operation name="ManageWLConnection">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/ManageWLConnection"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="ApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:ABHeader" part="AuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:ServiceHeader" part="ServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <binding name="WhatsUpServiceBinding" type="msnab:WhatsUpServicePortType">\r
+        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>\r
+        <operation name="GetContactsRecentActivity">\r
+            <soap:operation soapAction="http://www.msn.com/webservices/AddressBook/GetContactsRecentActivity"/>\r
+            <input>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNApplicationHeader" use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNAuthHeader" use="literal"/>\r
+            </input>\r
+            <output>\r
+                <soap:body use="literal"/>\r
+                <soap:header message="msnab:WNHeader" part="WNServiceHeader" use="literal"/>\r
+            </output>\r
+        </operation>\r
+    </binding>\r
+    <service name="SharingService">\r
+        <port name="FindMembershipPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="AddMemberPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="DeleteMemberPort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+        <port name="CreateCirclePort" binding="msnab:SharingServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/SharingService.asmx"/>\r
+        </port>\r
+    </service>\r
+    <service name="ABService">\r
+        <port name="ABFindAllPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupContactAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupUpdatePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABGroupContactDeletePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABContactUpdatePort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABAddPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="UpdateDynamicItemPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ABFindContactsPagedPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="CreateContactPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+        <port name="ManageWLConnectionPort" binding="msnab:ABServiceBinding">\r
+            <soap:address location="https://contacts.msn.com/abservice/abservice.asmx"/>\r
+        </port>\r
+    </service>\r
+    <service name="WhatsUpService">\r
+        <port name="GetContactsRecentActivityPort" binding="msnab:WhatsUpServiceBinding">\r
+            <soap:address location="http://sup.live.com/whatsnew/whatsnewservice.asmx"/>\r
+        </port>\r
+    </service>\r
+</definitions>\r
diff --git a/plugins/Msn/msn_waiting_message.php b/plugins/Msn/msn_waiting_message.php
new file mode 100644 (file)
index 0000000..0af7c4f
--- /dev/null
@@ -0,0 +1,132 @@
+<?php\r
+/**\r
+ * Table Definition for msn_waiting_message\r
+ */\r
+require_once INSTALLDIR.'/classes/Memcached_DataObject.php';\r
+\r
+class Msn_waiting_message extends Memcached_DataObject {\r
+\r
+    public $__table = 'msn_waiting_message'; // table name\r
+    public $id;                              // int primary_key not_null auto_increment\r
+    public $screenname;                      // varchar(255) not_null\r
+    public $message;                         // text not_null\r
+    public $created;                         // datetime() not_null\r
+    public $claimed;                         // datetime()\r
+\r
+    /* Static get */\r
+    public function staticGet($k, $v = null) {\r
+        return Memcached_DataObject::staticGet('Msn_waiting_message', $k, $v);\r
+    }\r
+\r
+    /**\r
+    * return table definition for DB_DataObject\r
+    *\r
+    * DB_DataObject needs to know something about the table to manipulate\r
+    * instances. This method provides all the DB_DataObject needs to know.\r
+    *\r
+    * @return array array of column definitions\r
+    */\r
+    public function table() {\r
+        return array('id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,\r
+                     'screenname' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,\r
+                     'message' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,\r
+                     'created' => DB_DATAOBJECT_TIME + DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,\r
+                     'claimed' => DB_DATAOBJECT_TIME + DB_DATAOBJECT_STR);\r
+    }\r
+\r
+    /**\r
+    * return key definitions for DB_DataObject\r
+    *\r
+    * DB_DataObject needs to know about keys that the table has, since it\r
+    * won't appear in StatusNet's own keys list. In most cases, this will\r
+    * simply reference your keyTypes() function.\r
+    *\r
+    * @return array list of key field names\r
+    */\r
+    public function keys() {\r
+        return array_keys($this->keyTypes());\r
+    }\r
+\r
+    /**\r
+    * return key definitions for Memcached_DataObject\r
+    *\r
+    * Our caching system uses the same key definitions, but uses a different\r
+    * method to get them. This key information is used to store and clear\r
+    * cached data, so be sure to list any key that will be used for static\r
+    * lookups.\r
+    *\r
+    * @return array associative array of key definitions, field name to type:\r
+    *         'K' for primary key: for compound keys, add an entry for each component;\r
+    *         'U' for unique keys: compound keys are not well supported here.\r
+    */\r
+    public function keyTypes() {\r
+        return array('id' => 'K');\r
+    }\r
+\r
+    /**\r
+    * Magic formula for non-autoincrementing integer primary keys\r
+    *\r
+    * If a table has a single integer column as its primary key, DB_DataObject\r
+    * assumes that the column is auto-incrementing and makes a sequence table\r
+    * to do this incrementation. Since we don't need this for our class, we\r
+    * overload this method and return the magic formula that DB_DataObject needs.\r
+    *\r
+    * @return array magic three-false array that stops auto-incrementing.\r
+    */\r
+    function sequenceKey() {\r
+        return array(false, false, false);\r
+    }\r
+\r
+    /**\r
+     * @param string $screenname screenname or array of screennames to pull from\r
+     *                          If not specified, checks all queues in the system.\r
+     */\r
+    public static function top($screenname = null) {\r
+        $wm = new Msn_waiting_message();\r
+        if ($screenname) {\r
+            if (is_array($screenname)) {\r
+                // @fixme use safer escaping\r
+                $list = implode("','", array_map('addslashes', $screenname));\r
+                $wm->whereAdd("screenname in ('$list')");\r
+            } else {\r
+                $wm->screenname = $screenname;\r
+            }\r
+        }\r
+        $wm->orderBy('created');\r
+        $wm->whereAdd('claimed is null');\r
+\r
+        $wm->limit(1);\r
+\r
+        $cnt = $wm->find(true);\r
+\r
+        if ($cnt) {\r
+            # XXX: potential race condition\r
+            # can we force it to only update if claimed is still null\r
+            # (or old)?\r
+            common_log(LOG_INFO, 'claiming msn waiting message id = ' . $wm->id);\r
+            $orig = clone($wm);\r
+            $wm->claimed = common_sql_now();\r
+            $result = $wm->update($orig);\r
+            if ($result) {\r
+                common_log(LOG_INFO, 'claim succeeded.');\r
+                return $wm;\r
+            } else {\r
+                common_log(LOG_INFO, 'claim failed.');\r
+            }\r
+        }\r
+        $wm = null;\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Release a claimed item.\r
+     */\r
+    public function releaseClaim() {\r
+        // DB_DataObject doesn't let us save nulls right now\r
+        $sql = sprintf("UPDATE msn_waiting_message SET claimed=NULL WHERE id=%d", $this->id);\r
+        $this->query($sql);\r
+\r
+        $this->claimed = null;\r
+        $this->encache();\r
+    }\r
+}\r
diff --git a/plugins/Msn/msnmanager.php b/plugins/Msn/msnmanager.php
new file mode 100644 (file)
index 0000000..8f434da
--- /dev/null
@@ -0,0 +1,275 @@
+<?php\r
+/*\r
+ * StatusNet - the distributed open-source microblogging tool\r
+ * Copyright (C) 2008, 2009, StatusNet, Inc.\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU Affero General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU Affero General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Affero General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }\r
+\r
+/**\r
+ * MSN background connection manager for MSN-using queue handlers,\r
+ * allowing them to send outgoing messages on the right connection.\r
+ *\r
+ * Input is handled during socket select loop, keepalive pings during idle.\r
+ * Any incoming messages will be handled.\r
+ *\r
+ * In a multi-site queuedaemon.php run, one connection will be instantiated\r
+ * for each site being handled by the current process that has MSN enabled.\r
+ */\r
+\r
+class MsnManager extends ImManager {\r
+    public $conn = null;\r
+    protected $lastPing = null;\r
+    protected $pingInterval;\r
+\r
+    /**\r
+     * Initialise connection to server.\r
+     *\r
+     * @return boolean true on success\r
+     */\r
+    public function start($master) {\r
+        if (parent::start($master)) {\r
+            $this->requeue_waiting_messages();\r
+            $this->connect();\r
+            return true;\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    /**\r
+    * Return any open sockets that the run loop should listen\r
+    * for input on.\r
+    *\r
+    * @return array Array of socket resources\r
+    */\r
+    public function getSockets() {\r
+        $this->connect();\r
+        if ($this->conn) {\r
+            return $this->conn->getSockets();\r
+        } else {\r
+            return array();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Idle processing for io manager's execution loop.\r
+     * Send keepalive pings to server.\r
+     *\r
+     * @return void\r
+     */\r
+    public function idle($timeout = 0) {\r
+        if (empty($this->lastPing) || time() - $this->lastPing > $this->pingInterval) {\r
+            $this->send_ping();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Message pump is triggered on socket input, so we only need an idle()\r
+     * call often enough to trigger our outgoing pings.\r
+     */\r
+    public function timeout() {\r
+        return $this->pingInterval;\r
+    }\r
+\r
+    /**\r
+     * Process MSN events that have come in over the wire.\r
+     *\r
+     * @param resource $socket Socket ready\r
+     * @return void\r
+     */\r
+    public function handleInput($socket) {\r
+        common_log(LOG_DEBUG, 'Servicing the MSN queue.');\r
+        $this->stats('msn_process');\r
+        $this->conn->receive();\r
+    }\r
+\r
+    /**\r
+    * Initiate connection\r
+    *\r
+    * @return void\r
+    */\r
+    public function connect() {\r
+        if (!$this->conn) {\r
+            $this->conn = new MSN(\r
+                array(\r
+                    'user' => $this->plugin->user,\r
+                    'password' => $this->plugin->password,\r
+                    'alias' => $this->plugin->nickname,\r
+                    'psm' => 'Send me a message to post a notice',\r
+                    'debug' => false\r
+                )\r
+            );\r
+            $this->conn->registerHandler('IMin', array($this, 'handle_msn_message'));\r
+            $this->conn->registerHandler('SessionReady', array($this, 'handle_session_ready'));\r
+            $this->conn->registerHandler('Pong', array($this, 'update_ping_time'));\r
+            $this->conn->registerHandler('ConnectFailed', array($this, 'handle_connect_failed'));\r
+            $this->conn->registerHandler('Reconnect', array($this, 'handle_reconnect'));\r
+            $this->conn->signon();\r
+            $this->lastPing = time();\r
+        }\r
+        return $this->conn;\r
+    }\r
+\r
+    /**\r
+    * Called by the idle process to send a ping\r
+    * when necessary\r
+    *\r
+    * @return void\r
+    */\r
+    protected function send_ping() {\r
+        $this->connect();\r
+        if (!$this->conn) {\r
+            return false;\r
+        }\r
+\r
+        $this->conn->sendPing();\r
+        $this->lastPing = time();\r
+        $this->pingInterval = 50;\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Update the time till the next ping\r
+     *\r
+     * @param $data Time till next ping\r
+     * @return void\r
+     */\r
+    public function update_ping_time($data) {\r
+        $this->pingInterval = $data;\r
+    }\r
+\r
+    /**\r
+    * Called via a callback when a message is received\r
+    *\r
+    * Passes it back to the queuing system\r
+    *\r
+    * @param array $data Data\r
+    * @return boolean\r
+    */\r
+    public function handle_msn_message($data) {\r
+        $this->plugin->enqueue_incoming_raw($data);\r
+        return true;\r
+    }\r
+\r
+    /**\r
+    * Called via a callback when a session becomes ready\r
+    *\r
+    * @param array $data Data\r
+    */\r
+    public function handle_session_ready($data) {\r
+        $sessionFailed = false;\r
+        $wm = Msn_waiting_message::top($data['to']);\r
+        while ($wm != NULL) {\r
+            if ($sessionFailed) {\r
+                $this->plugin->send_message($wm->screenname, $wm->message);\r
+                $sessionFailed = true;\r
+            } elseif (!$this->conn->sendMessage($wm->screenname, $wm->message, $ignore)) {\r
+                $this->plugin->send_message($wm->screenname, $wm->message);\r
+            }\r
+\r
+            $wm->delete();\r
+            $wm = Msn_waiting_message::top($data['to']);\r
+        }\r
+    }\r
+\r
+    /**\r
+    * Requeue messages from the waiting table so we try\r
+    * to send them again\r
+    *\r
+    * @return void\r
+    */\r
+    protected function requeue_waiting_messages() {\r
+        $wm = Msn_waiting_message::top($data['to']);\r
+        while ($wm != NULL) {\r
+            $this->plugin->send_message($wm->screenname, $wm->message);\r
+            $wm->delete();\r
+            $wm = Msn_waiting_message::top($data['to']);\r
+        }\r
+    }\r
+\r
+    /**\r
+    * Called by callback to log failure during connect\r
+    *\r
+    * @param void $data Not used (there to keep callback happy)\r
+    * @return void\r
+    */\r
+    public function handle_connect_failed($data) {\r
+        common_log(LOG_NOTICE, 'MSN connect failed, retrying');\r
+    }\r
+\r
+    /**\r
+    * Called by callback to log reconnection\r
+    *\r
+    * @param void $data Not used (there to keep callback happy)\r
+    * @return void\r
+    */\r
+    public function handle_reconnect($data) {\r
+        common_log(LOG_NOTICE, 'MSN reconnecting');\r
+        // Requeue messages waiting in the DB\r
+        $this->requeue_waiting_messages();\r
+    }\r
+\r
+    /**\r
+    * Enters a message into the database for sending via a callback\r
+    * when the session is established\r
+    *\r
+    * @param string $to Intended recipient\r
+    * @param string $message Message\r
+    */\r
+    protected function enqueue_waiting_message($to, $message) {\r
+        $wm = new Msn_waiting_message();\r
+\r
+        $wm->screenname = $to;\r
+        $wm->message    = $message;\r
+        $wm->created    = common_sql_now();\r
+        $result         = $wm->insert();\r
+\r
+        if (!$result) {\r
+            common_log_db_error($wm, 'INSERT', __FILE__);\r
+            throw new ServerException('DB error inserting queue item');\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Send a message using the daemon\r
+     *\r
+     * @param $data Message data\r
+     * @return boolean true on success\r
+     */\r
+    public function send_raw_message($data) {\r
+        $this->connect();\r
+        if (!$this->conn) {\r
+            return false;\r
+        }\r
+\r
+        $waitForSession = false;\r
+        if (!$this->conn->sendMessage($data['to'], $data['message'], $waitForSession)) {\r
+            if ($waitForSession) {\r
+                $this->enqueue_waiting_message($data['to'], $data['message']);\r
+            } else {\r
+                return false;\r
+            }\r
+        }\r
+\r
+        // Sending a command updates the time till next ping\r
+        $this->lastPing = time();\r
+        $this->pingInterval = 50;\r
+        return true;\r
+    }\r
+}\r