diff --git a/Commands.hs b/Commands.hs
new file mode 100644
--- /dev/null
+++ b/Commands.hs
@@ -0,0 +1,65 @@
+module Commands where
+
+import System.Process
+import System.Exit
+import System.IO (hClose, hGetLine)
+
+import Monitors.Common ( runM )
+import Monitors.Weather
+import Monitors.Net
+import Monitors.Mem
+import Monitors.Swap
+import Monitors.Cpu
+import Monitors.Batt
+
+data Command = Exec Program Args Alias 
+             | Weather Station Args 
+             | Network Interface Args
+             | Memory Args
+             | Swap Args
+             | Cpu Args
+             | Battery Args
+               deriving (Read,Eq)
+
+type Args = [String]
+type Program = String
+type Alias = String
+type Station = String
+type Interface = String
+
+instance Show Command where
+    show (Weather s _) = s
+    show (Network i _) = i
+    show (Memory _) = "memory"
+    show (Swap _) = "swap"
+    show (Cpu _) = "cpu"
+    show (Battery _) = "battery"
+    show (Exec p _ a) | p /= "" = if  a == "" then p else a
+                      | otherwise = ""
+class Exec e where
+    run :: e -> IO String
+
+instance Exec Command where
+    run (Weather s a) = do let af = return "No station ID specified"
+                           runM (a ++ [s]) weatherConfig af runWeather 
+    run (Network i a) = do let f = return "No device specified"
+                           runM (a ++ [i]) netConfig f runNet
+    run (Memory args) = do let af = runMem []
+                           runM args memConfig af runMem
+    run (Swap args) = do let af = runSwap []
+                         runM args swapConfig af runSwap
+    run (Cpu args) = do let af = runCpu []
+                        runM args cpuConfig af runCpu
+    run (Battery args) = do let af = runBatt []
+                            runM args battConfig af runBatt
+    run (Exec prog args _) = do (i,o,e,p) <- runInteractiveCommand (prog ++ concat (map (' ':) args))
+                                exit <- waitForProcess p
+                                let closeHandles = do hClose o
+                                                      hClose i
+                                                      hClose e
+                                case exit of
+                                  ExitSuccess -> do str <- hGetLine o
+                                                    closeHandles
+                                                    return str
+                                  _ -> do closeHandles
+                                          return $ "Could not execute command " ++ prog
diff --git a/Config.hs b/Config.hs
--- a/Config.hs
+++ b/Config.hs
@@ -18,41 +18,41 @@
               , defaultConfig
               ) where
 
+import Commands
 -- $config
 -- Configuration data type and default configuration
 
 -- | The configuration data type
 data Config = 
-    Config { fonts          :: String   -- ^ Fonts
+    Config { font           :: String   -- ^ Font
            , bgColor        :: String   -- ^ Backgroud color
            , fgColor        :: String   -- ^ Default font color
            , xPos           :: Int      -- ^ x Window position (origin in the upper left corner) 
            , yPos           :: Int      -- ^ y Window position 
            , width          :: Int      -- ^ Window width
-           , hight          :: Int      -- ^ Window hight
+           , height         :: Int      -- ^ Window height
            , align          :: String   -- ^ text alignment
            , refresh        :: Int      -- ^ Refresh rate in tenth of seconds
-           , commands       :: [(String, Int, [String])]   -- ^ For setting the refresh rate and 
-                                                           -- options for the programs to run (optionals)
-           , sepChar        :: String     -- ^ The character to be used for indicating 
-                                        --   commands in the output template (default '%')
-           , template       :: String   -- ^ The output template 
-           } deriving (Eq, Show, Read, Ord)
+           , commands       :: [(Command,Int)] -- ^ For setting the command, the command argujments 
+                                               -- and refresh rate for the programs to run (optional)
+           , sepChar        :: String -- ^ The character to be used for indicating
+                                      -- commands in the output template (default '%')
+           , template       :: String -- ^ The output template 
+           } deriving (Read)
 
 -- | The default configuration values
 defaultConfig :: Config
 defaultConfig =
