function Sender (sessionid, msgid) {

   var _cb;
   var _handler;
   var _sessionid;
   var _nextmsgid;

   _sessionid = sessionid;
   _nextmsgid = msgid;

   this.execute = function (fromNumber, fromName, to, text, callback) {

      if (! _handler) {
         if (window.XMLHttpRequest) _handler = new XMLHttpRequest ();
         else _handler = new ActiveXObject ("Microsoft.XMLHTTP");
      }

      if (_handler) {

         _cb = callback;

         var hostname = window.location.hostname.toString ();

         _handler.open ("POST", "http://" + hostname + "/perl/mxmd/webchat/text", true);
         _handler.onreadystatechange = onresponse;
         _handler.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

         var msg = "<text><task>sendtext</task><sessionid>" + _sessionid + "</sessionid><messageid>" + _nextmsgid + "</messageid><data>";
         msg += "<from><number>" + fromNumber + "</number>";
         if (fromName)
            msg += "<name><![CDATA[" + fromName + "]]></name>";
         msg += "</from>";
         msg += "<to>" + to + "</to>";
         msg += "<msg><![CDATA[" + text + "]]></msg>";
         msg += "</data></text>";

         _handler.send (msg);

      } else {

         showMsg ("An error occured. Please try again later");
      }
   }

   function onresponse () {

      if (_handler.readyState != 4 || _handler.status != 200)
         return;

      var xml = _handler.responseXML;
      if (xml == null || ! findNode (xml, 'ok')) {
         if (_cb != null)
            _cb ({'status': 0, 'msg': 'Unexpected error, please try again later'});
         return;
      }

      var status = findNodeValue (xml, 'status');
      var msg    = findNodeValue (xml, 'msg');

      if (status == 1) {

         _nextmsgid   = findNodeValue (xml, 'nextmsg_id');

         if (_cb != null)
            _cb ({'status': status, 'msg': msg, 'friendadded': findNodeValue (xml, 'friendadded')});

      } else {

         if (_cb != null) {

            var showaddtoaddressbookpopup = findNode (xml, 'showaddtoaddressbookpopup');
            if (showaddtoaddressbookpopup) {
               _cb ({'status': status, 'msg': msg, 'showaddtoaddressbookpopup': 1, 'name': findNodeValue (showaddtoaddressbookpopup, 'name'), 'number': findNodeValue (showaddtoaddressbookpopup, 'number') });
            } else {
               _cb ({'status': status, 'msg': msg});
            }
         }

      }

   }

   function findNodeValue (node, tag) { try { return node.getElementsByTagName (tag)[0].firstChild.nodeValue; } catch (err) { return null; } }
   function findAttrValue (node, tag) { try { return node.attributes.getNamedItem (tag).value; } catch (err) { return null; } }
   function findNode (node, tag) { try { return node.getElementsByTagName (tag)[0]; } catch (err) { return null; } }
}

