diff --git a/index.js b/index.js
index 2ebe56f..fd431dd 100644
--- a/index.js
+++ b/index.js
@@ -1,16 +1,12 @@
 var iniparser = require('iniparser');
 var config = iniparser.parseSync('./config.ini');
 
-var keepAliveTimer;
-
 if (config.yahoomessenger.keepalive_interval == null) {
   config.yahoomessenger.keepalive_interval = 60;
 }
 
 var strftime = require('strftime');
 
-var loggedPM = [];
-
 var logger = require('winston');
 logger.remove(logger.transports.Console);
 logger.add(logger.transports.Console, { timestamp: function() { return (strftime('%F %T'));  }});
@@ -18,11 +14,6 @@ logger.add(logger.transports.Console, { timestamp: function() { return (strftime
 var db = require('./db.js');
 db_connection = db.start(config.db.host, config.db.username, config.db.password, config.db.name, logger);
 
-function isAdmin(user) {
-  var admins = config.yahoomessenger.admin.split(',');
-
-  return (admins.indexOf(user) >= 0);
-}
 
 function insertMessages(db_connection, logger_id, direction, partner, message, sentdate) {
 
@@ -45,179 +36,8 @@ function insertMessages(db_connection, logger_id, direction, partner, message, s
     );
 }
 
-var striptags = require('striptags');
-
-var YahooMessenger = require("yahoomessenger");
-YahooMessenger.newInstance();
-
-function sendPM(destination, message) {
-    logger.info("Sending to " + destination + ": " + message);
-
-    //try {
-        YahooMessenger.sendPM(destination, message);
-    /*
-    }
-    catch (e) {
-        logger.info("Something wrong");
-        logger.info(e);
-        logger.info("Try to reconnecting to yahoo messenger");
-        YahooMessenger.login(config.yahoomessenger.username, config.yahoomessenger.password);
-        return false;
-    }
-
-    return true;
-    */
-}
-
-function broadcast(destinations, message, exclude) {
-    var destinations = destinations.split(',');
-    var destinationCount = destinations.length;
-
-    for (var i=0; i < destinationCount; i++) {
-        destination = destinations[i];
-        if (destination == exclude) {
-            continue;
-        }
-
-        sendPM(destination, message);
-    }
-}
-
-var _keepAliveLoop = function() {
-    logger.info('Keep alive loop');
-
-    //try {
-        YahooMessenger.keepAlive();
-    /*
-    }
-    catch(e) {
-        logger.info("Something wrong");
-        logger.info(e);
-        logger.info("Try to reconnecting to yahoo messenger");
-        YahooMessenger.login(config.yahoomessenger.username, config.yahoomessenger.password);
-        return;
-    }
-    */
-
-    keepAliveLoop();
-}
-
-function keepAliveLoop() {
-    keepAliveTimer = setTimeout(_keepAliveLoop, config.yahoomessenger.keepalive_interval * 1000);
-}
-
-function ymLogin(){
-    logger.info("Login to YM as " + config.yahoomessenger.username)
-    YahooMessenger.login(config.yahoomessenger.username, config.yahoomessenger.password);
-}
-
-function onYmLoginSuccesful(data){
-    logger.info('Online on YM as ' + data.user_id + ' (' + data.firstname + ' ' + data.lastname + ')');
-
-    if (config.yahoomessenger.status) {
-        logger.info('Set status to: ' + config.yahoomessenger.status);
-        YahooMessenger.setCustomAwayStatus(config.yahoomessenger.status);
-    };
-
-    broadcast(config.yahoomessenger.report_to, config.yahoomessenger.report_message);
-
-    keepAliveLoop();
-}
-
-function onYmLoginError(data){
-    logger.info("YM login error");
-}
-
-function onYmPM(data) {
-    var direction = 'IN';
-
-    if (config.globals.debug == 1) {
-      console.log(data);
-    }
-
-    // check duplicate message
-    if (loggedPM.indexOf(data.message_id) >= 0) {
-        return;
-    }
-
-    loggedPM.unshift(data.message_id);
-    if (loggedPM.length > 30) {
-        loggedPM = loggedPM.slice(0, 10);
-    }
-
-    partner = data.sender;
-    if (partner == data.user_id) {
-        partner = data.target_user;
-        direction = 'OUT';
-    }
-
-    var message = striptags(data.message).trim();
-
-    logger.info('New ' + direction + ' message from ' + data.sender + ' to ' +  data.target_user + ': ' + message);
-
-    if (isAdmin(data.sender)) {
-        logger.info('Sender (' + data.sender + ') is an admin');
-    }
-
-    var sentdate = Date.parse(data.time);
-    var strftime = require('strftime');
-    sentdate = strftime('%Y-%m-%d %H:%M:%S', sentdate);
-
-    insertMessages(
-        db_connection,
-        data.user_id,
-        direction,
-        partner,
-        message,
-        sentdate
-    );
-
-    broadcast(config.yahoomessenger.report_to, '@' + data.sender + ': ' + message, partner);
-
-    if ((direction == 'IN') && (isAdmin(partner))) {
-        if (message.charAt(0) == '@') {
-            target = message.split(' ', 1).join();
-            target = target.slice(1);
-
-            var messageToForward = message.replace('@' + target, '').trim();
-            if (messageToForward == '') {
-                return;
-            }
-
-            logger.info('Forward to ' + target + ': ' + messageToForward);
-            sendPM(target, '@' + partner + ': ' + messageToForward);
-
-        } else if (message.charAt(0) == '+') {
-            target = message.split(' ', 1).join();
-            target = target.slice(1);
-
-            var messageToForward = message.replace('+' + target, '').trim();
-            if (messageToForward == '') {
-                return;
-            }
-
-            logger.info('Clean forward to ' + target + ': ' + messageToForward);
-            sendPM(target, messageToForward);
-        }
-
-    }
-}
-
-function onYmBuddyAddRequest(data) {
-    logger.info("Got request to add buddy from " + data.username);
-    YahooMessenger.acceptAddBuddy(data.username);
-}
-
-
-function onYmReady(){
-    ymLogin();
-}
-
-YahooMessenger.on('ready', onYmReady);
-YahooMessenger.on('loginSuccessful', onYmLoginSuccesful);
-YahooMessenger.on('loginError', onYmLoginError);
-YahooMessenger.on('pm', onYmPM);
-YahooMessenger.on('buddyAddRequest', onYmBuddyAddRequest);
+var ym = require('./ym');
+var YahooMessenger = ym.start(config, logger);
 
 var http = require('http');
 var nsr = require('node-simple-router');
diff --git a/ym.js b/ym.js
new file mode 100644
index 0000000..15432ad
--- /dev/null
+++ b/ym.js
@@ -0,0 +1,161 @@
+var YahooMessenger = require("yahoomessenger");
+var striptags = require('striptags');
+
+function start(config, logger) {
+    var oldMessages = [];
+
+    var keepAliveTimer;
+
+    var _keepAliveLoop = function() {
+        logger.info('Keep alive loop');
+
+        YahooMessenger.keepAlive();
+        keepAliveLoop();
+    }
+
+    function isAdmin(user) {
+      var admins = config.yahoomessenger.admin.split(',');
+
+      return (admins.indexOf(user) >= 0);
+    }
+
+    function keepAliveLoop() {
+        keepAliveTimer = setTimeout(_keepAliveLoop, config.yahoomessenger.keepalive_interval * 1000);
+    }
+
+    function login(){
+        logger.info("Login to YM as " + config.yahoomessenger.username)
+        YahooMessenger.login(config.yahoomessenger.username, config.yahoomessenger.password);
+    }
+
+    function pm(destination, message) {
+        logger.info("Sending to " + destination + ": " + message);
+
+        YahooMessenger.sendPM(destination, message);
+    }
+
+    function sendPM(destination, message) {
+        pm(destination, message);
+    }
+
+    function broadcast(destinations, message, exclude) {
+        var destinations = destinations.split(',');
+        var destinationCount = destinations.length;
+
+        for (var i=0; i < destinationCount; i++) {
+            destination = destinations[i];
+            if (destination == exclude) {
+                continue;
+            }
+
+            sendPM(destination, message);
+        }
+    }
+
+    function onReady() {
+        login();
+    }
+
+    function onLoginSuccesful(data) {
+        logger.info('Online on YM as ' + data.user_id + ' (' + data.firstname + ' ' + data.lastname + ')');
+
+        if (config.yahoomessenger.status) {
+            logger.info('Set status to: ' + config.yahoomessenger.status);
+            YahooMessenger.setCustomAwayStatus(config.yahoomessenger.status);
+        };
+
+        broadcast(config.yahoomessenger.report_to, config.yahoomessenger.report_message);
+        keepAliveLoop();
+    }
+
+    function onBuddyAddRequest(data) {
+        logger.info("Got request to add buddy from " + data.username);
+        YahooMessenger.acceptAddBuddy(data.username);
+    }
+
+    function onPM(data) {
+        var direction = 'IN';
+
+        if (config.globals.debug == 1) {
+          console.log(data);
+        }
+
+        // check duplicate message
+        if (oldMessages.indexOf(data.message_id) >= 0) {
+            return;
+        }
+
+        oldMessages.unshift(data.message_id);
+        if (oldMessages.length > 30) {
+            oldMessages = oldMessages.slice(0, 10);
+        }
+
+        partner = data.sender;
+        if (partner == data.user_id) {
+            partner = data.target_user;
+            direction = 'OUT';
+        }
+
+        var message = striptags(data.message).trim();
+
+        logger.info('New ' + direction + ' message from ' + data.sender + ' to ' +  data.target_user + ': ' + message);
+
+        if (isAdmin(data.sender)) {
+            logger.info('Sender (' + data.sender + ') is an admin');
+        }
+
+        var sentdate = Date.parse(data.time);
+        var strftime = require('strftime');
+        sentdate = strftime('%Y-%m-%d %H:%M:%S', sentdate);
+
+        /*
+        insertMessages(
+            db_connection,
+            data.user_id,
+            direction,
+            partner,
+            message,
+            sentdate
+        );
+        */
+
+        broadcast(config.yahoomessenger.report_to, '@' + data.sender + ': ' + message, partner);
+
+        if ((direction == 'IN') && (isAdmin(partner))) {
+            if (message.charAt(0) == '@') {
+                target = message.split(' ', 1).join();
+                target = target.slice(1);
+
+                var messageToForward = message.replace('@' + target, '').trim();
+                if (messageToForward == '') {
+                    return;
+                }
+
+                logger.info('Forward to ' + target + ': ' + messageToForward);
+                sendPM(target, '@' + partner + ': ' + messageToForward);
+
+            } else if (message.charAt(0) == '+') {
+                target = message.split(' ', 1).join();
+                target = target.slice(1);
+
+                var messageToForward = message.replace('+' + target, '').trim();
+                if (messageToForward == '') {
+                    return;
+                }
+
+                logger.info('Clean forward to ' + target + ': ' + messageToForward);
+                sendPM(target, messageToForward);
+            }
+        }
+    }
+
+    YahooMessenger.newInstance();
+    YahooMessenger.on('ready', onReady);
+    YahooMessenger.on('loginSuccessful', onLoginSuccesful);
+    YahooMessenger.on('buddyAddRequest', onBuddyAddRequest);
+    YahooMessenger.on('pm', onPM);
+
+    return YahooMessenger;
+}
+
+exports.start = start;