-    Config { fonts = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
+    Config { font = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
            , bgColor = "#000000"
            , fgColor = "#BFBFBF"
            , xPos = 0
            , yPos = 0
            , width = 1024
-           , hight = 15
+           , height = 15
            , align = "left"
            , refresh = 10
-           , commands = [("date", 10, [])]
+           , commands = [(Memory [],10)]
            , sepChar = "%"
-           , template = "Uptime: <fc=#00FF00>%uptime%</fc> ** <fc=#FF0000>%date%</fc>"
+           , template = "Uptime: <fc=#00FF00>%uptime%</fc> ** <fc=#FF0000>%date%</fc> %memory%"
            }
-
diff --git a/Monitors/Batt.hs b/Monitors/Batt.hs
--- a/Monitors/Batt.hs
+++ b/Monitors/Batt.hs
@@ -12,7 +12,7 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Batt where
 
 import Data.IORef
 import qualified Data.ByteString.Lazy.Char8 as B
@@ -20,8 +20,8 @@
 
 import Monitors.Common
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+battConfig :: IO MConfig
+battConfig = 
     do lc <- newIORef "#FF0000"
        l <- newIORef 25
        nc <- newIORef "#FF0000"
@@ -79,7 +79,9 @@
        l <- formatBatt c
        parseTemplate l 
     
+{-
 main :: IO ()
 main =
     do let af = runBatt []
-       runMonitor monitorConfig af runBatt
+       runMonitor battConfig af runBatt
+-}
diff --git a/Monitors/Common.hs b/Monitors/Common.hs
--- a/Monitors/Common.hs
+++ b/Monitors/Common.hs
@@ -21,6 +21,7 @@
                        , setConfigValue
                        , getConfigValue
                        , runMonitor
+                       , runM
                        , io
                        -- * Parsers
                        -- $parsers
@@ -29,6 +30,8 @@
                        , getNumbers
                        , getNumbersAsString
                        , getAllBut
+                       , getAfterString
+                       , skipTillString
                        , parseTemplate
                        -- ** String Manipulation
                        -- $strings
@@ -130,7 +133,7 @@
        io $ putStr $ usageInfo ("Usage: " ++ pn ++ " [OPTIONS...] " ++ u) opts
 
 version :: String
-version = "0.4"
+version = "0.5"
 
 versinfo :: String -> String -> IO ()
 versinfo p v = putStrLn $ p ++" " ++ v
@@ -172,6 +175,12 @@
        let ac = doArgs args actionFail action
        putStrLn =<< runReaderT ac c
 
+runM :: [String] -> IO MConfig -> Monitor String -> ([String] -> Monitor String) -> IO String
+runM args conf actionFail action =
+    do c <- conf
+       let ac = doArgs args actionFail action
+       runReaderT ac c
+
 io :: IO a -> Monitor a
 io = liftIO
 
@@ -200,6 +209,16 @@
     do many $ noneOf "\n\r"
        newline
 
+getAfterString :: String -> Parser String
+getAfterString s =
+    do { try $ manyTill skipRestOfLine $ string s
+       ; v <- manyTill anyChar $ newline
+       ; return v
+       } <|> return ("<" ++ s ++ " not found!>")
+
+skipTillString :: String -> Parser String
+skipTillString s = 
+    manyTill skipRestOfLine $ string s
 
 -- | Parses the output template string
 templateStringParser :: Parser (String,String,String)
diff --git a/Monitors/Cpu.hs b/Monitors/Cpu.hs
--- a/Monitors/Cpu.hs
+++ b/Monitors/Cpu.hs
@@ -12,14 +12,14 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Cpu where
 
 import Monitors.Common
 import qualified Data.ByteString.Lazy.Char8 as B
 import Data.IORef
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+cpuConfig :: IO MConfig
+cpuConfig = 
     do lc <- newIORef "#BFBFBF"
        l <- newIORef 2
        nc <- newIORef "#00FF00"
@@ -65,7 +65,9 @@
        l <- formatCpu c
        parseTemplate l 
     
+{-
 main :: IO ()
 main =
     do let af = runCpu []
-       runMonitor monitorConfig af runCpu
+       runMonitor cpuConfig af runCpu
+-}
diff --git a/Monitors/Mem.hs b/Monitors/Mem.hs
--- a/Monitors/Mem.hs
+++ b/Monitors/Mem.hs
@@ -12,14 +12,14 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Mem where
 
 import Monitors.Common
 
 import Data.IORef
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+memConfig :: IO MConfig
+memConfig = 
     do lc <- newIORef "#BFBFBF"
        l <- newIORef 300
        nc <- newIORef "#00FF00"
@@ -59,7 +59,9 @@
        l <- formatMem m
        parseTemplate l 
     
+{-
 main :: IO ()
 main =
     do let af = runMem []
        runMonitor monitorConfig af runMem
+-}
diff --git a/Monitors/Net.hs b/Monitors/Net.hs
--- a/Monitors/Net.hs
+++ b/Monitors/Net.hs
@@ -1,6 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
--- Module      :  Monitors.Cpu
+-- Module      :  Monitors.Net
 -- Copyright   :  (c) Andrea Rossato
 -- License     :  BSD-style (see LICENSE)
 -- 
@@ -12,7 +12,7 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Net where
 
 import Monitors.Common
 
@@ -28,8 +28,8 @@
 interval :: Int
 interval = 500000
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+netConfig :: IO MConfig
+netConfig = 
     do lc <- newIORef "#BFBFBF"
        l <- newIORef 0
        nc <- newIORef "#00FF00"
@@ -94,10 +94,13 @@
               _ -> return $ NA
        printNet n
 
+
 package :: String
 package = "xmb-net"
 
+{-
 main :: IO ()
 main =
     do let f = return "No device specified"
-       runMonitor monitorConfig f runNet
+       runMonitor netConfig f runNet
+-}
diff --git a/Monitors/Swap.hs b/Monitors/Swap.hs
--- a/Monitors/Swap.hs
+++ b/Monitors/Swap.hs
@@ -12,15 +12,15 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Swap where
 
 import Monitors.Common
 
 import Data.IORef
 import qualified Data.ByteString.Lazy.Char8 as B
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+swapConfig :: IO MConfig
+swapConfig = 
     do lc <- newIORef "#BFBFBF"
        l <- newIORef 30
        nc <- newIORef "#00FF00"
@@ -42,23 +42,25 @@
        let p x y = flip (/) 1024 . read . stringParser x $ y
            tot = p (1,11) file
            free = p (1,12) file
-       return [tot, (tot - free), free, free / tot * 100]
+       return [tot, (tot - free), free, (tot - free) / tot * 100]
 
-formatMem :: [Float] -> Monitor [String] 
-formatMem x =
+formatSwap :: [Float] -> Monitor [String] 
+formatSwap x =
     do let f n = show (takeDigits 2 n)
        mapM (showWithColors f) x
 
 package :: String
 package = "xmb-swap"
 
-runMem :: [String] -> Monitor String
-runMem _ =
+runSwap :: [String] -> Monitor String
+runSwap _ =
     do m <- io $ parseMEM
-       l <- formatMem m
+       l <- formatSwap m
        parseTemplate l 
     
+{-
 main :: IO ()
 main =
-    do let af = runMem []
-       runMonitor monitorConfig af runMem
+    do let af = runSwap []
+       runMonitor swapConfig af runSwap
+-}
diff --git a/Monitors/Weather.hs b/Monitors/Weather.hs
--- a/Monitors/Weather.hs
+++ b/Monitors/Weather.hs
@@ -12,7 +12,7 @@
 --
 -----------------------------------------------------------------------------
 
-module Main where
+module Monitors.Weather where
 
 import Monitors.Common
 
@@ -25,8 +25,8 @@
 import Text.ParserCombinators.Parsec
 
 
-monitorConfig :: IO MConfig
-monitorConfig = 
+weatherConfig :: IO MConfig
+weatherConfig = 
     do lc <- newIORef "#BFBFBF"
        l <- newIORef 15
        nc <- newIORef "#00FF00"
@@ -53,8 +53,7 @@
                      ]
        return $ MC nc l lc h hc t p u a e
 
