diff --git a/Network/SimpleIRC.hs b/Network/SimpleIRC.hs
new file mode 100644
--- /dev/null
+++ b/Network/SimpleIRC.hs
@@ -0,0 +1,29 @@
+-- |
+-- Module : Network.SimpleIRC
+-- Copyright : (c) Dominik Picheta 2010
+-- License : BSD3
+--
+-- Maintainer : morfeusz8@gmail.com
+-- Stability : Alpha
+-- Portability : portable
+--
+-- Simple and efficient IRC Library
+--
+module Network.SimpleIRC (
+    -- * Core
+    module Network.SimpleIRC.Core
+
+    -- * Messages
+  , module Network.SimpleIRC.Messages
+  
+    -- * Utils
+  , module Network.SimpleIRC.Utils
+  
+    -- * Types
+  , module Network.SimpleIRC.Types
+  ) where
+
+import Network.SimpleIRC.Core
+import Network.SimpleIRC.Messages
+import Network.SimpleIRC.Utils
+import Network.SimpleIRC.Types
diff --git a/Network/SimpleIRC/Core.hs b/Network/SimpleIRC/Core.hs
new file mode 100644
--- /dev/null
+++ b/Network/SimpleIRC/Core.hs
@@ -0,0 +1,340 @@
+-- |
+-- Module : Network.SimpleIRC.Core
+-- Copyright : (c) Dominik Picheta 2010
+-- License : BSD3
+--
+-- Maintainer : morfeusz8@gmail.com
+-- Stability : provisional
+-- Portability : portable
+--
+-- For information on how to use this library please take a look at the readme file on github, <http://github.com/dom96/SimpleIRC#readme>.
+{-# LANGUAGE OverloadedStrings #-}
+module Network.SimpleIRC.Core
+  ( 
+    -- * Functions
+    connect
+  , disconnect
+  , sendRaw
+  , sendMsg
+  , sendCmd
+  , addEvent
+  , changeEvents
+  , remEvent
+  , defaultConfig
+  ) where
+  
+import Network
+import System.IO
+import Data.Maybe
+import Data.Char (isNumber)
+import Control.Monad
+import Control.Concurrent
+import Control.Concurrent.Chan
+import Network.SimpleIRC.Messages
+import Network.SimpleIRC.Types
+import Network.SimpleIRC.Utils
+import Data.Unique
+import System.IO.Error
+import Data.Time
+import System.Locale
+import qualified Data.ByteString.Char8 as B
+import qualified Data.Map as Map
+
+internalEvents     = [joinChans, pong, onJoin]
+internalNormEvents = [Privmsg ctcpHandler]
+
+-- |Connects to a server
+connect :: IrcConfig       -- ^ Configuration
+           -> Bool         -- ^ Run in a new thread
+           -> Bool         -- ^ Print debug messages
+           -> IO (Either IOError IrcServer) -- ^ IrcServer instance
+connect config threaded debug = try $ do
+  if debug
+    then B.putStrLn $ "Connecting to " `B.append` (B.pack $ cAddr config)
+    else return ()
+  h <- connectTo (cAddr config) (PortNumber $ fromIntegral $ cPort config)
+  hSetBuffering h NoBuffering
+  
+  cmdChan <- newChan
+  
+  server <- toServer config h cmdChan debug
+  -- Initialize connection with the server
+  greetServer server
+  
+  -- Start listening
+  if threaded
+    then do listenId <- forkIO (listenLoop server)
+            return server {sListenThread = Just listenId}
+    else do listenLoop server
+            return server
+    
+-- |Sends a QUIT command to the server.
+disconnect :: IrcServer
+              -> B.ByteString -- ^ Quit message
+              -> IO ()
+disconnect server quitMsg = do
+  write server $ "QUIT :" `B.append` quitMsg
+  return ()
+  where h = fromJust $ sSock server
+
+genUnique :: IrcEvent -> IO (Unique, IrcEvent)
+genUnique e = do
+  u <- newUnique
+  return (u, e)
+
+genUniqueMap :: [IrcEvent] -> IO (Map.Map Unique IrcEvent)
+genUniqueMap events = do
+  uEvents <- mapM genUnique events
+  return $ Map.fromList uEvents
+
+toServer :: IrcConfig -> Handle -> Chan SIrcCommand -> Bool -> IO IrcServer
+toServer config h cmdChan debug = do
+  uniqueEvents <- genUniqueMap $ internalNormEvents ++ (cEvents config)
+
+  return $ IrcServer (B.pack $ cAddr config) (cPort config)
+              (B.pack $ cNick config) (B.pack $ cUsername config) 
+              (B.pack $ cRealname config) (map B.pack $ cChannels config) 
+              uniqueEvents (Just h) Nothing cmdChan debug
+              (cCTCPVersion config) (cCTCPTime config)
+
+greetServer :: IrcServer -> IO IrcServer
+greetServer server = do
+  write server $ "NICK " `B.append` nick
+  write server $ "USER " `B.append` user `B.append` " " `B.append`
+      user `B.append` " " `B.append` addr `B.append` " :" `B.append` real
+  
+  return server
+  where nick = sNickname server
+        user = sUsername server
+        real = sRealname server
+        addr = sAddr server
+
+-- TODO: I think this should execute all commands that are available.
+execCmds :: IrcServer -> IO IrcServer
+execCmds server = do
+  empty <- isEmptyChan $ sCmdChan server
+  if not $ empty 
+    then do cmd <- readChan $ sCmdChan server
+            case cmd of (SIrcAddEvent uEvent) -> return server {sEvents = Map.insert (fst uEvent) (snd uEvent) (sEvents server)}
+                        (SIrcChangeEvents events) -> return server {sEvents = events}
+                        (SIrcRemoveEvent key) -> return server {sEvents = Map.delete key (sEvents server)}
+    else return server
+
+listenLoop :: IrcServer -> IO ()
+listenLoop s = do
+  server <- execCmds s
+
+  let h = fromJust $ sSock server
+  eof <- hIsEOF h
+  -- If EOF then we are disconnected
+  if eof 
+    then do
+      let comp   = (\a -> a `eqEvent` (Disconnect undefined))
+          events = Map.filter comp (sEvents server)
+          eventCall = (\obj -> (eventFuncD $ snd obj) server)
+      debugWrite s $ B.pack $ show $ length $ Map.toList events
+      mapM eventCall (Map.toList events)
+      return ()
+    else do
+      line <- B.hGetLine h
+      debugWrite s $ (B.pack ">> ") `B.append` line
+      
+      newServ <- foldM (\s f -> f s (parse line)) server internalEvents
+      
+      callEvents newServ (parse line)
+
+      listenLoop newServ
+    
+-- Internal Events - They can edit the server
+joinChans :: IrcServer -> IrcMessage -> IO IrcServer
+joinChans server msg = do
+  if code == "001"
+    then do mapM (\chan -> write server $ "JOIN " `B.append` chan) (sChannels server)
+            return server {sChannels = []}
+    else return server
+  where h    = fromJust $ sSock server
+        code = mCode msg
+
+pong :: IrcServer -> IrcMessage -> IO IrcServer
+pong server msg = do
+  if code == "PING"
+    then do
+      write server $ "PONG :" `B.append` pingMsg
+      return server
+    else return server
+    
+  where h       = fromJust $ sSock server
+        pingMsg = mMsg msg
+        code    = mCode msg
+
+onJoin :: IrcServer -> IrcMessage -> IO IrcServer
+onJoin server msg
+  | code == "JOIN" = do
+    let nick = fromJust $ mNick msg
+        chan  = mMsg msg
+    if nick == sNickname server
+      then return server { sChannels = chan:(sChannels server) }
+      else return server
+  | otherwise = return server
+  
+  where code = mCode msg
+
+-- Internal normal events
+ctcpHandler :: EventFunc
+ctcpHandler server iMsg
+  | msg == "\x01VERSION\x01" =
+    sendCmd server
+      (MNotice chan ("\x01VERSION " `B.append`
+        (B.pack $ sCTCPVersion server) `B.append` "\x01"))
+  | msg == "\x01TIME\x01" = do
+    time <- sCTCPTime server
+    sendCmd server
+      (MNotice chan ("\x01TIME " `B.append`
+        (B.pack time) `B.append` "\x01"))
+  | otherwise = return ()
+  where msg  = mMsg iMsg
+        chan = getChan server iMsg
+-- Event code
+events :: IrcServer -> IrcEvent -> IrcMessage -> IO ()
+events server event msg = do
+  mapM eventCall (Map.toList events)
+  return ()
+  where comp   = (\a -> a `eqEvent` event)
+        events = Map.filter comp (sEvents server)
+        eventCall = (\obj -> (eventFunc $ snd obj) server msg)
+
+callEvents :: IrcServer -> IrcMessage -> IO ()
+callEvents server msg
+  | mCode msg == "PRIVMSG"     = do
+    events server (Privmsg undefined) msg
+    
+  | mCode msg == "PING"        = do
+    events server (Ping undefined) msg
+
+  | mCode msg == "JOIN"        = do
+    events server (Join undefined) msg
+  
+  | mCode msg == "PART"        = do
+    events server (Part undefined) msg
+
+  | mCode msg == "MODE"        = do
+    events server (Mode undefined) msg
+
+  | mCode msg == "TOPIC"       = do
+    events server (Topic undefined) msg
+
+  | mCode msg == "INVITE"      = do
+    events server (Invite undefined) msg
+
+  | mCode msg == "KICK"        = do
+    events server (Kick undefined) msg
+
+  | mCode msg == "QUIT"        = do
+    events server (Quit undefined) msg
+
+  | mCode msg == "NICK"        = do
+    events server (Nick undefined) msg
+
+  | mCode msg == "NOTICE"      = do
+    events server (Notice undefined) msg
+
+  | B.all isNumber (mCode msg) = do
+    events server (Numeric undefined) msg
+  
+  | otherwise                = do
+    events server (RawMsg undefined) msg
+
+(Privmsg _) `eqEvent` (Privmsg _) = True
+(Numeric _) `eqEvent` (Numeric _) = True
+(Ping    _) `eqEvent` (Ping    _) = True
+(Join    _) `eqEvent` (Join    _) = True
+(Part    _) `eqEvent` (Part    _) = True
+(Mode    _) `eqEvent` (Mode    _) = True
+(Topic   _) `eqEvent` (Topic   _) = True
+(Invite  _) `eqEvent` (Invite  _) = True
+(Kick    _) `eqEvent` (Kick    _) = True
+(Quit    _) `eqEvent` (Quit    _) = True
+(Nick    _) `eqEvent` (Nick    _) = True
+(Notice  _) `eqEvent` (Notice  _) = True
+(RawMsg  _) `eqEvent` (RawMsg  _) = True
+(Disconnect  _) `eqEvent` (Disconnect  _) = True
+_ `eqEvent` _                     = False
+
+eventFunc :: IrcEvent -> EventFunc
+eventFunc (Privmsg f) = f
+eventFunc (Numeric f) = f
+eventFunc (Ping    f) = f
+eventFunc (Join    f) = f
+eventFunc (Part    f) = f
+eventFunc (Mode    f) = f
+eventFunc (Topic   f) = f
+eventFunc (Invite  f) = f
+eventFunc (Kick    f) = f
+eventFunc (Quit    f) = f
+eventFunc (Nick    f) = f
+eventFunc (Notice  f) = f
+eventFunc (RawMsg  f) = f
+
+eventFuncD (Disconnect  f) = f
+
+-- |Sends a raw command to the server
+sendRaw :: IrcServer -> B.ByteString -> IO ()
+sendRaw server msg = write server msg
+
+-- |Sends a message to a channel
+
+-- |Please note: As of now this function doesn't provide flood control.
+-- So be careful.
+sendMsg :: IrcServer 
+           -> B.ByteString -- ^ Channel
+           -> B.ByteString -- ^ Message
+           -> IO ()
+sendMsg server chan msg = do
+  mapM (s) lins
+  return ()
+  where lins = B.lines msg
+        s m = sendCmd server (MPrivmsg chan m)
+sendCmd :: IrcServer
+           -> Command -- Command to send
+           -> IO ()
+sendCmd server cmd =
+  sendRaw server (showCommand cmd)
+
+addEvent :: IrcServer -> IrcEvent -> IO Unique
+addEvent s event = do
+  u <- newUnique
+  writeChan (sCmdChan s) (SIrcAddEvent (u, event))
+  return u
+
+changeEvents :: IrcServer -> [IrcEvent] -> IO ()
+changeEvents s events = do
+  uniqueEvents <- genUniqueMap events
+  writeChan (sCmdChan s) (SIrcChangeEvents uniqueEvents)
+
+remEvent :: IrcServer -> Unique -> IO ()
+remEvent s uniq = do
+  writeChan (sCmdChan s) (SIrcRemoveEvent uniq)
+
+debugWrite :: IrcServer -> B.ByteString -> IO ()
+debugWrite s msg = do
+  if sDebug s
+    then B.putStrLn msg
+    else return ()
+
+write :: IrcServer -> B.ByteString -> IO ()
+write s msg = do
+  debugWrite s $ "<< " `B.append` msg `B.append` "\\r\\n"
+  B.hPutStr h (msg `B.append` "\r\n")
+  where h = fromJust $ sSock s
+  
+
+defaultConfig = IrcConfig
+  { cPort     = 6667
+  , cUsername = "simpleirc"
+  , cRealname = "SimpleIRC Bot"
+  , cChannels = []
+  , cEvents   = []
+  , cCTCPVersion = "SimpleIRC v0.1"
+  , cCTCPTime    =  getZonedTime >>= 
+    (\t -> return $ formatTime defaultTimeLocale "%c" t)
+  }
diff --git a/Network/SimpleIRC/Messages.hs b/Network/SimpleIRC/Messages.hs
new file mode 100644
--- /dev/null
+++ b/Network/SimpleIRC/Messages.hs
@@ -0,0 +1,143 @@
+-- |
+-- Module : Network.SimpleIRC.Core
+-- Copyright : (c) Dominik Picheta 2010
+-- License : BSD3
+--
+-- Maintainer : morfeusz8@gmail.com
+-- Stability : provisional
+-- Portability : portable
+--
+-- Messages module
+--
+{-# LANGUAGE OverloadedStrings #-}
+module Network.SimpleIRC.Messages 
+  ( Command(..)
+  , parse
+  , showCommand  
+  ) 
+where
+import Data.Maybe
+import Network.SimpleIRC.Types
+import qualified Data.ByteString.Char8 as B
+
+-- PING :asimov.freenode.net
+-- :haskellTestBot!~test@host86-177-151-242.range86-177.btcentralplus.com JOIN :#()
+
+-- :dom96!~dom96@unaffiliated/dom96 PRIVMSG #() :it lives!
+-- :haskellTestBot MODE haskellTestBot :+i
+-- :asimov.freenode.net 376 haskellTestBot :End of /MOTD command.
+
+-- :asimov.freenode.net 332 haskellTestBot #() :Parenthesis
+
+-- :asimov.freenode.net 333 haskellTestBot #() Raynes!~macr0@unaffiliated/raynes 1281221819
+
+data Command = Command
+  | MPrivmsg B.ByteString B.ByteString              -- ^ PRIVMSG #chan :msg
+  | MJoin    B.ByteString (Maybe B.ByteString)      -- ^ JOIN #chan key
+  | MPart    B.ByteString B.ByteString              -- ^ PART #chan :msg
+  | MMode    B.ByteString B.ByteString 
+      (Maybe B.ByteString)                          -- ^ MODE #chan +o user
+  | MTopic   B.ByteString (Maybe B.ByteString)      -- ^ TOPIC #chan :topic
+  | MInvite  B.ByteString B.ByteString              -- ^ INVITE user #chan
+  | MKick    B.ByteString B.ByteString B.ByteString -- ^ KICK #chan user :msg
+  | MQuit    B.ByteString                           -- ^ QUIT :msg
+  | MNick    B.ByteString                           -- ^ NICK newnick
+  | MNotice  B.ByteString B.ByteString              -- ^ NOTICE usr/#chan :msg
+  | MAction  B.ByteString B.ByteString              -- ^ PRIVMSG usr/#chan :\\x01ACTION msg\\x01
+  deriving (Eq, Read, Show)
+
+-- |Parse a raw IRC message
+parse :: B.ByteString -> IrcMessage
+parse txt = 
+  case length split of 2 -> (parse2 split) txt
+                       3 -> (parse3 split) txt
+                       4 -> (parse4 split) txt 
+                       5 -> (parse5 split) txt
+                       otherwise -> (parseOther split) txt
+                       
+  where split = smartSplit (takeCarriageRet txt)
+
+parse4 :: [B.ByteString] -> (B.ByteString -> IrcMessage)
+parse4 (first:code:chan:msg:_) = 
+  let (nick, host, server) = parseFirst first
+  in IrcMessage nick host server (code)
+       (dropColon msg) (Just chan) Nothing
+
+-- Nick, Host, Server
+parseFirst :: B.ByteString -> (Maybe B.ByteString, Maybe B.ByteString, Maybe B.ByteString)
+parseFirst first = 
+  if '!' `B.elem` first
+    then let (nick, host) = B.break (== '!') (dropColon first)
+         in (Just nick, Just host, Nothing)
+    else (Nothing, Nothing, Just $ dropColon first) 
+
+dropColon :: B.ByteString -> B.ByteString
+dropColon xs =
+  if B.take 1 xs == (B.pack ":")
+    then B.drop 1 xs
+    else xs
+
+parse2 :: [B.ByteString] -> (B.ByteString -> IrcMessage)
+parse2 (code:msg:_) =
+  IrcMessage Nothing Nothing Nothing (code)
+    (dropColon msg) Nothing Nothing
+    
+parse3 :: [B.ByteString] -> (B.ByteString -> IrcMessage)
+parse3 (first:code:msg:_) =
+  let (nick, host, server) = parseFirst first
+  in IrcMessage nick host server (code) (dropColon msg) Nothing Nothing
+  
+parse5 :: [B.ByteString] -> (B.ByteString -> IrcMessage)
+parse5 (server:code:nick:chan:msg:_) =
+  IrcMessage (Just nick) Nothing (Just server) (code)
+    (dropColon msg) (Just chan) Nothing
+
+parseOther :: [B.ByteString] -> (B.ByteString -> IrcMessage)
+parseOther (server:code:nick:chan:other) =
+  IrcMessage (Just nick) Nothing (Just server) (code)
+    (B.unwords other) (Just chan) (Just other)
+
+smartSplit :: B.ByteString -> [B.ByteString]
+smartSplit txt
+  | ':' `B.elem` (dropColon txt) =
+    let (first, msg) = B.break (== ':') (dropColon txt)
+    in (B.words $ takeLast first) ++ [msg]
+  | otherwise = B.words $ txt
+
+takeLast :: B.ByteString -> B.ByteString
+takeLast xs = B.take (B.length xs - 1) xs
+
+takeCarriageRet :: B.ByteString -> B.ByteString
+takeCarriageRet xs = 
+  if B.drop (B.length xs - 1) xs == (B.pack "\r")
+    then takeLast xs
+    else xs
+
+showCommand :: Command -> B.ByteString
+showCommand (MPrivmsg chan msg)             = "PRIVMSG " `B.append` chan `B.append`
+                                              " :" `B.append` msg
+showCommand (MJoin    chan (Just key))      = "JOIN " `B.append` chan `B.append` 
+                                              " " `B.append` key
+showCommand (MJoin    chan Nothing)         = "JOIN " `B.append` chan
+showCommand (MPart    chan msg)             = "PART " `B.append` chan `B.append` 
+                                              " :" `B.append` msg
+showCommand (MMode    chan mode (Just usr)) = "MODE " `B.append` chan `B.append`
+                                              " " `B.append` mode `B.append`
+                                              " " `B.append` usr
+showCommand (MMode    chan mode Nothing)    = "MODE " `B.append` chan `B.append`
+                                              " " `B.append` mode
+showCommand (MTopic   chan (Just msg))      = "TOPIC " `B.append` chan `B.append`
+                                              " :" `B.append` msg
+showCommand (MTopic   chan Nothing)         = "TOPIC " `B.append` chan
+showCommand (MInvite  usr chan)             = "INVITE " `B.append` usr `B.append`
+                                              " " `B.append` chan
+showCommand (MKick    chan usr msg)         = "KICK " `B.append` chan `B.append`
+                                              " " `B.append` usr `B.append`
+                                              " :" `B.append` msg
+showCommand (MQuit    msg)                  = "QUIT :" `B.append` msg
+showCommand (MNick    nick)                 = "NICK " `B.append` nick
+showCommand (MNotice  chan msg)             = "NOTICE " `B.append` chan `B.append`
+                                              " :" `B.append` msg
+showCommand (MAction  chan msg)             = showCommand $ MPrivmsg chan
+                                              ("\x01 ACTION " `B.append` msg
+                                              `B.append` "\x01")
diff --git a/Network/SimpleIRC/Types.hs b/Network/SimpleIRC/Types.hs
new file mode 100644
--- /dev/null
+++ b/Network/SimpleIRC/Types.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+module Network.SimpleIRC.Types
+  ( 
+    -- * Datatypes
+    IrcConfig(..)
+  , IrcServer(..)
+  , SIrcCommand(..)
+  , IrcEvent(..)
+  , EventFunc
+  , IrcMessage(..)
+  ) where
+import qualified Data.ByteString.Char8 as B
+import Control.Concurrent (ThreadId)
+import Control.Concurrent.Chan (Chan)
+import System.IO (Handle)
+import Data.Unique (Unique)
+import Data.Map (Map)
+import Data.Typeable
+
+data IrcConfig = IrcConfig
+  { cAddr     :: String   -- ^ Server address to connect to
+  , cPort     :: Int      -- ^ Server port to connect to
+  , cNick     :: String   -- ^ Nickname
+  , cUsername :: String   -- ^ Username
+  , cRealname :: String   -- ^ Realname
+  , cChannels :: [String]   -- ^ List of channels to join on connect
+  , cEvents   :: [IrcEvent] -- ^ Events to bind
+  , cCTCPVersion :: String  -- ^ What to send on CTCP VERSION
+  , cCTCPTime    :: IO String  -- ^ What to send on CTCP TIME
+  }
+
+
+data SIrcCommand =
+    SIrcAddEvent (Unique, IrcEvent)
+  | SIrcChangeEvents (Map Unique IrcEvent)
+  | SIrcRemoveEvent Unique
+  
+data IrcServer = IrcServer
+  { sAddr         :: B.ByteString
+  , sPort         :: Int
+  , sNickname     :: B.ByteString
+  , sUsername     :: B.ByteString
+  , sRealname     :: B.ByteString
+  , sChannels     :: [B.ByteString]
+  , sEvents       :: Map Unique IrcEvent
+  , sSock         :: Maybe Handle
+  , sListenThread :: Maybe ThreadId
+  , sCmdChan      :: Chan SIrcCommand
+  , sDebug        :: Bool
+  -- Other info
+  , sCTCPVersion  :: String
+  , sCTCPTime     :: IO String
+  }
+
+type EventFunc = (IrcServer -> IrcMessage -> IO ())
+
+-- When adding events here, remember add them in callEvents and in eventFunc
+-- AND also in the Show instance and Eq instance
+
+data IrcEvent = 
+    Privmsg EventFunc -- ^ PRIVMSG
+  | Numeric EventFunc -- ^ Numeric, 001, 002, 372 etc.
+  | Ping EventFunc    -- ^ PING
+  | Join EventFunc    -- ^ JOIN
+  | Part EventFunc    -- ^ PART
+  | Mode EventFunc    -- ^ MODE
+  | Topic EventFunc   -- ^ TOPIC
+  | Invite EventFunc  -- ^ INVITE
+  | Kick EventFunc    -- ^ KICK
+  | Quit EventFunc    -- ^ QUIT
+  | Nick EventFunc    -- ^ NICK
+  | Notice EventFunc  -- ^ NOTICE
+  | RawMsg EventFunc  -- ^ This event gets called on every message received
+  | Disconnect (IrcServer -> IO ()) -- ^ This event gets called whenever the
+                                    --   connection with the server is dropped
+  
+  
+instance Show IrcEvent where
+  show (Privmsg _) = "IrcEvent - Privmsg"
+  show (Numeric _) = "IrcEvent - Numeric"
+  show (Ping    _) = "IrcEvent - Ping"
+  show (Join    _) = "IrcEvent - Join"
+  show (Part    _) = "IrcEvent - Part"
+  show (Mode    _) = "IrcEvent - Mode"
+  show (Topic   _) = "IrcEvent - Topic"
+  show (Invite  _) = "IrcEvent - Invite"
+  show (Kick    _) = "IrcEvent - Kick"
+  show (Quit    _) = "IrcEvent - Quit"
+  show (Nick    _) = "IrcEvent - Nick"
+  show (Notice  _) = "IrcEvent - Notice"
+  show (RawMsg  _) = "IrcEvent - RawMsg"
+  show (Disconnect  _) = "IrcEvent - Disconnect"
+  
+data IrcMessage = IrcMessage
+  { mNick   :: Maybe B.ByteString
+  , mHost   :: Maybe B.ByteString
+  , mServer :: Maybe B.ByteString
+  , mCode   :: B.ByteString
+  , mMsg    :: B.ByteString
+  , mChan   :: Maybe B.ByteString
+  , mOther  :: Maybe [B.ByteString]
+  , mRaw    :: B.ByteString
+  } deriving (Show, Typeable)
+  
+  
+   
diff --git a/Network/SimpleIRC/Utils.hs b/Network/SimpleIRC/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Network/SimpleIRC/Utils.hs
@@ -0,0 +1,29 @@
+-- |
+-- Module : Network.SimpleIRC.Core
+-- Copyright : (c) Dominik Picheta 2010
+-- License : BSD3
+--
+-- Maintainer : morfeusz8@gmail.com
+-- Stability : provisional
+-- Portability : portable
+--
+-- Utils module
+--
+
+module Network.SimpleIRC.Utils
+  ( 
+    -- * Functions
+    getChan
+  ) where
+import Network.SimpleIRC.Types
+import qualified Data.ByteString.Char8 as B
+import Data.Maybe (fromJust)
+  
+-- |If the IrcMessage was sent directly to you returns the nick otherwise the channel.
+getChan :: IrcServer -> IrcMessage -> B.ByteString
+getChan s m =
+  if sNickname s == chan
+    then (fromJust $ mNick m)
+    else chan
+  
+  where chan = fromJust $ mChan m
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,4 @@
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMain
diff --git a/license b/license
new file mode 100644
--- /dev/null
+++ b/license
@@ -0,0 +1,25 @@
+Copyright (c) 2010, Dominik Picheta <morfeusz8@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the author nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL DOMINIK PICHETA BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/simpleirc.cabal b/simpleirc.cabal
new file mode 100644
--- /dev/null
+++ b/simpleirc.cabal
@@ -0,0 +1,40 @@
+Name:          simpleirc
+Version:       0.1.0
+Category:      Network, IRC
+Synopsis:      Simple IRC Library
+Package-URL:   http://code.haskell.org/fastirc/
+Maintainer:    Dominik Picheta <dominikpicheta@googlemail.com>
+Author:        Dominik Picheta <dominikpicheta@googlemail.com>
+Copyright:     (c) 2010 Dominik Picheta
+License:       BSD3
+License-file:  license
+Homepage: http://github.com/dom96/SimpleIRC  
+Build-type:    Simple
+Stability:     provisional
+Cabal-version: >= 1.6
+Description:
+  Simple IRC Library. This IRC Library aims to be simple and lightweight.
+
+Source-repository head
+  Type:     git
+  Location: git://github.com/dom96/SimpleIRC.git
+
+Source-repository this
+  Type:     git
+  Location: git://github.com/dom96/SimpleIRC.git
+  tag:      V0.1.0
+
+Library
+  Build-depends:
+    base >= 4 && < 5,
+    bytestring >= 0.9.1.7,
+    network >= 2.2.1.7,
+    containers >= 0.3.0.0,
+    time >= 1.1.4,
+    old-locale >= 1.0.0.2
+  Exposed-modules:
+    Network.SimpleIRC
+    Network.SimpleIRC.Core
+    Network.SimpleIRC.Messages
+    Network.SimpleIRC.Utils
+    Network.SimpleIRC.Types
