diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Sergey Mironov
+
+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 Sergey Mironov nor the names of other
+      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/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/src/Help.txt b/src/Help.txt
new file mode 100644
--- /dev/null
+++ b/src/Help.txt
@@ -0,0 +1,27 @@
+
+  Converts a set of FILEs into the Ur/Web modules. Each Module will contain
+  following functions:
+
+    val binary : unit -> transaction blob
+    val blobpage : unit -> transaction page
+    val text : unit -> transaction string
+
+    Additionally, FFI signatures will be provided for JavaScript files. In order
+    to enable this, you have to name your JS functions using the name__type
+    scheme. See README for details. Also, uru project uses this a lot.
+
+    (NOTE: the interface is not stable. Pleas, fork the Urembed sources
+    before using)
+
+  The master project (specified with -o FILE.urp) will contain a dictionary
+  version of those functions taking the datatype key as an argument, instead of
+  unit. In order to actually compile the binaries, you have to call
+
+    make -f FILE.mk CC=.. LD=.. UR_INCLUDE_DIR=.. urp
+
+  Where FILE.mk is the Makefile, generated by urembed.
+
+    Example: urembed -o static/Static.urp Style.css Script.js
+             make -C static -f Static.mk CC=gcc LD=ld UR_INCLUDE_DIR=/usr/local/include/urweb urp
+
+  Note: output directory should exist
diff --git a/src/Urembed.hs b/src/Urembed.hs
new file mode 100644
--- /dev/null
+++ b/src/Urembed.hs
@@ -0,0 +1,412 @@
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE RecursiveDo #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ImpredicativeTypes #-}
+module Main where
+
+import Control.Monad.Error
+import Control.Monad.State
+import Control.Monad.Writer
+import Language.JavaScript.Parser
+import System.Environment
+import System.Process
+import System.Exit
+import System.IO
+import System.FilePath
+import System.Directory
+import System.Info
+import Network.Mime
+import Text.Printf
+import Data.Either
+import Data.Generics
+import Data.Char
+import Data.List
+import Data.Data
+import Data.Typeable
+import Data.Maybe
+import Data.String
+import qualified Data.Text as T
+import qualified Data.ByteString.Char8 as BS
+
+import qualified Development.Cake3 as C3
+import Development.Cake3(runMake,makevar,cmd,rule,extvar,File(..),phony,depend)
+import qualified Development.Cake3.Rules.UrWeb as C3
+import Development.Cake3.Rules.UrWeb (Config(..), urdeps,defaultConfig)
+
+import Options.Applicative
+
+import Paths_urembed
+
+io :: (MonadIO m) => IO a -> m a
+io = liftIO
+
+hio :: (MonadIO m) => Handle -> String -> m ()
+hio h = io . hPutStrLn h
+
+err,out :: (MonadIO m) => String -> m ()
+err = hio stderr
+out = hio stdout
+
+
+span2 :: String -> String -> Maybe (String,String)
+span2 inf s = span' [] s where
+  span' _ [] = Nothing
+  span' acc (c:cs)
+    | isPrefixOf inf (c:cs) = Just (acc, drop (length inf) (c:cs))
+    | otherwise = span' (acc++[c]) cs
+
+data JSFunc = JSFunc {
+    urdecl :: String
+  , urname :: String
+  , jsname :: String
+  } deriving(Show)
+
+data JSType = JSType {
+    urtdecl :: String
+  } deriving(Show)
+
+-- | Parse the JavaScript file, extract top-level functions, convert their
+-- signatures into Ur/Web format, return them as the list of strings
+parse_js :: FilePath -> IO (Either String ([JSType],[JSFunc]))
+parse_js file = do
+  s <- readFile file
+  runErrorT $ do
+    c <- either fail return (parse s file)
+    f <- concat <$> (forM (findTopLevelFunctions c) $ \f@(fn:_) -> (do
+      ts <- mapM extractEmbeddedType (f`zip`(False:repeat True))
+      let urdecl_ = urs_line ts
+      let urname_ = (fst (head ts))
+      let jsname_ = fn
+      return [JSFunc urdecl_ urname_ jsname_]
+      ) `catchError` (\(e::String) -> do
+        err $ printf "ignoring function %s, reason:\n\t%s" fn e
+        return []))
+    t <- concat <$> (forM (findTopLevelVars c) $ \vn -> (do
+      (n,t) <- extractEmbeddedType (vn,False)
+      return [JSType $ printf "type %s" t]
+      )`catchError`  (\(e::String) -> do
+        err $ printf "ignoring variable %s, reason:\n\t%s" vn e
+        return []))
+
+    return (t,f)
+
+  where
+    urs_line :: [(String,String)] -> String
+    urs_line [] = error "wrong function signature"
+    urs_line ((n,nt):args) = printf "val %s : %s" n (fmtargs args) where
+      fmtargs :: [(String,String)] -> String
+      fmtargs ((an,at):as) = printf "%s -> %s" at (fmtargs as)
+      fmtargs [] = let pf = stripPrefix "pure_" nt in
+                   case pf of
+                     Just p -> p
+                     Nothing -> printf "transaction %s" nt
+
+    extractEmbeddedType :: (Monad m) => (String,Bool) -> m (String,String)
+    extractEmbeddedType ([],_) = error "BUG: empty identifier"
+    extractEmbeddedType (name,fallback) = check (msum [span2  "__" name , span2 "_as_" name]) where
+      check (Just (n,t)) = return (n,t)
+      check _ | fallback == True = return (name,name)
+              | fallback == False = fail $ printf "Can't extract the type from the identifier '%s'" name
+
+    findTopLevelFunctions :: JSNode -> [[String]]
+    findTopLevelFunctions top = map decls $ listify is_func top where
+      is_func n@(JSFunction a b c d e f) = True
+      is_func _ = False
+      decls (JSFunction a b c d e f) = (identifiers b) ++ (identifiers d)
+
+    findTopLevelVars :: JSNode -> [String]
+    findTopLevelVars top = map decls $ listify is_var top where
+      is_var n@(JSVarDecl a []) = True
+      is_var _ = False
+      decls (JSVarDecl a _) = (head $ identifiers a);
+      
+    identifiers x = map name $ listify ids x where
+      ids i@(JSIdentifier s) = True
+      ids _ = False
+      name (JSIdentifier n) = n
+
+data Args = A
+  { tgtdir :: FilePath
+  , version :: Bool
+  , files :: [FilePath]
+  }
+
+pargs :: Parser Args
+pargs = A
+  <$> strOption
+      (  long "output"
+      <> short 'o'
+      <> metavar "FILE.urp"
+      <> help "Name of the Ur/Web project being generated"
+      <> value "")
+  <*> flag False True ( long "version" <> help "Show version information" )
+  <*> arguments str ( metavar "FILE" <> help "File to embed" )
+  where
+    osdefgcc | isInfixOf "linux" os = "/usr/bin/gcc"
+             | isInfixOf "windows" os = "c:\\cygwin\\usr\\bin\\gcc"
+             | otherwise = "/usr/local/bin/gcc"
+
+
+replaceExtensions f x = addExtension (dropExtensions f) x
+f .= x = replaceExtensions f x
+
+guessMime inf = fixup $ BS.unpack (defaultMimeLookup (fromString inf)) where
+  fixup "application/javascript" = "text/javascript"
+  fixup m = m
+
+-- readBinaryFile name = BS.openBinaryFile name ReadMode >>= BS.hGetContents
+
+main :: IO ()
+main = do
+  h <- (getDataFileName >=> readFile) "Help.txt" 
+  main_ =<< execParser (
+    info (helper <*> pargs)
+      (  fullDesc
+      <> progDesc h
+      <> header "UrEmebed is the Ur/Web module generator" ))
+
+main_ (A tgturp True ins) = do
+  hPutStrLn stderr "urembed version 0.5.0.0"
+
+main_ (A tgturp False ins) = do
+
+  let tgtdir = takeDirectory tgturp
+
+  when (null tgtdir) $ do
+    fail "An output directory should be specified, use -o"
+
+  when (null ins) $ do
+    fail "At least one file should be specified, see --help"
+
+  exists <- doesDirectoryExist tgtdir
+  when (not exists) $ do
+    fail "Output is not a directory"
+
+  let indest n = tgtdir </> n
+  let write n wr = writeFile (indest n) $ execWriter $ wr
+
+  forM_ ins $ \inf -> do
+    hPutStrLn stderr (printf "Processing %s" inf)
+
+    let modname = (mkname inf)
+    let modname_c = modname ++ "_c"
+    let blobname = modname ++ "_c_blob"
+    let modname_js = modname ++ "_js"
+    let mime = guessMime inf
+
+    -- Module_c.urp
+    let binfunc = printf "uw_%s_binary" modname_c
+    let textfunc = printf "uw_%s_text" modname_c
+
+    write (replaceExtension modname_c ".urs") $ do
+      line $ "val binary : unit -> transaction blob"
+      line $ "val text : unit -> transaction string"
+
+    content <- liftIO $ BS.readFile inf
+    let csrc = replaceExtension modname_c ".c"
+    write csrc $ do
+      line $ "// Thanks, http://stupefydeveloper.blogspot.ru/2008/08/cc-embed-binary-data-into-elf.html"
+      line $ "#include <urweb.h>"
+      line $ "#include <stdio.h>"
+      -- let start = printf "_binary___%s_start" blobname
+      -- let size = printf "_binary___%s_size" blobname
+      line $ printf "#define BLOBSZ %d" (BS.length content)
+      line $ "static char blob[BLOBSZ];"
+      line $ "uw_Basis_blob " ++ binfunc ++ " (uw_context ctx, uw_unit unit)"
+      line $ "{"
+      line $ "  uw_Basis_blob uwblob;"
+      line $ "  uwblob.data = &blob[0];"
+      line $ "  uwblob.size = BLOBSZ;"
+      line $ "  return uwblob;"
+      line $ "}"
+      line $ ""
+      line $ "uw_Basis_string " ++ textfunc ++ " (uw_context ctx, uw_unit unit) {"
+      line $ "  char* data = &blob[0];"
+      line $ "  size_t size = sizeof(blob);"
+      line $ "  char * c = uw_malloc(ctx, size+1);"
+      line $ "  char * write = c;"
+      line $ "  int i;"
+      line $ "  for (i = 0; i < size; i++) {"
+      line $ "    *write =  data[i];"
+      line $ "    if (*write == '\\0')"
+      line $ "    *write = '\\n';"
+      line $ "    *write++;"
+      line $ "  }"
+      line $ "  *write=0;"
+      line $ "  return c;"
+      line $ "  }"
+      line $ ""
+
+    let append n wr = BS.appendFile (indest n) $ execWriter $ wr
+    append csrc $ do
+      let line s = tell ((BS.pack s)`mappend`(BS.pack "\n"))
+      line $ ""
+      line $ "static char blob[BLOBSZ] = {"
+      let buf = reverse $ BS.foldl (\a c -> (BS.pack (printf "0x%02X ," c)) : a) [] content
+      tell (BS.concat buf)
+      line $ "};"
+      line $ ""
+
+    let header = (replaceExtension modname_c ".h")
+    write header $ do
+      line $ "#include <urweb.h>"
+      line $ "uw_Basis_blob " ++ binfunc ++ " (uw_context ctx, uw_unit unit);"
+      line $ "uw_Basis_string " ++ textfunc ++ " (uw_context ctx, uw_unit unit);"
+
+    let binobj = replaceExtension modname_c ".o"
+    -- let dataobj = replaceExtension modname_c ".data.o"
+
+    write (replaceExtension modname_c ".urp") $ do
+      line $ "ffi " ++ modname_c
+      line $ "include " ++ header
+      line $ "link " ++ binobj
+      -- line $ "link " ++ dataobj
+
+    -- Copy the file to the target dir and run linker from there. Thus the names
+    -- it places will be correct (see start,size in _c)
+    -- copyFile inf (indest blobname)
+
+    -- Module_js.urp
+    (jstypes,jsdecls) <- if ((takeExtension inf) == ".js") then do
+                            e <- parse_js inf
+                            case e of
+                              Left e -> do
+                                err $ printf "Error while parsing %s" (takeFileName inf)
+                                fail e
+                              Right decls -> do
+                                -- err (show decls)
+                                return decls
+                         else
+                            return ([],[])
+
+    write (replaceExtension modname_js ".urs") $ do
+      forM_ jstypes $ \decl -> line (urtdecl decl)
+      forM_ jsdecls $ \decl -> line (urdecl decl)
+
+    write (replaceExtension modname_js ".urp") $ do
+      line $ "ffi " ++ modname_js
+      forM_ jsdecls $ \decl -> do
+        line $ printf "jsFunc %s.%s = %s" modname_js (urname decl) (jsname decl)
+        line $ printf "benignEffectful %s.%s" modname_js (urname decl)
+    
+    -- Module.urp
+    write (replaceExtension modname ".urs") $ do
+      line $ "val binary : unit -> transaction blob"
+      line $ "val text : unit -> transaction string"
+      line $ "val blobpage : unit -> transaction page"
+      line $ "val geturl : url"
+      forM_ jstypes $ \decl -> line (urtdecl decl)
+      forM_ jsdecls $ \d -> line (urdecl d)
+
+    write (replaceExtension modname ".ur") $ do
+      line $ "val binary = " ++ modname_c ++ ".binary"
+      line $ "val text = " ++ modname_c ++ ".text"
+      forM_ jsdecls $ \d ->
+        line $ printf "val %s = %s.%s" (urname d) modname_js (urname d)
+      line $ printf "fun blobpage {} = b <- binary () ; returnBlob b (blessMime \"%s\")" mime
+      line $ "val geturl = url(blobpage {})"
+
+    write (replaceExtension modname ".urp") $ do
+      line $ "library " ++ modname_c
+      line $ "library " ++ modname_js
+      line $ printf "safeGet %s/blobpage" modname
+      line $ printf "safeGet %s/blob" modname
+      line $ ""
+      line $ modname
+
+  -- Static.urp
+  let tgt_in = replaceExtensions tgturp ".urp.in"
+
+  writeFile tgt_in $ execWriter $ do
+    forM_ ins $ \inf -> do
+      line $ printf "library %s" (mkname inf)
+    line []
+    line (takeBaseName tgturp)
+
+  let datatype = execWriter $ do
+        tell "datatype content = "
+        tell (mkname (head ins))
+        forM_ (tail ins) (\f -> tell $ printf " | %s" (mkname f))
+
+  writeFile (replaceExtensions tgt_in "urs") $ execWriter $ do
+    line datatype
+    line "val binary : content -> transaction blob"
+    line "val text : content -> transaction string"
+    line "val blobpage : content -> transaction page"
+    line "val urls : list url"
+
+  writeFile (replaceExtensions tgt_in "ur") $ execWriter $ do
+    line datatype
+    line $ "fun binary c = case c of"
+    line $ printf "      %s => %s.binary ()" (mkname (head ins)) (mkname (head ins))
+    forM_ (tail ins) (\f -> line $
+          printf "    | %s => %s.binary ()" (mkname f) (mkname f))
+    line $ "fun blobpage c = case c of"
+    line $ printf "      %s => %s.blobpage ()" (mkname (head ins)) (mkname (head ins))
+    forM_ (tail ins) (\f -> line $
+           printf "    | %s => %s.blobpage ()" (mkname f) (mkname f))
+    line $ "fun text c = case c of"
+    line $ printf "      %s => %s.text ()" (mkname (head ins)) (mkname (head ins))
+    forM_ (tail ins) (\f -> line $
+           printf "    | %s => %s.text ()" (mkname f) (mkname f))
+    line $ "val urls ="
+    forM_ ins (\f -> line $
+      printf "     %s.geturl :: " (mkname f))
+    line $ "       []"
+
+  -- Build the Makefile
+  setCurrentDirectory tgtdir
+  writeFile ((takeBaseName tgturp) .= ".mk") =<< (mdo
+    let file x = C3.file' tgtdir tgtdir x
+    let cc = extvar "CC"
+    let ld = extvar "LD"
+    let incl = extvar "UR_INCLUDE_DIR"
+
+    let tgt_in = file (takeBaseName tgturp .= ".urp.in") 
+    let tgt = file (takeBaseName tgturp .= ".urp") 
+
+    urp_in <- C3.ruleM tgt_in $ do
+      flip urdeps tgt_in (
+        defaultConfig {
+          urObjRule = \f -> rule f $ do
+            case isInfixOf "data" (C3.takeExtensions f) of
+              True -> do
+                let src = C3.fromFilePath . (++"_blob") . dropExtensions . C3.toFilePath $ f
+                C3.shell [cmd| $(ld) -r -b binary -o $f $(src :: File) |]
+              False -> do
+                let src = C3.fromFilePath . flip replaceExtensions "c" . C3.toFilePath $ f
+                C3.shell [cmd| $(cc) -c -I $incl -o $f $(src :: File) |]
+          })
+
+    urp <- C3.ruleM tgt $ do
+      C3.shell [cmd|cp $(urp_in) $(urp) |]
+      C3.shell [cmd|echo $urp|]
+
+    runMake $ do
+      C3.place (phony "urp" (depend urp))
+    )
+
+  hPutStrLn stderr "Done"
+
+    where
+
+      line s = tell (s++"\n")
+      
+      process = process' Nothing
+      process' wd args = do
+        (_,hout,herr,ph) <- runInteractiveProcess (head args) (tail args) wd Nothing
+        code <- waitForProcess ph
+        when (code /= ExitSuccess) $ do
+          hGetContents hout >>= hPutStrLn stderr
+          hGetContents herr >>= hPutStrLn stderr 
+          fail $ printf "process %s failed to complete with %s" (show args) (show code)
+        return ()
+
+      mkname f = upper1 . notnum . map under . takeFileName $ f where
+        under c | c`elem`"_-. /" = '_'
+                | otherwise = c
+        upper1 [] = []
+        upper1 (x:xs) = (toUpper x) : xs
+        notnum n@(x:xs) | isDigit x = "f" ++ n
+                        | otherwise = n
+
diff --git a/urembed.cabal b/urembed.cabal
new file mode 100644
--- /dev/null
+++ b/urembed.cabal
@@ -0,0 +1,51 @@
+-- Initial urembed.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                urembed
+version:             0.5.0.0
+synopsis:            Ur/Web static content generator
+description:         Urembed converts a set of FILEs into the Ur/Web modules. Each Module will contain
+                      following functions:
+
+                        val binary : unit -> transaction blob
+                        val blobpage : unit -> transaction page
+                        val text : unit -> transaction string
+
+                        Additionally, FFI signatures will be provided for JavaScript files. In order
+                        to enable this, you have to name your JS functions using the name__type
+                        scheme. See README for details. Also, uru project uses this a lot.
+
+                        (NOTE: the interface is not stable. Pleas, fork the Urembed sources
+                        before using)
+
+                      The master project (specified with -o FILE.urp) will contain a dictionary
+                      version of those functions taking the datatype key as an argument, instead of
+                      unit. In order to actually compile the binaries, you have to call
+
+                        make -f FILE.mk CC=.. LD=.. UR_INCLUDE_DIR=.. urp
+
+                      Where FILE.mk is the Makefile, generated by urembed.
+
+                        Example: urembed -o static/Static.urp Style.css Script.js
+                                 make -C static -f Static.mk CC=gcc LD=ld UR_INCLUDE_DIR=/usr/local/include/urweb urp
+
+                      Note: output directory should exist
+homepage:            http://github.com/grwlf/urembed
+license:             BSD3
+license-file:        LICENSE
+author:              Sergey Mironov
+maintainer:          grrwlf@gmail.com
+-- copyright:           
+category:            Development
+build-type:          Simple
+cabal-version:       >=1.8
+data-dir:            src
+data-files:          Help.txt
+
+executable urembed
+  main-is:             Urembed.hs
+  build-depends:       base == 4.6.*, mtl, language-javascript ==0.5.*, process,
+                       filepath, syb, optparse-applicative, directory,
+                       mime-types, text, bytestring, cake3
+  hs-source-dirs:      src
+