-
-data WeatherInfo = 
+data WeatherInfo =
     WI { stationPlace :: String
        , stationState :: String
        , year :: String
@@ -70,8 +69,6 @@
        , pressure :: String
        } deriving (Show)
 
-
-
 pTime :: Parser (String, String, String, String)
 pTime = do y <- getNumbersAsString
            char '.'
@@ -102,20 +99,15 @@
        ss <- getAllBut "("
        skipRestOfLine >> getAllBut "/"
        (y,m,d,h) <- pTime
-       skipRestOfLine >> string "Wind: "
-       w <- manyTill anyChar $ newline 
-       manyTill skipRestOfLine $ string "Visibility: "
-       v <- manyTill anyChar $ newline
-       manyTill skipRestOfLine $ string "Sky conditions: "
-       sk <- manyTill anyChar $ newline
-       manyTill skipRestOfLine $ string "Temperature"
+       w <- getAfterString "Wind: "
+       v <- getAfterString "Visibility: "
+       sk <- getAfterString "Sky conditions: "
+       skipTillString "Temperature"
        temp <- pTemp
-       manyTill skipRestOfLine $ string "Dew Point: "
-       dp <- manyTill anyChar $ newline
-       manyTill skipRestOfLine $ string "Relative Humidity"
+       dp <- getAfterString "Dew Point: "
+       skipTillString "Relative Humidity"
        rh <- pRh
