diff --git a/src/matrix.rs b/src/bot.rs
similarity index 65%
rename from src/matrix.rs
rename to src/bot.rs
index 2b031f1259f680cafa3c530f322d09be9f7aa069..8217fabaa0deb886868dcf74f0ac71a9bafa6603 100644
--- a/src/matrix.rs
+++ b/src/bot.rs
@@ -22,9 +22,15 @@ use matrix_sdk::{
     },
     Client, Result, SyncSettings,
 };
-use std::{convert::TryFrom, lazy::SyncLazy, process::abort, sync::Arc, sync::Mutex};
+use std::{convert::TryFrom, process::abort, sync::Mutex};
 use tokio::time::{sleep, Duration};
 
+pub struct Bot {
+    config: Config,
+    client: Option<Client>,
+    packages: Mutex<Vec<CmdPackage>>,
+}
+
 async fn join_room(room: &Invited) {
     info!("Autojoining room {}", room.room_id());
     let mut delay = 2; // seconds
@@ -86,40 +92,6 @@ async fn startup_and_log_rooms(client: &Client) {
     join_all(list_to_wait_for).await;
 }
 
-async fn on_msg_room_event(
-    ev: SyncMessageEvent<MessageEventContent>,
-    room: Room,
-    __info: Option<EncryptionInfo>,
-) {
-    let sender_id = ev.sender.clone();
-    return_if!(sender_id.as_str() == room.own_user_id().as_str(), ());
-
-    if let (Room::Joined(joined), MessageType::Text(TextMessageEventContent { ref body, .. })) =
-        (room, ev.content.msgtype.clone())
-    {
-        if body.starts_with("%") {
-            if let Some(stripped) = body.strip_prefix("%") {
-                let args = stripped.split(' ').collect::<Vec<&str>>();
-                let mut res: String = format!("Command not found");
-                if let Some(pkg) = GLOBAL_PKG
-                    .lock()
-                    .unwrap()
-                    .iter()
-                    .find(|x| x.has_command(&args))
-                {
-                    res = pkg.handle(&joined, &sender_id, args);
-                }
-
-                let event = ev.into_full_event(joined.room_id().clone());
-                let msg = AnyMessageEventContent::RoomMessage(
-                    MessageEventContent::text_reply_html(res.clone(), res, &event),
-                );
-                joined.send(msg, None).await.unwrap();
-            }
-        }
-    };
-}
-
 async fn on_msg_room_reaction(
     ev: SyncMessageEvent<ReactionEventContent>,
     room: Room,
@@ -149,9 +121,6 @@ async fn on_msg_room_reaction(
     };
 }
 
-static GLOBAL_PKG: SyncLazy<Arc<Mutex<Vec<CmdPackage>>>> =
-    SyncLazy::new(|| Arc::new(Mutex::new(Vec::<CmdPackage>::new())));
-
 macro_rules! register_handler_if_enabled {
     ($client: expr, $config: expr, $handler: expr, $handler_name: expr) => {{
         if ($config) {
@@ -163,11 +132,6 @@ macro_rules! register_handler_if_enabled {
     }};
 }
 
-pub struct Bot {
-    config: Config,
-    client: Option<Client>,
-}
-
 impl Bot {
     pub fn new(config_file: String) -> Bot {
         match config_from_file(&config_file) {
@@ -183,6 +147,7 @@ impl Bot {
                 Bot {
                     config: config,
                     client: None,
+                    packages: Mutex::new(Vec::<CmdPackage>::new()),
                 }
             }
         }
@@ -212,6 +177,41 @@ impl Bot {
             "state member"
         );
 
+        let on_msg_room_event = |ev: SyncMessageEvent<MessageEventContent>,
+                                 room: Room,
+                                 __info: Option<EncryptionInfo>| async {
+            let sender_id = ev.sender.clone();
+            return_if!(sender_id.as_str() == room.own_user_id().as_str(), ());
+
+            if let (
+                Room::Joined(joined),
+                MessageType::Text(TextMessageEventContent { ref body, .. }),
+            ) = (room, ev.content.msgtype.clone())
+            {
+                if body.starts_with("%") {
+                    if let Some(stripped) = body.strip_prefix("%") {
+                        let args = stripped.split(' ').collect::<Vec<&str>>();
+                        let mut res: String = format!("Command not found");
+                        if let Some(pkg) = self
+                            .packages
+                            .lock()
+                            .unwrap()
+                            .iter()
+                            .find(|x| x.has_command(&args))
+                        {
+                            res = pkg.handle(&joined, &sender_id, args);
+                        }
+
+                        let event = ev.into_full_event(joined.room_id().clone());
+                        let msg = AnyMessageEventContent::RoomMessage(
+                            MessageEventContent::text_reply_html(res.clone(), res, &event),
+                        );
+                        joined.send(msg, None).await.unwrap();
+                    }
+                }
+            };
+        };
+
         client.register_event_handler(on_msg_room_event).await;
         client.register_event_handler(on_msg_room_reaction).await;
 
@@ -231,60 +231,14 @@ impl Bot {
         }
     }
 
-    pub fn add_package(&self, name: String, cmds: Vec<Cmd>) -> &Self {
+    pub fn add_package(&mut self, name: String, cmds: Vec<Cmd>) -> &mut Self {
         let pkg = match self.config.section(&name) {
             Some(section) => CmdPackage::from_config(&section, cmds),
             None => {
                 abort();
             }
         };
-        GLOBAL_PKG.lock().unwrap().push(pkg);
-        &self
-    }
-
-    pub async fn connect_and_handle(config: Config) -> Result<()> {
-        // TODO: Refactor
-        let pkg_commands_vec = vec![
-            Cmd::new_simple(format!("ping"), 0, |_x| true),
-            Cmd::new_echo(format!("bot_name"), 0, |_x| format!("toto")),
-        ];
-        let pkg = match config.section("basic") {
-            Some(section) => CmdPackage::from_config(&section, pkg_commands_vec),
-            None => {
-                abort();
-            }
-        };
-        GLOBAL_PKG.lock().unwrap().push(pkg);
-
-        let alice = UserId::try_from(config.user_name)?;
-        let client = Client::new(config.homeserver_url)?;
-
-        client
-            .login(
-                alice.localpart(),
-                config.user_password.as_str(),
-                None,
-                Some(config.display_name.as_str()),
-            )
-            .await?;
-        info!("Logged as: {}", alice);
-
-        client.sync_once(SyncSettings::default()).await?;
-        startup_and_log_rooms(&client).await;
-        register_handler_if_enabled!(
-            client,
-            config.handle_state_member,
-            on_state_member,
-            "state member"
-        );
-
-        client.register_event_handler(on_msg_room_event).await;
-        client.register_event_handler(on_msg_room_reaction).await;
-
-        info!("Entering sync loop");
-        let token = client.sync_token().await.unwrap();
-        let settings = SyncSettings::default().token(token);
-        client.sync(settings).await;
-        Ok(())
+        self.packages.lock().unwrap().push(pkg);
+        self
     }
 }
diff --git a/src/cmd/acl.rs b/src/cmd/acl.rs
index 405b0e9c3eaf9785748278cbb665e5844f78c083..d27de8ee0c2fdde29f2210f4eaae4db06d25463b 100644
--- a/src/cmd/acl.rs
+++ b/src/cmd/acl.rs
@@ -1,10 +1,11 @@
+#![allow(dead_code)]
+
 use crate::bool_to_result;
 use log::{error, warn};
 use matrix_sdk::{room::Joined as JoinedRoom, ruma::UserId};
 use std::fmt;
 use std::{process::abort, result::Result};
 
-#[allow(dead_code)]
 #[derive(Clone)]
 pub enum CmdAcl {
     Any,
@@ -13,7 +14,6 @@ pub enum CmdAcl {
     List(Vec<CmdAcl>),
 }
 
-#[allow(dead_code)]
 #[derive(Clone)]
 pub struct CmdAdminRegister {
     admins: Vec<UserId>,
@@ -42,14 +42,12 @@ impl CmdAdminRegister {
         return self.admins.iter().position(|x| *x == user_id).is_some();
     }
 
-    #[allow(dead_code)]
     pub fn add_admin(&mut self, user_id: UserId) {
         if !self.is_admin(user_id.clone()) {
             self.admins.push(user_id);
         }
     }
 
-    #[allow(dead_code)]
     pub fn revoke_admin(&mut self, user_id: UserId) -> Result<(), String> {
         match self.admins.iter().position(|x| *x == user_id) {
             Some(index) => {
@@ -60,7 +58,6 @@ impl CmdAdminRegister {
         }
     }
 
-    #[allow(dead_code)]
     pub fn from_vec(admins_vec: Vec<UserId>) -> CmdAdminRegister {
         CmdAdminRegister { admins: admins_vec }
     }
@@ -91,7 +88,6 @@ impl fmt::Display for CmdAcl {
 }
 
 impl CmdAcl {
-    #[allow(dead_code)]
     pub fn action_permited(
         cmd_admin_register: &CmdAdminRegister,
         acls: &CmdAcl,
@@ -147,7 +143,6 @@ impl CmdAcl {
         }
     }
 
-    #[allow(dead_code)]
     pub fn from_string(string: String) -> CmdAcl {
         let acl_list = string
             .split(",")
diff --git a/src/cmd/package.rs b/src/cmd/package.rs
index 206611a1969631068be6f59af06ad323eef07ffa..ce9199e312d3090eef067ff5a23b2c3b9cd6d7c4 100644
--- a/src/cmd/package.rs
+++ b/src/cmd/package.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+
 use crate::cmd::{
     acl::{CmdAcl, CmdAdminRegister},
     Cmd,
@@ -10,12 +12,10 @@ pub struct CmdPackage {
     name: String,
     acl: CmdAcl,
     admin_register: CmdAdminRegister,
-
     commands: Vec<Cmd>,
 }
 
 impl CmdPackage {
-    #[allow(dead_code)]
     pub fn has_command(&self, user_cmd: &Vec<&str>) -> bool {
         match user_cmd.split_first() {
             None => false,
@@ -30,7 +30,6 @@ impl CmdPackage {
         }
     }
 
-    #[allow(dead_code)]
     pub fn handle(&self, room: &JoinedRoom, user_id: &UserId, user_cmd: Vec<&str>) -> String {
         match CmdAcl::action_permited(&self.admin_register, &self.acl, room, user_id) {
             Err(string) => "Action not permited: ".to_string() + &string,
@@ -48,7 +47,6 @@ impl CmdPackage {
         }
     }
 
-    #[allow(dead_code)]
     pub fn from_config(section: &IniSection, commands: Vec<Cmd>) -> CmdPackage {
         CmdPackage {
             name: section.get("name").unwrap().to_string(),
diff --git a/src/main.rs b/src/main.rs
index 12fc6106caca25c20a7699d2e09c635d9aa6585b..b9ff40b1c548437d9e9719497524fedc4b296b51 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,11 @@
 #![feature(new_uninit, once_cell, trait_alias)]
 
+mod bot;
 mod cmd;
 mod config;
-mod matrix;
 mod utils;
 
+use crate::bot::Bot;
 use crate::cmd::Cmd;
 use matrix_sdk;
 use std::env;
@@ -19,10 +20,10 @@ async fn main() -> matrix_sdk::Result<()> {
         Cmd::new_echo(format!("bot_name"), 0, |_x| format!("toto")),
     ];
 
-    matrix::Bot::new(env::args().last().unwrap())
+    Bot::new(env::args().last().unwrap())
+        .add_package(format!("basic"), basic_cmds)
         .connect()
         .await?
-        .add_package(format!("basic"), basic_cmds)
         .listen()
         .await
 }