diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2012 Formal Methods
+Copyright (c) 2012 Tim, Max
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/WeatherApi.hs b/WeatherApi.hs
new file mode 100644
--- /dev/null
+++ b/WeatherApi.hs
@@ -0,0 +1,79 @@
+-- | Usage:
+--
+-- required imports
+--
+-- > import WeatherApi
+-- > import WeatherApi.Google
+--
+-- With handler in case server will alow you to make
+-- few requests with one connection
+--
+-- >>> let h = mkWeatherHandler $ initApi "en" "utf-8"
+-- >>> getWeather h "moscow"
+-- Right (Weather { tempF = 75.0
+--                , tempC = 24.0
+--                , humidity = "Humidity: 25%"
+--                , windCondition = "Wind: S at 16 mph"
+--                , condition = "Clear"
+--                })
+--
+-- Simple case
+--
+-- >>> getWeather' (initApi "en" "utf-8") "moscow"
+-- Right (Weather { tempF = 75.0
+--                , tempC = 24.0
+--                , humidity = "Humidity: 25%"
+--                , windCondition = "Wind: S at 16 mph"
+--                , condition = "Clear"
+--                })
+
+module WeatherApi (WeatherApiHandler(..)
+                  ,Config(..)
+                  ,Weather(..)
+                  ,getWeather
+                  ,getWeather'
+                  ,mkWeatherHandler
+                  ,isHandlerAlive
+                  ,closeHandler) where
+
+import Network.HTTP
+import Network.URI
+
+data Config = Config { apiHost  :: String
+                     , apiPort  :: Int
+                     , queryFun :: HandleStream String ->
+                                  String              ->
+                                      IO (Either String Weather)
+                     }
+
+data WeatherApiHandler = WeatherApiHandler
+    { stream :: IO (HandleStream String)
+    , config :: Config
+    }
+
+data Weather = Weather { tempF, tempC  :: Double
+                       , humidity      :: String
+                       , windCondition :: String
+                       , condition     :: String
+                       } deriving (Eq, Show)
+
+mkWeatherHandler c@(Config apiHost apiPort queryFun) =
+  WeatherApiHandler { stream = openStream apiHost apiPort
+                    , config = c
+                    }
+
+isHandlerAlive (WeatherApiHandler stream (Config h p _)) =
+    stream >>= \s -> isTCPConnectedTo s (EndPoint h p)
+
+closeHandler (WeatherApiHandler stream _) = stream >>= closeQuick
+
+-- | Retrieve weather using existing handler
+getWeather (WeatherApiHandler stream c) city =
+    stream >>= \s -> queryFun c s city
+
+-- | Retrieve weather using just config
+-- It's usefull when you don't need one connection for few requests
+getWeather' (Config apiHost apiPort queryFun) city =
+    openStream apiHost apiPort >>= \s -> queryFun s city
+
+
diff --git a/WeatherApi/Google.hs b/WeatherApi/Google.hs
new file mode 100644
--- /dev/null
+++ b/WeatherApi/Google.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
+module WeatherApi.Google (initApi) where
+
+import Text.XML.HXT.Core
+import Network.HTTP
+import Network.URI
+import WeatherApi
+import Control.Monad (liftM)
+apiUrl  = "http://www.google.com/ig/api?"
+
+type Lang = String
+type Enc  = String
+
+-- | Make config for use with WeatherApi functions
+initApi :: Lang -> Enc -> Config
+initApi   lang   enc =
+    let params = [("hl", lang), ("oe", enc)]
+        urn c  = urlEncodeVars $ params ++ [("weather", c)]
+    in Config { apiHost  = "www.google.com"
+              , apiPort  = 80
+              , queryFun = makeQueryFun urn
+              }
+
+retrieve s urn =
+    case parseURI $ apiUrl ++ urn of
+      Nothing  -> return $ Left "Invalid URL"
+      Just uri -> get s uri
+
+get s uri =
+    do
+      eresp <- sendHTTP s (Request uri GET [] "")
+      case eresp of
+        Left err  -> return $ Left $ show err
+        Right res -> return $ Right $ rspBody res
+
+atTag tag = deep (isElem >>> hasName tag)
+dataAtTag tag = atTag tag >>> getAttrValue "data"
+
+parseWeather = atTag "current_conditions" >>>
+  proc x -> do
+    tempF'         <- dataAtTag "temp_f"         -< x
+    tempC'         <- dataAtTag "temp_c"         -< x
+    humidity'      <- dataAtTag "humidity"       -< x
+    windCondition' <- dataAtTag "wind_condition" -< x
+    condition'     <- dataAtTag "condition"      -< x
+    returnA -< Weather
+      { tempF         = read tempF'
+      , tempC         = read tempC'
+      , humidity      = humidity'
+      , windCondition = windCondition'
+      , condition     = condition'
+      }
+
+parseXML = readString [ withValidate no
+                      , withRemoveWS yes
+                      ]
+
+-- | This return function witch will actualy retrieve and parse weather from stream
+makeQueryFun q stream city =
+    do
+      resp <- retrieve stream $ q city
+      case liftM parseXML resp of
+        Left a  -> return $ Left a
+        Right a -> do
+          r <- runX(a >>> parseWeather)
+          case r of
+            []     -> return $ Left "can't retrieve weather"
+            (x:xs) -> return $ Right x
diff --git a/weather-api.cabal b/weather-api.cabal
new file mode 100644
--- /dev/null
+++ b/weather-api.cabal
@@ -0,0 +1,27 @@
+Name:              weather-api
+Version:           0.0
+Synopsis:          Weather api implemented in haskell
+Description:
+        This library implement generic api for retrieving weather
+        by http, and has google weather api as example.
+
+Homepage: https://github.com/cvb/hs-weather-api.git
+License:           MIT
+License-file:      LICENSE
+Author:            Peter
+Maintainer:        peter@standalone.su
+Build-type:        Simple
+Category:          API
+
+Cabal-version:     >= 1.6
+Library
+  Exposed-modules: WeatherApi, WeatherApi.Google
+  Build-depends:   base          == 4.*
+                  ,network       == 2.3.*
+                  ,hxt           == 9.2.*
+                  ,HTTP          == 4000.2.*
+                  ,resource-pool == 0.2.1.*
+
+source-repository head
+  type:     git
+  location: git://github.com/cvb/hs-weather-api.git