-       manyTill skipRestOfLine $ string "Pressure (altimeter): "
-       p <- manyTill anyChar $ newline
+       p <- getAfterString "Pressure (altimeter): "
        manyTill skipRestOfLine eof
        return $ [WI st ss y m d h w v sk temp dp rh p]
 
@@ -152,7 +144,9 @@
 package :: String
 package = "xmb-weather"
 
+{-
 main :: IO ()
 main =
     do let af = return "No station ID specified"
-       runMonitor monitorConfig af runWeather
+       runMonitor weatherConfig af runWeather
+-}
diff --git a/Parsers.hs b/Parsers.hs
--- a/Parsers.hs
+++ b/Parsers.hs
@@ -26,7 +26,9 @@
                ) where
 
 import Config
+import Commands
 import Text.ParserCombinators.Parsec
+import qualified Data.Map as Map
 
 
 {- $parser
@@ -59,22 +61,31 @@
 -- | Parses a string with a color set
 colorsAndText :: Config -> Parser (String, String) 
 colorsAndText config = 
-    do { string "<fc=#"
-       ; n <- count 6 hexDigit
+    do { string "<fc="
+       ; c <- colorSpec
        ; string ">"
        ; s <- many $ noneOf "<"
        ; string "</fc>"
-       ; return (s,"#"++n)
+       ; return (s,c)
        }
     <|> defaultColors config
 
+-- | Parses a color specification (hex or named)
+colorSpec :: Parser String
+colorSpec =
+    do { c <- char '#'
+       ; s <- count 6 hexDigit
+       ; return $ c:s
+       }
+    <|> many1 alphaNum
+
 -- | Parses the output template string
 templateStringParser :: Config -> Parser (String,String,String)
 templateStringParser c =
     do{ s <- many $ noneOf (sepChar c)
-      ; (_,com,_) <- templateCommandParser c
+      ; (com,_,_) <- templateCommandParser c
       ; ss <- many $ noneOf (sepChar c)
-      ; return (s, com, ss)
+      ; return (com, s, ss)
       } 
 
 -- | Parses the command part of the template string
@@ -84,16 +95,28 @@
        ; char chr
        ; com <- many $ noneOf (sepChar c)
        ; char chr
-       ; return $ ("",com,"")
-       }
+       ; return $ (com,"","")
+       } 
+
 -- | Combines the template parsers
 templateParser :: Config -> Parser [(String,String,String)]
 templateParser c = many (templateStringParser c)
 
 -- | Actually runs the template parsers
