]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Initial commit of msn-plugin work
authorLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Sat, 12 Jun 2010 16:28:43 +0000 (17:28 +0100)
committerLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Sat, 12 Jun 2010 16:30:11 +0000 (17:30 +0100)
14 files changed:
plugins/Msn/MsnPlugin.php [new file with mode: 0644]
plugins/Msn/Queued_Msn.php [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/sample.php [new file with mode: 0644]
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/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..6737e72
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Send and receive notices using the AIM network
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  IM
+ * @package   StatusNet
+ * @author    Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+    // This check helps protect against security problems;
+    // your code file can't be executed directly from the web.
+    exit(1);
+}
+// We bundle the phptoclib library...
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phptoclib');
+
+/**
+ * Plugin for AIM
+ *
+ * @category  Plugin
+ * @package   StatusNet
+ * @author    Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
+
+class MsnPlugin extends ImPlugin
+{
+    public $user =  null;
+    public $password = null;
+    public $publicFeed = array();
+
+    public $transport = 'msnim';
+
+    function getDisplayName()
+    {
+        return _m('MSN');
+    }
+
+    function normalize($screenname)
+    {
+               $screenname = str_replace(" ","", $screenname);
+        return strtolower($screenname);
+    }
+
+    function daemon_screenname()
+    {
+        return $this->user;
+    }
+
+    function validate($screenname)
+    {
+        if(preg_match('/^[a-z]\w{2,15}$/i', $screenname)) {
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * Load related modules when needed
+     *
+     * @param string $cls Name of the class to be loaded
+     *
+     * @return boolean hook value; true means continue processing, false means stop.
+     */
+    function onAutoload($cls)
+    {
+        $dir = dirname(__FILE__);
+
+        switch ($cls)
+        {
+        case 'Msn':
+            require_once(INSTALLDIR.'/plugins/Msn/extlib/phpmsnclass/msn.class.php');
+            return false;
+        case 'MsnManager':
+            include_once $dir . '/'.strtolower($cls).'.php';
+            return false;
+        case 'Fake_Msn':
+            include_once $dir . '/'. $cls .'.php';
+            return false;
+        default:
+            return true;
+        }
+    }
+
+    function onStartImDaemonIoManagers(&$classes)
+    {
+        parent::onStartImDaemonIoManagers(&$classes);
+        $classes[] = new MsnManager($this); // handles sending/receiving
+        return true;
+    }
+
+    function microiduri($screenname)
+    {
+        return 'msnim:' . $screenname;    
+    }
+
+    function send_message($screenname, $body)
+    {
+        //$this->fake_aim->sendIm($screenname, $body);
+           //$this->enqueue_outgoing_raw($this->fake_aim->would_be_sent);
+           $this->enqueue_outgoing_raw(array($screenname, $body));
+        return true;
+    }
+
+    /**
+     * Accept a queued input message.
+     *
+     * @return true if processing completed, false if message should be reprocessed
+     */
+    function receive_raw_message($message)
+    {
+        $info=Aim::getMessageInfo($message);
+        $from = $info['from'];
+        $user = $this->get_user($from);
+        $notice_text = $info['message'];
+
+        $this->handle_incoming($from, $notice_text);
+
+        return true;
+    }
+
+    function initialize(){
+        if(!isset($this->user)){
+            throw new Exception("must specify a user");
+        }
+        if(!isset($this->password)){
+            throw new Exception("must specify a password");
+        }
+        if(!isset($this->nickname)) {
+            throw new Exception("must specify a nickname");
+        }
+
+        $this->fake_msn = new Fake_Msn($this->user,$this->password,4);
+        return true;
+    }
+
+    function onPluginVersion(&$versions)
+    {
+        $versions[] = array('name' => 'MSN',
+                            'version' => STATUSNET_VERSION,
+                            'author' => 'Luke Fitzgerald',
+                            'homepage' => 'http://status.net/wiki/Plugin:MSN',
+                            'rawdescription' =>
+                            _m('The MSN plugin allows users to send and receive notices over the MSN network.'));
+        return true;
+    }
+}
+
diff --git a/plugins/Msn/Queued_Msn.php b/plugins/Msn/Queued_Msn.php
new file mode 100644 (file)
index 0000000..bc8e0a1
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Queue-mediated proxy class for outgoing MSN messages.
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Network
+ * @package   StatusNet
+ * @author    Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @copyright 2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+class Queued_XMPP extends MSN {
+    /**
+     * Reference to the MsnPlugin object we're hooked up to.
+     */
+    public $plugin;
+
+    /**
+     * Constructor
+     *
+     * @param MsnPlugin $plugin
+     * @param string  $host
+     * @param integer $port
+     * @param string  $user
+     * @param string  $password
+     * @param string  $resource
+     * @param string  $server
+     * @param boolean $printlog
+     * @param string  $loglevel
+     */
+    public function __construct($plugin, $host, $port, $user, $password, $resource, $server = null, $printlog = false, $loglevel = null)
+    {
+        $this->plugin = $plugin;
+
+        parent::__construct($host, $port, $user, $password, $resource, $server, $printlog, $loglevel);
+
+        // We use $host to connect, but $server to build JIDs if specified.
+        // This seems to fix an upstream bug where $host was used to build
+        // $this->basejid, never seen since it isn't actually used in the base
+        // classes.
+        if (!$server) {
+            $server = $this->host;
+        }
+        $this->basejid = $this->user . '@' . $server;
+
+        // Normally the fulljid is filled out by the server at resource binding
+        // time, but we need to do it since we're not talking to a real server.
+        $this->fulljid = "{$this->basejid}/{$this->resource}";
+    }
+
+    /**
+     * Send a formatted message to the outgoing queue for later forwarding
+     * to a real XMPP connection.
+     *
+     * @param string $msg
+     */
+    public function send($msg, $timeout=NULL)
+    {
+        $this->plugin->enqueue_outgoing_raw($msg);
+    }
+
+    //@{
+    /**
+     * Stream i/o functions disabled; only do output
+     */
+    public function connect($timeout = 30, $persistent = false, $sendinit = true)
+    {
+        throw new Exception("Can't connect to server from fake XMPP.");
+    }
+
+    public function disconnect()
+    {
+        throw new Exception("Can't connect to server from fake XMPP.");
+    }
+
+    public function process()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function processUntil($event, $timeout=-1)
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function read()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function readyToProcess()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+    //@}
+
+}
+
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..355d828
--- /dev/null
@@ -0,0 +1,3755 @@
+<?php\r
+/*\r
+\r
+MSN class ver 2.0 by Tommy Wu, Ricky Su\r
+License: GPL\r
+\r
+You can find MSN protocol from this site: http://msnpiki.msnfanatic.com/index.php/Main_Page\r
+\r
+This class support MSNP15 for send message. The PHP module needed:\r
+\r
+MSNP15: curl pcre mhash mcrypt bcmath\r
+\r
+Usually, this class will try to use MSNP15 if your system can support it, if your system can't support it,\r
+it will switch to use MSNP9. But if you use MSNP9, it won't support OIM (Offline Messages).\r
+*/\r
+\r
+class MSN {\r
+    private $debug;\r
+    private $timeout;\r
+    private $protocol = 'MSNP15';\r
+    private $passport_url = 'https://login.live.com/RST.srf';\r
+    private $buildver = '8.1.0178';\r
+    private $prod_key = 'PK}_A_0N_K%O?A9S';\r
+    private $prod_id = 'PROD0114ES4Z%Q5W';\r
+    private $login_method = 'SSO';\r
+    private $oim_send_url = 'https://ows.messenger.msn.com/OimWS/oim.asmx';\r
+    private $oim_send_soap = 'http://messenger.live.com/ws/2006/09/oim/Store2';\r
+    private $windows;\r
+    private $kill_me = false;\r
+    private $id;\r
+    private $ticket;\r
+    private $user = '';\r
+    private $password = '';\r
+    private $NSfp=false;\r
+    private $SBfp;\r
+    private $passport_policy = '';\r
+    private $alias;\r
+    private $psm;\r
+    private $use_ping;\r
+    private $retry_wait;\r
+    private $backup_file;\r
+    private $update_pending;\r
+    private $PhotoStickerFile=false;\r
+    private $Emotions=false;\r
+    private $MessageQueue=array();\r
+    private $ChildProcess=array();\r
+    private $MAXChildProcess=3;\r
+    private $ReqSBXFRTimeout=60;\r
+    private $SBTimeout=2;\r
+    private $LastPing;\r
+    private $ping_wait=50;\r
+    private $SBIdleTimeout=10;\r
+    private $SBStreamTimeout=10;\r
+    private $NSStreamTimeout=2;\r
+    private $MsnObjArray=array();\r
+    private $MsnObjMap=array();\r
+    private $SwitchBoardProcess=false;     // false=>Main Process,1 => sb_control_process,2 => sb_ring_process\r
+    private $SwitchBoardSessionUser=false;\r
+    private $SwitchBoardMessageQueue=array();\r
+    private $ABAuthHeader;\r
+    private $ABService;\r
+    private $Contacts;\r
+\r
+    public $server = 'messenger.hotmail.com';\r
+    public $port = 1863;\r
+\r
+\r
+    public $clientid = '';\r
+\r
+    public $oim_maildata_url = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    public $oim_maildata_soap = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata';\r
+    public $oim_read_url = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    public $oim_read_soap = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMessage';\r
+    public $oim_del_url = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
+    public $oim_del_soap = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/DeleteMessages';\r
+\r
+    public $membership_url = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    public $membership_soap = 'http://www.msn.com/webservices/AddressBook/FindMembership';\r
+\r
+    public $addmember_url = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    public $addmember_soap = 'http://www.msn.com/webservices/AddressBook/AddMember';\r
+\r
+    public $addcontact_url = 'https://contacts.msn.com/abservice/abservice.asmx';\r
+    public $addcontact_soap = 'http://www.msn.com/webservices/AddressBook/ABContactAdd';\r
+\r
+    public $delmember_url = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
+    public $delmember_soap = 'http://www.msn.com/webservices/AddressBook/DeleteMember';\r
+\r
+\r
+    public $error = '';\r
+\r
+    public $authed = false;\r
+\r
+    public $oim_try = 3;\r
+\r
+    public $log_file = '';\r
+\r
+    public $log_path = false;\r
+\r
+    public $font_fn = 'Arial';\r
+    public $font_co = '333333';\r
+    public $font_ef = '';\r
+\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
+    public $max_msn_message_len = 1664;\r
+    public $max_yahoo_message_len = 518;\r
+    \r
+    // Begin added for StatusNet\r
+    \r
+    private $aContactList = array();\r
+    private $switchBoardSessions = array();\r
+    \r
+    /** \r
+     * Event Handler Functions\r
+     */\r
+    private $myEventHandlers = array();\r
+    \r
+    // End added for StatusNet\r
+\r
+    private function Array2SoapVar($Array,$ReturnSoapVarObj=true,$TypeName=null,$TypeNameSpace=null)\r
+    {\r
+        $ArrayString='';\r
+        foreach($Array as $Key => $Val)\r
+        {\r
+            if($Key{0}==':') continue;\r
+            $Attrib='';\r
+            if(is_array($Val[':']))\r
+            {\r
+                foreach($Val[':'] as $AttribName => $AttribVal)\r
+                $Attrib.=" $AttribName='$AttribVal'";\r
+            }\r
+            if($Key{0}=='!')\r
+            {\r
+                //List Type Define\r
+                $Key=substr($Key,1);\r
+                foreach($Val as $ListKey => $ListVal)\r
+                {\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
+    public function End()\r
+    {\r
+        $this->log_message("*** someone kill me ***");\r
+        $this->kill_me=true;\r
+    }\r
+    public function __construct ($Configs=array(), $timeout = 15, $client_id = 0x7000800C)\r
+    {\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
+        $my_add_function = isset($Configs['add_user_function']) ? $Configs['add_user_function'] : false;\r
+        $my_rem_function = isset($Configs['remove_user_function']) ? $Configs['remove_user_function'] : false;\r
+        $this->use_ping = isset($Configs['use_ping']) ? $Configs['use_ping'] : false;\r
+        $this->retry_wait = isset($Configs['retry_wait']) ? $Configs['retry_wait'] : 30;\r
+        $this->backup_file = isset($Configs['backup_file']) ? $Configs['backup_file'] : true;\r
+        $this->update_pending = isset($Configs['update_pending']) ? $Configs['update_pending'] : true;\r
+        $this->PhotoStickerFile=$Configs['PhotoSticker'];\r
+        if($this->Emotions = isset($Configs['Emotions']) ? $Configs['Emotions']:false)\r
+        {\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
+        // check support\r
+        if (!function_exists('curl_init')) throw new Exception("We need curl module!\n");\r
+        if (!function_exists('preg_match')) throw new Exception("We need pcre module!\n");\r
+        if (!function_exists('mhash')) throw new Exception("We need mhash module!\n");\r
+\r
+        if (!function_exists('mcrypt_cbc')) throw new Exception("We need mcrypt module!\n");\r
+        if (!function_exists('bcmod')) throw new Exception("We need bcmath module for $protocol!\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->windows =(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');\r
+        $this->ABService=new SoapClient(realpath(dirname(__FILE__)).'/soap/msnab_sharingservice.wsdl',array('trace' => 1));\r
+    }\r
+\r
+    private function get_passport_ticket($url = '')\r
+    {\r
+        $user = $this->user;\r
+        $password = htmlspecialchars($this->password);\r
+\r
+        if ($url === '')\r
+        $passport_url = $this->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, rediret 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("*** Can't 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("*** redirect, but can't get redirect URL!");\r
+                return false;\r
+            }\r
+            $redirect_url = $matches[1];\r
+            if ($redirect_url == $passport_url) {\r
+                $this->debug_message("*** redirect, but redirect to same URL!");\r
+                return false;\r
+            }\r
+            $this->debug_message("*** redirect to $redirect_url");\r
+            return $this->get_passport_ticket($redirect_url);\r
+        }\r
+\r
+        // sometimes, rediret 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("*** redirect, but redirect to same URL!");\r
+                    return false;\r
+                }\r
+                $this->debug_message("*** redirect 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("*** Can't 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
+        file_put_contents('/tmp/STTicket.txt',htmlspecialchars($this->ticket['storage_ticket']));\r
+        //$this->debug_message("StorageTicket:\n",htmlspecialchars($this->ticket['storage_ticket']));\r
+        return $aTickets;\r
+    }\r
+    private function UpdateContacts()\r
+    {\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
+  $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
+  {\r
+      $this->debug_message("*** Update 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
+  }\r
+  catch(Exception $e)\r
+  {\r
+      $this->debug_message("*** Update Contacts Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage());\r
+  }\r
+    }\r
+    protected function addContact($email, $network, $display = '', $sendADL = false)\r
+    {\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
+        {\r
+            $this->debug_message("*** Add Contacts $email...");\r
+            $this->ABService->ABContactAdd($ABContactAdd);\r
+        }\r
+        catch(Exception $e)\r
+        {\r
+            $this->debug_message("*** Add Contacts Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage());\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
+        $ABContactAdd=new SoapParam($this->Array2SoapVar($ABContactAddArray),'ABContactAdd');\r
+\r
+        // add contact for WLM\r
+        $ticket = htmlspecialchars($this->ticket['contact_ticket']);\r
+        $displayName = htmlspecialchars($display);\r
+        $user = $email;\r
+\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>CFE80F9D-180F-4399-82AB-413F33A1FA11</ApplicationId>\r
+        <IsMigration>false</IsMigration>\r
+        <PartnerScenario>ContactSave</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
+    <ABContactAdd xmlns="http://www.msn.com/webservices/AddressBook">\r
+        <abId>00000000-0000-0000-0000-000000000000</abId>\r
+        <contacts>\r
+            <Contact xmlns="http://www.msn.com/webservices/AddressBook">\r
+                <contactInfo>\r
+                    <contactType>LivePending</contactType>\r
+                    <passportName>'.$user.'</passportName>\r
+                    <isMessengerUser>true</isMessengerUser>\r
+                    <MessengerMemberInfo>\r
+                        <DisplayName>'.$displayName.'</DisplayName>\r
+                    </MessengerMemberInfo>\r
+                </contactInfo>\r
+            </Contact>\r
+        </contacts>\r
+        <options>\r
+            <EnableAllowListManagement>true</EnableAllowListManagement>\r
+        </options>\r
+    </ABContactAdd>\r
+</soap:Body>\r
+</soap:Envelope>';\r
+\r
+        $header_array = array(\r
+            'SOAPAction: '.$this->addcontact_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: $this->addcontact_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->addcontact_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->log_message("*** can't add contact (network: $network) $email");\r
+                    return false;\r
+                }\r
+                $faultcode = trim($matches[1]);\r
+                $faultstring = trim($matches[2]);\r
+                $this->log_message("*** can't add contact (network: $network) $email, error code: $faultcode, $faultstring");\r
+                return false;\r
+            }\r
+            $this->log_message("*** add contact (network: $network) $email");\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
+    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: '.$this->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: $this->delmember_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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->log_message("*** can't delete member (network: $network) $email ($memberID) to $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->log_message("*** can't delete member (network: $network) $email ($memberID) to $list, error code: $faultcode, $faultstring");\r
+                    return false;\r
+                }\r
+                $this->log_message("*** delete member (network: $network) $email ($memberID) from $list, not exist");\r
+                return true;\r
+            }\r
+            $this->log_message("*** delete member (network: $network) $email ($memberID) from $list");\r
+            return true;\r
+    }\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: '.$this->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: $this->addmember_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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->log_message("*** can't add member (network: $network) $email to $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->log_message("*** can't add member (network: $network) $email to $list, error code: $faultcode, $faultstring");\r
+                    return false;\r
+                }\r
+                $this->log_message("*** add member (network: $network) $email to $list, already exist!");\r
+                return true;\r
+            }\r
+            $this->log_message("*** add member (network: $network) $email to $list");\r
+            return true;\r
+    }\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: '.$this->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: $this->membership_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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
+            if(($http_code != 200)||(!$returnData)) return array();\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->log_message("*** add new contact (network: $network, status: $sMemberRole): $u_name@$u_domain ($id)");\r
+                    }\r
+                }\r
+            }\r
+            return $aContactList;\r
+    }\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, 5);\r
+            if (!$this->NSfp) {\r
+                $this->error = "Can't 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, 5);\r
+            if (!$this->NSfp) {\r
+                $this->error = "Can't connect to $redirect_server:$redirect_port, error => $errno, $errstr";\r
+                return false;\r
+            }\r
+        }\r
+\r
+        stream_set_timeout($this->NSfp, $this->NSStreamTimeout);\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 $this->protocol CVR0");\r
+\r
+        $start_tm = time();\r
+        while (!feof($this->NSfp))\r
+        {\r
+            $data = $this->ns_readln();\r
+            // no data?\r
+            if ($data === false) {\r
+                if ($this->timeout > 0) {\r
+                    $now_tm = time();\r
+                    $used_time = ($now_tm >= $start_tm) ? $now_tm - $start_tm : $now_tm;\r
+                    if ($used_time > $this->timeout) {\r
+                        // logout now\r
+                        // NS: >>> OUT\r
+                        $this->ns_writeln("OUT");\r
+                        fclose($this->NSfp);\r
+                        $this->error = 'Timeout, maybe protocol changed!';\r
+                        $this->debug_message("*** $this->error");\r
+                        return false;\r
+                    }\r
+                }\r
+                continue;\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 $this->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 $this->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 authenticated fail!';\r
+                        $this->debug_message("*** $this->error");\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 $this->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, 5);\r
+                    if (!$this->NSfp) {\r
+                        $this->error = "Can't connect to $ip:$port, error => $errno, $errstr";\r
+                        $this->debug_message("*** $this->error");\r
+                        return false;\r
+                    }\r
+\r
+                    stream_set_timeout($this->NSfp, $this->NSStreamTimeout);\r
+                    // MSNP9\r
+                    // NS: >> VER {id} MSNP9 CVR0\r
+                    // MSNP15\r
+                    // NS: >>> VER {id} MSNP15 CVR0\r
+                    $this->ns_writeln("VER $this->id $this->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
+                        $this->debug_message("*** $this->error");\r
+                        return false;\r
+                    }\r
+                    // unknown response from server, just ignore it\r
+                    break;\r
+            }\r
+        }\r
+        // never goto here\r
+    }\r
+\r
+    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
+    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
+    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: '.$this->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 '.$this->buildver.')'\r
+            );\r
+\r
+            $this->debug_message("*** URL: $this->oim_maildata_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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("*** Can't 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("*** Can't get OIM maildata");\r
+                return '';\r
+            }\r
+            return $matches[2];\r
+    }\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: '.$this->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 '.$this->buildver.')'\r
+            );\r
+\r
+            $this->debug_message("*** URL: $this->oim_read_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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: '.$this->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 '.$this->buildver.')'\r
+            );\r
+\r
+            $this->debug_message("*** URL: $this->oim_del_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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("*** Can't delete OIM: $msgid, http code = $http_code");\r
+            else\r
+            $this->debug_message("*** OIM ($msgid) deleted");\r
+            return $sMsg;\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->log_message("*** logout now!");\r
+        }\r
+\r
+    }\r
+    private function NSRetryWait($Wait) {\r
+        $this->log_message("*** wait for $Wait seconds");\r
+        for($i=0;$i<$Wait;$i++) {\r
+            sleep(1);\r
+            if($this->kill_me) return false;\r
+        }\r
+        return true;\r
+    }\r
+    public function ProcessSendMessageFileQueue() {\r
+        $aFiles = glob(MSN_CLASS_SPOOL_DIR.DIRECTORY_SEPARATOR.'*.msn');\r
+        if (!is_array($aFiles)) return true;\r
+        clearstatcache();\r
+        foreach ($aFiles as $filename) {\r
+            $fp = fopen($filename, 'rt');\r
+            if (!$fp) continue;\r
+            $aTo = array();\r
+            $sMessage = '';\r
+            $buf = trim(fgets($fp));\r
+            if (substr($buf, 0, 3) == 'TO:') {\r
+                $aTo = @explode(',', str_replace(array("\r","\n","\t",' '),'',substr($buf, 3)));\r
+                while (!feof($fp)) $sMessage.=rtrim(fgets($fp))."\n";\r
+            }\r
+            fclose($fp);\r
+            if (!is_array($aTo) || count($aTo) == 0 || $sMessage == '')\r
+            $this->log_message("!!! message format error? delete $filename");\r
+            else\r
+            {\r
+                foreach($aTo as $To)\r
+                {\r
+                    @list($user, $domain, $network) = @explode('@', $To);\r
+                    $MessageList[$network]["$user@$domain"]=$sMessage;\r
+                }\r
+            }\r
+            if($this->backup_file)\r
+            {\r
+                $backup_dir = MSN_CLASS_SPOOL_DIR.'/backup';\r
+                if (!file_exists($backup_dir)) @mkdir($backup_dir);\r
+                $backup_name = $backup_dir.'/'.strftime('%Y%m%d%H%M%S').'_'.posix_getpid().'_'.basename($filename);\r
+                if (@rename($filename, $backup_name))\r
+                $this->log_message("*** move file to $backup_name");\r
+            }\r
+            else @unlink($filename);\r
+        }\r
+        foreach ($MessageList as $network => $Messages)\r
+        {\r
+            switch(trim($network))\r
+            {\r
+                case '':\r
+                case 1:   //MSN\r
+                    // okay, try to ask a switchboard (SB) for sending message\r
+                    // NS: >>> XFR {id} SB\r
+                    // $this->ns_writeln("XFR $this->id SB");\r
+                    foreach($Messages as $User => $Message)\r
+                    $this->MessageQueue[$User][]=$Message;\r
+                    break;\r
+                case 'Offline':  //MSN\r
+                    //Send OIM\r
+                    //FIXME: 修正Send OIM\r
+                    foreach($Messages as $To => $Message)\r
+                    {\r
+                        $lockkey='';\r
+                        for ($i = 0; $i < $this->oim_try; $i++)\r
+                        {\r
+                            if(($oim_result = $this->sendOIM($To, $Message, $lockkey))===true) break;\r
+                            if (is_array($oim_result) && $oim_result['challenge'] !== false) {\r
+                                // need challenge lockkey\r
+                                $this->log_message("*** we need a new 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
+                            {\r
+                                if ($re_login)\r
+                                {\r
+                                    $this->log_message("*** can't send OIM, but we already re-login again, so ignore this OIM");\r
+                                    break;\r
+                                }\r
+                                $this->log_message("*** can't send OIM, maybe ticket expired, try to login again");\r
+                                // maybe we need to re-login again\r
+                                if(!$this->get_passport_ticket())\r
+                                {\r
+                                    $this->log_message("*** can't re-login, something wrong here, ignore this OIM");\r
+                                    break;\r
+                                }\r
+                                $this->log_message("**** get new ticket, try it again");\r
+                                continue;\r
+                            }\r
+                        }\r
+                    }\r
+                    break;\r
+                default:  //Other\r
+                    foreach($Messages as $To => $Message) {\r
+                        $Message=$this->getMessage($Message, $network);\r
+                        $len = strlen($Message);\r
+                        $this->ns_writeln("UUM $this->id $To $network 1 $len");\r
+                        $this->ns_writedata($Message);\r
+                        $this->log_message("*** sent to $To (network: $network):\n$Message");\r
+                    }\r
+            }\r
+        }\r
+        if(isset($this->MessageQueue[$User])&&(!isset($this->MessageQueue[$User]['XFRSent'])))\r
+        {\r
+            $this->MessageQueue[$User]['XFRSent']=false;\r
+            $this->MessageQueue[$User]['ReqTime']=false;\r
+        }\r
+        return true;\r
+    }\r
+    public function SignalFunction($signal)\r
+    {\r
+        switch($signal)\r
+        {\r
+            case SIGTRAP:\r
+            case SIGTERM:\r
+            case SIGHUP:\r
+                $this->End();\r
+                return;\r
+            case SIGCHLD:\r
+                $ChildPid=pcntl_wait($status,WUNTRACED);\r
+                if($ChildPid>0)\r
+                {\r
+                    $this->log_message("*** Child Process End for ".$this->ChildProcess[$ChildPid]);\r
+                    unset($this->ChildProcess[$ChildPid]);\r
+                }\r
+                return;\r
+        }\r
+    }\r
+\r
+    public function Run()\r
+    {\r
+        $this->log_message("*** startup ***");\r
+        if(!pcntl_signal(SIGCHLD,array($this,'SignalFunction'))) die("Signal SIGCHLD Error\n");\r
+        if(!pcntl_signal(SIGTERM,array($this,'SignalFunction'))) die("Signal SIGTERM Error\n");\r
+        if(!pcntl_signal(SIGTRAP,array($this,'SignalFunction'))) die("Signal SIGTRAP Error\n");\r
+        $process_file = false;\r
+        $sent = false;\r
+        $aADL = array();\r
+        $aContactList = array();\r
+        while (true)\r
+        {\r
+            if($this->kill_me)\r
+            {\r
+                $this->log_message("*** Okay, kill me now!");\r
+                return $this->NSLogout();\r
+            }\r
+            if (!is_resource($this->NSfp) || feof($this->NSfp))\r
+            {\r
+                $this->log_message("*** try to connect to MSN network");\r
+                if (!$this->connect($this->user, $this->password))\r
+                {\r
+                    $this->log_message("!!! Can't connect to server: $this->error");\r
+                    if(!$this->NSRetryWait($this->retry_wait)) continue;\r
+                }\r
+                $this->UpdateContacts();\r
+                $this->LastPing=time();\r
+                $this->log_message("*** connected, wait for command");\r
+                $start_tm = time();\r
+                $ping_tm = time();\r
+                stream_set_timeout($this->NSfp, $this->NSStreamTimeout);\r
+                    $aContactList = $this->getMembershipList(true);\r
+                    if ($this->update_pending) {\r
+                        if (is_array($aContactList)) {\r
+                            $pending = 'Pending';\r
+                            foreach ($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
+                                                        $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($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
+                                                    $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($aContactList)) {\r
+                        foreach ($aContactList as $u_domain => $aUserList) {\r
+                            $str = '<d n="'.$u_domain.'">';\r
+                            $len += strlen($str);\r
+                            if ($len > 7400) {\r
+                                $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
+                                        $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
+                    $aADL[$n] = '<ml l="1">'.$sList.'</ml>';\r
+                    // NS: >>> BLP {id} BL\r
+                    $this->ns_writeln("BLP $this->id BL");\r
+                    foreach ($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
+            }\r
+            $data = $this->ns_readln();\r
+            if($data===false)\r
+            {\r
+                //If No NS Message Process SendMessageFileQueue\r
+                if (time()-$this->LastPing > $this->ping_wait)\r
+                {\r
+                    // NS: >>> PNG\r
+                    $this->ns_writeln("PNG");\r
+                    $this->LastPing = time();\r
+                }\r
+                if(count($this->ChildProcess)<$this->MAXChildProcess)\r
+                {\r
+                    $Index=0;\r
+                    foreach($this->MessageQueue as $User => $Message)\r
+                    {\r
+                        if(!trim($User)) continue;\r
+                        if($Inxdex>=$this->MAXChildProcess-count($this->ChildProcess)) break;\r
+                        if((!$Message['XFRSent'])||($Message['XFRSent']&&(time()-$this->MessageQueue[$User]['ReqTime']>$this->ReqSBXFRTimeout)))\r
+                        {\r
+                            $this->MessageQueue[$User]['XFRSent']=true;\r
+                            $this->MessageQueue[$User]['ReqTime']=time();\r
+                            $this->log_message("*** Request SB for $User");\r
+                            $this->ns_writeln("XFR $this->id SB");\r
+                            $Index++;\r
+                        }\r
+                    }\r
+                }\r
+                if($this->ProcessSendMessageFileQueue()) continue;\r
+                break;\r
+            }\r
+            switch (substr($data,0,3))\r
+            {\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($aADL)) {\r
+                        foreach ($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, /* alias */, ) = @explode(' ', $data);\r
+                    @list($u_name, $u_domain) = @explode('@', $email);\r
+                    if (!isset($aContactList[$u_domain][$u_name][1])) {\r
+                        $aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow';\r
+                        $this->log_message("*** add to our contact list: $u_name@$u_domain");\r
+                    }\r
+                    break;\r
+\r
+                case 'ADL':\r
+                    // randomly, we get ADL command, someome 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
+                    {\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
+                        {\r
+                            $u_domain = $matches[1];\r
+                            $u_name = $matches[2];\r
+                            $network = $matches[4];\r
+                            if (isset($aContactList[$u_domain][$u_name][$network]))\r
+                            $this->log_message("*** someone (network: $network) add us to their list (but already in our list): $u_name@$u_domain");\r
+                            else\r
+                            {\r
+                                $re_login = false;\r
+                                $cnt = 0;\r
+                                foreach (array('Allow', 'Reverse') as $list)\r
+                                {\r
+                                    if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list))\r
+                                    {\r
+                                        if ($re_login) {\r
+                                            $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                            continue;\r
+                                        }\r
+                                        $aTickets = $this->get_passport_ticket();\r
+                                        if (!$aTickets || !is_array($aTickets)) {\r
+                                            // failed to login? ignore it\r
+                                            $this->log_message("*** can't re-login, something wrong here");\r
+                                            $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                            continue;\r
+                                        }\r
+                                        $re_login = true;\r
+                                        $this->ticket = $aTickets;\r
+                                        $this->log_message("**** get new ticket, try it again");\r
+                                        if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list))\r
+                                        {\r
+                                            $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                            continue;\r
+                                        }\r
+                                    }\r
+                                    $aContactList[$u_domain][$u_name][$network][$list] = false;\r
+                                    $cnt++;\r
+                                }\r
+                                $this->log_message("*** someone (network: $network) add 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
+                        else\r
+                        $this->log_message("*** someone add us to their list: $data");\r
+                        $this->AddUsToMemberList($u_name.'@'.$u_domain, $network);\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
+                    {\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
+                        {\r
+                            $u_domain = $matches[1];\r
+                            $u_name = $matches[2];\r
+                            $network = $matches[4];\r
+                            if (isset($aContactList[$u_domain][$u_name][$network]))\r
+                            {\r
+                                $aData = $aContactList[$u_domain][$u_name][$network];\r
+                                foreach ($aData as $list => $id)\r
+                                $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list);\r
+                                unset($aContactList[$u_domain][$u_name][$network]);\r
+                                $this->log_message("*** someone (network: $network) remove us from their list: $u_name@$u_domain");\r
+                            }\r
+                            else\r
+                            $this->log_message("*** someone (network: $network) remove us from their list (but not in our list): $u_name@$u_domain");\r
+                            $this->RemoveUsFromMemberList($u_name.'@'.$u_domain, $network);\r
+                        }\r
+                        else\r
+                        $this->log_message("*** someone remove 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 &&\r
+                                    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->log_message("*** ingnore MSG for: $line");\r
+                            break;\r
+                        }\r
+                        if ($maildata == '') {\r
+                            $this->log_message("*** ingnore MSG not for OIM");\r
+                            break;\r
+                        }\r
+                        $re_login = false;\r
+                        if (strcasecmp($maildata, 'too-large') == 0) {\r
+                            $this->log_message("*** large mail-data, need to get the data via SOAP");\r
+                            $maildata = $this->getOIM_maildata();\r
+                            if ($maildata === false) {\r
+                                $this->log_message("*** can't get mail-data via SOAP");\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->log_message("*** can't re-login, something wrong here, ignore this OIM");\r
+                                    break;\r
+                                }\r
+                                $re_login = true;\r
+                                $this->ticket = $aTickets;\r
+                                $this->log_message("**** get new ticket, try it again");\r
+                                $maildata = $this->getOIM_maildata();\r
+                                if ($maildata === false) {\r
+                                    $this->log_message("*** can't get mail-data via SOAP, and we already re-login again, so ignore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** You've OIM sent by $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size");\r
+                            $sMsg = $this->getOIM_message($oim_msgid);\r
+                            if ($sMsg === false) {\r
+                                $this->log_message("*** can't get OIM, msgid = $oim_msgid");\r
+                                if ($re_login) {\r
+                                    $this->log_message("*** can't get OIM via SOAP, and we already re-login again, so ignore 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->log_message("*** can't re-login, something wrong here, ignore this OIM");\r
+                                    continue;\r
+                                }\r
+                                $re_login = true;\r
+                                $this->ticket = $aTickets;\r
+                                $this->log_message("**** get new ticket, try it again");\r
+                                $sMsg = $this->getOIM_message($oim_msgid);\r
+                                if ($sMsg === false) {\r
+                                    $this->log_message("*** can't get OIM via SOAP, and we already re-login again, so ignore this OIM");\r
+                                    continue;\r
+                                }\r
+                            }\r
+                            $this->log_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg");\r
+\r
+                            $this->ReceivedMessage($oim_sender,$sMsg,$network,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
+                    {\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
+                        {\r
+                            $this->log_message("*** ingnore from $from_email: $line");\r
+                            break;\r
+                        }\r
+                        $this->log_message("*** MSG from $from_email (network: $network): $sMsg");\r
+                        $this->ReceivedMessage($from_email,$sMsg,$network,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 $this->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
+                    if(count($this->MessageQueue))\r
+                    {\r
+                        foreach($this->MessageQueue as $User => $Message)\r
+                        {\r
+                            //$this->ChildProcess[$ChildPid]\r
+                            $this->log_message("*** XFR SB $User");\r
+                            $pid=pcntl_fork();\r
+                            if($pid)\r
+                            {\r
+                                //Parrent Process\r
+                                $this->ChildProcess[$pid]=$User;\r
+                                break;\r
+                            }\r
+                            elseif($pid==-1)\r
+                            {\r
+                                $this->log_message("*** Fork Error $User");\r
+                                break;\r
+                            }\r
+                            else\r
+                            {\r
+                                //Child Process\r
+                                $this->log_message("*** Child Process Start for $User");\r
+                                unset($Message['XFRSent']);\r
+                                unset($Message['ReqTime']);\r
+                                $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $User, $Message);\r
+                                if ($bSBresult === false)\r
+                                {\r
+                                    // error for switchboard\r
+                                    $this->log_message("!!! error for sending message to ".$User);\r
+                                }\r
+                                die;\r
+                            }\r
+                        }\r
+                        unset($this->MessageQueue[$User]);\r
+                    }\r
+                    /*\r
+                     $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $aMSNUsers[$nCurrentUser], $sMessage);\r
+                     if ($bSBresult === false) {\r
+                     // error for switchboard\r
+                     $this->log_message("!!! error for sending message to ".$aMSNUsers[$nCurrentUser]);\r
+                     $aOfflineUsers[] = $aMSNUsers[$nCurrentUser];\r
+                     }*/\r
+                    break;\r
+                case 'QNG':\r
+                    // NS: <<< QNG {time}\r
+                    @list(/* QNG */, $this->ping_wait) = @explode(' ', $data);\r
+                    if ($this->ping_wait == 0) $this->ping_wait = 50;\r
+                    //if (is_int($use_ping) && $use_ping > 0) $ping_wait = $use_ping;\r
+                    //Mod by Ricky Set Online\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->log_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->log_message("*** RING from $email, $sb_ip:$sb_port");\r
+                    $this->addContact($email,1,$email, true);\r
+                    $pid=pcntl_fork();\r
+                    if($pid)\r
+                    {\r
+                        //Parrent Process\r
+                        $this->ChildProcess[$pid]='RNG';\r
+                        break;\r
+                    }\r
+                    elseif($pid==-1)\r
+                    {\r
+                        $this->log_message("*** Fork Error $User");\r
+                        break;\r
+                    }\r
+                    else\r
+                    {\r
+                        //Child Process\r
+                        $this->log_message("*** Ring Child Process Start for $User");\r
+                        $this->switchboard_ring($sb_ip, $sb_port, $sid, $ticket,$email);\r
+                        die;\r
+                    }\r
+                    break;\r
+                case 'OUT':\r
+                    // force logout from NS\r
+                    // NS: <<< OUT xxx\r
+                    fclose($this->NSfp);\r
+                    $this->log_message("*** LOGOUT from NS");\r
+                    break;\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
+        return $this->NsLogout();\r
+    }\r
+\r
+    /*public function SendMessage($Message, $To)\r
+    {\r
+        $FileName = MSN_CLASS_SPOOL_DIR.'/'.strftime('%Y%m%d%H%M%S',time()).'_'.posix_getpid().'_sendMessage.msn';\r
+        if(!is_array($To))\r
+        $To=array($To);\r
+        $Receiver='';\r
+        foreach($To as $Email)\r
+        {\r
+            list($name,$host,$network)=explode('@',$Email);\r
+            $network=$network==''?1:$network;\r
+            if($network==1 && $this->SwitchBoardProcess && $this->SwitchBoardSessionUser=="$name@$host" )\r
+            {\r
+                $this->debug_message("*** SendMessage to $Receiver use SB message queue.");\r
+                array_push($this->SwitchBoardMessageQueue,$Message);\r
+                continue;\r
+            }\r
+            $Receiver.="$name@$host@$network,";\r
+        }\r
+        if($Receiver=='') return;\r
+        $Receiver=substr($Receiver,0,-1);\r
+        $this->debug_message("*** SendMessage to $Receiver use File queue.");\r
+        file_put_contents($FileName,"TO: $Receiver\n$Message\n");\r
+    }*/\r
+\r
+    function getChallenge($code)\r
+    {\r
+        // MSNP15\r
+        // http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges\r
+        // Step 1: The MD5 Hash\r
+        $md5Hash = md5($code.$this->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.$this->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.$this->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
+    private function getMessage($sMessage, $network = 1)\r
+    {\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 = $this->max_msn_message_len - $msg_header_len;\r
+        else\r
+        $maxlen = $this->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
+     * @param $Action 連線模式 'Active' => 主動傳送訊息,'Passive' => 接收訊息\r
+     * @param $Param\r
+     * @return boolean\r
+     */\r
+    private function DoSwitchBoard($Action,$Param)\r
+    {\r
+        $SessionEnd=false;\r
+        $Joined=false;\r
+        $id=1;\r
+        $LastActive=time();\r
+        stream_set_timeout($this->SBFp, $this->SBTimeout);\r
+        switch($Action)\r
+        {\r
+            case 'Active':\r
+                $cki_code=$Param['cki'];\r
+                $user=$Param['user'];\r
+                $this->SwitchBoardMessageQueue=$Param['Msg'];\r
+                // SB: >>> USR {id} {user} {cki}\r
+                $this->SB_writeln("USR $id $this->user $cki_code");\r
+                $id++;\r
+                $this->SwitchBoardSessionUser=$user;\r
+                break;\r
+            case 'Passive':\r
+                $ticket=$Param['ticket'];\r
+                $sid=$Param['sid'];\r
+                $user=$Param['user'];\r
+                // SB: >>> ANS {id} {user} {ticket} {session_id}\r
+                $this->SB_writeln("ANS $id $this->user $ticket $sid");\r
+                $id++;\r
+                $this->SwitchBoardSessionUser=$user;\r
+                break;\r
+            default:\r
+                return false;\r
+        }\r
+        while((!feof($this->SBFp))&&(!$SessionEnd))\r
+        {\r
+            $data = $this->SB_readln();\r
+            if($this->kill_me)\r
+            {\r
+                $this->log_message("*** SB Okay, kill me now!");\r
+                break;\r
+            }\r
+            if($data === false)\r
+            {\r
+                if(time()-$LastActive > $this->SBIdleTimeout)\r
+                {\r
+                    $this->debug_message("*** SB Idle Timeout!");\r
+                    break;\r
+                }\r
+                if(!$Joined) continue;\r
+                foreach($this->SwitchBoardMessageQueue as $Message)\r
+                {\r
+                    if($Message=='') continue;\r
+                    $aMessage = $this->getMessage($Message);\r
+                    //CheckEmotion...\r
+                    $MsnObjDefine=$this->GetMsnObjDefine($aMessage);\r
+                    if($MsnObjDefine!=='')\r
+                    {\r
+                        $SendString="MIME-Version: 1.0\r\nContent-Type: text/x-mms-emoticon\r\n\r\n$MsnObjDefine";\r
+                        $len = strlen($SendString);\r
+                        $this->SB_writeln("MSG $id N $len");\r
+                        $id++;\r
+                        $this->SB_writedata($SendString);\r
+                        $this->id++;\r
+                    }\r
+                    $len = strlen($aMessage);\r
+                    $this->SB_writeln("MSG $id N $len");\r
+                    $id++;\r
+                    $this->SB_writedata($aMessage);\r
+                }\r
+                $this->SwitchBoardMessageQueue=array();\r
+                $LastActive=time();\r
+                continue;\r
+            }\r
+            $code = substr($data, 0, 3);\r
+            switch($code)\r
+            {\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->log_message("*** $email join us");\r
+                    $Joined=true;\r
+                    break;\r
+                case 'BYE':\r
+                    $this->log_message("*** Quit for BYE");\r
+                    $SessionEnd=true;\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("CAL $id $user");\r
+                    $id++;\r
+                    break;\r
+                case 'CAL':\r
+                    // SB: <<< CAL {id} RINGING {?}\r
+                    // we don't need this, just ignore, and wait for other response\r
+                    $this->id++;\r
+                    break;\r
+                case 'JOI':\r
+                    // SB: <<< JOI {user} {alias} {clientid?}\r
+                    // someone join us\r
+                    // we don't need the data, just ignore it\r
+                    // no more user here\r
+                    $Joined=true;\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($len);\r
+                    $aLines = @explode("\n", $data);\r
+                    $header = true;\r
+                    $ignore = false;\r
+                    $is_p2p = false;\r
+                    $sMsg = '';\r
+                    foreach ($aLines as $line)\r
+                    {\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
+                    {\r
+                        $this->log_message("*** ingnore from $from_email: $line");\r
+                        break;\r
+                    }\r
+                    if ($is_p2p)\r
+                    {\r
+                        // we will ignore any p2p message after sending acknowledgement\r
+                        $ignore = true;\r
+                        $len = strlen($sMsg);\r
+                        $this->log_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->log_message("*** p2p: size error, less than 52!");\r
+                            break;\r
+                        }*/\r
+                        $aDwords = @unpack("V12dword", $sMsg);\r
+                        if (!is_array($aDwords)) {\r
+                            $this->log_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
+                        {\r
+                            while(true)\r
+                            {\r
+                                if($this->SB_readln()===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("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("MSG $id D $len");\r
+                            $id++;\r
+                            $this->SB_writedata($message);\r
+                            $this->log_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();//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("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
+                            $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("MSG $id D ".strlen($message));\r
+                            $id++;\r
+                            $this->SB_writedata($message);\r
+                            $this->debug_message("*** p2p: dump 200 ok message:\n".$this->dump_binary($message));\r
+                            $this->SB_readln();//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("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
+                            $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("MSG $id D ".strlen($message));\r
+                            $id++;\r
+                            $this->SB_writedata($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();//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
+                            {\r
+                                $Offset=0;\r
+                                //$new_id++;\r
+                                while(!feof($hTitle))\r
+                                {\r
+                                    $FileContent=fread($hTitle,1024);\r
+                                    $FileContentSize=strlen($FileContent);\r
+                                    $hdr = pack("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("MSG $id D ".strlen($message));\r
+                                    $id++;\r
+                                    $this->SB_writedata($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();//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("MSG $id D ".strlen($message));\r
+                            $id++;\r
+                            $this->SB_writedata($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("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("MSG $id D $len");\r
+                         $id++;\r
+                         $this->SB_writedata($message);\r
+                         $this->log_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->log_message("*** MSG from $from_email: $sMsg");\r
+                    $this->ReceivedMessage($from_email,$sMsg,$network,false);\r
+                    break;\r
+                case '217':\r
+                    $this->log_message("*** User $user is offline. Try OIM.");\r
+                    foreach($this->SwitchBoardMessageQueue as $Message)\r
+                    $this->SendMessage($Message,"$user@Offline");\r
+                    $SessionEnd=true;\r
+                    break;\r
+                default:\r
+                    if (is_numeric($code))\r
+                    {\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
+                        $SessionEnd=true;\r
+                    }\r
+                    break;\r
+            }\r
+            $LastActive = time();\r
+        }\r
+        if (feof($this->SBFp))\r
+        {\r
+            // lost connection? error? try OIM later\r
+            @fclose($this->SBFp);\r
+            return false;\r
+        }\r
+        $this->SB_writeln("OUT");\r
+        @fclose($this->SBFp);\r
+        return true;\r
+    }\r
+    private function switchboard_control($ip, $port, $cki_code, $user, $Messages)\r
+    {\r
+        $this->SwitchBoardProcess=1;\r
+        $this->debug_message("*** SB: try to connect to switchboard server $ip:$port");\r
+        $this->SBFp = @fsockopen($ip, $port, $errno, $errstr, 5);\r
+        if (!$this->SBFp)\r
+        {\r
+            $this->debug_message("*** SB: Can't connect to $ip:$port, error => $errno, $errstr");\r
+            return false;\r
+        }\r
+        return $this->DoSwitchBoard('Active',array('cki'=>$cki_code, 'user'=>$user,'Msg'=>$Messages));\r
+    }\r
+    private function switchboard_ring($ip, $port, $sid, $ticket,$user)\r
+    {\r
+        $this->SwitchBoardProcess=2;\r
+        $this->debug_message("*** SB: try to connect to switchboard server $ip:$port");\r
+        $this->SBFp = @fsockopen($ip, $port, $errno, $errstr, 5);\r
+        if (!$this->SBFp)\r
+        {\r
+            $this->debug_message("*** SB: Can't connect to $ip:$port, error => $errno, $errstr");\r
+            return false;\r
+        }\r
+        return $this->DoSwitchBoard('Passive',array('sid'=>$sid,'user'=>$user,'ticket'=>$ticket));\r
+    }\r
+\r
+    private function sendOIM($to, $sMessage, $lockkey)\r
+    {\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="'.$this->protocol.'"\r
+        buildVer="'.$this->buildver.'"/>\r
+  <To memberName="'.$to.'" xmlns="http://messenger.msn.com/ws/2004/09/oim/"/>\r
+  <Ticket passport="'.htmlspecialchars($this->ticket['oim_ticket']).'"\r
+          appid="'.$this->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: '.$this->oim_send_soap,\r
+            'Content-Type: text/xml',\r
+            'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.$this->buildver.')'\r
+            );\r
+\r
+            $this->debug_message("*** URL: $this->oim_send_url");\r
+            $this->debug_message("*** Sending SOAP:\n$XML");\r
+            $curl = curl_init();\r
+            curl_setopt($curl, CURLOPT_URL, $this->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
+    // read data for specified size\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
+    // read one line\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
+    // write to server, append \r\n, also increase id\r
+    private function ns_writeln($data) {\r
+        @fwrite($this->NSfp, $data."\r\n");\r
+        $this->debug_message("NS: >>> $data");\r
+        $this->id++;\r
+        return;\r
+    }\r
+\r
+    // write data to server\r
+    private function ns_writedata($data) {\r
+        @fwrite($this->NSfp, $data);\r
+        $this->debug_message("NS: >>> $data");\r
+        return;\r
+    }\r
+\r
+    // read data for specified size for SB\r
+    private function sb_readdata($size) {\r
+        $data = '';\r
+        $count = 0;\r
+        while (!feof($this->SBFp)) {\r
+            $buf = @fread($this->SBFp, $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
+    // read one line for SB\r
+    private function sb_readln() {\r
+        $data = @fgets($this->SBFp, 4096);\r
+        if ($data !== false) {\r
+            $data = trim($data);\r
+            $this->debug_message("SB: <<< $data");\r
+        }\r
+        return $data;\r
+    }\r
+\r
+    // write to server for SB, append \r\n, also increase id\r
+    // switchboard server only accept \r\n, it will lost connection if just \n only\r
+    private function sb_writeln($data) {\r
+        @fwrite($this->SBFp, $data."\r\n");\r
+        $this->debug_message("SB: >>> $data");\r
+        $this->id++;\r
+        return;\r
+    }\r
+\r
+    // write data to server\r
+    private function sb_writedata($data) {\r
+        @fwrite($this->SBFp, $data);\r
+        $this->debug_message("SB: >>> $data");\r
+        return;\r
+    }\r
+\r
+    // show debug information\r
+    function debug_message($str) {\r
+        if (!$this->debug) return;\r
+        if($this->debug===STDOUT) echo $str."\n";\r
+        /*$fname=MSN_CLASS_LOG_DIR.DIRECTORY_SEPARATOR.'msn_'.strftime('%Y%m%d').'.debug';\r
+        $fp = fopen($fname, 'at');\r
+        if ($fp) {\r
+            fputs($fp, strftime('%m/%d/%y %H:%M:%S').' ['.posix_getpid().'] '.$str."\n");\r
+            fclose($fp);\r
+            return;\r
+        }*/\r
+        // still show debug information, if we can't open log_file\r
+        echo $str."\n";\r
+        return;\r
+    }\r
+\r
+    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
+    // write log\r
+    function log_message($str) {\r
+        /*$fname = MSN_CLASS_LOG_DIR.DIRECTORY_SEPARATOR.'msn_'.strftime('%Y%m%d').'.log';\r
+        $fp = fopen($fname, 'at');\r
+        if ($fp) {\r
+            fputs($fp, strftime('%m/%d/%y %H:%M:%S').' ['.posix_getpid().'] '.$str."\n");\r
+            fclose($fp);\r
+        }*/\r
+        $this->debug_message($str);\r
+        return;\r
+    }\r
+    /**\r
+     *\r
+     * @param $FilePath 圖檔路徑\r
+     * @param $Type     檔案類型 3=>大頭貼,2表情圖案    \r
+     * @return array\r
+     */\r
+    private function MsnObj($FilePath,$Type=3)\r
+    {\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
+    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
+    private function GetPictureFilePath($Context)\r
+    {\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
+    private function GetMsnObjDefine($Message)\r
+    {\r
+        $DefineString='';\r
+        if(is_array($this->Emotions))\r
+        foreach($this->Emotions as $Pattern => $FilePath)\r
+        {\r
+            if(strpos($Message,$Pattern)!==false)\r
+            $DefineString.="$Pattern\t".$this->MsnObj($FilePath,2)."\t";\r
+        }\r
+        return $DefineString;\r
+    }\r
+    /**\r
+     * Receive Message Overload Function\r
+     * @param $Sender\r
+     * @param $Message\r
+     * @param $Network   1 => msn , 32 =>yahoo\r
+     * @param $IsOIM\r
+     * @return unknown_type\r
+     */\r
+    protected function ReceivedMessage($Sender,$Message,$Network,$IsOIM=false){}\r
+    /**\r
+     * Remove Us From Member List Overload Function\r
+     * @param $User\r
+     * @param $Message\r
+     * @param $Network   1 => msn , 32 =>yahoo\r
+     * @return unknown_type\r
+     */\r
+    protected function RemoveUsFromMemberList($User,$Network){}\r
+    /**\r
+     * Add Us to Member List Overload Function\r
+     * @param $User\r
+     * @param $Message\r
+     * @param $Network   1 => msn , 32 =>yahoo\r
+     * @return unknown_type\r
+     */\r
+    protected function AddUsToMemberList($User,$Network){}\r
+    \r
+    public function signon() {\r
+        $this->log_message("*** try to connect to MSN network");\r
+        while(!$this->connect($this->user, $this->password))\r
+        {\r
+            $this->log_message("!!! Can't connect to server: $this->error");\r
+            if(!$this->NSRetryWait($this->retry_wait)) return;\r
+        }\r
+        $this->UpdateContacts();\r
+        $this->LastPing=time();\r
+        $this->log_message("*** connected, wait for command");\r
+        $start_tm = time();\r
+        $ping_tm = time();\r
+        stream_set_timeout($this->NSfp, $this->NSStreamTimeout);\r
+        $this->aContactList = $this->getMembershipList(true);\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
+                    $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
+                            $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
+        $aADL[$n] = '<ml l="1">'.$sList.'</ml>';\r
+        // NS: >>> BLP {id} BL\r
+        $this->ns_writeln("BLP $this->id BL");\r
+        foreach ($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
+    }\r
+    \r
+    public function NSreceive() {\r
+        $this->log_message("*** startup ***");\r
+        \r
+        $aADL = array();\r
+        \r
+        // Sign in again if not signed in or socket failed\r
+        if (!is_resource($this->NSfp) || feof($this->NSfp)) {\r
+            $this->signon();\r
+        }\r
+        \r
+        $data = $this->ns_readln();\r
+        /*if($data===false)\r
+        {\r
+            //If No NS Message Process SendMessageFileQueue\r
+            if (time()-$this->LastPing > $this->ping_wait)\r
+            {\r
+                // NS: >>> PNG\r
+                $this->ns_writeln("PNG");\r
+                $this->LastPing = time();\r
+            }\r
+            if(count($this->ChildProcess)<$this->MAXChildProcess)\r
+            {\r
+                $Index=0;\r
+                foreach($this->MessageQueue as $User => $Message)\r
+                {\r
+                    if(!trim($User)) continue;\r
+                    if($Inxdex>=$this->MAXChildProcess-count($this->ChildProcess)) break;\r
+                    if((!$Message['XFRSent'])||($Message['XFRSent']&&(time()-$this->MessageQueue[$User]['ReqTime']>$this->ReqSBXFRTimeout)))\r
+                    {\r
+                        $this->MessageQueue[$User]['XFRSent']=true;\r
+                        $this->MessageQueue[$User]['ReqTime']=time();\r
+                        $this->log_message("*** Request SB for $User");\r
+                        $this->ns_writeln("XFR $this->id SB");\r
+                        $Index++;\r
+                    }\r
+                }\r
+            }\r
+            if($this->ProcessSendMessageFileQueue()) continue;\r
+            break;\r
+        }*/\r
+        switch (substr($data,0,3))\r
+        {\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($aADL)) {\r
+                    foreach ($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, /* alias */, ) = @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->log_message("*** add to our contact list: $u_name@$u_domain");\r
+                }\r
+                break;\r
+\r
+            case 'ADL':\r
+                // randomly, we get ADL command, someome 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
+                {\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
+                    {\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->log_message("*** someone (network: $network) add us to their list (but already in our list): $u_name@$u_domain");\r
+                        else\r
+                        {\r
+                            $re_login = false;\r
+                            $cnt = 0;\r
+                            foreach (array('Allow', 'Reverse') as $list)\r
+                            {\r
+                                if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list))\r
+                                {\r
+                                    if ($re_login) {\r
+                                        $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                        continue;\r
+                                    }\r
+                                    $aTickets = $this->get_passport_ticket();\r
+                                    if (!$aTickets || !is_array($aTickets)) {\r
+                                        // failed to login? ignore it\r
+                                        $this->log_message("*** can't re-login, something wrong here");\r
+                                        $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                        continue;\r
+                                    }\r
+                                    $re_login = true;\r
+                                    $this->ticket = $aTickets;\r
+                                    $this->log_message("**** get new ticket, try it again");\r
+                                    if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list))\r
+                                    {\r
+                                        $this->log_message("*** can't add $u_name@$u_domain (network: $network) to $list");\r
+                                        continue;\r
+                                    }\r
+                                }\r
+                                $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
+                                $cnt++;\r
+                            }\r
+                            $this->log_message("*** someone (network: $network) add 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
+                    else\r
+                    $this->log_message("*** someone add us to their list: $data");\r
+                    $this->AddUsToMemberList($u_name.'@'.$u_domain, $network);\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
+                {\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
+                    {\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
+                        {\r
+                            $aData = $this->aContactList[$u_domain][$u_name][$network];\r
+                            foreach ($aData as $list => $id)\r
+                            $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list);\r
+                            unset($this->aContactList[$u_domain][$u_name][$network]);\r
+                            $this->log_message("*** someone (network: $network) remove us from their list: $u_name@$u_domain");\r
+                        }\r
+                        else\r
+                        $this->log_message("*** someone (network: $network) remove us from their list (but not in our list): $u_name@$u_domain");\r
+                        $this->RemoveUsFromMemberList($u_name.'@'.$u_domain, $network);\r
+                    }\r
+                    else\r
+                    $this->log_message("*** someone remove 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 &&\r
+                                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->log_message("*** ingnore MSG for: $line");\r
+                        break;\r
+                    }\r
+                    if ($maildata == '') {\r
+                        $this->log_message("*** ingnore MSG not for OIM");\r
+                        break;\r
+                    }\r
+                    $re_login = false;\r
+                    if (strcasecmp($maildata, 'too-large') == 0) {\r
+                        $this->log_message("*** large mail-data, need to get the data via SOAP");\r
+                        $maildata = $this->getOIM_maildata();\r
+                        if ($maildata === false) {\r
+                            $this->log_message("*** can't get mail-data via SOAP");\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->log_message("*** can't re-login, something wrong here, ignore this OIM");\r
+                                break;\r
+                            }\r
+                            $re_login = true;\r
+                            $this->ticket = $aTickets;\r
+                            $this->log_message("**** get new ticket, try it again");\r
+                            $maildata = $this->getOIM_maildata();\r
+                            if ($maildata === false) {\r
+                                $this->log_message("*** can't get mail-data via SOAP, and we already re-login again, so ignore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** ingnore 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->log_message("*** You've OIM sent by $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size");\r
+                        $sMsg = $this->getOIM_message($oim_msgid);\r
+                        if ($sMsg === false) {\r
+                            $this->log_message("*** can't get OIM, msgid = $oim_msgid");\r
+                            if ($re_login) {\r
+                                $this->log_message("*** can't get OIM via SOAP, and we already re-login again, so ignore 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->log_message("*** can't re-login, something wrong here, ignore this OIM");\r
+                                continue;\r
+                            }\r
+                            $re_login = true;\r
+                            $this->ticket = $aTickets;\r
+                            $this->log_message("**** get new ticket, try it again");\r
+                            $sMsg = $this->getOIM_message($oim_msgid);\r
+                            if ($sMsg === false) {\r
+                                $this->log_message("*** can't get OIM via SOAP, and we already re-login again, so ignore this OIM");\r
+                                continue;\r
+                            }\r
+                        }\r
+                        $this->log_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg");\r
+\r
+                        //$this->ReceivedMessage($oim_sender,$sMsg,$network,true);\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
+                {\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
+                    {\r
+                        $this->log_message("*** ingnore from $from_email: $line");\r
+                        break;\r
+                    }\r
+                    $this->log_message("*** MSG from $from_email (network: $network): $sMsg");\r
+                    //$this->ReceivedMessage($from_email,$sMsg,$network,false);\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 $this->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
+                if(count($this->MessageQueue))\r
+                {\r
+                    foreach($this->MessageQueue as $User => $Message)\r
+                    {\r
+                        //$this->ChildProcess[$ChildPid]\r
+                        $this->log_message("*** XFR SB $User");\r
+                        $pid=pcntl_fork();\r
+                        if($pid)\r
+                        {\r
+                            //Parrent Process\r
+                            $this->ChildProcess[$pid]=$User;\r
+                            break;\r
+                        }\r
+                        elseif($pid==-1)\r
+                        {\r
+                            $this->log_message("*** Fork Error $User");\r
+                            break;\r
+                        }\r
+                        else\r
+                        {\r
+                            //Child Process\r
+                            $this->log_message("*** Child Process Start for $User");\r
+                            unset($Message['XFRSent']);\r
+                            unset($Message['ReqTime']);\r
+                            $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $User, $Message);\r
+                            if ($bSBresult === false)\r
+                            {\r
+                                // error for switchboard\r
+                                $this->log_message("!!! error for sending message to ".$User);\r
+                            }\r
+                            die;\r
+                        }\r
+                    }\r
+                    unset($this->MessageQueue[$User]);\r
+                }\r
+                /*\r
+                 $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $aMSNUsers[$nCurrentUser], $sMessage);\r
+                 if ($bSBresult === false) {\r
+                 // error for switchboard\r
+                 $this->log_message("!!! error for sending message to ".$aMSNUsers[$nCurrentUser]);\r
+                 $aOfflineUsers[] = $aMSNUsers[$nCurrentUser];\r
+                 }*/\r
+                break;\r
+            case 'QNG':\r
+                // NS: <<< QNG {time}\r
+                @list(/* QNG */, $this->ping_wait) = @explode(' ', $data);\r
+                if ($this->ping_wait == 0) $this->ping_wait = 50;\r
+                //if (is_int($use_ping) && $use_ping > 0) $ping_wait = $use_ping;\r
+                //Mod by Ricky Set Online\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->log_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->log_message("*** RING from $email, $sb_ip:$sb_port");\r
+                $this->addContact($email,1,$email, true);\r
+                $pid=pcntl_fork();\r
+                if($pid)\r
+                {\r
+                    //Parrent Process\r
+                    $this->ChildProcess[$pid]='RNG';\r
+                    break;\r
+                }\r
+                elseif($pid==-1)\r
+                {\r
+                    $this->log_message("*** Fork Error $User");\r
+                    break;\r
+                }\r
+                else\r
+                {\r
+                    //Child Process\r
+                    $this->log_message("*** Ring Child Process Start for $User");\r
+                    $this->switchboard_ring($sb_ip, $sb_port, $sid, $ticket,$email);\r
+                    die;\r
+                }\r
+                break;\r
+            case 'OUT':\r
+                // force logout from NS\r
+                // NS: <<< OUT xxx\r
+                $this->log_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
+    public function SendMessage($Message, $To) {\r
+        if(!is_array($To))\r
+            $To=array($To);\r
+        $Receiver='';\r
+        foreach($To as $Email)\r
+        {\r
+            list($name,$host,$network)=explode('@',$Email);\r
+            $network=$network==''?1:$network;\r
+            if($network==1 && isset($this->switchBoardSessions[$Email]) ) {\r
+                $this->debug_message("*** SendMessage to $Receiver use SB message queue.");\r
+                array_push($this->SwitchBoardMessageQueue,$Message);\r
+                continue;\r
+            }\r
+            $Receiver.="$name@$host@$network,";\r
+        }\r
+        if($Receiver=='') return;\r
+        $Receiver=substr($Receiver,0,-1);\r
+        $this->debug_message("*** SendMessage to $Receiver use File queue.");\r
+        file_put_contents($FileName,"TO: $Receiver\n$Message\n");\r
+    }\r
+    \r
+    public function getNSSocket() {\r
+        return $this->NSfp;\r
+    }\r
+    \r
+    public function getSBSocket() {\r
+        return $this->SBfp;\r
+    }\r
+    \r
+    public function getSockets() {\r
+        return array($this->NSfp, $this->SBfp);\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 String $data Raw message from server\r
+     * @see registerHandler\r
+     * @return void\r
+     */\r
+    private function callHandler($event, $data) {\r
+        if (isset($this->myEventHandlers[$event])) {\r
+            call_user_func($this->myEventHandlers[$event], $data);\r
+        } else {\r
+            $this->noHandler($data);\r
+        }\r
+    }\r
+    \r
+    /** \r
+     * Registers a user handler\r
+     * \r
+     * Handler List\r
+     * IMIn\r
+     *\r
+     * @param String $event Event name\r
+     * @param String $handler User function to call\r
+     * @see callHandler\r
+     * @return boolean Returns 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
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/sample.php b/plugins/Msn/extlib/phpmsnclass/sample.php
new file mode 100644 (file)
index 0000000..32539c5
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/php -Cq\r
+<?php\r
+\r
+error_reporting(E_ALL);\r
+include_once('msn.class.php');\r
+\r
+// force to use MSNP9, without debug information\r
+// $msn = new MSN('MSNP9');\r
+\r
+// force to use MSNP9, with debug information\r
+// $msn = new MSN('MSNP9', true);\r
+\r
+// force to use MSNP15, without debug information\r
+// $msn = new MSN('MSNP15');\r
+\r
+// force to use MSNP15, with debug information\r
+// $msn = new MSN('MSNP15', true);\r
+\r
+// auto detect MSN protocol, without debug information\r
+// $msn = new MSN;\r
+\r
+// auto detect MSN protocol, with debug information\r
+$msn = new MSN(array('user' => 'statusnetbot@inflatablegoldfish.com', 'password' => 'statusnetplugin', 'alias' => 'statusnetbot', 'psm' => '', 'debug' => true));\r
+\r
+if ($msn->Run()) {\r
+    echo "Error for connect to MSN network\n";\r
+    echo "$msn->error\n";\r
+    exit;\r
+}\r
+\r
+//$msn->sendMessage('Now: '.strftime('%D %T')."\nTesting\nSecond Line\n\n\n\nand Empty Line",\r
+ //                 array(\r
+  //                  'darkip@inflatablegoldfish.com'\r
+   //                    )\r
+    //             );\r
+echo "Done!\n";\r
+exit;\r
+\r
+?>\r
+\r
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/msnmanager.php b/plugins/Msn/msnmanager.php
new file mode 100644 (file)
index 0000000..72de11c
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2008, 2009, StatusNet, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+
+/**
+ * AIM background connection manager for AIM-using queue handlers,
+ * allowing them to send outgoing messages on the right connection.
+ *
+ * Input is handled during socket select loop, keepalive pings during idle.
+ * Any incoming messages will be handled.
+ *
+ * In a multi-site queuedaemon.php run, one connection will be instantiated
+ * for each site being handled by the current process that has XMPP enabled.
+ */
+
+class MsnManager extends ImManager
+{
+
+    public $conn = null;
+    /**
+     * Initialize connection to server.
+     * @return boolean true on success
+     */
+    public function start($master)
+    {
+        if(parent::start($master))
+        {
+            $this->connect();
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    public function getSockets()
+    {
+        $this->connect();
+        if($this->conn){
+            return $this->conn->getSockets();
+        }else{
+            return array();
+        }
+    }
+
+    /**
+     * Process AIM events that have come in over the wire.
+     * @param resource $socket
+     */
+    public function handleInput($socket)
+    {
+        common_log(LOG_DEBUG, "Servicing the MSN queue.");
+        $this->stats('msn_process');
+        $this->conn->receive();
+    }
+
+    function connect()
+    {
+        if (!$this->conn) {
+            $this->conn=new MSN(array(
+                                      'user' => $this->plugin->user,
+                                      'password' => $this->plugin->password,
+                                      'alias' => $this->plugin->nickname,
+                                      'psm' => 'Send me a message to post a notice',
+                                      'debug' => true
+                                )
+                        );
+            $this->conn->registerHandler("IMIn", array($this, 'handle_msn_message'));
+            $this->conn->signon();
+        }
+        return $this->conn;
+    }
+
+    function handle_msn_message($data)
+    {
+        $this->plugin->enqueue_incoming_raw($data);
+        return true;
+    }
+
+    function send_raw_message($data)
+    {
+        $this->connect();
+        if (!$this->conn) {
+            return false;
+        }
+        $this->conn->sflapSend($data[0],$data[1],$data[2],$data[3]);
+        return true;
+    }
+}