diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2010-2012 Hamish Mackenzie, Victor Nazarov, Luite Stegeman
+
+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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,6 @@
+#!/usr/bin/runhaskell 
+> module Main where
+> import Distribution.Simple
+> main :: IO ()
+> main = defaultMain
+
diff --git a/jsaddle.cabal b/jsaddle.cabal
new file mode 100644
--- /dev/null
+++ b/jsaddle.cabal
@@ -0,0 +1,101 @@
+name: jsaddle
+version: 0.1.1.3
+cabal-version: >=1.10
+license: MIT
+license-file: LICENSE
+maintainer: Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+synopsis: High level interface for webkit-javascriptcore
+description: This package provides an EDSL for calling JavaScript code using
+             the JavaScriptCore engine and low level Haskell bindings
+             in the webkit-javascriptcore library <https://github.com/ghcjs/webkit-javascriptcore>.
+author: Hamish Mackenzie
+data-dir: ""
+category: Web, Javascript
+build-type: Simple
+
+Source-Repository head
+  type:         git
+  location:     https://github.com/ghcjs/jsaddle
+
+flag gtk3
+    Description: Use GTK3 rather than GTK2
+    Default: True
+
+flag jsffi
+    description: Use JavaScriptFFI extension for GHCJS JavaScript output
+    default: True
+
+flag webkit
+    description: Use WebKitGtk and JavaScriptCore for GHCJS output
+    default: False
+
+flag jmacro
+    description: Include some JMacro support
+    default: True
+
+library
+--    if impl(ghcjs) && flag(jsffi)
+--        cpp-options: -DUSE_JAVASCRIPTFFI
+--        build-depends: ghcjs-base
+
+--    if !impl(ghcjs) || flag(webkit)
+    if impl(ghc)
+        cpp-options: -DUSE_WEBKIT
+        if flag(gtk3)
+            build-depends: webkitgtk3 >=0.12.5 && <0.13,
+                           webkitgtk3-javascriptcore >=0.12.5 && <0.13
+        else
+            build-depends: webkit >=0.12.5 && <0.13,
+                           webkit-javascriptcore >=0.12.5 && <0.13
+
+    if flag(jmacro)
+        exposed-modules: Language.Javascript.JSaddle.JMacro
+        build-depends: jmacro >=0.6.3 && <0.8
+
+    build-depends: template-haskell -any, base <5, lens >=3.8.5 && <4.1,
+                   text >=0.11.2.3 && <1.2, transformers >=0.3.0.0 && <0.4
+
+    exposed-modules: Language.Javascript.JSaddle
+                     Language.Javascript.JSaddle.Arguments Language.Javascript.JSaddle.Classes
+                     Language.Javascript.JSaddle.Evaluate Language.Javascript.JSaddle.Exception
+                     Language.Javascript.JSaddle.Monad
+                     Language.Javascript.JSaddle.Object Language.Javascript.JSaddle.Properties
+                     Language.Javascript.JSaddle.String Language.Javascript.JSaddle.Value
+                     Language.Javascript.JSaddle.Types
+    exposed: True
+    buildable: True
+    default-language: Haskell2010
+    hs-source-dirs: src
+    other-modules: Language.Javascript.JSaddle.PropRef
+
+test-suite test-tool
+    if flag(jsffi)
+        buildable: False
+
+--    if impl(ghcjs) && flag(jsffi)
+--        cpp-options: -DUSE_JAVASCRIPTFFI
+--        build-depends: ghcjs-base
+
+--    if !impl(ghcjs) || flag(webkit)
+    if impl(ghc)
+        cpp-options: -DUSE_WEBKIT
+        build-depends: glib >=0.12.3.1 && <0.13
+        if flag(gtk3)
+            build-depends: gtk3 >= 0.12.4.1 && <0.13,
+                           webkitgtk3 >=0.12.5 && <0.13,
+                           webkitgtk3-javascriptcore >=0.12.5 && <0.13
+        else
+            build-depends: gtk >= 0.12.4.1 && <0.13,
+                           webkit >=0.12.5 && <0.13,
+                           webkit-javascriptcore >=0.12.5 && <0.13
+
+    if flag(jmacro)
+        build-depends: jmacro >=0.6.3 && <0.8
+
+    build-depends: template-haskell -any, base <5, lens >=3.8.5 && <4.1,
+                   text >=0.11.2.3 && <1.2, transformers >=0.3.0.0 && <0.4,
+                   hslogger -any, jsaddle ==0.1.1.3
+    type: exitcode-stdio-1.0
+    main-is: TestJSaddle.hs
+    default-language: Haskell2010
+    hs-source-dirs: tests
diff --git a/src/Language/Javascript/JSaddle.hs b/src/Language/Javascript/JSaddle.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | This package provides an EDSL for calling JavaScript code using
+--   the JavaScriptCore engine and low level Haskell bindings
+--   in the webkit-javascriptcore library <https://github.com/ghcjs/webkit-javascriptcore>.
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle (
+  -- * JSaddle EDSL
+  -- | The 'JSM' monad gives us the context for evaluation.  In keeping
+  --   with JavaScript the EDSL has
+  --
+  --   * /Weakish typing/ - type classes are used to convert to JSValueRef
+  --   and JSObjectRef types
+  --
+  --   * /Strict evaluation/ - function in the 'JSM' monad can be passed in
+  --   place of a value and will evaluated and converted to JSValueRef or
+  --   JSObjectRef and then passed on to JavaScript
+  --
+  --   JSaddle should be used to write wrappers for JavaScript libraries that provide
+  --   more type safety.
+
+  -- * Code Examples
+  -- | The code examples in this documentation are executed with a 'runjs'
+  --   function that executes the example code in the JSM monad and converts
+  --   the result to 'Text' with 'valToText'.  It also catches unhandled
+  --   exceptions with 'catch'.  The source code can be found in tests/TestJSaddle.hs
+  --
+  --   Where it makes sense code examples are given in two forms.  One
+  --   that uses 'eval' to run a purely JavaScript version and one that
+  --   uses more of the JSaddle EDSL feature being demonstated.
+
+  -- * Calling Haskell from JavaScript
+  -- | You can call back into haskell from JavaScript using 'fun' to
+  --   convert a Haskell function in the JSM monad into a javascript
+  --   value.
+
+  -- * JMacro Support
+  -- | If you want a more JavaScript like syntax we also have a
+  --   JMacro based QuasiQuoter 'evalJM'.  This converts your JMacro
+  --   code into a string literal and a call to @eval@ to evaluate it
+  --   using JavaScriptCore.
+
+  -- * GHCJS Support
+  -- | Because it uses webkit-javascriptcore you can compile your JSaddle code to
+  --   JavaScript using GHCJS <https://github.com/ghcjs/ghcjs> and run it
+  --   in a web browser.  Calls to the WebKitGTK+ JavaScriptCore C functions
+  --   will be replaced with JavaScript function calls.
+
+  -- * Modules
+    module Language.Javascript.JSaddle.Monad
+  , module Language.Javascript.JSaddle.Exception
+  , module Language.Javascript.JSaddle.Value
+  , module Language.Javascript.JSaddle.Arguments
+  , module Language.Javascript.JSaddle.Properties
+  , module Language.Javascript.JSaddle.Object
+  , module Language.Javascript.JSaddle.Evaluate
+#ifdef MIN_VERSION_jmacro
+  , module Language.Javascript.JSaddle.JMacro
+#endif
+  , module Language.Javascript.JSaddle.String
+) where
+
+import Language.Javascript.JSaddle.Monad
+import Language.Javascript.JSaddle.Exception
+import Language.Javascript.JSaddle.Value
+import Language.Javascript.JSaddle.Arguments
+import Language.Javascript.JSaddle.Properties
+import Language.Javascript.JSaddle.Object
+import Language.Javascript.JSaddle.Evaluate
+#ifdef MIN_VERSION_jmacro
+import Language.Javascript.JSaddle.JMacro
+#endif
+import Language.Javascript.JSaddle.String
diff --git a/src/Language/Javascript/JSaddle/Arguments.hs b/src/Language/Javascript/JSaddle/Arguments.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Arguments.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Arguments
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Arguments (
+    MakeArgRefs(..)
+) where
+
+import Language.Javascript.JSaddle.Classes
+       (MakeValueRef(..), MakeValueRef, MakeArgRefs(..), MakeArgRefs)
+import Language.Javascript.JSaddle.Monad (JSM)
+
+instance MakeArgRefs arg => MakeArgRefs (JSM arg) where
+    makeArgRefs arg = arg >>= makeArgRefs
+
+instance MakeValueRef arg => MakeArgRefs [arg] where
+    makeArgRefs = mapM makeValueRef
+
+instance (MakeValueRef arg1, MakeValueRef arg2) => MakeArgRefs (arg1, arg2) where
+    makeArgRefs (arg1, arg2) = do
+        rarg1 <- makeValueRef arg1
+        rarg2 <- makeValueRef arg2
+        return [rarg1, rarg2]
+
+instance (MakeValueRef arg1, MakeValueRef arg2, MakeValueRef arg3) => MakeArgRefs (arg1, arg2, arg3) where
+    makeArgRefs (arg1, arg2, arg3) = do
+        rarg1 <- makeValueRef arg1
+        rarg2 <- makeValueRef arg2
+        rarg3 <- makeValueRef arg3
+        return [rarg1, rarg2, rarg3]
+
+instance (MakeValueRef arg1, MakeValueRef arg2, MakeValueRef arg3, MakeValueRef arg4) => MakeArgRefs (arg1, arg2, arg3, arg4) where
+    makeArgRefs (arg1, arg2, arg3, arg4) = do
+        rarg1 <- makeValueRef arg1
+        rarg2 <- makeValueRef arg2
+        rarg3 <- makeValueRef arg3
+        rarg4 <- makeValueRef arg4
+        return [rarg1, rarg2, rarg3, rarg4]
+
+instance (MakeValueRef arg1, MakeValueRef arg2, MakeValueRef arg3, MakeValueRef arg4, MakeValueRef arg5) => MakeArgRefs (arg1, arg2, arg3, arg4, arg5) where
+    makeArgRefs (arg1, arg2, arg3, arg4, arg5) = do
+        rarg1 <- makeValueRef arg1
+        rarg2 <- makeValueRef arg2
+        rarg3 <- makeValueRef arg3
+        rarg4 <- makeValueRef arg4
+        rarg5 <- makeValueRef arg5
+        return [rarg1, rarg2, rarg3, rarg4, rarg5]
+
diff --git a/src/Language/Javascript/JSaddle/Classes.hs b/src/Language/Javascript/JSaddle/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Classes.hs
@@ -0,0 +1,52 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Classes
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | These classes are used to make various JavaScript types
+--   out of whatever we have.  Functions in jsaddle take these as inputs.
+--   This alows implicit casting and eager evaluation.
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Classes (
+  -- * Type classes to convert Haskell data to JavaScript
+    MakeValueRef(..)
+  , MakeStringRef(..)
+  , MakeArgRefs(..)
+  , MakeObjectRef(..)
+  , MakePropRef(..)
+) where
+
+import Control.Monad.IO.Class (MonadIO)
+import Language.Javascript.JSaddle.Types
+       (JSObjectRef, JSStringRef, JSValueRef)
+import Language.Javascript.JSaddle.Monad (JSM)
+import Language.Javascript.JSaddle.PropRef (JSPropRef)
+
+-- | Anything that can be used to make a JavaScript value reference
+class MakeValueRef a where
+    makeValueRef :: a -> JSM JSValueRef
+
+-- | Anything that can be used to make a JavaScript string reference
+class MakeStringRef a where
+    makeStringRef :: a -> JSStringRef
+
+-- | Anything that can be used to make a list of JavaScript value
+--   references for use as function arguments
+class MakeArgRefs this where
+    makeArgRefs :: this -> JSM [JSValueRef]
+
+-- | Anything that can be used to make a JavaScript object reference
+class MakeObjectRef this where
+    makeObjectRef :: this -> JSM JSObjectRef
+
+-- | Anything that can be used to make a JavaScript property reference
+class MakePropRef this where
+    makePropRef :: this -> JSM JSPropRef
+
+
+
diff --git a/src/Language/Javascript/JSaddle/Evaluate.hs b/src/Language/Javascript/JSaddle/Evaluate.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Evaluate.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE CPP #-}
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+{-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI #-}
+#endif
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Evaluate
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | If you just want to run some JavaScript that you have as a string this is
+--   you can use 'eval' or 'evaluateScript'.
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Evaluate (
+    evaluateScript
+  , eval
+) where
+
+import Control.Monad.Trans.Reader (ask)
+import Control.Monad.IO.Class (MonadIO(..))
+import Language.Javascript.JSaddle.Types
+       (JSStringRef, JSValueRef, JSObjectRef,
+        JSValueRefRef)
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Types (nullRef)
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSBase
+       (jsevaluatescript)
+import Foreign (nullPtr)
+#endif
+import Language.Javascript.JSaddle.Exception (rethrow)
+import Language.Javascript.JSaddle.Value ()
+import Language.Javascript.JSaddle.Object ()
+import Language.Javascript.JSaddle.Classes
+       (MakeObjectRef(..), MakeStringRef(..))
+import Language.Javascript.JSaddle.Monad (JSM)
+
+
+-- | Evaluates a script (like eval in java script).  Unlike 'eval' this function lets you
+--   specify a source URL and starting line number for beter error information.
+--
+-- >>> testJSaddle $ (evaluateScript "\n\n{" global "FileName" 53 >>= valToText) `catch` \(JSException e) -> array (e,e!"sourceURL", e!"line") >>= valToText
+-- SyntaxError: Expected token '}',FileName,55
+evaluateScript :: (MakeStringRef script, MakeObjectRef this, MakeStringRef url)
+               => script         -- ^ JavaScript to evaluate
+               -> this
+               -> url
+               -> Int            -- ^ The Line number of the first line of the script
+               -> JSM JSValueRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+evaluateScript script this url line = liftIO $ js_eval (makeStringRef script)
+foreign import javascript unsafe "$r = eval(s);"
+    js_eval :: JSStringRef -> IO JSValueRef
+#elif defined(USE_WEBKIT)
+evaluateScript script this url line = do
+    gctxt <- ask
+    thisr <- makeObjectRef this
+    rethrow $ liftIO . jsevaluatescript gctxt (makeStringRef script) thisr (makeStringRef url) line
+#else
+evaluateScript = undefined
+#endif
+
+-- | Evaluates a script (like eval in java script)
+--
+-- >>> testJSaddle $ eval "1+1"
+-- 2
+eval :: MakeStringRef script
+     => script         -- ^ JavaScript to evaluate
+     -> JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+eval script = evaluateScript script (nullRef::JSObjectRef) (nullRef::JSStringRef) 1
+#else
+eval script = evaluateScript script (nullPtr::JSObjectRef) (nullPtr::JSStringRef) 1
+#endif
+
diff --git a/src/Language/Javascript/JSaddle/Exception.hs b/src/Language/Javascript/JSaddle/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Exception.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Exception
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Exception (
+    JSException(..)
+  , rethrow
+) where
+
+import qualified Control.Exception as E (throwIO, Exception)
+import Language.Javascript.JSaddle.Types
+       (JSValueRefRef, JSValueRef)
+import Data.Typeable (Typeable)
+import Language.Javascript.JSaddle.Monad (catchval, JSM)
+import Control.Monad.IO.Class (MonadIO(..))
+import Data.Text (Text)
+
+data JSException = JSException JSValueRef deriving (Show, Typeable)
+
+instance E.Exception JSException
+
+-- | Catch JavaScript exceptions and rethrow Haskell ones
+rethrow :: (JSValueRefRef -> JSM a) -> JSM a
+rethrow f = f `catchval` \e -> do
+    liftIO . E.throwIO $ JSException e
+
diff --git a/src/Language/Javascript/JSaddle/JMacro.hs b/src/Language/Javascript/JSaddle/JMacro.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/JMacro.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.JMacro
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | Helper function to make it easy to embed JMacro in your code and
+--   use it from JSaddle
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.JMacro (
+    evalJM
+  , evalJME
+) where
+
+import Language.Haskell.TH.Quote (QuasiQuoter(..))
+import Language.Haskell.TH
+       (varE, appE, Lit(..), Exp(..), mkName, ExpQ)
+import Language.Javascript.JMacro (jmacro, jmacroE, renderJs)
+
+-- | Quasi quoter that creates a JavaScript string from JMacro expression
+--   and stores it in a string litteral
+evalJME :: QuasiQuoter
+evalJME = jmacroE {quoteExp = quoteEvalJME}
+
+quoteEvalJME :: String -> ExpQ
+quoteEvalJME s =
+    appE (varE 'return) [|AppE (VarE $ mkName "Language.Javascript.JSaddle.eval")
+        (LitE . StringL . show $ renderJs $(quoteExp jmacroE s))|]
+
+-- | Quasi quoter that creates a JavaScript string from JMacro statement
+--   and stores it in a string litteral
+evalJM :: QuasiQuoter
+evalJM = jmacro {quoteExp = quoteEvalJM}
+
+quoteEvalJM :: String -> ExpQ
+quoteEvalJM s =
+    appE (varE 'return) [|AppE (VarE $ mkName "Language.Javascript.JSaddle.eval")
+        (LitE . StringL . show $ renderJs $(quoteExp jmacro s))|]
diff --git a/src/Language/Javascript/JSaddle/Monad.hs b/src/Language/Javascript/JSaddle/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Monad.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Monad
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | JSM monad keeps track of the JavaScript context
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Monad (
+  -- * Types
+    JSM(..)
+  , JSContextRef
+
+  -- * Running JSaddle given a DOM Window
+  , runJSaddle
+  , runJSaddle_
+
+  -- * Exception Handling
+  , catchval
+  , catch
+) where
+
+import Prelude hiding (catch)
+import Control.Monad.Trans.Reader (runReaderT, ask, ReaderT(..))
+import Language.Javascript.JSaddle.Types
+       (JSValueRefRef, JSValueRef, JSContextRef)
+import Control.Monad.IO.Class (MonadIO(..))
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Types (isUndefined, isNull)
+import GHCJS.Foreign (newArray, indexArray)
+#else
+import Foreign (nullPtr, alloca)
+import Foreign.Storable (Storable(..))
+import Graphics.UI.Gtk.WebKit.Types
+       (WebView(..))
+import Graphics.UI.Gtk.WebKit.WebView
+       (webViewGetMainFrame)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.WebFrame
+       (webFrameGetGlobalContext)
+#endif
+import qualified Control.Exception as E (Exception, catch)
+
+-- | The @JSM@ monad keeps track of the JavaScript context.
+--
+-- Given a @JSM@ function and a 'JSContextRef' you can run the
+-- function like this...
+--
+-- > runReaderT jsmFunction javaScriptContext
+--
+-- For an example of how to set up WebKitGTK+ see tests/TestJSaddle.hs
+type JSM = ReaderT JSContextRef IO
+
+-- | Wrapped version of 'E.catch' that runs in a MonadIO that works
+--   a bit better with 'JSM'
+catch :: (MonadIO m, E.Exception e)
+      => ReaderT r IO b
+      -> (e -> ReaderT r IO b)
+      -> ReaderT r m b
+t `catch` c = do
+    r <- ask
+    liftIO (runReaderT t r `E.catch` \e -> runReaderT (c e) r)
+
+-- | Handle JavaScriptCore functions that take a JSValueRefRef in order
+--   to throw exceptions.
+catchval :: (JSValueRefRef -> JSM a) -> (JSValueRef -> JSM a) -> JSM a
+catchval f catcher = do
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+    pexc <- liftIO $ newArray
+    result <- f pexc
+    exc <- liftIO $ indexArray 0 pexc
+    if isUndefined exc || isNull exc
+        then return result
+        else catcher exc
+#else
+    gctxt <- ask
+    liftIO . alloca $ \pexc -> flip runReaderT gctxt $ do
+        liftIO $ poke pexc nullPtr
+        result <- f pexc
+        exc <- liftIO $ peek pexc
+        if exc == nullPtr
+            then return result
+            else catcher exc
+#endif
+
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+runJSaddle :: w -> JSM a -> IO a
+runJSaddle _ f = runReaderT f ()
+#else
+runJSaddle :: WebView -> JSM a -> IO a
+runJSaddle webView f = do
+    gctxt <- webViewGetMainFrame webView >>= webFrameGetGlobalContext
+    runReaderT f gctxt
+#endif
+
+runJSaddle_ w f = runJSaddle w f >> return ()
diff --git a/src/Language/Javascript/JSaddle/Object.hs b/src/Language/Javascript/JSaddle/Object.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Object.hs
@@ -0,0 +1,523 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+{-# LANGUAGE JavaScriptFFI #-}
+#endif
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Object
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | Interface to JavaScript object
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Object (
+    JSObjectRef
+  , MakeObjectRef(..)
+
+  -- * Property lookup
+  , (!)
+  , (!!)
+  , js
+  , JSF(..)
+  , jsf
+  , js0
+  , js1
+  , js2
+  , js3
+  , js4
+  , js5
+  , jsg
+
+  -- * Setting the value of a property
+  , (<#)
+
+  -- * Calling JavaSctipt
+  , (#)
+  , new
+  , call
+  , obj
+
+  -- * Calling Haskell From JavaScript
+  , function
+  , fun
+  , JSCallAsFunction(..)
+  -- ** Object Constructors
+
+  -- | There is no good way to support calling haskell code as a JavaScript
+  --   constructor for the same reason that the return type of
+  --   'JSCallAsFunction' is 'JSUndefined'.
+  --
+  --   Instead of writing a constructor in Haskell write a function
+  --   that takes a continuation.  Create the JavaScript object
+  --   and pass it to the continuation.
+
+  -- * Arrays
+  , array
+
+  -- * Global Object
+  , global
+
+  -- * Enumerating Properties
+  , propertyNames
+
+  -- * Low level
+  , objCallAsFunction
+  , objCallAsConstructor
+) where
+
+import Prelude hiding ((!!))
+import Language.Javascript.JSaddle.Types
+       (JSPropertyNameArrayRef, JSStringRef, JSObjectRef, JSValueRefRef,
+        JSValueRef, JSContextRef, Index)
+import Foreign.C.Types (CSize(..), CULong(..), CUInt(..))
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Types (nullRef, castRef, JSArray, JSFun)
+import GHCJS.Foreign (newObj, toArray, fromArray, syncCallback2)
+import Control.Monad (liftM)
+import Control.Applicative ((<$>))
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef
+       (jsobjectmake, jspropertynamearraygetnameatindex,
+        jspropertynamearraygetcount, jsobjectcopypropertynames,
+        jsobjectsetpropertyatindex, jsobjectgetpropertyatindex,
+        jsobjectcallasconstructor, jsobjectmakearray,
+        jsobjectcallasfunction, jsobjectgetproperty, jsobjectsetproperty,
+        JSPropertyAttributes, JSObjectCallAsFunctionCallback,
+        jsobjectmakefunctionwithcallback, JSObjectCallAsFunctionCallback')
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSValueRef
+       (jsvaluemakeundefined)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSContextRef
+       (jscontextgetglobalobject)
+import Foreign (peekArray, nullPtr, withArrayLen)
+#endif
+import Language.Javascript.JSaddle.Exception (rethrow)
+import Language.Javascript.JSaddle.Value
+       (JSUndefined, valMakeUndefined, valToObject)
+import Language.Javascript.JSaddle.PropRef (JSPropRef(..))
+import Language.Javascript.JSaddle.Classes
+       (MakeValueRef(..), MakeStringRef(..), MakeArgRefs(..), MakePropRef(..),
+        MakeObjectRef(..))
+import Language.Javascript.JSaddle.Monad
+       (JSM)
+import Control.Monad.Trans.Reader (runReaderT, ask)
+import Control.Monad.IO.Class (MonadIO(..))
+import qualified Control.Exception as E (catch)
+import Control.Exception (SomeException)
+import qualified Data.Text as T (pack)
+import Foreign.Storable (Storable(..))
+import Language.Javascript.JSaddle.Properties
+import Control.Lens
+       (IndexPreservingGetter, to, (^.))
+import Language.Javascript.JSaddle.String (textToStr)
+
+-- | If we already have a JSObjectRef we are fine
+instance MakeObjectRef JSObjectRef where
+    makeObjectRef = return
+
+-- | JSObjectRef can be made by evaluating a function in 'JSM' as long
+--   as it returns something we can make into a JSObjectRef.
+instance MakeObjectRef v => MakeObjectRef (JSM v) where
+    makeObjectRef v = v >>= makeObjectRef
+
+-- | Lookup a property based on its name.  This function just constructs a JSPropRef
+--   the lookup is delayed until we use the JSPropRef.  This makes it a bit lazy compared
+--   to JavaScript's @.@ operator.
+--
+-- >>> testJSaddle $ eval "'Hello World'.length"
+-- >>> testJSaddle $ val "Hello World" ! "length"
+-- 11
+(!) :: (MakeObjectRef this, MakeStringRef name)
+    => this          -- ^ Object to look on
+    -> name          -- ^ Name of the property to find
+    -> JSM JSPropRef -- ^ Property reference
+this ! name = do
+    rthis <- makeObjectRef this
+    return (JSPropRef rthis rname)
+  where
+    rname = makeStringRef name
+
+-- | Lookup a property based on its index.  This function just constructs a JSPropRef
+--   the lookup is delayed until we use the JSPropRef.  This makes it a bit lazy compared
+--   to JavaScript's @[]@ operator.
+--
+-- >>> testJSaddle $ eval "'Hello World'[6]"
+-- >>> testJSaddle $ val "Hello World" !! 6
+-- W
+(!!) :: (MakeObjectRef this)
+     => this          -- ^ Object to look on
+     -> Index         -- ^ Index of the property to lookup
+     -> JSM JSPropRef -- ^ Property reference
+this !! index = do
+    rthis <- makeObjectRef this
+    return (JSPropIndexRef rthis index)
+
+-- | Makes a getter for a particular property name.
+--
+-- > js name = to (!name)
+--
+-- >>> testJSaddle $ eval "'Hello World'.length"
+-- >>> testJSaddle $ val "Hello World" ^. js "length"
+-- 11
+js :: (MakeObjectRef s, MakeStringRef name)
+   => name          -- ^ Name of the property to find
+   -> IndexPreservingGetter s (JSM JSPropRef)
+js name = to (!name)
+
+-- | Java script function applications have this type
+type JSF = MakeObjectRef o => IndexPreservingGetter o (JSM JSValueRef)
+
+-- | Handy way to call a function
+--
+-- > jsf name = js name . to (# args)
+--
+-- >>> testJSaddle $ val "Hello World" ^. jsf "indexOf" ["World"]
+-- 6
+jsf :: (MakeStringRef name, MakeArgRefs args) => name -> args -> JSF
+jsf name args = function . to (# args)
+    where
+        function = js name
+
+-- | Handy way to call a function that expects no arguments
+--
+-- > js0 name = jsf name ()
+--
+-- >>> testJSaddle $ val "Hello World" ^. js0 "toLowerCase"
+-- hello world
+js0 :: (MakeStringRef name) => name -> JSF
+js0 name = jsf name ()
+
+-- | Handy way to call a function that expects one argument
+--
+-- > js1 name a0 = jsf name [a0]
+--
+-- >>> testJSaddle $ val "Hello World" ^. js1 "indexOf" "World"
+-- 6
+js1 :: (MakeStringRef name, MakeValueRef a0) => name -> a0 -> JSF
+js1 name a0 = jsf name [a0]
+
+-- | Handy way to call a function that expects two arguments
+js2 :: (MakeStringRef name, MakeValueRef a0, MakeValueRef a1) => name -> a0 -> a1 -> JSF
+js2 name a0 a1 = jsf name (a0, a1)
+
+-- | Handy way to call a function that expects three arguments
+js3 :: (MakeStringRef name, MakeValueRef a0, MakeValueRef a1, MakeValueRef a2)
+    => name -> a0 -> a1 -> a2 -> JSF
+js3 name a0 a1 a2 = jsf name (a0, a1, a2)
+
+-- | Handy way to call a function that expects four arguments
+js4 :: (MakeStringRef name, MakeValueRef a0, MakeValueRef a1, MakeValueRef a2,
+        MakeValueRef a3)
+    => name -> a0 -> a1 -> a2 -> a3 -> JSF
+js4 name a0 a1 a2 a3 = jsf name (a0, a1, a2, a3)
+
+-- | Handy way to call a function that expects five arguments
+js5 :: (MakeStringRef name, MakeValueRef a0, MakeValueRef a1, MakeValueRef a2,
+        MakeValueRef a3, MakeValueRef a4)
+    => name -> a0 -> a1 -> a2 -> a3 -> a4 -> JSF
+js5 name a0 a1 a2 a3 a4 = jsf name (a0, a1, a2, a3, a4)
+
+
+-- | Handy way to get and hold onto a reference top level javascript
+--
+-- >>> testJSaddle $ eval "w = console; w.log('Hello World')"
+-- >>> testJSaddle $ do w <- jsg "console"; w ^. js "log" # ["Hello World"]
+-- 11
+jsg :: MakeStringRef a => a -> JSM JSPropRef
+jsg name = global ! name
+
+-- | Call a JavaScript function
+--
+-- >>> testJSaddle $ eval "'Hello World'.indexOf('World')"
+-- >>> testJSaddle $ val "Hello World" ! "indexOf" # ["World"]
+-- 6
+infixr 2 #
+(#) :: (MakePropRef prop, MakeArgRefs args)
+    => prop -> args -> JSM JSValueRef
+prop # args = do
+    rprop <- makePropRef prop
+    (this, f) <- objGetProperty' rprop
+    rethrow $ objCallAsFunction f this args
+
+-- | Call a JavaScript function
+--
+-- >>> testJSaddle $ eval "var j = {}; j.x = 1; j.x"
+-- >>> testJSaddle $ do {j <- eval "({})"; j!"x" <# 1; j!"x"}
+-- 1
+infixr 0 <#
+(<#) :: (MakePropRef prop, MakeValueRef val)
+     => prop          -- ^ Property to set
+     -> val           -- ^ Value to set it to
+     -> JSM JSPropRef -- ^ Reference to the property set
+prop <# val = do
+    p <- makePropRef prop
+    objSetProperty p val
+    return p
+
+-- | Use this to create a new JavaScript object
+--
+-- >>> testJSaddle $ new "Date" (2013, 1, 1)
+-- Fri Feb 01 2013 00:00:00 GMT+1300 (NZDT)
+new :: (MakeObjectRef constructor, MakeArgRefs args)
+    => constructor
+    -> args
+    -> JSM JSValueRef
+new constructor args = do
+    f <- makeObjectRef constructor
+    rethrow $ objCallAsConstructor f args
+
+-- | Call function with a given @this@.  In most cases you should use '#'.
+--
+-- >>> testJSaddle $ eval "(function(){return this;}).apply('Hello', [])"
+-- >>> testJSaddle $ do { test <- eval "(function(){return this;})"; call test (val "Hello") () }
+-- Hello
+call :: (MakeObjectRef function, MakeObjectRef this, MakeArgRefs args)
+    => function -> this -> args -> JSM JSValueRef
+call function this args = do
+    rfunction <- makeObjectRef function
+    rthis     <- makeObjectRef this
+    rethrow $ objCallAsFunction rfunction rthis args
+
+-- | Make an empty object using the default constuctor
+--
+-- >>> testJSaddle $ eval "var a = {}; a.x = 'Hello'; a.x"
+-- >>> testJSaddle $ do { a <- obj; a ^. js "x" <# "Hello"; a ^. js "x" }
+-- Hello
+obj :: JSM JSObjectRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+obj = liftIO $ newObj
+#else
+obj = do
+    gctxt <- ask
+    liftIO $ jsobjectmake gctxt nullPtr nullPtr
+#endif
+
+-- | Type used for Haskell functions called from JavaScript.
+type JSCallAsFunction = JSValueRef      -- ^ Function object
+                     -> JSValueRef      -- ^ this
+                     -> [JSValueRef]    -- ^ Function arguments
+                     -> JSM JSUndefined -- ^ Only 'JSUndefined' can be returned because
+                                        --   the function may need to be executed in a
+                                        --   different thread.  If you need to get a
+                                        --   value out pass in a continuation function
+                                        --   as an argument and invoke it from haskell.
+
+-- | Short hand @::JSCallAsFunction@ so a haskell function can be passed to
+--   a to a JavaScipt one.
+--
+-- >>> testJSaddle $ eval "(function(f) {f('Hello');})(function (a) {console.log(a)})"
+-- >>> testJSaddle $ call (eval "(function(f) {f('Hello');})") global [fun $ \ _ _ args -> valToText (head args) >>= (liftIO . putStrLn . T.unpack) ]
+-- Hello
+-- undefined
+fun :: JSCallAsFunction -> JSCallAsFunction
+fun = id
+
+#if (!defined(ghcjs_HOST_OS) || !defined(USE_JAVASCRIPTFFI)) && defined(USE_WEBKIT)
+foreign import ccall "wrapper"
+  mkJSObjectCallAsFunctionCallback :: JSObjectCallAsFunctionCallback' -> IO JSObjectCallAsFunctionCallback
+#endif
+
+-- ^ Make a JavaScript function object that wraps a Haskell function.
+function :: MakeStringRef name
+         => name             -- ^ Name of the function
+         -> JSCallAsFunction -- ^ Haskell function to call
+         -> JSM JSObjectRef  -- ^ Returns a JavaScript function object that will
+                             --   call the Haskell one when it is called
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+function name f = liftIO $ do
+    callback <- syncCallback2 False True $ \this args -> do
+        rargs <- fromArray args
+        runReaderT (f this this rargs) () -- TODO pass function object through
+    makeFunctionWithCallback (makeStringRef name) callback
+foreign import javascript unsafe "$r = function () { $2(this, arguments); }"
+    makeFunctionWithCallback :: JSStringRef -> JSFun (JSValueRef -> JSValueRefRef -> IO ()) -> IO JSObjectRef
+#elif defined(USE_WEBKIT)
+function name f = do
+    gctxt <- ask
+    callback <- liftIO $ mkJSObjectCallAsFunctionCallback wrap
+    liftIO $ jsobjectmakefunctionwithcallback gctxt (makeStringRef name) callback
+  where
+    wrap ctx fobj this argc argv exception = do
+            args <- peekArray (fromIntegral argc) argv
+            (`runReaderT` ctx) $
+                f fobj this args >>= makeValueRef
+      `E.catch` \(e :: SomeException) -> do
+            str <- runReaderT (makeValueRef . T.pack $ show e) ctx
+            poke exception str
+            jsvaluemakeundefined ctx
+#else
+function  = undefined
+#endif
+
+-- | A callback to Haskell can be used as a JavaScript value.  This will create
+--   an anonymous JavaScript function object.  Use 'function' to create one with
+--   a name.
+instance MakeValueRef JSCallAsFunction where
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+    makeValueRef = function (nullRef::JSStringRef)
+#else
+    makeValueRef = function (nullPtr::JSStringRef)
+#endif
+
+instance MakeArgRefs JSCallAsFunction where
+    makeArgRefs f = do
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+        rarg <- function (nullRef::JSStringRef) f
+#else
+        rarg <- function (nullPtr::JSStringRef) f
+#endif
+        return [rarg]
+
+makeArray :: MakeArgRefs args => args -> JSValueRefRef -> JSM JSObjectRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+makeArray args exceptions = makeArgRefs args >>= liftM castRef . liftIO . toArray
+#else
+makeArray args exceptions = do
+    gctxt <- ask
+    rargs <- makeArgRefs args
+    liftIO $ withArrayLen rargs $ \ len ptr ->
+        jsobjectmakearray gctxt (fromIntegral len) ptr exceptions
+#endif
+
+-- | Make an JavaScript array from a list of values
+--
+-- >>> testJSaddle $ eval "['Hello', 'World'][1]"
+-- >>> testJSaddle $ array ["Hello", "World"] !! 1
+-- World
+-- >>> testJSaddle $ eval "['Hello', null, undefined, true, 1]"
+-- >>> testJSaddle $ array ("Hello", JSNull, (), True, 1.0::Double)
+-- Hello,,,true,1
+array :: MakeArgRefs args => args -> JSM JSObjectRef
+array = rethrow . makeArray
+
+-- | JavaScript's global object
+global :: JSM JSObjectRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+global = liftIO js_window
+foreign import javascript unsafe "$r = window"
+    js_window :: IO JSObjectRef
+#elif defined(USE_WEBKIT)
+global = ask >>= (liftIO . jscontextgetglobalobject)
+#else
+global = undefined
+#endif
+
+-- | Get an array containing the property names present on a given object
+#if (!defined(ghcjs_HOST_OS) || !defined(USE_JAVASCRIPTFFI)) && defined(USE_WEBKIT)
+copyPropertyNames :: MakeObjectRef this => this -> JSM JSPropertyNameArrayRef
+copyPropertyNames this = do
+    gctxt <- ask
+    rthis <- makeObjectRef this
+    liftIO $ jsobjectcopypropertynames gctxt rthis
+
+-- | Get the number of names in a property name array
+propertyNamesCount :: MonadIO m => JSPropertyNameArrayRef -> m CSize
+propertyNamesCount names = liftIO $ jspropertynamearraygetcount names
+
+-- | Get a name out of a property name array
+propertyNamesAt :: MonadIO m => JSPropertyNameArrayRef -> CSize -> m JSStringRef
+propertyNamesAt names index = liftIO $ jspropertynamearraygetnameatindex names index
+
+-- | Convert property array to a list
+propertyNamesList :: MonadIO m => JSPropertyNameArrayRef -> m [JSStringRef]
+propertyNamesList names = do
+    count <- propertyNamesCount names
+    mapM (propertyNamesAt names) $ enumFromTo 0 (count - 1)
+#endif
+
+-- | Get a list containing the property names present on a given object
+propertyNames :: MakeObjectRef this => this -> JSM [JSStringRef]
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+propertyNames this = makeObjectRef this >>= liftIO . js_propertyNames >>= liftIO . fromArray
+foreign import javascript unsafe "$r = []; h$forIn($1, function(n){$r.push(n);})"
+    js_propertyNames :: JSObjectRef -> IO (JSArray a)
+#elif defined(USE_WEBKIT)
+propertyNames this = copyPropertyNames this >>= propertyNamesList
+#else
+propertyNames = undefined
+#endif
+
+-- | Get a list containing references to all the  properties present on a given object
+properties :: MakeObjectRef this => this -> JSM [JSPropRef]
+properties this = propertyNames this >>= mapM (this !)
+
+-- | Call a JavaScript object as function.  Consider using '#'.
+objCallAsFunction :: MakeArgRefs args
+                  => JSObjectRef
+                  -> JSObjectRef
+                  -> args
+                  -> JSValueRefRef
+                  -> JSM JSValueRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objCallAsFunction function this args exceptions = do
+    rargs <- makeArgRefs args >>= liftIO . toArray
+    liftIO $ js_apply function this rargs exceptions
+foreign import javascript unsafe "try { $r = $1.apply($2, $3) } catch(e) { $4[0] = e }"
+    js_apply :: JSObjectRef -> JSObjectRef -> JSValueRefRef -> JSValueRefRef -> IO JSValueRef
+#elif defined(USE_WEBKIT)
+objCallAsFunction function this args exceptions = do
+    gctxt <- ask
+    rargs <- makeArgRefs args
+    liftIO $ withArrayLen rargs $ \ largs pargs ->
+        jsobjectcallasfunction gctxt function this (fromIntegral largs) pargs exceptions
+#else
+objCallAsFunction = undefined
+#endif
+
+-- | Call a JavaScript object as a constructor. Consider using 'new'.
+objCallAsConstructor :: MakeArgRefs args
+                     => JSObjectRef
+                     -> args
+                     -> JSValueRefRef
+                     -> JSM JSValueRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objCallAsConstructor function args exceptions = do
+    rargs <- makeArgRefs args >>= liftIO . toArray
+    liftIO $ js_new function rargs exceptions
+foreign import javascript unsafe "\
+    try {\
+        switch($2.length) {\
+            case 0 : $r = new $1();\
+            case 1 : $r = new $1($2[0]);\
+            case 2 : $r = new $1($2[0],$2[1]);\
+            case 3 : $r = new $1($2[0],$2[1],$2[2]);\
+            case 4 : $r = new $1($2[0],$2[1],$2[2],$2[3]);\
+            case 5 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4]);\
+            case 6 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4],$2[5]);\
+            case 6 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4],$2[5],$2[6]);\
+            default:\
+                var ret;\
+                var temp = function() {\
+                    ret = $1.apply(this, $2);\
+                };\
+                temp.prototype = f.prototype;\
+                var i = new temp();\
+                $r = ret instanceof Object ? ret : i;\
+        }\
+    }\
+    catch(e) {\
+        $3[0] = e;\
+    }"
+    js_new :: JSObjectRef -> JSValueRefRef -> JSValueRefRef -> IO JSValueRef
+#elif defined(USE_WEBKIT)
+objCallAsConstructor function args exceptions = do
+    gctxt <- ask
+    rargs <- makeArgRefs args
+    liftIO $ withArrayLen rargs $ \ largs pargs ->
+        jsobjectcallasconstructor gctxt function (fromIntegral largs) pargs exceptions
+#else
+objCallAsConstructor = undefined
+#endif
+
+
+
+
+
diff --git a/src/Language/Javascript/JSaddle/PropRef.hs b/src/Language/Javascript/JSaddle/PropRef.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/PropRef.hs
@@ -0,0 +1,25 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.PropRef
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | Implements a reference to a property
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.PropRef (
+    JSPropRef(..)
+) where
+
+import Language.Javascript.JSaddle.Types
+       (JSStringRef, JSObjectRef, Index)
+
+-- | A reference to a property.
+--   Implemented as a reference to an object and something to find the property.
+data JSPropRef = JSPropRef JSObjectRef JSStringRef -- ^ Object and property name.
+               | JSPropIndexRef JSObjectRef Index  -- ^ Object and property index.
+
+
diff --git a/src/Language/Javascript/JSaddle/Properties.hs b/src/Language/Javascript/JSaddle/Properties.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Properties.hs
@@ -0,0 +1,196 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+{-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI #-}
+#endif
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Properties
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | Low level JavaScript object property access.  In most cases you
+--   should use "Language.Javascript.JSaddle.Object" instead.
+--
+--   This module is mostly here to implement functions needed to use
+--   'JSPropRef'.
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Properties (
+  -- * Propery Reference
+    JSPropRef(..)
+  , MakePropRef(..)
+
+  -- * Getting Property Values
+  , objGetPropertyByName
+  , objGetPropertyAtIndex
+  , objGetProperty
+  , objGetProperty'
+  -- * Setting Property Values
+  , objSetPropertyByName
+  , objSetPropertyAtIndex
+  , objSetProperty
+) where
+
+import Control.Applicative ((<$>))
+import Language.Javascript.JSaddle.PropRef (JSPropRef(..))
+import Language.Javascript.JSaddle.Classes
+       (MakePropRef(..), MakeObjectRef(..), MakeValueRef(..),
+        MakeArgRefs(..), MakeStringRef(..))
+import Language.Javascript.JSaddle.Monad (JSM)
+import Language.Javascript.JSaddle.Types
+       (JSValueRefRef, JSObjectRef, JSPropertyAttributes,
+        Index(..), JSStringRef)
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef
+       (jsobjectgetpropertyatindex, jsobjectgetproperty,
+        jsobjectsetpropertyatindex, jsobjectsetproperty,
+        JSPropertyAttributes)
+#endif
+import Control.Monad.Trans.Reader (ask)
+import Control.Monad.IO.Class (MonadIO(..))
+import Language.Javascript.JSaddle.Exception (rethrow)
+import Language.Javascript.JSaddle.Value (JSValueRef)
+import Language.Javascript.JSaddle.Arguments ()
+import Language.Javascript.JSaddle.String ()
+
+-- | If we already have a JSPropRef we are fine
+instance MakePropRef JSPropRef where
+    makePropRef = return
+
+-- | JSPropRef can be made by evaluating a function in 'JSM' as long
+--   as it returns something we can make into a JSPropRef.
+instance MakePropRef prop => MakePropRef (JSM prop) where
+    makePropRef prop = prop >>= makePropRef
+
+-- | We can use a property as an object.
+instance MakeObjectRef JSPropRef where
+    makeObjectRef = objGetProperty
+
+-- | We can use a property as a value.
+instance MakeValueRef JSPropRef where
+    makeValueRef = objGetProperty
+
+-- | We can pass a property as the only paramter to a function.
+instance MakeArgRefs JSPropRef where
+    makeArgRefs p = do
+        rarg <- objGetProperty p
+        return [rarg]
+
+-- | Get a property value given the object and the name of the property.
+objGetPropertyByName :: MakeStringRef name
+                     => JSObjectRef    -- ^ object to find the property on.
+                     -> name           -- ^ name of the property.
+                     -> JSValueRefRef  -- ^ exception if one is raised.
+                     -> JSM JSValueRef -- ^ returns the property value.
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objGetPropertyByName this name = liftIO . js_tryGetProp (makeStringRef name) this
+foreign import javascript unsafe "try { $r=$2[$1] } catch(e) { $3[0] = e }"
+    js_tryGetProp :: JSStringRef -> JSObjectRef -> JSValueRefRef -> IO JSValueRef
+#elif defined(USE_WEBKIT)
+objGetPropertyByName this name exceptions = do
+    gctxt <- ask
+    liftIO $ jsobjectgetproperty gctxt this (makeStringRef name) exceptions
+#else
+objGetPropertyByName = undefined
+#endif
+
+-- | Get a property value given the object and the index of the property.
+objGetPropertyAtIndex :: JSObjectRef    -- ^ object to find the property on.
+                      -> Index          -- ^ index of the property.
+                      -> JSValueRefRef  -- ^ exception if one is raised.
+                      -> JSM JSValueRef -- ^ returns the property value.
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objGetPropertyAtIndex this index = liftIO . js_tryIndex index this
+foreign import javascript unsafe "try { $r=$2[$1] } catch(e) { $3[0] = e }"
+    js_tryIndex :: Index -> JSObjectRef -> JSValueRefRef -> IO JSValueRef
+#elif defined(USE_WEBKIT)
+objGetPropertyAtIndex this index exceptions = do
+    gctxt <- ask
+    liftIO $ jsobjectgetpropertyatindex gctxt this index exceptions
+#else
+objGetPropertyAtIndex = undefined
+#endif
+
+-- | Gets the value of a property given a 'JSPropRef'.
+objGetProperty :: JSPropRef      -- ^ property reference.
+               -> JSM JSValueRef -- ^ returns the property value.
+objGetProperty (JSPropRef      this name ) =
+    rethrow $ objGetPropertyByName  this name
+objGetProperty (JSPropIndexRef this index) =
+    rethrow $ objGetPropertyAtIndex this index
+
+-- | This version of 'objGetProperty' is handy when you also need to perform.
+--   another operation on the object the property is on.
+objGetProperty' :: JSPropRef                     -- ^ property reference.
+                -> JSM (JSObjectRef, JSValueRef) -- ^ returns the object and property value.
+objGetProperty' (JSPropRef this name) = do
+    p <- rethrow $ objGetPropertyByName this name
+    return (this, p)
+objGetProperty' (JSPropIndexRef this index) = do
+    p <- rethrow $ objGetPropertyAtIndex this index
+    return (this, p)
+
+
+-- | Set a property value given the object and the name of the property.
+objSetPropertyByName :: (MakeStringRef name, MakeValueRef val)
+                     => JSObjectRef          -- ^ object to set the property on.
+                     -> name                 -- ^ name of the property.
+                     -> val                  -- ^ new value to set the property to.
+                     -> JSPropertyAttributes -- ^ property attributes to give the property.
+                     -> JSValueRefRef        -- ^ exception if one is raised.
+                     -> JSM ()
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objSetPropertyByName this name val attributes exceptions = do
+    vref <- makeValueRef val
+    liftIO $ js_trySetProp (makeStringRef name) this vref exceptions
+foreign import javascript unsafe "try { $2[$1]=$3 } catch(e) { $4[0] = e }"
+    js_trySetProp :: JSStringRef -> JSObjectRef -> JSValueRef -> JSValueRefRef -> IO ()
+#elif defined(USE_WEBKIT)
+objSetPropertyByName this name val attributes exceptions = do
+    gctxt <- ask
+    vref <- makeValueRef val
+    liftIO $ jsobjectsetproperty gctxt this (makeStringRef name) vref attributes exceptions
+#else
+objSetPropertyByName = undefined
+#endif
+
+-- | Set a property value given the object and the index of the property.
+objSetPropertyAtIndex :: (MakeValueRef val)
+                      => JSObjectRef    -- ^ object to find property on.
+                      -> Index          -- ^ index of the property.
+                      -> val            -- ^ new value to set the property to.
+                      -> JSValueRefRef  -- ^ exception if one is raised.
+                      -> JSM ()
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+objSetPropertyAtIndex this index val exceptions = do
+    vref <- makeValueRef val
+    liftIO $ js_trySetAtIndex index this vref exceptions
+foreign import javascript unsafe "try { $2[$1]=$3 } catch(e) { $4[0] = e }"
+    js_trySetAtIndex :: Index -> JSObjectRef -> JSValueRef -> JSValueRefRef -> IO ()
+#elif defined(USE_WEBKIT)
+objSetPropertyAtIndex this index val exceptions = do
+    gctxt <- ask
+    vref <- makeValueRef val
+    liftIO $ jsobjectsetpropertyatindex gctxt this index vref exceptions
+#else
+objSetPropertyAtIndex = undefined
+#endif
+
+-- | Sets the value of a property given a 'JSPropRef'.
+objSetProperty :: (MakeValueRef val)
+               => JSPropRef -- ^ property reference.
+               -> val       -- ^ new value to set the property to.
+               -> JSM ()
+objSetProperty (JSPropRef      this name ) val = rethrow $ objSetPropertyByName  this name  val 0
+objSetProperty (JSPropIndexRef this index) val = rethrow $ objSetPropertyAtIndex this index val
+
+
+
+
+
diff --git a/src/Language/Javascript/JSaddle/String.hs b/src/Language/Javascript/JSaddle/String.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/String.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.String
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | JavaScript string conversion functions
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.String (
+    JSStringRef
+  , MakeStringRef(..)
+
+  -- * Data.Text helpers
+  , strToText
+  , textToStr
+) where
+
+import Data.Text (Text)
+import qualified Data.Text as T (pack)
+import Control.Monad.IO.Class (MonadIO(..))
+import Language.Javascript.JSaddle.Types (JSStringRef)
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Foreign (fromJSString, toJSString)
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSStringRef
+       (jsstringcreatewithcharacters, jsstringgetcharactersptr,
+        jsstringgetlength)
+#endif
+import qualified Data.Text.Foreign as T (fromPtr)
+import Foreign (castPtr)
+import Data.Text.Foreign (useAsPtr)
+import Language.Javascript.JSaddle.Classes (MakeStringRef(..))
+import System.IO.Unsafe (unsafePerformIO)
+
+-- | If we already have a JSStringRef we are fine
+instance MakeStringRef JSStringRef where
+    makeStringRef = id
+
+instance MakeStringRef Text where
+    makeStringRef = textToStr
+
+instance MakeStringRef String where
+    makeStringRef = textToStr . T.pack
+
+-- | Convert a JavaScript string to a Haskell 'Text'
+strToText :: MonadIO m => JSStringRef -> m Text
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+strToText = return . fromJSString
+#else
+strToText jsstring = liftIO $ do
+    l <- jsstringgetlength jsstring
+    p <- jsstringgetcharactersptr jsstring
+    T.fromPtr (castPtr p) (fromIntegral l)
+#endif
+
+-- | Convert a Haskell 'Text' to a JavaScript string
+textToStr :: Text -> JSStringRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+textToStr = toJSString
+#else
+textToStr text = unsafePerformIO $
+    useAsPtr text $ \p l ->
+        jsstringcreatewithcharacters (castPtr p) (fromIntegral l)
+#endif
+
+
+
diff --git a/src/Language/Javascript/JSaddle/Types.hs b/src/Language/Javascript/JSaddle/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Types.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE CPP, FlexibleInstances #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Properties
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Types (
+    JSValueRef(..)
+  , JSValueRefRef(..)
+  , JSObjectRef(..)
+  , JSPropertyNameArrayRef(..)
+  , JSPropertyAttributes(..)
+  , JSContextRef(..)
+  , JSStringRef(..)
+  , Index(..)
+) where
+
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Types
+import Data.Word (Word(..))
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSBase
+       (JSValueRef, JSValueRefRef, JSObjectRef, JSStringRef,
+        JSContextRef, JSPropertyNameArrayRef)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef (JSPropertyAttributes)
+import Foreign.C (CUInt(..))
+#endif
+
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+data ValueOrObject
+data Object
+data PropertyNameArray
+type JSValueRef    = JSRef ValueOrObject
+type JSValueRefRef = JSArray ValueOrObject
+type JSObjectRef   = JSRef ValueOrObject
+type JSPropertyNameArrayRef = JSRef PropertyNameArray
+type JSPropertyAttributes = Word
+type JSContextRef  = ()
+type JSStringRef   = JSString
+type Index         = Int
+
+instance Show (JSRef ValueOrObject)
+instance Eq (JSRef ValueOrObject)
+#else
+type Index = CUInt
+#endif
diff --git a/src/Language/Javascript/JSaddle/Value.hs b/src/Language/Javascript/JSaddle/Value.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Javascript/JSaddle/Value.hs
@@ -0,0 +1,502 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+{-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI #-}
+#endif
+-----------------------------------------------------------------------------
+--
+-- Module      :  Language.Javascript.JSaddle.Value
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- | Deals with JavaScript values.  These can be
+--
+--   * null
+--
+--   * undefined
+--
+--   * true | false
+--
+--   * a double precision floating point number
+--
+--   * a string
+--
+--   * an object
+--
+-----------------------------------------------------------------------------
+
+module Language.Javascript.JSaddle.Value (
+  -- * JavaScript value references
+    JSValueRef
+  , MakeValueRef(..)
+
+  -- * Haskell types for JavaScript values
+  , JSNull(..)
+  , JSUndefined(..)
+  , JSBool(..)
+  , JSNumber(..)
+  , JSString(..)
+  , JSValue(..)
+
+  -- * Converting JavaScript values
+  , valToBool
+  , valToNumber
+  , valToStr
+  , valToObject
+  , valToText
+  , valToJSON
+
+  -- * Make JavaScript values from Haskell ones
+  , val
+  , valMakeNull
+  , valMakeUndefined
+  , valMakeBool
+  , valMakeNumber
+  , valMakeString
+
+  -- * Conver to and from JSValue
+  , deRefVal
+  , valMakeRef
+) where
+
+import Prelude hiding (catch)
+import Language.Javascript.JSaddle.Types
+       (JSValueRefRef, JSObjectRef, JSStringRef, JSValueRef)
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+import GHCJS.Types (castRef, JSRef(..))
+import GHCJS.Foreign (toJSBool, fromJSBool', jsNull, jsUndefined, toJSString)
+import GHCJS.Marshal (toJSRef)
+#else
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSValueRef
+       (jsvaluecreatejsonstring, JSType(..), jsvaluegettype,
+        jsvaluemakestring, jsvaluemakenumber, jsvaluemakeboolean,
+        jsvaluemakeundefined, jsvaluemakenull, jsvaluetoobject,
+        jsvaluetostringcopy, jsvaluetonumber, jsvaluetoboolean)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSStringRef
+       (jsstringcreatewithcharacters, jsstringgetcharactersptr,
+        jsstringgetlength)
+#endif
+import Language.Javascript.JSaddle.Monad (JSM, catchval)
+import Language.Javascript.JSaddle.Exception (rethrow)
+import Control.Monad.Trans.Reader (ask)
+import Control.Monad.IO.Class (MonadIO, MonadIO(..))
+import qualified Data.Text.Foreign as T (fromPtr)
+import Foreign (castPtr)
+import Data.Text.Foreign (useAsPtr)
+import Control.Applicative ((<$>))
+import Data.Text (Text)
+import qualified Data.Text as T (pack)
+import Language.Javascript.JSaddle.Classes
+       (MakeObjectRef(..), MakeStringRef(..), MakeValueRef(..),
+        MakeArgRefs(..))
+import Language.Javascript.JSaddle.String (strToText, textToStr)
+import Language.Javascript.JSaddle.Arguments ()
+import Data.Word (Word)
+
+data JSNull      = JSNull -- ^ Type that represents a value that can only be null.
+                          --   Haskell of course has no null so we are adding this type.
+type JSUndefined = ()     -- ^ A type that can only be undefined in JavaScript.  Using ()
+                          --   because functions in JavaScript that have no return, impicitly
+                          --   return undefined.
+type JSBool      = Bool   -- ^ JavaScript boolean values map the 'Bool' haskell type.
+type JSNumber    = Double -- ^ A number in JavaScript maps nicely to 'Double'.
+type JSString    = Text   -- ^ JavaScript strings can be represented with the Haskell 'Text' type.
+
+-- | An algebraic data type that can represent a JavaScript value.  Any JavaScriptCore
+--   'JSValueRef' can be converted into this type.
+data JSValue = ValNull                   -- ^ null
+             | ValUndefined              -- ^ undefined
+             | ValBool      JSBool       -- ^ true or false
+             | ValNumber    JSNumber     -- ^ a number
+             | ValString    JSString     -- ^ a string
+             | ValObject    JSObjectRef  -- ^ an object
+             deriving(Show, Eq)
+
+-- | Given a JavaScript value get its boolean value.
+--   All values in JavaScript convert to bool.
+--
+-- >>> testJSaddle $ valToBool JSNull
+-- false
+-- >>> testJSaddle $ valToBool ()
+-- false
+-- >>> testJSaddle $ valToBool True
+-- true
+-- >>> testJSaddle $ valToBool False
+-- false
+-- >>> testJSaddle $ valToBool (1.0 :: Double)
+-- true
+-- >>> testJSaddle $ valToBool (0.0 :: Double)
+-- false
+-- >>> testJSaddle $ valToBool ""
+-- false
+-- >>> testJSaddle $ valToBool "1"
+-- true
+valToBool :: MakeValueRef val => val -> JSM JSBool
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valToBool val = fromJSBool' <$> makeValueRef val
+#else
+valToBool val = do
+    gctxt <- ask
+    rval <- makeValueRef val
+    liftIO $ jsvaluetoboolean gctxt rval
+#endif
+
+-- | Given a JavaScript value get its numeric value.
+--   May throw JSException.
+--
+-- >>> testJSaddle $ show <$> valToNumber JSNull
+-- 0.0
+-- >>> testJSaddle $ show <$> valToNumber ()
+-- NaN
+-- >>> testJSaddle $ show <$> valToNumber True
+-- 1.0
+-- >>> testJSaddle $ show <$> valToNumber False
+-- 0.0
+-- >>> testJSaddle $ show <$> valToNumber (1.0 :: Double)
+-- 1.0
+-- >>> testJSaddle $ show <$> valToNumber (0.0 :: Double)
+-- 0.0
+-- >>> testJSaddle $ show <$> valToNumber ""
+-- 0.0
+-- >>> testJSaddle $ show <$> valToNumber "1"
+-- 1.0
+valToNumber :: MakeValueRef val => val -> JSM JSNumber
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+valToNumber val = jsrefToNumber <$> makeValueRef val
+foreign import javascript unsafe "$r = Number($1);" jsrefToNumber :: JSRef a -> Double
+#elif defined(USE_WEBKIT)
+valToNumber val = do
+    gctxt <- ask
+    rval <- makeValueRef val
+    rethrow $ liftIO . jsvaluetonumber gctxt rval
+#else
+valToNumber = undefined
+#endif
+
+-- | Given a JavaScript value get its string value (as a JavaScript string).
+--   May throw JSException.
+--
+-- >>> testJSaddle $ valToStr JSNull >>= strToText
+-- null
+-- >>> testJSaddle $ valToStr () >>= strToText
+-- undefined
+-- >>> testJSaddle $ valToStr True >>= strToText
+-- true
+-- >>> testJSaddle $ valToStr False >>= strToText
+-- false
+-- >>> testJSaddle $ valToStr (1.0 :: Double) >>= strToText
+-- 1
+-- >>> testJSaddle $ valToStr (0.0 :: Double) >>= strToText
+-- 0
+-- >>> testJSaddle $ valToStr "" >>= strToText
+--
+-- >>> testJSaddle $ valToStr "1" >>= strToText
+-- 1
+valToStr :: MakeValueRef val => val -> JSM JSStringRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+valToStr val = jsrefToString <$> makeValueRef val
+foreign import javascript unsafe "$r = $1.toString();" jsrefToString :: JSRef a -> JSStringRef
+#elif defined(USE_WEBKIT)
+valToStr val = do
+    gctxt <- ask
+    rval <- makeValueRef val
+    rethrow $ liftIO . jsvaluetostringcopy gctxt rval
+#else
+valToStr = undefined
+#endif
+
+-- | Given a JavaScript value get its string value (as a Haskell 'Text').
+--   May throw JSException.
+--
+-- >>> testJSaddle $ show <$> valToText JSNull
+-- "null"
+-- >>> testJSaddle $ show <$> valToText ()
+-- "undefined"
+-- >>> testJSaddle $ show <$> valToText True
+-- "true"
+-- >>> testJSaddle $ show <$> valToText False
+-- "false"
+-- >>> testJSaddle $ show <$> valToText (1.0 :: Double)
+-- "1"
+-- >>> testJSaddle $ show <$> valToText (0.0 :: Double)
+-- "0"
+-- >>> testJSaddle $ show <$> valToText ""
+-- ""
+-- >>> testJSaddle $ show <$> valToText "1"
+-- "1"
+valToText :: MakeValueRef val => val -> JSM Text
+valToText jsvar = valToStr jsvar >>= strToText
+
+-- | Given a JavaScript value get a JSON string value.
+--   May throw JSException.
+--
+-- >>> testJSaddle $ valToJSON 0 JSNull >>= strToText
+-- null
+-- >>> testJSaddle $ valToJSON 0 () >>= strToText
+--
+-- >>> testJSaddle $ valToJSON 0 True >>= strToText
+-- true
+-- >>> testJSaddle $ valToJSON 0 False >>= strToText
+-- false
+-- >>> testJSaddle $ valToJSON 0 (1.0 :: Double) >>= strToText
+-- 1
+-- >>> testJSaddle $ valToJSON 0 (0.0 :: Double) >>= strToText
+-- 0
+-- >>> testJSaddle $ valToJSON 0 "" >>= strToText
+-- ""
+-- >>> testJSaddle $ valToJSON 0 "1" >>= strToText
+-- "1"
+-- >>> testJSaddle $ obj >>= valToJSON 0 >>= strToText
+-- {}
+valToJSON :: MakeValueRef val => Word -> val -> JSM JSStringRef
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+valToJSON indent val = jsrefToJSON <$> makeValueRef val
+foreign import javascript unsafe "$r = JSON.stringify($1);" jsrefToJSON :: JSRef a -> JSStringRef
+#elif defined(USE_WEBKIT)
+valToJSON indent val = do
+    gctxt <- ask
+    rval <- makeValueRef val
+    rethrow $ liftIO . jsvaluecreatejsonstring gctxt rval (fromIntegral indent)
+#else
+valToJSON = undefined
+#endif
+
+-- | Given a JavaScript value get its object value.
+--   May throw JSException.
+--
+-- >>> testJSaddle $ (valToObject JSNull >>= valToText) `catch` \ (JSException e) -> valToText e
+-- TypeError: 'null' is not an object
+-- >>> testJSaddle $ (valToObject () >>= valToText) `catch` \ (JSException e) -> valToText e
+-- TypeError: 'undefined' is not an object
+-- >>> testJSaddle $ valToObject True
+-- true
+-- >>> testJSaddle $ valToObject False
+-- false
+-- >>> testJSaddle $ valToObject (1.0 :: Double)
+-- 1
+-- >>> testJSaddle $ valToObject (0.0 :: Double)
+-- 0
+-- >>> testJSaddle $ valToObject ""
+--
+-- >>> testJSaddle $ valToObject "1"
+-- 1
+valToObject :: MakeValueRef val => val -> JSM JSObjectRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valToObject val = castRef <$> makeValueRef val
+#else
+valToObject val = do
+    gctxt <- ask
+    rval <- makeValueRef val
+    rethrow $ liftIO . jsvaluetoobject gctxt rval
+#endif
+
+-- | Convert to a JavaScript value (just an alias for 'makeValueRef')
+val :: MakeValueRef value
+    => value          -- ^ value to convert to a JavaScript value
+    -> JSM JSValueRef
+val = makeValueRef
+
+-- | If we already have a JSValueRef we are fine
+instance MakeValueRef JSValueRef where
+    makeValueRef = return
+
+-- | A single JSValueRef can be used as the argument list
+instance MakeArgRefs JSValueRef where
+    makeArgRefs arg = return [arg]
+
+-- | JSValueRef can be made by evaluating a function in 'JSM' as long
+--   as it returns something we can make into a JSValueRef.
+instance MakeValueRef v => MakeValueRef (JSM v) where
+    makeValueRef v = v >>= makeValueRef
+
+----------- null ---------------
+-- | Make a @null@ JavaScript value
+valMakeNull :: JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valMakeNull = return jsNull
+#else
+valMakeNull = ask >>= (liftIO . jsvaluemakenull)
+#endif
+
+-- | Makes a @null@ JavaScript value
+instance MakeValueRef JSNull where
+    makeValueRef = const valMakeNull
+
+-- | Makes an argument list with just a single @null@ JavaScript value
+instance MakeArgRefs JSNull where
+    makeArgRefs _ = valMakeNull >>= (\ref -> return [ref])
+
+----------- undefined ---------------
+-- | Make an @undefined@ JavaScript value
+valMakeUndefined :: JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valMakeUndefined = return jsUndefined
+#else
+valMakeUndefined = ask >>= (liftIO . jsvaluemakeundefined)
+#endif
+
+-- | Makes an @undefined@ JavaScript value
+instance MakeValueRef JSUndefined where
+    makeValueRef = const valMakeUndefined
+
+--We can't allow this if JSUndefined is () as () is no args not "(null)".
+--Use [()] instead.
+--instance MakeArgRefs JSUndefined where
+--    makeArgRefs _ = valMakeUndefined >>= (\ref -> return [ref])
+
+-- | This allows us to pass no arguments easily (altenative would be to use @[]::[JSValueRef]@).
+instance MakeArgRefs () where
+    makeArgRefs _ = return []
+
+----------- booleans ---------------
+-- | Make a JavaScript boolean value
+valMakeBool :: JSBool -> JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valMakeBool b = return . castRef $ toJSBool b
+#else
+valMakeBool b = do
+    gctxt <- ask
+    liftIO $ jsvaluemakeboolean gctxt b
+#endif
+
+-- | Make a JavaScript boolean value
+instance MakeValueRef Bool where
+    makeValueRef = valMakeBool
+
+-- | Makes an argument list with just a single JavaScript boolean value
+instance MakeArgRefs Bool where
+    makeArgRefs b = valMakeBool b >>= (\ref -> return [ref])
+
+----------- numbers ---------------
+-- | Make a JavaScript number
+valMakeNumber :: JSNumber -> JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valMakeNumber n = liftIO $ castRef <$> toJSRef n
+#else
+valMakeNumber n = do
+    gctxt <- ask
+    liftIO $ jsvaluemakenumber gctxt n
+#endif
+
+-- | Makes a JavaScript number
+instance MakeValueRef Double where
+    makeValueRef = valMakeNumber
+
+-- | Makes an argument list with just a single JavaScript number
+instance MakeArgRefs Double where
+    makeArgRefs n = valMakeNumber n >>= (\ref -> return [ref])
+
+----------- numbers ---------------
+-- | Make a JavaScript string
+valMakeString :: Text -> JSM JSValueRef
+#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
+valMakeString = return . castRef . toJSString
+#else
+valMakeString text = do
+    gctxt <- ask
+    liftIO $ jsvaluemakestring gctxt (textToStr text)
+#endif
+
+-- | Makes a JavaScript string
+instance MakeValueRef Text where
+    makeValueRef = valMakeString
+
+-- | Makes an argument list with just a single JavaScript string
+instance MakeArgRefs Text where
+    makeArgRefs t = valMakeString t >>= (\ref -> return [ref])
+
+-- | Makes a JavaScript string
+instance MakeValueRef String where
+    makeValueRef = valMakeString . T.pack
+
+-- | Derefernce a value reference.
+--
+-- >>> testJSaddle $ show <$> deRefVal JSNull
+-- ValNull
+-- >>> testJSaddle $ show <$> deRefVal ()
+-- ValUndefined
+-- >>> testJSaddle $ show <$> deRefVal True
+-- ValBool True
+-- >>> testJSaddle $ show <$> deRefVal False
+-- ValBool False
+-- >>> testJSaddle $ show <$> deRefVal (1.0 :: Double)
+-- ValNumber 1.0
+-- >>> testJSaddle $ show <$> deRefVal (0.0 :: Double)
+-- ValNumber 0.0
+-- >>> testJSaddle $ show <$> deRefVal ""
+-- ValString ""
+-- >>> testJSaddle $ show <$> deRefVal "1"
+-- ValString "1"
+-- >>> testJSaddle $ show <$> valToObject True >>= deRefVal
+-- ValObject 0x...
+deRefVal :: MakeValueRef val => val -> JSM JSValue
+#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
+deRefVal val = do
+    gctxt <- ask
+    valref <- makeValueRef val
+    case (jsrefGetType valref :: Int) of
+        0 -> return ValUndefined
+        1 -> return ValNull
+        2 -> ValBool   <$> valToBool valref
+        3 -> ValNumber <$> valToNumber valref
+        4 -> ValString <$> (valToStr valref >>= strToText)
+        5 -> ValObject <$> valToObject valref
+foreign import javascript unsafe "$r = ($1 === undefined)?0:\
+                                       ($1===null)?1:\
+                                       (typeof $1===\"boolean\")?2:\
+                                       (typeof $1===\"number\")?3:\
+                                       (typeof $1===\"string\")?4:\
+                                       (typeof $1===\"object\")?5:-1;" jsrefGetType :: JSValueRef -> Int
+#elif defined(USE_WEBKIT)
+deRefVal val = do
+    gctxt <- ask
+    valref <- makeValueRef val
+    t <- liftIO $ jsvaluegettype gctxt valref
+    case t of
+        Kjstypenull      -> return ValNull
+        Kjstypeundefined -> return ValUndefined
+        Kjstypeboolean   -> ValBool   <$> valToBool valref
+        Kjstypenumber    -> ValNumber <$> valToNumber valref
+        Kjstypestring    -> ValString <$> (valToStr valref >>= strToText)
+        Kjstypeobject    -> ValObject <$> valToObject valref
+#else
+deRefVal = undefined
+#endif
+
+-- | Make a JavaScript value out of a 'JSValue' ADT.
+--
+-- >>> testJSaddle $ valMakeRef ValNull
+-- "null"
+-- >>> testJSaddle $ valMakeRef ValUndefined
+-- "undefined"
+-- >>> testJSaddle $ valMakeRef (ValBool True)
+-- "true"
+-- >>> testJSaddle $ valMakeRef (ValNumber 1)
+-- "1"
+-- >>> testJSaddle $ valMakeRef (ValString $ pack "Hello")
+-- "Hello"
+valMakeRef :: JSValue -> JSM JSValueRef
+valMakeRef val =
+    case val of
+        ValNull      -> valMakeNull
+        ValUndefined -> valMakeUndefined
+        ValBool b    -> valMakeBool b
+        ValNumber n  -> valMakeNumber n
+        ValString s  -> valMakeString s
+        ValObject o  -> return o
+
+-- | Makes a JavaScript value from a 'JSValue' ADT.
+instance MakeValueRef JSValue where
+    makeValueRef = valMakeRef
+
+-- | Makes an argument list with just a single JavaScript value from a 'JSValue' ADT.
+instance MakeArgRefs JSValue where
+    makeArgRefs v = valMakeRef v >>= (\ref -> return [ref])
+
+instance MakeObjectRef JSNull where
+    makeObjectRef = const valMakeNull
+
diff --git a/tests/TestJSaddle.hs b/tests/TestJSaddle.hs
new file mode 100644
--- /dev/null
+++ b/tests/TestJSaddle.hs
@@ -0,0 +1,141 @@
+{-# LANGUAGE RecordWildCards #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  TestJSC
+-- Copyright   :  (c) Hamish Mackenzie
+-- License     :  MIT
+--
+-- Maintainer  :  Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Main (
+    main
+) where
+
+import Prelude hiding((!!), catch)
+import Graphics.UI.Gtk
+       (Window, widgetDestroy, postGUIAsync, postGUISync, widgetShowAll,
+        mainGUI, mainQuit, on, objectDestroy, containerAdd, scrolledWindowNew,
+        windowSetPosition, windowSetDefaultSize, timeoutAddFull, windowNew,
+        initGUI)
+import Control.Concurrent
+       (tryTakeMVar, forkIO, newMVar, putMVar, takeMVar, newEmptyMVar,
+        yield)
+import System.Glib.MainLoop (priorityHigh)
+import Graphics.UI.Gtk.General.Enums (WindowPosition(..))
+import Graphics.UI.Gtk.WebKit.WebView
+       (webViewGetMainFrame, webViewNew)
+import System.IO.Unsafe (unsafePerformIO)
+import Control.Monad.Trans.Reader (runReaderT)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSBase (JSContextRef)
+import Graphics.UI.Gtk.WebKit.JavaScriptCore.WebFrame
+       (webFrameGetGlobalContext)
+import Language.Javascript.JSaddle
+import Data.Text (Text)
+import qualified Data.Text as T
+import Control.Applicative
+import Control.Monad.IO.Class (MonadIO(..))
+import Control.Monad (forM, when)
+import System.Log.Logger (debugM)
+import Control.Lens.Getter ((^.))
+import Data.Monoid ((<>))
+
+data TestState = TestState { jsContext :: JSContextRef, window :: Window }
+
+state = unsafePerformIO $ newMVar Nothing
+done = unsafePerformIO $ newEmptyMVar
+
+-- >>> testJSaddle $ ((global ^. js "console" . js "log") # ["Hello"])
+testJSaddle :: MakeValueRef val => JSM val -> IO ()
+testJSaddle = testJSaddle' False
+
+-- >>> showJSaddle $ eval "document.body.innerHTML = 'Test'"
+showJSaddle :: MakeValueRef val => JSM val -> IO ()
+showJSaddle = testJSaddle' True
+
+debugLog = debugM "jsaddle"
+
+testJSaddle' :: MakeValueRef val => Bool -> JSM val -> IO ()
+testJSaddle' showWindow f = do
+    debugLog "taking done"
+    tryTakeMVar done
+    debugLog "taking state"
+    mbState <- takeMVar state
+    TestState {..} <- case mbState of
+        Nothing -> do
+            debugLog "newState"
+            newState <- newEmptyMVar
+            debugLog "fork"
+            forkIO $ do
+                debugLog "initGUI"
+                initGUI
+                debugLog "windowNew"
+                window <- windowNew
+                debugLog "timeoutAdd"
+                timeoutAddFull (yield >> return True) priorityHigh 10
+                windowSetDefaultSize window 900 600
+                windowSetPosition window WinPosCenter
+                scrollWin <- scrolledWindowNew Nothing Nothing
+                webView <- webViewNew
+                window `containerAdd` scrollWin
+                scrollWin `containerAdd` webView
+                on window objectDestroy $ do
+                    debugLog "onDestroy"
+                    tryTakeMVar state
+                    debugLog "put state"
+                    putMVar state Nothing
+                    debugLog "mainQuit"
+                    mainQuit
+                    debugLog "put done"
+                    putMVar done ()
+                    return True
+                debugLog "get context"
+                jsContext <- webViewGetMainFrame webView >>= webFrameGetGlobalContext
+                debugLog "put initial state"
+                putMVar newState TestState {..}
+                debugLog "maybe show"
+                when showWindow $ widgetShowAll window
+                debugLog "mainGUI"
+                mainGUI
+                debugLog "mainGUI exited"
+            takeMVar newState
+        Just s@TestState {..} -> do
+            debugLog "maybe show (2)"
+            when showWindow . postGUISync $ widgetShowAll window
+            return s
+    x <- postGUISync $ runReaderT ((f >>= valToText >>= liftIO . putStrLn . T.unpack)
+            `catch` \ (JSException e) -> valToText e >>= liftIO . putStrLn . T.unpack) jsContext
+    debugLog "put state"
+    putMVar state $ Just TestState {..}
+    return x
+
+main = do
+    testJSaddle $ return ()
+    Just TestState{..} <- takeMVar state
+    postGUIAsync $ widgetDestroy window
+    takeMVar done
+
+listWindowProperties = testJSaddle $ T.pack . show <$> do
+  window <- jsg "window"
+  names <- propertyNames window
+  forM names $ \name -> do
+        v <- window ^. js name >>= valToText
+        n <- strToText name
+        return (n, v)
+    `catch`
+        \(JSException e) -> do
+            n <- strToText name
+            msg <- valToText e
+            return (n, (T.pack $ " error ") <> msg)
+
+
+
+
+
+
+
+
+