-parseTemplate :: Config -> String -> IO [(String,String,String)]
+parseTemplate :: Config -> String -> IO [(Command,String,String)]
 parseTemplate config s = 
-    case (parse (templateParser config) "" s) of
-      Left _ -> return [("","","")]
-      Right x  -> return x
+    do str <- case (parse (templateParser config) "" s) of
+                Left _ -> return [("","","")]
+                Right x  -> return x
+       let comList = map (show . fst) $ commands config
+           m = Map.fromList . zip comList . map fst $ (commands config)
+       return $ combine m str
 
+-- | Given a finite "Map" and a parsed templatet produces the
+-- | resulting output string.
+combine :: Map.Map String Command -> [(String, String, String)] -> [(Command,String,String)]
+combine _ [] = []
+combine m ((ts,s,ss):xs) = 
+    [(com, s, ss)] ++ combine m xs
+        where com = Map.findWithDefault dflt ts m
+              dflt = Exec ts [] [] --"<" ++ ts ++ " not found!>"
diff --git a/README b/README
--- a/README
+++ b/README
@@ -1,9 +1,10 @@
 XMobar - a status bar for the XMonad Window Manager
 
 ABOUT
------
+=====
 
-Xmobar is a minimal status bar for the XMonad Window Manager.
+Xmobar is a minimalisti, text based, status bar, designed for the
+XMonad Window Manager.
 
 It was inspired by the Ion3 status bar, and supports similar features.
 See xmobar.config-sample for a sample configuration.
@@ -12,9 +13,9 @@
 xmobar xmobar.config-sample
 
 INSTALLATION
-------------
+============
 
-tar xvfz xmobar-0.1
+tar xvfz xmobar-0.5
 runhaskell Setup.lhs configure --prefix=/usr/local
 runhaskell Setup.lhs build
 runhaskell Setup.lhs haddock (optional for building the code documentation)
@@ -24,8 +25,11 @@
 xmobar /path/to/config $
 
 CONFIGURATION
--------------
+=============
 
+Quick Start
+-----------
+
 See xmobar.config-sample for an example.
 
 For the output template:
@@ -37,32 +41,148 @@
 
 Other configuration options:
 
-fonts: Name of the font to be used
+font: Name of the font to be used
 bgColor: Backgroud color
 fgColor: Default font color
 xPos: x position (origin in the upper left corner) of the XMobar window 
 yPos: y position
 width: width of the XMobar window 
-hight: hight
+height: height
 align: text alignment 
 refresh: Refresh rate in tenth of seconds
-commands: For setting the options of the programs to run (optionals)
+commands: For setting the options of the programs to run (optional)
 sepChar: The character to be used for indicating commands in the
          output template (default '%')
 template: The output template 
 
+The Output Template
+-------------------
 
