diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2010, Ertugrul Soeylemez
+
+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 any 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 THE COPYRIGHT OWNER
+OR CONTRIBUTORS 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/Network/FastIRC.hs b/Network/FastIRC.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC.hs
@@ -0,0 +1,21 @@
+-- |
+-- Module:     Network.FastIRC
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- Fast IRC parsing and connection library.
+
+module Network.FastIRC
+  ( module Network.FastIRC.Messages,
+    module Network.FastIRC.ServerSet,
+    module Network.FastIRC.Users,
+    module Network.FastIRC.Utils
+  )
+  where
+
+import Network.FastIRC.Messages
+import Network.FastIRC.ServerSet
+import Network.FastIRC.Users
+import Network.FastIRC.Utils
diff --git a/Network/FastIRC/Messages.hs b/Network/FastIRC/Messages.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC/Messages.hs
@@ -0,0 +1,85 @@
+-- |
+-- Module:     Network.FastIRC.Messages
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- Parser for IRC messages.
+
+module Network.FastIRC.Messages
+  ( -- * IRC messages
+    Message(..),
+    messageParser,
+
+    -- * IRC commands
+    Command(..),
+    commandParser
+  )
+  where
+
+import qualified Data.ByteString.Char8 as B
+import Control.Applicative
+import Data.Attoparsec.Char8 as P hiding (many)
+import Network.FastIRC.ServerSet
+import Network.FastIRC.Users
+import Network.FastIRC.Utils
+
+
+-- | Data type for IRC messages.
+
+data Message =
+  Message {
+    msgOrigin  :: !(Maybe UserSpec), -- ^ Message origin (user/server).
+    msgCommand :: !Command           -- ^ Message command or numeric.
+  }
+  deriving (Eq, Show)
+
+
+-- | Data type for IRC commands.
+
+data Command
+  -- | Arbitrary string command.
+  = StringCmd B.ByteString [B.ByteString]
+
+  -- | Arbitrary numeric command.
+  | NumericCmd Integer [B.ByteString]
+
+  deriving (Eq, Show)
+
+
+-- | Parser for IRC commands and their arguments.
+
+commandParser :: Parser Command
+commandParser =
+  try numCmd <|> stringCmd
+
+  where
+    lastArg :: Parser B.ByteString
+    lastArg =
+      char ':' *>
+      P.takeWhile isMessageChar
+
+    cmdArgs :: Parser [B.ByteString]
+    cmdArgs =
+      many $ do
+        skipMany1 (char ' ')
+        try lastArg <|> takeWhile1 isIRCTokChar
+
+    stringCmd :: Parser Command
+    stringCmd = StringCmd <$> takeWhile1 isCommandChar <*> cmdArgs
+
+    numCmd :: Parser Command
+    numCmd = NumericCmd <$> decimal <*> cmdArgs
+
+
+-- | Parser for IRC messages.
+
+messageParser :: ServerSet -> Parser Message
+messageParser servers =
+  Message <$> option Nothing (Just <$> try userSpec)
+          <*> commandParser
+
+  where
+    userSpec :: Parser UserSpec
+    userSpec = char ':' *> userParser servers <* skipMany1 (char ' ')
diff --git a/Network/FastIRC/ServerSet.hs b/Network/FastIRC/ServerSet.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC/ServerSet.hs
@@ -0,0 +1,71 @@
+-- |
+-- Module:     Network.FastIRC.ServerSet
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- Functions for dealing with sets of IRC servers.  Note that servers
+-- are compared case-insensitively.
+
+module Network.FastIRC.ServerSet
+  ( -- * The server set type
+    ServerSet,
+
+    -- * Manipulation
+    addServer,
+    delServer,
+    emptyServers,
+    isServer,
+
+    -- * Conversion
+    serverList,
+    serversFromList
+  )
+  where
+
+import qualified Data.ByteString.Char8 as B
+import qualified Data.Set as S
+import Data.Char
+
+
+-- | A set of servers.  This data type uses 'S.Set' internally, but
+-- the strings are handled case-insensitively.
+
+newtype ServerSet = ServerSet (S.Set B.ByteString)
+
+
+-- | Empty set of servers.
+
+emptyServers :: ServerSet
+emptyServers = ServerSet S.empty
+
+
+-- | Add a server to a 'ServerSet'.
+
+addServer :: B.ByteString -> ServerSet -> ServerSet
+addServer s (ServerSet ss) = ServerSet $ S.insert (B.map toLower s) ss
+
+
+-- | Remove a server from a 'ServerSet'.
+
+delServer :: B.ByteString -> ServerSet -> ServerSet
+delServer s (ServerSet ss) = ServerSet $ S.delete (B.map toLower s) ss
+
+
+-- | Check whether specified server is in the set.
+
+isServer :: B.ByteString -> ServerSet -> Bool
+isServer s (ServerSet ss) = S.member (B.map toLower s) ss
+
+
+-- | Convert to list.
+
+serverList :: ServerSet -> [B.ByteString]
+serverList (ServerSet ss) = S.toList ss
+
+
+-- | Build from list.
+
+serversFromList :: [B.ByteString] -> ServerSet
+serversFromList = ServerSet . S.fromList
diff --git a/Network/FastIRC/Session.hs b/Network/FastIRC/Session.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC/Session.hs
@@ -0,0 +1,33 @@
+-- |
+-- Module:     Network.FastIRC.Session
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- This module implements the 'IRC' monad, which you can use to write
+-- IRC applications.
+--
+-- This module is completely useless for now.
+
+module Network.FastIRC.Session
+  ( Config(..),
+    IRC
+  )
+  where
+
+import MonadLib
+import Network.FastIRC.ServerSet
+
+
+-- | Session configuration.
+
+data Config =
+  Config {
+    cfgServers :: ServerSet
+  }
+
+
+-- | Monad for IRC sessions.
+
+type IRC = StateT Config IO
diff --git a/Network/FastIRC/Users.hs b/Network/FastIRC/Users.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC/Users.hs
@@ -0,0 +1,55 @@
+-- |
+-- Module:     Network.FastIRC.Users
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- This module includes parsers for IRC users.
+
+module Network.FastIRC.Users
+  ( UserSpec(..),
+    userParser )
+  where
+
+import qualified Data.ByteString.Char8 as B
+import Control.Applicative
+import Control.Monad
+import Data.Attoparsec.Char8 as P
+import Network.FastIRC.ServerSet
+import Network.FastIRC.Utils
+
+
+-- | IRC user or server.
+
+data UserSpec
+  -- | Nickname.
+  = Nick B.ByteString
+  -- | Nickname, username and hostname.
+  | User B.ByteString B.ByteString B.ByteString
+  -- | IRC server.
+  | Server B.ByteString
+  deriving (Eq, Read, Show)
+
+
+-- | A 'Parser' for IRC users and servers.
+
+userParser :: ServerSet -> Parser UserSpec
+userParser servers =
+  try server <|> try full <|> nickOnly
+
+  where
+    server :: Parser UserSpec
+    server = do
+      srv <- P.takeWhile1 isIRCTokChar
+      guard $ srv `isServer` servers
+      return (Server srv)
+
+    full :: Parser UserSpec
+    full =
+      User <$> P.takeWhile1 isNickChar <* char '!'
+           <*> P.takeWhile1 isUserChar <* char '@'
+           <*> P.takeWhile1 isHostChar
+
+    nickOnly :: Parser UserSpec
+    nickOnly = Nick <$> P.takeWhile1 isNickChar
diff --git a/Network/FastIRC/Utils.hs b/Network/FastIRC/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Network/FastIRC/Utils.hs
@@ -0,0 +1,96 @@
+-- |
+-- Module:     Network.FastIRC.Utils
+-- Copyright:  (c) 2010 Ertugrul Soeylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Soeylemez
+-- Stability:  experimental
+--
+-- Utility functions for parsing IRC messages.
+
+module Network.FastIRC.Utils
+  ( -- * Character predicates for IRC
+    isCommandChar,
+    isHostChar,
+    isIRCEOLChar,
+    isIRCTokChar,
+    isMessageChar,
+    isNickChar,
+    isServerChar,
+    isUserChar,
+
+    -- * Other helper functions
+    parseComplete
+  )
+  where
+
+import qualified Data.ByteString.Char8 as B
+import Data.Attoparsec.Char8
+
+
+-- | Character predicate for IRC commands.
+
+isCommandChar :: Char -> Bool
+isCommandChar = inClass "A-Za-z0-9_"
+
+
+-- | Character predicate for IRC tokens.
+
+isIRCTokChar :: Char -> Bool
+isIRCTokChar c = c /= ' ' && c /= '\r' && c /= '\n'
+
+
+-- | Character predicate for IRC end of line characters.
+
+isIRCEOLChar :: Char -> Bool
+isIRCEOLChar c = c == '\n' || c == '\r'
+
+
+-- | Character predicate for IRC messages.
+
+isMessageChar :: Char -> Bool
+isMessageChar c = c /= '\n' && c /= '\r'
+
+
+-- | Character predicate for nicknames, usernames and hostnames.
+
+isUserSpecChar :: Char -> Bool
+isUserSpecChar c = c > '!' && c /= '@'
+
+
+-- | Character predicate for IRC nicknames.  This function considers
+-- high bytes (0x80 to 0xFF) and most nonstandard ASCII bytes as valid,
+-- because most modern IRC daemons allow nonstandard nicknames.
+
+isNickChar :: Char -> Bool
+isNickChar = isUserSpecChar
+
+
+-- | Character predicate for IRC usernames.  In the string @x!y\@z@ the
+-- substring @y@ is the user's username.
+
+isUserChar :: Char -> Bool
+isUserChar = isUserSpecChar
+
+
+-- | Character predicate for IRC user hostnames.  In the string @x!y\@z@
+-- the substring @z@ is the user's hostname.
+
+isHostChar :: Char -> Bool
+isHostChar = isUserSpecChar
+
+
+-- | Character predicate for IRC servers.
+
+isServerChar :: Char -> Bool
+isServerChar c = inClass "a-zA-Z0-9.:-" c || c >= '\x80'
+
+
+-- | Run a parser completely.
+
+parseComplete :: Parser a -> B.ByteString -> Maybe a
+parseComplete p = complete . parse p
+  where
+    complete :: Result a -> Maybe a
+    complete (Partial f)  = complete (f B.empty)
+    complete (Done _ r)   = Just r
+    complete (Fail _ _ _) = Nothing
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+module Main where
+
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMain
diff --git a/Test.hs b/Test.hs
new file mode 100644
--- /dev/null
+++ b/Test.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import Network.FastIRC
+import Network.FastIRC.Session
+
+
+main :: IO ()
+main = return ()
diff --git a/fastirc.cabal b/fastirc.cabal
new file mode 100644
--- /dev/null
+++ b/fastirc.cabal
@@ -0,0 +1,47 @@
+Name:          fastirc
+Version:       0.1.1
+Category:      Network
+Synopsis:      Fast Internet Relay Chat (IRC) library
+Maintainer:    Ertugrul Söylemez
+Author:        Ertugrul Söylemez
+Copyright:     (c) 2010 Ertugrul Söylemez
+License:       BSD3
+License-file:  LICENSE
+Build-type:    Simple
+Stability:     experimental
+Cabal-version: >= 1.2
+Description:   Fast Internet Relay Chat (IRC) library.
+
+
+Flag debug
+  Description: Build the test program
+  Default:     False
+
+
+Library
+  Build-depends:
+    attoparsec >= 0.8,
+    base >= 4 && < 5,
+    bytestring >= 0.9.1.4,
+    containers >= 0.2.0.1,
+    monadLib >= 3.6.1
+  GHC-Options: -O2
+  Exposed-modules:
+    Network.FastIRC,
+    Network.FastIRC.Messages,
+    Network.FastIRC.ServerSet,
+    Network.FastIRC.Session,
+    Network.FastIRC.Users
+    Network.FastIRC.Utils
+
+
+Executable test
+  Build-depends:  base >= 4 && < 5
+  Main-is:        Test.hs
+  GHC-Options:    -O2
+  if flag(debug)
+    Buildable: True
+  else
+    Buildable: False
+  Other-modules:
+    Network.FastIRC
