
 var HTTP           = require('http');
 var HTTPS          = require('https');
 var fs             = require('fs');
 var console        = require('gifer-console');
 var domainRequire  = require('domain').create();

 // =============== VARS ===================

 var Service        = null;
 var Route          = null;
 var DropAllUsers   = null;
 var CMD            = null;
 var MCServer       = null;
 var MCPathes       = null;
 var HTTPServer     = null;
 var internalServer = null;
 var socketIO       = null;
 var __sockets      = []; // Открытые сокеты HTTP сервера
 var Configuration  = {
     HTTPSPort        : 443,
     HTTPPort         : 80,
     MyChatServerPort : 2004,
     MyChatServerIP   : "127.0.0.1",
     ServPass         : "",
     ServLang         : "en",
     AlternativePorts : [80, 8080, 8088],
     WEBBundleKeyPath : "",
     WEBPrivateKeyPath: "",
     WEBPublicKeyPath : ""
 };

 // var androidConnection  = null;
 var TelegramCheckTimer = null;
 var Request            = null;
 var customCommands     = null;
 var videoConfSignaling = null;

 // ============ INIT ========================

 domainRequire.on('error', function(err) {
    fs.appendFileSync('./CRASH.log', '[' + new Date() + '] ' +  err.stack + '\n');

    console.immediately(err.stack, console.logLevel.FATAL);

    process.exit(703);
 });

 domainRequire.run(function(){
     Service        = require('./service/service.js');
     Route          = require('./service/router.js');
     DropAllUsers   = require('./service/mcconnect').KILL_ALL_CONNECTION;
     CMD            = require('./service/cmd/cmd').CMD;
     internalServer = require('./service/mctools/mcInternalConnection.js');
     Request        = require('request');
     customCommands = require('./service/mctools/mcCustomCommands');

     MCServer = Service.MCServer;
     MCPathes = Service.MCPathes;

     console.SetLogLevel(console.logLevel.DEBUG);

     startInternalServer();

     // Send Push Notification to android client

     // Request({
     //     headers: {
     //         "Content-Type" : "application/json",
     //         "Authorization" : "key=AIzaSyBGzp2Qu8-wMk4DcEj3UVCwDiSqnKnN5gM"
     //     },
     //     method: "POST",
     //     url: "https://fcm.googleapis.com/fcm/send",
     //     body: JSON.stringify({
     //         "data": {
     //             url:'MYCHAT',
     //             foo:'feeeeeeeeeeeee',
     //             bar:'1bar 2bar 3bar'
     //         },
     //         "to" : "fLXrSZlmwK8:APA91bEjcIMMI3sW247CYf0HcNOwVXDhlvlZ_Rmeu0uHpnQNLuXi7jF9bPFfVGSaYdvYmWyEa3wml-yWTP4wRjbMDcq-4ngoMrHrrb1AgSoSBjzXbVJrkzyqmw_jaMu4vCvqr3Zoq-IH"
     //     })
     // });
 });
 
 // ============= MAIN =======================

 function updateOptions(config) {

     MCPathes.Backup     = config.PathBackup;
     MCPathes.Files      = config.PathFiles;
     MCPathes.Uploads    = config.PathFiles;
     MCPathes.History    = config.PathLogs;
     MCServer.LogLevel   = config.LogLevel;

     MCServer.MaxUploadFileSize = config.MaxUploadFileSize * 1024 * 1024;

     MCServer.ProtocolVersion = config.ServerProtocol;
     MCServer.ClientVersion   = config.ServerVersion;
     MCServer.FTPPublicAccess = config.FTPPublicAccess || false;
     MCServer.FTPPublicDir    = config.FTPPublicDir    || "";

     MCServer.NoSSLPort  = config.HTTPNoSSLPort   || 8080;
     MCServer.Port       = config.HTTPPort;
     MCServer.MCPort     = config.MyChatServerPort   || 2004;
     MCServer.Host       = config.MyChatServerIP     || "127.0.0.1";
     MCServer.ServPass   = config.ServPass           || "";
     MCServer.IPVer      = config.IPVer              || 0;
     MCServer.Lang       = config.ServLang           || MCServer.Lang;
     MCServer.IPList     = config.IPList             || "";
     MCServer.PushTokens = config.PushTokens         || [];
     MCServer.ExternalIP = config.ExternalIP         || "";
     MCServer.WEBUseSSL  = config.WEBUseSSL          || false;
     MCServer.ServerID   = config.ServerID;
     MCServer.ClientVersion  = config.ClientVersion  || "";
     MCServer.CertificatePWD = config.CertificatePWD || "";
     MCServer.TelegramToken  = config.TelegramToken  || "";

     MCServer.TURNPwd  = config.Credential;
     MCServer.TURNUser = config.UserName;
     MCServer.TURNPort = config.TURNPort;

     MCServer.WEBUseCache      = !!config.WEBUseCache;
     MCServer.WEBCacheTTL      = config.WEBCacheTTL || 24;
     MCServer.WEBCacheOneFileSizeLimit = config.WEBCacheOneFileSizeLimit;
     MCServer.WEBCacheTotalSizeLimit   = config.WEBCacheTotalSizeLimit;

     MCServer.Aliases = {
         chat    : { path: config.AliasChat,    enabled: config.ChatEnable},
         admin   : { path: config.AliasAdmin,   enabled: config.AdminEnable},
         forum   : { path: config.AliasForum,   enabled: config.ForumEnable},
         kanban  : { path: config.AliasKanban,  enabled: config.KanbanEnable},

         API     : { path: config.AliasAPI,     enabled: true},
         files   : { path: config.AliasFiles,   enabled: true},
         support : { path: config.AliasSupport, enabled: true}
     };

     console.SetLogLevel(MCServer.LogLevel || console.logLevel.INFO);
 }

 function ConfigurateStartParams(opt){
     updateOptions(opt);

     Service.WriteFile(MCPathes.ProfilNode + "node.pid", process.pid);
     
     console.DublicateToFile(/*MCPathes.Profile + "logs/"*/MCPathes.History + (new Date()).myFormat('yyyy') + "/" + (new Date()).myFormat('mm') + "/" + (new Date()).myFormat('dd') + "/node.log");

     console.log('', console.logLevel.INFO);
     console.log('==========================================', console.logLevel.INFO);
     console.log('============= START NODE.JS ==============', console.logLevel.INFO);
     console.log('==========================================', console.logLevel.INFO);
     console.log('', console.logLevel.INFO);

     console.info("MyChat server profile path list:\n" +
                  "Profile    : " + MCPathes.Profile + "\n" +
                  "ProfileNode: " + MCPathes.ProfilNode + "\n" +
                  "Events     : " + MCPathes.Events, console.logLevel.INFO);
 }

 function onRequest(request, response, noSSL) {
     if ((request.method !== 'GET') && (request.method !== 'POST') && (request.method !== 'HEAD')){
         console.warn('Unknown method: ' + request.method, console.logLevel.WARN);
     } else {
         console.DublicateToFile(/*MCPathes.Profile + "logs/"*/MCPathes.History + (new Date()).myFormat('yyyy') + "/" + (new Date()).myFormat('mm') + "/" + (new Date()).myFormat('dd') + "/node.log");

         request.remoteHostIp = request.socket._parent ? request.socket._parent.remoteHostIp : request.socket.remoteHostIp;

         Route.GO.call(request.socket, request, response, noSSL === "nossl");
     }
 }

 function StartHTTPServer(){
     __sockets = [];

     var HTTPListener = null;
     var _key   = null;
     var _cert  = null;
     var _ca    = null;
     var bindIP = MCServer.IPVer ? "::" : "0.0.0.0";
     var mcc    = require('./service/mcconnect.js');

     var defaultSslPath = {
         "public"  : "defaultPublicKey",
         "private" : "defaultPrivateKeyPath"
     };

     if (Configuration.WEBUseSSL) {
         try {
             var cc = Configuration.WEBBundleKeyPath ? (MCPathes.Cert + Configuration.WEBBundleKeyPath) : null;

             if (cc){
                 _ca  = fs.readFileSync(cc);
                 
                 console.log('SSL root certificate loaded: ' + cc);
             }
         } catch(e) {
             console.warn('Failed to load root file certificate: ' + e.message);
         }

         try {
             // -- no more build in certs --
             // var kk = Configuration.WEBPrivateKeyPath === defaultSslPath.private
             //     ? './service/ssl/private.pem'
             //     : MCPathes.Cert + Configuration.WEBPrivateKeyPath;
             // var ss = Configuration.WEBPublicKeyPath === defaultSslPath.public
             //     ? './service/ssl/public.pem'
             //     : MCPathes.Cert + Configuration.WEBPublicKeyPath;
             var kk = MCPathes.Cert + Configuration.WEBPrivateKeyPath;
             var ss = MCPathes.Cert + Configuration.WEBPublicKeyPath;

             _key  = fs.readFileSync(kk);
             _cert = fs.readFileSync(ss);

             console.log('SSL certificate loaded: ' + kk);
             console.log('SSL certificate loaded: ' + ss);
         } catch(e){
             Configuration.WEBUseSSL = false;

             internalServer.sendDataFromInternalServer(CMD.ns_https_error + '=' + JSON.stringify({
                 Error : e.message
             }));

             console.err("Fail of loading the HTTPS key files:\n " + Configuration.WEBPrivateKeyPath + "\n" + Configuration.WEBPublicKeyPath, console.logLevel.ERROR);
             console.err("Load cert files: " + e.message, console.logLevel.ERROR);
         }
     }

     function _http(port, main) {
         HTTPServer = HTTP.createServer(onRequest);

         HTTPListener = HTTPServer.listen(port /*MCServer.Port*/, bindIP, function(){
             console.important("HTTP   Server started at port tcp " + port /*MCServer.Port*/ + '\n');

             if (main) setTimeout(function (){
                 internalServer.sendDataFromInternalServer(CMD.ns_started);
             }, 100);
         });
     }

     if (Configuration.WEBUseSSL){
         var tlsMCServ = require('tls');
         var constants = require('constants');
         var options   = {
             key               : _key,
             cert              : _cert,
             passphrase        : MCServer.CertificatePWD || "",
             secureProtocol    : "TLSv1_2_method",
             secureContext     : tlsMCServ.createSecureContext({
                 secureOptions : constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3
             })
         };

         if (_ca){
             options.ca = _ca;
         }

         try {
             HTTPServer = HTTPS.createServer(options, onRequest);

             HTTPListener = HTTPServer.listen(MCServer.Port, bindIP, function(){
                 console.important("HTTPS  Server started at port tcp " + MCServer.Port + '\n');

                 setTimeout(function (){
                     internalServer.sendDataFromInternalServer(CMD.ns_started);
                 }, 100);
             });

             // =========================================================================
             // запускаем дублирующий веб-сервер для скачивания файлов и обновлений на ХР без SSL
             // =========================================================================

             try {
                 var HTTPServerNoSSL = HTTP.createServer(function (req, res){
                     onRequest(req, res, "nossl");
                 });

                 HTTPServerNoSSL.listen(MCServer.NoSSLPort, bindIP, function(){
                     console.important("HTTP   Server for XP updates, port " + MCServer.NoSSLPort + '\n');
                 });

                 HTTPServerNoSSL.on('error', function (e){
                     console.warn("No SSL server can't start: " + e.message);
                 });

                 HTTPServerNoSSL.on('connection', function (socket) {
                     socket.remoteHostIp     = socket.remoteAddress;
                     socket.connectID        = Service.RandomHash(7);
                     socket.sendDataInternal = internalServer.sendDataFromInternalServer;
                     socket.isIpChecked      = {}; // список провереных инструментов по IP фильтру
                 });

             } catch (e){
                 console.warn("No SSL server can't start: " + e.message);
             }
             // =========================================================================
         } catch (e){
             console.warn("Certificate error: " + e.message);

             internalServer.sendDataFromInternalServer(CMD.ns_https_error + '=' + JSON.stringify({
                 Error : e.message
             }));

             _http(MCServer.Port, true);
         }
     } else {
         _http(MCServer.Port, true);
     }

     try {
         socketIO = require('socket.io')(HTTPServer, {
             pingTimeout : 5000,
             pingInterval: 3000
         });

         mcc.startSocketIO(socketIO);

         // === Android & iOS Connections ===
         require('./service/mcWebGateWay.js')(socketIO);

         // === Test Video Conf, Signaling server ===
         require('./service/videoConfSignaling.js')(socketIO);
     } catch (e){
        console.err(e.stack, console.logLevel.ERROR);
        console.err(e.message, console.logLevel.ERROR);
     }

     mcc.httpStarted();

     HTTPServer.on('connection', function (socket) {
         socket.remoteHostIp     = socket.remoteAddress;
         socket.connectID        = Service.RandomHash(7);
         socket.sendDataInternal = internalServer.sendDataFromInternalServer;
         socket.isIpChecked      = {}; // список провереных инструментов по IP фильтру

         __sockets.push(socket);

         // if (socket.getPeerCertificate){
         //     var info       = socket.getPeerCertificate();
         //     var validTo    = new Date(info.valid_to);
         //
         //     console.log(JSON.stringify({
         //         daysRemaining : getDaysRemaining(new Date(), validTo),
         //         valid         : socket.authorized || false,
         //         validFrom     : info.valid_from,
         //         validTo       : info.valid_to
         //     }));
         // }

         socket.setTimeout(30000);

         socket.on('close', function () {
             console.log('HTTP socket closed', console.logLevel.DEBUG);

             __sockets.splice(__sockets.indexOf(socket), 1);
         });

         socket.on('error', function (err) {
             if (err.code !== "HPE_INVALID_METHOD"){
                 console.err('HTTPServer: [' + socket.remoteHostIp + '] HTTP socket ERROR! ' + Service.ObjToString(err), console.logLevel.ERROR);
             }
         });
     });

     HTTPListener.maxConnections = MCServer.MaximumHTTPConnections;

     setTimeout(function () {
         Route.enableCache(MCServer.WEBUseCache);
     }, 200);


     // =======================================================================
     // === CPU LOAD DETECTOR =================================================
     // =======================================================================

     var __os = require("os");

     /**
      * @description Measure the CPU usage calculated between two different CPU usage samples
      * @param {function} cb A callback function the result is passed to
      * @param {number} [core=-1] The CPU core index to measure. When is not greater than -1 then it is "averaged" for all CPU cores.
      * @param {number} [sampleMs=1000]  The number of milliseconds between the CPU usage samples
      */
     function cpuUsage(cb, core, sampleMs) {
         var deltaUsed;
         var deltaIdle;
         var timesKeys = ["user", "nice", "sys", "irq"];

         var allCores = null === core || !(core > -1);

         var byCore = function (cpu, i) {
             return allCores || core === i
         };

         var bySampleKey = function (sample, key) {
             return sample.filter(byCore).reduce(function (sum, cpu) {
                 return sum + cpu.times[key]
             }, 0);
         };

         var sample0 = __os.cpus();

         setTimeout(function() {
             var sample1 = __os.cpus();

             deltaUsed = timesKeys.reduce(function (diff, key) {
                 return diff + bySampleKey(sample1, key) - bySampleKey(sample0, key)
             }, 0);

             deltaIdle = bySampleKey(sample1, "idle") - bySampleKey(sample0, "idle");

             if ("function" === typeof cb) {
                 cb(Math.round(100 * (deltaUsed / (deltaUsed + deltaIdle))));
             }
         }, sampleMs || 1000);
     }

     const timeCount    = 30; // количество показателей нагрузки на проце, вычисляются каждый timeInterval
     const averageLimit = 55; // максимальное среднее значение нагрузки, псле которой будет выводиться лог
     const timeInterval = 1000; // как часто опрашивать CPU, по умолчанию 1 сек

     var timeList       = [];

     setInterval(function (){
         cpuUsage(function (perc) {
             var average = 0;

             if (timeList.length === timeCount){
                 timeList.shift();
             }

             timeList.push({
                 cpu: perc,
                 dt : (new Date()).getTime()
             });

             if (timeList.length === timeCount) {
                 timeList.forEach(function (ii){
                     average += ii.cpu;
                 });

                 average = Math.round(average / timeList.length);
             }

             if (average > averageLimit) {
                 console.log("CPU: " + perc + "% load, start time: " + (new Date(timeList[0].dt)).myFormat("hh:nn:ss:zzz"));

                 timeList = [];
             }
         }, -1, 0);
     }, timeInterval);

     // =======================================================================
     // =======================================================================

 }

 function StopHTTPServer(callback){
     if (HTTPServer){
         Route.clearCache();

         // if (androidConnection){
         //     androidConnection.close();
         //     androidConnection = null;
         // }

         for (var i = 0; i < __sockets.length; i++) {
             console.log('HTTP socket #' + i + ' destroyed', console.logLevel.DEBUG);

             __sockets[i].destroy();
         }

         HTTPServer.on('close', function(){
             console.immediately("HTTP Server stopped.", console.logLevel.INFO);

             if (callback) callback();
         });

         HTTPServer.close();

         HTTPServer = null;
     } else {
         callback && callback();
     }
 }

 /*function startTelegramBotUpdater(botID, checkInterval) {
     if (false){
         TelegramCheckTimer = setInterval(function () {
             var data = "";
             var _request = Request({
                 method: "GET",
                 url: "https://api.telegram.org/bot" + botID + "/getUpdates"
             });

             _request.on('data', function (chunk) {
                 data += chunk;
             });

             _request.on('end', function () {
                 console.log(data);
             });

             _request.on('error', function (err) {
                 console.error(err.message);
             });
         }, checkInterval);
     }
 }*/

 function startInternalServer() {
     // var icq = require('./service/icqbot/icq').ICQ(true);

     internalServer.startInternalServer();

     internalServer.onClose = function (type, err) {
         var socket = this;
         var code   = 0;

         if (socket.isMyChatServer) {
             switch (type){
                 case 'END':
                     console.immediately('MyChat Server disconnected from internal server!', console.logLevel.FATAL);
                 break;

                 case 'ERROR':
                     console.immediately('Internal Server ERROR!\n ' + Service.ObjToString(err), console.logLevel.FATAL);

                     code = 704;
                 break;

                 case 'TIMEOUT':
                     console.immediately('Internal Server: Timeout occurred!', console.logLevel.FATAL);

                     code = 704;
                 break;
             }

             StopHTTPServer(function () {
                 setTimeout(function(){
                     process.exit(code);
                 }, 100);
             });
         }
     };

     internalServer.addCmdParser(CMD.sn_config, function (Obj) {
         Obj.MyChatProfile = Obj.MyChatProfile.replace(/\\/g, '/');

         Service.InitMCPathes(Obj.MyChatProfile);

         // Configuration.TelegramUseSimpleIntegration = true;
         // Configuration.TelegramBotID                = "384707904:AAGRY2o0jqbd0sC0KHv4ONJVEa2Ga7U6NNA";
         // Configuration.TelegramCheckInterval        = 10000;
         // if (Configuration.TelegramUseSimpleIntegration && Configuration.TelegramBotID){
         //     startTelegramBotUpdater(Configuration.TelegramBotID, Configuration.TelegramCheckInterval);
         // }

         Configuration = Service.MargeObj(Configuration, Obj);

         ConfigurateStartParams(Configuration);

         if (Configuration.EnableUpdatesDownloadLimit){
             internalServer.setDownloadUpdatesLimit(Configuration.LimitUpdateDownloads);
         }

         process.chdir(MCPathes.Index);

         Route.setAliases();
     });

     internalServer.addCmdParser(CMD.sn_start, function (Obj) {
         if (HTTPServer) {
             console.err('Trying to repeat start server!', console.logLevel.ERROR);

             try {
                 console.err(JSON.stringify(Obj), console.logLevel.ERROR);
             } catch (e){}
         } else {
             StartHTTPServer();
         }
     });

     internalServer.addCmdParser(CMD.sn_quit, function () {
         console.immediately("From server sended \"QUIT\" command", console.logLevel.INFO);

         this.sendDataFromInternalServer(CMD.ns_bye);

         internalServer.closeServer();
     });

     internalServer.addCmdParser(CMD.sn_update_options, function (Obj) {
         Obj.MyChatProfile = Obj.MyChatProfile.replace(/\\/g, '/');

         Service.InitMCPathes(Obj.MyChatProfile);

         Configuration = Service.MargeObj(Configuration, Obj);

         updateOptions(Configuration);
     });

     internalServer.addCmdParser(CMD.sn_info, function (info) {
         MCServer.ServerName       = info.ServerName;
         MCServer.Lobby            = info.LobbyEnable;
         // MCServer.OnlySecuredLogin = info.OnlySecuredLogin;
         MCServer.UseServerPass    = info.UseServerPass;
     });

     internalServer.addCmdParser(CMD.sn_path_info, function (info) {
         // info.sPathFTPPublic;
         // info.sPathFTPPersonal;
         MCPathes.Backup  = info.PathBackup;
         MCPathes.Files   = info.PathFiles;
         MCPathes.Uploads = info.PathFiles;
         MCPathes.History = info.PathLogs;
     });

     // internalServer.addCmdParser(CMD.sn_icq_connect, function (user) {
     //     icq.createIcqConnection(user.UIN, user.Login, user.Pass, icqHandleEvents);
     // });

     // internalServer.addCmdParser(CMD.sn_icq_send_message, function (user) {
     //     icq.sendMessage(user.UIN, user.ICQ, user.Msg);
     // });

     internalServer.addCmdParser(CMD.sn_run_command, function (_data) {
         var data = Service.StringToObj(_data);

         setTimeout(() => {
             customCommands.runCMD(data, this.sendDataFromInternalServer);
         }, 10);
     });

     internalServer.addCmdParser(CMD.sn_check_ssl_info, function () {
         var _send = this.sendDataFromInternalServer;

         setTimeout(function () {
             var postData = JSON.stringify({
                 host : MCServer.ExternalIP || MCServer.Host,
                 port : MCServer.Port
             });

             var options = {
                 hostname: 'mychat-server.com',
                 port    : 80,
                 path    : '/checkMySSL',
                 method  : 'POST',
                 headers : {
                     'Content-Type': 'application/x-www-form-urlencoded',
                     'Content-Length': Buffer.byteLength(postData)
                 }
             };

             var reqData = "";

             var req = require('http').request(options, (res) => {
                 res.on('data', (chunk) => {
                     reqData += chunk;
                 });

                 res.on('end', () => {
                     _send(CMD.ns_check_ssl_info + "=" + reqData);
                 })
             });

             req.on('error', (e) => {
                 console.log('problem with request: ' + e.message);
             });

             req.write(postData);
             req.end();
         }, 10);
     });

     global._internalServer = internalServer;
 }

 // function icqHandleEvents(userData, oscarConst) {
 //     var aim   = userData.aim;
 //
 //     aim.on('typing', function(who, type) {
 //         switch (type){
 //             case oscarConst.TYPING_NOTIFY.START       : type = 'started typing'; break;
 //             case oscarConst.TYPING_NOTIFY.FINISH      : type = 'finished typing'; break;
 //             case oscarConst.TYPING_NOTIFY.TEXT_ENTERED: type = 'entered text'; break;
 //
 //             default: type = 'closed the IM';
 //         }
 //
 //         console.log('[ ICQ ]: typing notification: ' + who + ' ' + type, console.logLevel.L_Extended);
 //     });
 //
 //     aim.on('im', function(text, sender, flags, when) {
 //         console.log('[ ICQ ]: received ' + (when ? 'offline ' : '') + 'IM from ' + sender.name + (when ? ' (on ' + when + ')' : '') + ': ' + text, console.logLevel.L_Extended);
 //
 //         if (!when){
 //             internalServer.sendDataFromInternalServer(CMD.ns_icq_send_message + "=" + JSON.stringify({
 //                 sender: sender.name,
 //                 msg   : text,
 //                 flags : flags,
 //                 when  : when
 //             }));
 //         }
 //     });
 //
 //     aim.on('missed', function(sender, numMissed, reason, channel) {
 //         console.log('[ ICQ ]: missed ' + numMissed + ' messages from ' + sender.name + '. Reason: ' + reason + '. Channel: ' + channel, console.logLevel.L_Extended);
 //     });
 //
 //     aim.on('connectedto', function(conn) {
 //         console.info('[ ICQ ]: Connected to ' + conn.serverType + ' server (' + conn.remoteAddress + ')', console.logLevel.L_Extended);
 //     });
 //
 //     aim.on('contactonline', function(user) {
 //         var status = 'other';
 //
 //         if (user.idleMins){
 //             status = 'idle (' + user.idleMins + ' mins)';
 //         } else
 //             switch (user.status){
 //                 case oscarConst.USER_STATUSES.ONLINE : status = 'available'; break;
 //                 case oscarConst.USER_STATUSES.AWAY   : status = 'away'; break;
 //             }
 //
 //         console.log('[ ICQ ]: ' + user.name + ' is now online and ' + status + (user.statusMsg ? ': ' + user.statusMsg : ''), console.logLevel.L_Extended);
 //
 //         // console.log('\nFull info:' + JSON.stringify(user));
 //     });
 //
 //     aim.on('contactupdate', function(user) {
 //         var status = 'other';
 //
 //         if (user.idleMins){
 //             status = 'idle (' + user.idleMins + ' mins)';
 //         } else
 //             switch (user.status){
 //                 case oscarConst.USER_STATUSES.ONLINE : status = 'available'; break;
 //                 case oscarConst.USER_STATUSES.AWAY   : status = 'away'; break;
 //             }
 //
 //         console.log('[ ICQ ]: ' + user.name + ' is now ' + status + (user.statusMsg ? ': ' + user.statusMsg : ''), console.logLevel.L_Extended);
 //     });
 //
 //     aim.on('contactoffline', function(user) {
 //         console.log('[ ICQ ]: ' + user.name + ' is now offline', console.logLevel.L_Extended);
 //     });
 //
 //     aim.on('icon', function(who, icon, size) {
 //         console.log('[ ICQ ]: Got ' + size + ' buddy icon for ' + who, console.logLevel.L_Extended);
 //     });
 // }

 process.on('uncaughtException', function (err) {
     console.immediately("FATAL - " + err.message + '\n', console.logLevel.FATAL);
     console.immediately(err.stack + '\n', console.logLevel.FATAL);

     fs.appendFileSync('./CRASH.log', '[' + new Date() + '] ' + err.stack + '\n');

     process.exit(700);
 });

 // function manualStartNodeJS(){
 //     var _configuration = Service.Read_JSON_File('./config.json', true) || {};
 //
 //     Service.InitMCPathes(_configuration.MyChatProfile);
 //
 //     ConfigurateStartParams(_configuration.MyChatProfile);
 //
 //     Service.InitMCPathes(_configuration.MyChatProfile);
 //
 //     process.chdir(MCPathes.Index);
 //
 //     StartHTTPServer();
 // }

 // manualStartNodeJS();

 