diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2010, Yuriy Iskra
+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.
+
+    * The names of its contributors may not 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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMain
diff --git a/examples/Example1.hs b/examples/Example1.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example1.hs
@@ -0,0 +1,56 @@
+import Text.HJson hiding (toString)
+import Text.HJson.Query
+import Text.HJson.Pretty as PP 
+
+-- parse JSON
+jParse :: String -> Json
+jParse jstr = case (fromString  jstr) of
+    Left l  -> error l
+    Right json -> json
+
+j0 = jParse "{}"
+j1 = jParse "{\"Europa\": {\"Ukraine\": [\"Kiyv\", \"Gitomir\", \"Lviv\"]}}"
+j2 = jParse "{\"Asia\": {\"Japan\": [\"Tokyo\"]}}"
+j3 = jParse "{\"Europa\": {\"UnitedKingdom\": [\"London\", \"Glasgow\"]}}"
+j4 = jParse "{\"Europa\": {\"Germany\": [\"Berlin\", \"Bonn\"]}}"
+j5 = jParse "{\"Africa\": {}}"
+j6 = jParse"{\"America\": {\"USA\": [], \"Canada\": [\"Toronto\"]}}"
+j7 = jParse "{\"Australia\": [\"Melburn\", \"Adelaida\"]}"
+merg = jMergesRec [j0, j1, j2, j3, j4, j5, j6, j7]
+ex0 = putStrLn $ toString "   " merg
+---------------------------------------------------------------------------
+
+pprint js = mapM_ putStrLn $ map (toString "   ") js --pretty print 
+
+query1 = getFromKeys ["Europa", "America", "Africa"] 
+json1 = query1 merg 
+ex1 = pprint json1
+---------------------------------------------------------------------------
+record1 =  fromString "[\"Sidoroff\",\"Jhon\",1975,null]"
+ex11 = getFromIndexes [3,1,0] `fmap` record1
+
+---------------------------------------------------------------------------
+
+query2 = query1 >>> getFromObj 
+json2 = query2 merg
+ex2 = pprint json2
+---------------------------------------------------------------------------
+
+-- Qwery:  All citys Europa, America, Australia and Africa
+q31 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+  >>> (getFromArr `orElse`  getFromObj)
+  >>> (isStr `orElse` getFromArr)
+ex31 = pprint $ q31 merg
+
+q32 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+  >>> (getFromObj `when` isObj)
+  >>> getFromArr
+ex32 = pprint $ q32 merg
+
+q33 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+  >>> 
+  deep getFromArr
+ex33 = pprint $ q33 merg
+
+----------------------------------------------------------------------------
+ex4 = debug (deep isPrimitive) "[1,[false, true, [null]]]"
diff --git a/hjson-query.cabal b/hjson-query.cabal
new file mode 100644
--- /dev/null
+++ b/hjson-query.cabal
@@ -0,0 +1,29 @@
+Name:                hjson-query
+Version:             0.4
+Synopsis:            library for querying from JSON
+Category:            Text
+Description:         library(HXT-like) for querying from JSON
+License:             BSD3
+License-file:        LICENSE
+Author:              YuriyIskra  <iskra.yw@gmail.com>
+Maintainer:          YuriyIskra  <iskra.yw@gmail.com>
+Stability:           Experimental
+Copyright:           Copyright (c) 2010 Yuriy Iskra
+Build-type: Simple
+Cabal-version: >= 1.6
+
+extra-source-files:
+  examples/Example1.hs
+
+library
+  Exposed-modules:     Text.HJson.Query
+                       
+  Build-Depends:       hjson, 
+                       base       >= 4   && < 5,
+                       containers >= 0.2 && < 1
+                
+  hs-source-dirs:      src
+
+Source-repository head
+    Type: git
+    Location: git://github.com/iskra/hjson-query.git
diff --git a/src/Text/HJson/Query.hs b/src/Text/HJson/Query.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/HJson/Query.hs
@@ -0,0 +1,271 @@
+module Text.HJson.Query where
+import qualified Data.Map as M (empty, unionWith, elems, union, lookup)
+import qualified Data.Maybe as Mb (catMaybes)
+import qualified Data.List as L (nub)
+import qualified Text.HJson.Pretty as PP (toString)
+import Text.HJson
+
+type Jsons = [Json]
+type JFilter = Json -> Jsons
+
+infixl 1 >>>
+infixr 2 <+>
+
+--------------------------------------------------------------------------
+
+-- | create empty JSON object
+jEmpty :: Json
+jEmpty = JObject (M.empty)
+
+-- | merge two JSON Objects
+jMerge :: Json -> Json -> Json
+jMerge (JObject x ) (JObject y)  = JObject $ M.union x y
+jMerge _ _ = jEmpty
+
+
+-- | recursive merge two JSON Objects
+jMergeRec :: Json -> Json -> Json
+jMergeRec (JObject x) (JObject y) = JObject $ M.unionWith (\m n -> jMergeRec m n) x y
+jMmergeRec _ _    = jEmpty
+
+-- | merge list JSON Objects
+jMerges :: [Json] -> Json
+jMerges [] = jEmpty
+jMerges js = foldl1 jMerge js
+
+-- | recursive merge lists JSON Objects
+--
+-- Example:
+--
+-- > import Text.HJson  hiding (toString)
+-- > import Text.HJson.Query
+-- > import Text.HJson.Pretty
+-- > 
+-- > --  Parse JSON
+-- > jParse :: String -> Json
+-- > jParse jstr = case (fromString  jstr) of
+-- >     Left l  -> error l
+-- >     Right json -> json
+-- > 
+-- > j0 = jParse "{}"
+-- > j1 = jParse "{\"Europa\": {\"Ukraine\": [\"Kiyv\", \"Gitomir\", \"Lviv\"]}}"
+-- > j2 = jParse "{\"Asia\": {\"Japan\": [\"Tokyo\"]}}"
+-- > j3 = jParse "{\"Europa\": {\"UnitedKingdom\": [\"London\", \"Glasgow\"]}}"
+-- > j4 = jParse "{\"Europa\": {\"Germany\": [\"Berlin\", \"Bonn\"]}}"
+-- > j5 = jParse "{\"Africa\": {}}"
+-- > j6 = jParse"{\"America\": {\"USA\": [], \"Canada\": [\"Toronto\"]}}"
+-- > j7 = jParse "{\"Australia\": [\"Melburn\", \"Adelaida\"]}"
+-- > merg = jMergesRec [j0, j1, j2, j3, j4, j5, j6, j7]
+-- > ex0 = putStrLn $ toString "   " merg
+--
+-- Result:
+--
+-- >{
+-- >   "Africa": {
+-- >   },
+-- >   "America": {
+-- >      "Canada": ["Toronto"],
+-- >      "USA": []
+-- >   },
+-- >   "Asia": {
+-- >      "Japan": ["Tokyo"]
+-- >   },
+-- >   "Australia": ["Melburn", "Adelaida"],
+-- >   "Europa": {
+-- >      "Germany": ["Berlin", "Bonn"],
+-- >      "Ukraine": ["Kiyv", "Gitomir", "Lviv"],
+-- >      "UnitedKingdom": ["London", "Glasgow"]
+-- >   }
+-- >}
+
+jMergesRec :: [Json] -> Json
+jMergesRec [] = jEmpty
+jMergesRec js = foldl1 jMergeRec js
+
+--------------------------------------------------------------------------
+
+-- | filter JSON objects 
+isObj :: JFilter
+isObj (JObject o) = [JObject o]
+isObj _              = []
+
+-- | filter JSON arrays
+-- Example 
+isArr :: JFilter
+isArr (JArray a)  = [JArray a]
+isArr _              = []
+
+-- | filter JSON strings
+isStr :: JFilter
+isStr (JString s)  = [JString s]
+isStr _            = []
+
+-- | filter JSON numbers
+isNum :: JFilter
+isNum (JNumber n) = [JNumber n]
+isNum _           = []
+
+-- | filter JSON Bool
+isBool :: JFilter
+isBool (JBool p)   = [JBool p]
+isBool _           = []
+
+-- | filter JSON null
+isNull :: JFilter
+isNull JNull = [JNull]
+isNull _ = []
+
+-- | filter primitive types
+isPrimitive :: JFilter
+isPrimitive (JString s)  = [JString s]
+isPrimitive (JNumber n)  = [JNumber n]
+isPrimitive (JBool p)    = [JBool p]
+isPrimitive JNull        = [JNull]
+isPrimitive _            = []
+
+-- | get elements from object with key
+getFromKey :: String -> JFilter
+getFromKey k (JObject m) = Mb.catMaybes  [(M.lookup k m)]
+getFromKey _ _                = []
+
+-- | get elements from object with keys
+-- 
+--  Example:
+-- 
+-- > pprint js = mapM_ putStrLn $ map (toString "   ") js --pretty print 
+--
+-- > query1 = getFromKeys ["Europa", "America", "Africa"] 
+-- > json1 = query1 merg 
+-- > ex1 = pprint json1
+-- 
+-- Result:
+--
+-- > {
+-- >    "Germany": ["Berlin", "Bonn"],
+-- >    "Ukraine": ["Kiyv", "Gitomir", "Lviv"],
+-- >    "UnitedKingdom": ["London", "Glasgow"]
+-- > }
+-- > {
+-- >    "Canada": ["Toronto"],
+-- >    "USA": []
+-- > }
+-- > {
+-- > 
+-- > }
+
+getFromKeys :: [String] -> JFilter
+getFromKeys ks (JObject m) = Mb.catMaybes $ map (\k -> (M.lookup k m)) (L.nub ks) 
+getFromKeys _ _            = []
+
+-- | get all elements from object
+getFromObj :: JFilter
+getFromObj (JObject o) = M.elems o
+getFromObj _              = []
+
+-- | get all elements from array
+getFromArr :: JFilter
+getFromArr (JArray a)  = a
+getFromArr _           = []
+
+-- | get element from array with index
+getFromIndex :: Int -> JFilter
+getFromIndex i (JArray a) = if i < length a  then [a !! i] else []
+getFromIndex _ _          = []
+
+-- | get elements from array with indexes
+getFromIndexes :: [Int] -> JFilter
+getFromIndexes is ja        = concat [getFromIndex i ja | i <- is]
+
+-- | get all elements from object and array
+getChildern :: JFilter
+getChildern (JObject o) = M.elems o
+getChildern (JArray a)  = a
+getChildern _              = []
+
+-- | filter combinators
+-- 
+--  Example:
+-- 
+-- > query2 = query1 >>> getFromObj 
+-- > json2 = query2 merg
+-- > ex2 = pprint json2
+-- 
+--  Result:
+-- 
+-- > ["Berlin", "Bonn"]
+-- > ["Kiyv", "Gitomir", "Lviv"]
+-- > ["London", "Glasgow"]
+-- > ["Toronto"]
+-- > []
+-- 
+(>>>)	    :: JFilter -> JFilter -> JFilter 
+(f >>> g) t =  concat [g t' | t' <- f t]
+
+-- | filter combinators
+(<+>)	    :: JFilter -> JFilter -> JFilter
+(f <+> g) t =  f t ++ g t
+
+-- | filter combinators
+orElse	:: JFilter -> JFilter -> JFilter
+orElse f g t
+  | null res1 = g t
+  | otherwise = res1
+  where
+  res1 = f t
+
+-- | filter combinators
+when	:: JFilter -> JFilter -> JFilter
+when f g t
+  | null (g t) = [t]
+  | otherwise  = f t
+
+-- | filter combinators
+guards	:: JFilter -> JFilter -> JFilter
+guards g f t
+  | null (g t) = []
+  | otherwise  = f t
+
+-- | tree traversal filter for object
+deepObj	:: JFilter -> JFilter
+deepObj f  = f `orElse` (getFromObj >>> deepObj f)
+
+-- | tree traversal filter for array
+deepArr :: JFilter -> JFilter
+deepArr f  = f `orElse` (getFromArr >>> deepArr f)
+
+-- | tree traversal filter for objects and arrays
+--
+-- Example:
+--
+-- > -- Qwery:  All city Europa, America, Australia and Africa
+-- > -- q31, q32, q33 is equal
+-- > 
+-- > q31 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+-- >   >>> (getFromArr `orElse`  getFromObj)
+-- >   >>> (isStr `orElse` getFromArr)
+-- > 
+-- > q32 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+-- >   >>> (getFromObj `when` isObj)
+-- >   >>> getFromArr
+-- > 
+-- > q33 = getFromKeys ["Europa", "America", "Africa", "Australia"] 
+-- >   >>> 
+-- > deep getFromArr
+-- >
+-- 
+--  See also: <www.haskell.org/haskellwiki/HXT> 
+-- |
+deep	:: JFilter -> JFilter
+deep f  = f `orElse` (getChildern >>> deep f)
+
+--- Debug ----------------------------------------------------------------
+
+-- | pretty print query from JSON string
+--
+-- > debug (deep isPrimitive) "[1, [false, true, [null]]]" == "[1, false, true, null]"
+--
+debug ::  JFilter -> String ->  String
+debug  query  jstr = case (fromString jstr) of
+    Left errmsg -> error errmsg
+    Right json  -> PP.toString "-  "$ JArray $ query json
+