+The output template must contain at least one command. XMobar will
+parse the template and will search for the commands to be executed in
+the "commands" configuration option. First an "alias" will be search
+(internal commands such as Weather or Network have default aliasing,
+see below). After that the command name will be tried. If a command is
+found, its arguments will be used. If no command is found in the
+commands list, then XMobar will try to execute the program with the
+name found in the template. If the execution is not successful an
+error will be reported.
+   
+The "commands" Configuration Option
+-----------------------------------
+
+The "commands" configuration option is a list of commands for storing
+information to be used by XMobar wen parsing the template. Each member
+of the list consists in a tuple formed by a command with arguments and
+a number, the refresh rate in tenth of second.
+
+Available commands are: Weather, Network, memory, Swap, Cpu, Battery,
+and Exec. This last one is used to execute external programs.
+
+Es: (Memory ["-t","Mem: <usedratio>%"], 10)
+
+Internal Commands and Aliases
+-----------------------------
+
+Each command in the "commands" configuration option has an alias to be
+used in the template.
+
+Internal commands have default aliases:
+Weather StationID Args
+- aliases to the Station ID: so Weather "LIPB" [] can be used in template as %LIBP%
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "station", "stationState", "year", "month", "day", "hour",
+	    "wind", "visibility", "skyCondition", "tempC", "tempF",
+	    "dewPoint", "rh", "pressure"
+- Default template: "<station>: <tempC>C, rh <rh>% (<hour>)"
+
+Network Interface ARGS
+- aliases to the interface name: so Network "eth0" [] can be used as %eth0%
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "dev", "rx", "tx"
+- Default template: "<dev>: <rx>|<tx>"
+
+Memory Args
+- aliases to "memory"
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "total", "free", "buffer", "cache", "rest", "used", "usedratio"
+- Default template: "Mem: <usedratio>% (<cache>M)"
+
+Swap Args
+- aliases to "swap"
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "total", "used", "free", "usedratio"
+- Default template: "Swap: <usedratio>%"
+
+Cpu Args
+- aliases to "cpu"
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "total", "user", "nice", "system", "idle"
+- Default template: "Cpu: <total>"
+
+Battery Args
+- aliases to "battery"
+- Args: the argument list (see below)
+- Variables that can be used with the "-t"/"--template" argument: 
+	    "left"
+- Default template: "Batt: <left>"
+
+Internal Commands Arguments
+---------------------------
+
+These are the arguments that can be used for internal commands in the
+"commands" configuration option:
+
+-H number           --High=number               The high threshold
+-L number           --Low=number                The low threshold
+                    --high=color number         Color for the high threshold: es "#FF0000"
+                    --normal=color number       Color for the normal threshold: es "#00FF00"
+                    --low=color number          Color for the low threshold: es "#0000FF"
+-t output template  --template=output template  Output template
+
+Commands must be set as a list. Es:
+(Weather "EGPF" ["-t","<station>: <tempC>C"], 36000)
+
+Executing External Commands
+---------------------------
+
+In order to execute an external command you can either write the
+command name in the template, in this case it will be executed without
+arguments, or you can configure it in the "commands" configuration
+option with the Exec command:
+
+Exec ProgarmName Args Alias
+- ProgramName: the name of the program
+- Args: the arguments to be passed to the program at execution time
+- Alias: a name to be used in the template. If the alias is en empty
+  string the program name can be used in the template.
+Es:
+(Exec "uname" ["-s","-r"] "", 36000)
+can be used in the output template as %uname%
+(Exec "date" ["+\"%a %b %_d %H:%M\""] "mydate", 600)
+can be used in the output template as %mydate%
+
 AUTHOR
-------
+======
 
 Andrea Rossato <andrea.rossato@unibz.it>
 
+CREDITS
+=======
 
+XMobar incorporates patches from:
+Krzysztof Kosciuszkiewicz
+
 LINKS
------
+=====
 
 The XMobar home page:
-http://gorgias.mine.nu/xmobar/
+http://gorgias.mine.nu/repos/xmobar/
 
 XMobars darcs repository:
 http://gorgias.mine.nu/repos/xmobar/
diff --git a/XMobar.hs b/XMobar.hs
--- a/XMobar.hs
+++ b/XMobar.hs
@@ -25,7 +25,6 @@
               , printStrings
               -- * Program Execution
               -- $commands
-              , getOptions
               , execCommands
               , execCommand
               , runCommandLoop
@@ -45,12 +44,9 @@
 import Control.Monad.Reader
 import Control.Concurrent
 
-import System.Process
-import System.Exit
-import System.IO (hClose, hGetLine)
-
 import Config
 import Parsers
+import Commands
 
 -- $main
 --
@@ -97,7 +93,7 @@
             (fromIntegral $ xPos config) 
             (fromIntegral $ yPos config) 
             (fromIntegral $ width config) 
-            (fromIntegral $ hight config)
+            (fromIntegral $ height config)
      mapWindow dpy win
      return (dpy,win)
 
@@ -113,21 +109,21 @@
        bgcolor  <-  io $ initColor dpy $ bgColor config
        gc <- io $ createGC dpy win
        --let's get the fonts
-       fontst <-  io $ loadQueryFont dpy (fonts config)
+       fontst <-  io $ loadQueryFont dpy (font config)
        io $ setFont dpy gc (fontFromFontStruct fontst)
 
        -- set window background 
        io $ setForeground dpy gc bgcolor
        io $ fillRectangle dpy win gc 0 0 
               (fromIntegral $ width config) 
-              (fromIntegral $ hight config)
+              (fromIntegral $ height config)
        -- write
        let strWithLenth = map (\(s,c) -> (s,c,textWidth fontst s)) str
        printStrings gc fontst 1 strWithLenth 
        -- free everything
        io $ freeFont dpy fontst
        io $ freeGC dpy gc
-       io $ flush dpy
+       io $ sync dpy True
 
 -- | An easy way to print the stuff we need to print
 printStrings :: GC
@@ -141,10 +137,11 @@
        st <- get
        let (_,asc,_,_) = textExtents fontst s
            totSLen = foldr (\(_,_,len) -> (+) len) 0 sl
-           valign = (fromIntegral (hight config) + fromIntegral asc) `div` 2
+           valign = (fromIntegral (height config) + fromIntegral asc) `div` 2
+           remWidth = fromIntegral (width config) - fromIntegral totSLen
            offset = case (align config) of
-                      "center" -> (fromIntegral (width config) - fromIntegral totSLen) `div` 2
-                      "right" -> fromIntegral (width config) - fromIntegral totSLen - 1
+                      "center" -> (remWidth + offs) `div` 2
+                      "right" -> remWidth - 1
                       "left" -> offs
                       _ -> offs
        color <- io $ initColor (display st) c
@@ -154,64 +151,41 @@
 
 -- $commands
 
--- | Gets the command options set in configuration.
-getOptions :: Config -> String -> [String]
-getOptions c com =
-    let l = commands c
-        p = filter (\(s,_,_) -> s == com) l
-    in case p of
-         [(_,_,opts)] -> opts
-         _ -> []
-
 -- | Gets the refresh rate set in configuration for a given command.
-getRefRate :: Config -> String -> Int
+getRefRate :: Config -> Command -> Int
 getRefRate c com =
     let l = commands c
-        p = filter (\(s,_,_) -> s == com) l
+        p = filter (\(s,_) -> s == com) l
     in case p of
-         [(_,int,_)] -> int
+         [(_,int)] -> int
          _ -> refresh c
 
--- | Runs a list of programs
-execCommands :: Config -> [(String,String,String)] -> IO [(ThreadId, MVar String)]
+-- | Runs a list of programs as independent threads and returns their thread id
+-- and the MVar they will be writing to.
+execCommands :: Config -> [(Command,String,String)] -> IO [(ThreadId, MVar String)]
 execCommands _ [] = return []
 execCommands c (x:xs) =
     do i <- execCommand c x
        is <- execCommands c xs
        return $ i : is
 
-execCommand :: Config -> (String,String,String) -> IO (ThreadId, MVar String)
+execCommand :: Config -> (Command,String,String) -> IO (ThreadId, MVar String)
 execCommand c com = 
     do var <- newMVar "Updating..."
        h <- forkIO $ runCommandLoop var c com
        return (h,var)
 
--- | Runs the external program
-runCommandLoop :: MVar String -> Config -> (String,String,String) -> IO ()
-runCommandLoop var conf c@(s,com,ss) 
-    | com == "" = 
+runCommandLoop :: MVar String -> Config -> (Command,String,String) -> IO ()
+runCommandLoop var conf c@(com,s,ss)
+    | show com == "" = 
         do modifyMVar_ var (\_ -> return $ "Could not parse the template")
            tenthSeconds (refresh conf)
            runCommandLoop var conf c
     | otherwise =
-        do (i,o,e,p) <- runInteractiveCommand (com ++ concat (map (' ':) $ getOptions conf com))
-           -- the followinf leaks memory
-           --(i,o,e,p) <- runInteractiveProcess com (getOptions c com) Nothing Nothing
-           exit <- waitForProcess p
-           let closeHandles = do hClose o
-                                 hClose i
-                                 hClose e
-           case exit of
-             ExitSuccess -> do str <- hGetLine o
-                               closeHandles
-                               modifyMVar_ var (\_ -> return $ s ++ str ++ ss)
-                               tenthSeconds (getRefRate conf com)
-                               runCommandLoop var conf c
-             _ -> do closeHandles
-                     modifyMVar_ var $ \_ -> return $ "Could not execute command " ++ com
-                     tenthSeconds (getRefRate conf com)
-                     runCommandLoop var conf c
-                                  
+        do str <- run com
+           modifyMVar_ var (\_ -> return $ s ++ str ++ ss)
+           tenthSeconds (getRefRate conf com)
+           runCommandLoop var conf c
 
 -- | Reads MVars set by 'runCommandLoop'
 readVariables :: [(ThreadId, MVar String)] -> IO String
diff --git a/xmobar.cabal b/xmobar.cabal
--- a/xmobar.cabal
+++ b/xmobar.cabal
@@ -1,5 +1,5 @@
 name:               xmobar
-version:            0.4
+version:            0.5
 homepage:           http://gorgias.mine.nu/repos/xmobar/
 synopsis:           A Statusbar for the XMonad Window Manager
 description: 	    Xmobar is a minimal status bar for the XMonad Window Manager.
@@ -10,41 +10,12 @@
 license-file:       LICENSE
 author:             Andrea Rossato
 maintainer:         andrea.rossato@unibz.it
-build-depends:      base>=2.0, X11>=1.2.1, mtl>=1.0, unix>=1.0, parsec>=2.0
+build-depends:      base>=2.0, X11>=1.2.1, mtl>=1.0, unix>=1.0, parsec>=2.0, filepath>=1.0
 
 executable:         xmobar
 main-is:            Main.hs
 Hs-Source-Dirs:     ./
-Other-Modules:      XMobar, Config, Parsers, Monitors.Common 
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s -threaded
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-cpu
-main-is:            Monitors/Cpu.hs
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s -threaded
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-mem
-main-is:            Monitors/Mem.hs
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-swap
-main-is:            Monitors/Swap.hs
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-net
-main-is:            Monitors/Net.hs
+Other-Modules:      XMobar, Config, Parsers, Commands, Monitors.Common, Monitors.Batt 
+		    Monitors.Weather, Monitors.Swap, Monitors.Mem, Monitors.Cpu
 ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s -threaded
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-weather
-main-is:            Monitors/Weather.hs
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s
-ghc-prof-options:   -prof -auto-all
-
-executable:         xmb-batt
-main-is:            Monitors/Batt.hs
-ghc-options:        -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s
 ghc-prof-options:   -prof -auto-all
diff --git a/xmobar.config-sample b/xmobar.config-sample
--- a/xmobar.config-sample
+++ b/xmobar.config-sample
@@ -1,13 +1,22 @@
-Config { fonts = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
+Config { font = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
        , bgColor = "#000000"
        , fgColor = "#BFBFBF"
        , xPos = 0
        , yPos = 0
        , width = 1024
-       , hight = 15
+       , height = 15
        , align = "right"
        , refresh = 10
-       , commands = [("xmb-weather", 36000, ["EGPF"]), ("xmb-net", 10, ["eth0"])]
+       , commands = [ (Weather "EGPF" ["-t","<station>: <tempC>C"], 36000)
+                    , (Network "eth0" [], 10)
+                    , (Network "eth1" [], 10)
+                    , (Cpu [], 10)
+                    , (Exec "date" ["+\"%a %b %_d %H:%M\""] "mydate", 600)
+                    , (Exec "date" ["+%Y"] "year", 304128000)
+                    , (Memory ["-t","Mem: <usedratio>%"], 10)
+                    , (Swap [], 10)
+                    , (Exec "uname" ["-s","-r"] "", 36000)
+                    ]
        , sepChar = "%"
-       , template = "%xmb-cpu% | %xmb-mem% * %xmb-swap% | %xmb-net% | %xmb-weather% | <fc=#ee9a00>%date%</fc>"
+       , template = "%cpu% | %memory% * %swap% | %eth0% - %eth1% | %EGPF% | <fc=#ee9a00>%mydate% of %year%</fc> %uname%"
        }
