diff --git a/Network/CURL000.hs b/Network/CURL000.hs
new file mode 100644
--- /dev/null
+++ b/Network/CURL000.hs
@@ -0,0 +1,23 @@
+-------------------------------------------------------------------------------
+-- |
+-- Module      :  Network.CURL000
+-- Copyright   :  Copyright © 2012-2014 Krzysztof Kardzis
+-- License     :  ISC License (MIT/BSD-style, see LICENSE file for details)
+-- 
+-- Maintainer  :  Krzysztof Kardzis <kkardzis@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- <<http://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURL000>>
+-------------------------------------------------------------------------------
+
+module Network.CURL000 (
+  -----------------------------------------------------------------------------
+  -- * Run-Time Linking
+  -----------------------------------------------------------------------------
+    module Network.CURL000.LibLD
+
+  ) where
+
+import Network.CURL000.LibLD
+
diff --git a/Network/CURL000/LibHS.hsc b/Network/CURL000/LibHS.hsc
--- a/Network/CURL000/LibHS.hsc
+++ b/Network/CURL000/LibHS.hsc
@@ -542,7 +542,7 @@
   #{setopt CURLOPT_ISSUERCERT             , string   }
   #{setopt CURLOPT_CAPATH                 , string   }
   #{setopt CURLOPT_CRLFILE                , string   }
-  #{setopt CURLOPT_SSL_VERIFYHOST         , clong    }
+  #{setopt CURLOPT_SSL_VERIFYHOST         , bool2    }
   #{setopt CURLOPT_CERTINFO               , bool     }
   #{setopt CURLOPT_RANDOM_FILE            , string   }
   #{setopt CURLOPT_EGDSOCKET              , string   }
@@ -574,10 +574,12 @@
     ---------------------------------------------------------------------------
     enum  ccurl copt x = C.curl_easy_setopt'Long ccurl copt (toCLong      x)
     bool  ccurl copt x = C.curl_easy_setopt'Long ccurl copt (fromBool     x)
+    bool2 ccurl copt x = C.curl_easy_setopt'Long ccurl copt (fromBool2    x)
     time  ccurl copt x = C.curl_easy_setopt'Long ccurl copt (fromUTCTime  x)
     clong ccurl copt x = C.curl_easy_setopt'Long ccurl copt (fromIntegral x)
     int64 ccurl copt x = C.curl_easy_setopt'COff ccurl copt (fromIntegral x)
     fromUTCTime = truncate . utcTimeToPOSIXSeconds
+    fromBool2 False = 0; fromBool2 True = 2
     ---------------------------------------------------------------------------
     string ccurl copt x = withCAString x $ \p ->
       C.curl_easy_setopt'DPtr ccurl copt (castPtr p)
diff --git a/Network/CURL000/Types.hsc b/Network/CURL000/Types.hsc
--- a/Network/CURL000/Types.hsc
+++ b/Network/CURL000/Types.hsc
@@ -628,7 +628,7 @@
   | CURLOPT_ISSUERCERT              FilePath
   | CURLOPT_CAPATH                  FilePath
   | CURLOPT_CRLFILE                 FilePath
-  | CURLOPT_SSL_VERIFYHOST          CLong
+  | CURLOPT_SSL_VERIFYHOST          Bool
   | CURLOPT_CERTINFO                Bool
   | CURLOPT_RANDOM_FILE             FilePath
   | CURLOPT_EGDSOCKET               String
diff --git a/Network/CURL720.hs b/Network/CURL720.hs
--- a/Network/CURL720.hs
+++ b/Network/CURL720.hs
@@ -8,25 +8,22 @@
 -- Stability   :  experimental
 -- Portability :  non-portable
 --
--- <<https://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURL720>>
+-- <<http://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURL720>>
 -------------------------------------------------------------------------------
 
 module Network.CURL720
-  ( module Network.CURLXXX
+  ( module Network.CURL000
 
   -- |
-  -- To use functions from this module it is required to explicitly link
-  -- with @libcurl\/7.20@ (or newer) at runtime. So first things first:
+  -- Using functions from this module requires an explicit linking
+  -- with @libcurl\/7.20@ or newer at program runtime:
   --
   -- > main = withlib CURL720 $ do
   -- >   ...
   --
-  -- Without such statement any use of the 'curl*' functions will fail.
-  -- Runtime linker will first try to load @libcurl@ binary image into
-  -- memory and after succesful loading, library version will be checked.
-  -- Standard dynamic loader search path is used to locate required
-  -- so\/dll\/dylib. Just install libcurl.so\/dll\/dylib into one of
-  -- the searched places (could be current directory).
+  -- Without that, any foreign call to @libcurl@ will fail.
+  --
+  -- More info may be found in the <docs>.
 
  
 -------------------------------------------------------------------------------
@@ -521,5 +518,5 @@
 
 import Network.CURL000.LibHS
 import Network.CURL000.Types
-import Network.CURLXXX
+import Network.CURL000
 
diff --git a/Network/CURL730.hs b/Network/CURL730.hs
--- a/Network/CURL730.hs
+++ b/Network/CURL730.hs
@@ -8,25 +8,22 @@
 -- Stability   :  experimental
 -- Portability :  non-portable
 --
--- <<https://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURL730>>
+-- <<http://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURL730>>
 -------------------------------------------------------------------------------
 
 module Network.CURL730
-  ( module Network.CURLXXX
+  ( module Network.CURL000
 
   -- |
-  -- To use functions from this module it is required to explicitly link
-  -- with @libcurl\/7.30@ (or newer) at runtime. So first things first:
+  -- Using functions from this module requires an explicit linking
+  -- with @libcurl\/7.30@ or newer at program runtime:
   --
   -- > main = withlib CURL730 $ do
   -- >   ...
   --
-  -- Without such statement any use of the 'curl*' functions will fail.
-  -- Runtime linker will first try to load @libcurl@ binary image into
-  -- memory and after succesful loading, library version will be checked.
-  -- Standard dynamic loader search path is used to locate required
-  -- so\/dll\/dylib. Just install libcurl.so\/dll\/dylib into one of
-  -- the searched places (could be current directory).
+  -- Without that, any foreign call to @libcurl@ will fail.
+  --
+  -- More info may be found in the <docs>.
 
 
 -------------------------------------------------------------------------------
@@ -571,5 +568,5 @@
 
 import Network.CURL000.LibHS
 import Network.CURL000.Types
-import Network.CURLXXX
+import Network.CURL000
 
diff --git a/Network/CURLXXX.hs b/Network/CURLXXX.hs
deleted file mode 100644
--- a/Network/CURLXXX.hs
+++ /dev/null
@@ -1,23 +0,0 @@
--------------------------------------------------------------------------------
--- |
--- Module      :  Network.CURLXXX
--- Copyright   :  Copyright © 2012-2014 Krzysztof Kardzis
--- License     :  ISC License (MIT/BSD-style, see LICENSE file for details)
--- 
--- Maintainer  :  Krzysztof Kardzis <kkardzis@gmail.com>
--- Stability   :  experimental
--- Portability :  non-portable
---
--- <<https://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs/CURLXXX>>
--------------------------------------------------------------------------------
-
-module Network.CURLXXX (
-  -----------------------------------------------------------------------------
-  -- * Run-Time Linking
-  -----------------------------------------------------------------------------
-    module Network.CURL000.LibLD
-
-  ) where
-
-import Network.CURL000.LibLD
-
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,15 +1,23 @@
-# Network.CURL [![Build Status][travis.img]][travis.htm]
+# Network.CURL [![Hackage][hackage.img]][hackage.htm] [![Build Status][travis.img]][travis.htm]
 
-Package *curlhs* provides Haskell bindings to *libcurl*, the multiprotocol
-file transfer library which powers the popular tool *curl*
-(see http://curl.haxx.se/libcurl for more info).
+Package [*curlhs*][hackage.htm] provides a mid-level [Haskell][haskell.htm]
+interface to *libcurl*, the multiprotocol file transfer library which powers
+the popular tool *curl* (please see <http://curl.haxx.se/> for more info
+about *curl* and *libcurl*).
 
+# Documentation
+More info about *curlhs*, such as tutorials or examples, may be found in the
+[docs](docs) section. Please check out the short [tutorial](docs/tutorial.md)
+about installation and basic usage of *curlhs* and *libcurl*.
 
-[![Analytics][ga.img]][ga.htm]
 
-[ga.img]: https://ga-beacon.appspot.com/UA-53767359-1/github/curlhs
-[ga.htm]: https://github.com/igrigorik/ga-beacon
 
 [travis.img]: https://travis-ci.org/kkardzis/curlhs.svg
 [travis.htm]: https://travis-ci.org/kkardzis/curlhs
 
+[hackage.img]: https://img.shields.io/hackage/v/curlhs.svg
+[hackage.htm]: https://hackage.haskell.org/package/curlhs
+
+[haskell.htm]: http://www.haskell.org/
+
+![GA](https://ga-beacon.appspot.com/UA-53767359-1/curlhs/readme)
diff --git a/curlhs.cabal b/curlhs.cabal
--- a/curlhs.cabal
+++ b/curlhs.cabal
@@ -1,24 +1,29 @@
-name:           curlhs
-version:        0.1.1
-synopsis:       bindings to libcurl, the multiprotocol file transfer library
-author:         Krzysztof Kardzis <kkardzis@gmail.com>
-maintainer:     Krzysztof Kardzis <kkardzis@gmail.com>
-copyright:      Copyright © 2012-2014 Krzysztof Kardzis
--- license:     ISC License (MIT/BSD-style, see LICENSE file for details)
-license:        OtherLicense
-license-file:   LICENSE
-category:       Network
-stability:      Experimental
-build-type:     Simple
-cabal-version:  >=1.6
-homepage:       https://kkardzis.github.com/curlhs
+name:          curlhs
+version:       0.1.2
+synopsis:      bindings to libcurl, the multiprotocol file transfer library
+homepage:      https://kkardzis.github.com/curlhs
+category:      Network
 
+author:        Krzysztof Kardzis <kkardzis@gmail.com>
+maintainer:    Krzysztof Kardzis <kkardzis@gmail.com>
+copyright:     Copyright © 2012-2014 Krzysztof Kardzis
+-- license:    ISC License (MIT/BSD-style, see LICENSE file for details)
+license:       OtherLicense
+license-file:  LICENSE
+
+stability:     Experimental
+build-type:    Simple
+cabal-version: >=1.8
+-- should be >=1.18 actually, because of 'extra-doc-files', but oh well...
+
 description:
-  Package @curlhs@ provides a mid-level interface to @libcurl@, the
-  multiprotocol file transfer library which powers the popular tool @curl@
-  (please see <http://curl.haxx.se/> for more info). As described on the
-  @libcurl@'s project site (<http://curl.haxx.se/libcurl/>):
+  Package @curlhs@ provides a mid-level Haskell interface to @libcurl@,
+  the multiprotocol file transfer library which powers the popular tool
+  @curl@ (please see <http://curl.haxx.se/> for more info about @curl@
+  and @libcurl@). As described on the @libcurl@ project site:
   .
+  >
+  .
   /libcurl is a free and easy-to-use client-side URL transfer library,       /
   /supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, /
   /LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.  /
@@ -36,23 +41,30 @@
   /supported, fast, thoroughly documented and is already used by many        /
   /known, big and successful companies and numerous applications.            /
   .
-  Package is distributed under ISC License (MIT/BSD-style, see LICENSE file
-  for details). It is marked as @OtherLicense@ due to limitations of Cabal.
+  >
   .
-  <<https://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs>>
+  More info about @curlhs@, such as tutorials or examples, may be found
+  in the <docs> section (if on Hackage try <docs/docs> or <src/docs>).
+  .
+  Package is distributed under the
+  <http://choosealicense.com/licenses/isc/ ISC License>
+  (MIT\/BSD-style, see <src/LICENSE LICENSE> file for details).
+  .
+  <<http://ga-beacon.appspot.com/UA-53767359-1/hackage/curlhs>>
 
+
+-------------------------------------------------------------------------------
 extra-source-files:
   Network/CURL000/curl-7.30.0/COPYING
-  Network/CURL000/curl-7.30.0/curl.h
-  Network/CURL000/curl-7.30.0/curlbuild.h
-  Network/CURL000/curl-7.30.0/curlrules.h
-  Network/CURL000/curl-7.30.0/curlver.h
-  Network/CURL000/curl-7.30.0/easy.h
-  Network/CURL000/curl-7.30.0/multi.h
-  Network/CURL000/curl-7.30.0/stdcheaders.h
-  Network/CURL000/curl-7.30.0/typecheck-gcc.h
+  Network/CURL000/curl-7.30.0/*.h
+
+extra-doc-files:
+  docs/examples/*.hs
+  docs/index.htm
+  docs/*.md
   README.md
 
+-------------------------------------------------------------------------------
 library
   ghc-options: -Wall -fwarn-tabs
   build-tools: hsc2hs
@@ -61,9 +73,9 @@
     base ==4.*, rtld, bytestring, time
 
   exposed-modules:
+    Network.CURL000
     Network.CURL720
     Network.CURL730
-    Network.CURLXXX
 
   other-modules:
     Network.CURL000.LibCC
@@ -77,6 +89,22 @@
   include-dirs:
     Network/CURL000
 
+
+-------------------------------------------------------------------------------
+test-suite hspec
+  type:           exitcode-stdio-1.0
+  build-depends:  base, hspec, curlhs
+  ghc-options:    -Wall -fwarn-tabs
+  main-is:        Spec.hs
+  hs-source-dirs: test
+
+  other-modules:
+    Network.CURL000Spec
+    Network.CURL720Spec
+    Network.CURL730Spec
+
+
+-------------------------------------------------------------------------------
 source-repository head
   location: https://github.com/kkardzis/curlhs
   type:     git
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,34 @@
+# Documentation
+
+This is the documentation section of the [*curlhs*][hackage.htm] package.
+There is not much here right now, but this should change over time.
+
+Please check out the short [tutorial](tutorial.md) about installation
+and basic usage of *curlhs* and *libcurl*.
+
+
+# Examples
+
+The examples below are translations to Haskell of the examples found at
+<http://curl.haxx.se/libcurl/c/example.html>.
+
+### simple HTTP
+
+[Simple.hs](examples/Simple.hs)
+shows how to get a remote web page in only four libcurl function calls.
+
+### simple HTTPS
+
+[Https.hs](examples/Https.hs)
+gets a single HTTPS page.
+
+### get a remote file in memory only
+[GetInMemory.hs](examples/GetInMemory.hs)
+describes how you can use the callback system to fetch documents
+into a ram buffer with no file writing necessary.
+
+
+
+[hackage.htm]: https://hackage.haskell.org/package/curlhs
+
+![GA](https://ga-beacon.appspot.com/UA-53767359-1/curlhs/docs/readme)
diff --git a/docs/examples/GetInMemory.hs b/docs/examples/GetInMemory.hs
new file mode 100644
--- /dev/null
+++ b/docs/examples/GetInMemory.hs
@@ -0,0 +1,47 @@
+-------------------------------------------------------------------------------
+-- Based on <http://curl.haxx.se/libcurl/c/getinmemory.html>
+-- Example source code to show how the callback function can be used to
+-- download data into a chunk of memory instead of storing it in a file.
+-------------------------------------------------------------------------------
+
+module GetInMemory where
+
+import qualified Data.ByteString.Lazy.Char8 as BL
+import qualified Data.ByteString.Builder    as BB
+
+import Control.Exception
+import Data.Monoid
+import Data.IORef
+
+import Network.CURL720
+
+
+main = withlib CURL720 $ do
+  lbs <- curlGET "http://httpbin.org/get"
+  BL.putStrLn lbs
+
+
+curlGET :: String -> IO BL.ByteString
+curlGET url =
+  bracket (curl_easy_init) (curl_easy_cleanup) $ \curl -> do
+    ref <- newIORef mempty
+    curl_easy_setopt curl
+      [ CURLOPT_URL url
+      -- specify URL to get
+ 
+      , CURLOPT_WRITEFUNCTION $ Just (memwrite ref)
+      -- send all data to this function
+ 
+      , CURLOPT_USERAGENT "libcurl-agent/1.0"
+      -- some servers don't like requests that are made without a user-agent
+      -- field, so we provide one
+      ]
+    curl_easy_perform curl
+    fmap BB.toLazyByteString (readIORef ref)
+
+
+memwrite :: IORef BB.Builder -> CURL_write_callback
+memwrite ref bs = do
+  modifyIORef ref (flip mappend (BB.byteString bs))
+  return CURL_WRITEFUNC_OK
+
diff --git a/docs/examples/Https.hs b/docs/examples/Https.hs
new file mode 100644
--- /dev/null
+++ b/docs/examples/Https.hs
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+-- Based on <http://curl.haxx.se/libcurl/c/https.html>
+-- Gets a single HTTPS page.
+-------------------------------------------------------------------------------
+
+module Https where
+
+import Network.CURL720
+
+
+main = withlib CURL720 $ do
+  curl <- curl_easy_init
+  curl_easy_setopt curl
+    [ CURLOPT_URL "https://httpbin.org/get"
+
+    , CURLOPT_SSL_VERIFYPEER True
+    -- If you want to connect to a site who isn't using a certificate that is
+    -- signed by one of the certs in the CA bundle you have, you can skip the
+    -- verification of the server's certificate. This makes the connection
+    -- A LOT LESS SECURE.
+    --
+    -- If you have a CA cert for the server stored someplace else than in the
+    -- default bundle, then the CURLOPT_CAPATH option might come handy for
+    -- you.
+
+    , CURLOPT_SSL_VERIFYHOST True
+    -- If the site you're connecting to uses a different host name that what
+    -- they have mentioned in their server certificate's commonName (or
+    -- subjectAltName) fields, libcurl will refuse to connect. You can skip
+    -- this check, but this will make the connection less secure.
+
+    ]
+  curl_easy_perform curl
+  curl_easy_cleanup curl
+
diff --git a/docs/examples/Simple.hs b/docs/examples/Simple.hs
new file mode 100644
--- /dev/null
+++ b/docs/examples/Simple.hs
@@ -0,0 +1,19 @@
+-------------------------------------------------------------------------------
+-- Based on <http://curl.haxx.se/libcurl/c/simple.html>
+-- Shows how to get a remote web page in only four libcurl function calls.
+-------------------------------------------------------------------------------
+
+module Simple where
+
+import Network.CURL720
+
+
+main = withlib CURL720 $ do
+  curl <- curl_easy_init
+  curl_easy_setopt curl
+    [ CURLOPT_URL "http://httpbin.org/get"
+    , CURLOPT_FOLLOWLOCATION True
+    ]
+  curl_easy_perform curl
+  curl_easy_cleanup curl
+
diff --git a/docs/index.htm b/docs/index.htm
new file mode 100644
--- /dev/null
+++ b/docs/index.htm
@@ -0,0 +1,85 @@
+<!DOCTYPE html><!-- Simple Markdown Browser by Krzysztof Kardzis -->
+<html ng-app="App" ng-controller="AppCtrl">
+
+<head>
+<meta charset="utf-8">
+<title ng-bind="mdpage"></title>
+<link rel="stylesheet" ng-href="{{github1css}}">
+<link rel="stylesheet" ng-href="{{github2css}}">
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/2.0.2/octicons.min.css">
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-53767359-2', 'auto');
+</script>
+</head>
+
+<body>
+
+<div ng-show="ready" class="container" style="padding-top:20px">
+  <div id="readme" class="boxed-group ng-cloak">
+    <h3>
+      <span class="octicon octicon-book"></span>
+      <a ng-href="{{mdfile}}">{{mdfile}}</a>
+    </h3>
+    <article class="markdown-body" ng-bind-html="mdhtml"></article>
+  </div>
+</div>
+
+<script>
+angular.module('App', []).controller('AppCtrl',
+function ($scope, $http, $location, $anchorScroll, $sce, $timeout) {
+  $http.get('https://cors-anywhere.herokuapp.com/https://github.com').
+    error(function(raw) { $scope.ready = true; }).
+    success(function(raw) {
+      var reg = /href="([^"]+github2?-[^"]+\.css)"/g;
+      var cs1; if (cs1=reg.exec(raw)) {$scope.github1css = cs1[1];};
+      var cs2; if (cs2=reg.exec(raw)) {$scope.github2css = cs2[1];};
+      var css = getComputedStyle(document.getElementById('readme'));
+      var check = function () {
+        var ready = css.position === 'relative';
+        if (ready) { $scope.ready = true; } else { $timeout(check, 10); };
+      }; $timeout(check, 10);
+    });
+  $scope.cache = {};
+  $scope.$on('$locationChangeSuccess', function() {
+    var mdfile = $location.path().replace(/^\//, '') || 'README.md';
+    var mdlink = $location.absUrl().replace(/\/\#\//, '/');
+    var mdpage = 'curlhs: ' + mdfile;
+    ga('send', 'pageview', {'location': mdlink, 'title': mdpage});
+    var mdshow = function () {
+      $scope.mdfile = mdfile; $scope.mdpage = mdpage;
+      $scope.mdhtml = $scope.cache[mdfile]
+      $timeout($anchorScroll);
+    };
+    if ($scope.cache[mdfile]) { mdshow(); } else {
+      var onfail = function(data, statusnum, headers, config, statustxt) {
+        $scope.mdfile = mdfile; $scope.mdpage = mdpage;
+        $scope.mdhtml = $sce.trustAsHtml
+          ( '<h1>' + statusnum.toString() + ' - ' + statustxt + '</h1>'
+          + '<pre>' + config.method + ' ' + config.url + '</pre>'
+          + '<pre>' + JSON.stringify(headers(), null, 2) + '</pre>');
+      };
+      $http.get(mdfile).error(onfail).success(function(raw) {
+        var cfg = {'headers':{'content-type':'text/plain'}};
+        var url = 'https://api.github.com/markdown/raw';
+        var ext; if (ext=/\.([^\.]+)$/.exec(mdfile)) {ext = ext[1];};
+        if (ext !== 'md') {raw = '```' + ext + '\n' + raw + '\n```';};
+        raw = raw.replace('UA-53767359-1', 'UA-53767359-1/hackage');
+        $http.post(url, raw, cfg).error(onfail).success(function(data) {
+          $scope.cache[mdfile] = $sce.trustAsHtml(data
+            .replace(/(href="#)([^"]+")/g,'$1/'+mdfile+'#$2 id="$2')
+            .replace(/(href="(?![\/#]))([^":]+")/g,'$1#/$2')
+          ); mdshow();
+        });
+      });
+    };
+  });
+});
+</script>
+
+</body>
+</html>
diff --git a/docs/tutorial.md b/docs/tutorial.md
new file mode 100644
--- /dev/null
+++ b/docs/tutorial.md
@@ -0,0 +1,256 @@
+# What is *curlhs*?
+
+*curlhs* is a [Haskell][haskell.htm] library that provides
+a [Haskell][haskell.htm] interface to *libcurl* - the multiprotocol
+file transfer library.
+
+> *libcurl* is most probably the most portable, most powerful
+> and most often used C-based multi-platform file transfer library
+> on this planet - be it open source or commercial. 
+
+The main *libcurl* web site is at <http://curl.haxx.se/libcurl/>
+and it contains a vast amount of documentation and resources.
+It is highly recommended to be familiar with those materials
+to comfortably use *curlhs*.
+
+
+# How to install?
+
+*curlhs* is written in the [Haskell][haskell.htm] programming language
+and requires the Haskell compiler [GHC][ghc.htm] and the Haskell's
+package manager [Cabal][cabal.htm] to build. The easiest way to get
+them is with the [Haskell Platform][platform.htm] binary installer.
+
+If you already have Cabal set up, then getting *curlhs*
+should be as simple as running two commands:
+
+```sh
+$ cabal update
+$ cabal install curlhs
+```
+
+This will download and install the latest *curlhs* package from
+[Hackage][hackage.htm].
+
+The most recent *curlhs* can be installed from GitHub:
+
+```sh
+$ git clone https://github.com/kkardzis/curlhs.git
+$ git clone https://github.com/kkardzis/rtld.git
+$ cabal update && cabal install ./rtld ./curlhs
+```
+
+One way or another, installation should pass without complications.
+Tested on Windows, FreeBSD and Linux ([travis-ci][travis.htm]).
+
+
+# Does it work?
+
+To see if *curlhs* works, let's try to check *libcurl* version. Run GHCi:
+
+```sh
+$ ghci
+```
+
+The simple call to `curl_version` should return the *libcurl* version string:
+
+```hs
+ghci> :m Network.CURL720
+ghci> curl_version
+*** Exception: <curlhs> failed to call 'curl_version' (NULL)
+```
+
+Obviously not what was expected. But what's wrong?
+The short answer is that *libcurl* was not loaded before use.
+*curlhs* depends on *libcurl*, but does not link with it at compile/build
+time like usually. It is required to explicitly load *libcurl* at runtime.
+So let's try:
+
+```hs
+ghci> loadlib CURL720
+*** Exception: <curlhs> failed to load libcurl/7.20 ["libcurl.dll"]
+```
+
+What now? Let's assume we are on Windows, where *libcurl* is not installed
+by default. Dynamic loader searchs for "libcurl.dll", but it cannot find
+it in the default search path. It's time to install *libcurl*.
+
+
+# Where is *libcurl*?
+
+### Windows
+
+Using *libcurl* from Haskell was always a pain on Windows. But not anymore.
+With *curlhs* it's now easy to use them together. All that *curlhs* needs
+to work is a "libcurl.dll" with its dependencies like SSL, SSH etc.
+
+*libcurl* can be build from sources of course, but the recommended
+way is to search for the precompiled binaries for Windows.
+Good place to start may be at <http://www.confusedbycode.com/curl/>.
+
+Be carefull however. *libcurl* uses many different libraries behind the scenes 
+to do its work, some of them may be optional, some none. It may be build
+with different implementations of SSL for example, or even without SSL
+support at all. The same with other features, so pay attention to how
+a package was build and that all dependencies are included.
+
+Good choice, though not the latest now, are these packages from
+<http://curl.haxx.se/download.html>:
+
+* <http://curl.haxx.se/gknw.net/7.34.0/dist-w32/curl-7.34.0-devel-mingw32.zip>
+* <http://curl.haxx.se/gknw.net/7.34.0/dist-w64/curl-7.34.0-devel-mingw64.7z>
+
+For Win32 for example in 'curl-7.34.0-devel-mingw32\bin\' we have:
+
+* libcurl.dll
+* libeay32.dll
+* libidn-11.dll
+* librtmp.dll
+* libssh2.dll
+* ssleay32.dll
+* zlib1.dll
+
+Where to put those dll's? Please refer to the `LoadLibrary` function
+documentation on MSDN for exhaustive information about the default
+search path used to locate the libraries in Windows. Three notable
+places where Windows looks for the dll's are:
+
+* the directory from which the application was loaded (where the exe is)
+* the directories listed in the PATH environment variable
+* the current directory
+
+That's it. To test just `cd` into the directory where those dll's
+are placed and run GHCi from there.
+
+
+### Linux
+
+In the unix world *libcurl* is a widely used library and is probably
+installed by default, or as a dependency for some tool, notably the
+popular tool *curl*. To check it, use the command `curl --version`.
+In case *libcurl* is not installed, the easiest way to get it and its
+dependencies, is with the system package manager like *apt-get*, *yum*
+or similar. For example:
+
+```sh
+$ apt-get update
+$ apt-get install curl
+```
+
+On Linux systems *curlhs* searchs for "libcurl.so.4" or "libcurl.so"
+(in that order). Default search path is implementation dependent.
+Please refer to the `dlopen` man page for more information.
+
+
+### BSD
+
+Like on Linux systems: first check if *libcurl* is not installed already,
+for example with `curl --version`, and if it's not, use the system package
+manager to install it. For example:
+
+```sh
+$ pkg update
+$ pkg install curl
+```
+
+On BSD systems *curlhs* searchs for "libcurl.so". Please refer to
+the `dlopen` man page for information about the default search path
+used to locate libraries.
+
+### OS X
+
+On OS X system *curlhs* searchs for "libcurl.dylib".
+
+Disclaimer: this platform was not tested, sorry.
+
+
+# It works? Really?
+
+Now, when *libcurl* is in the scope, let's try again. Let's assume we
+are on Windows with "libcurl/7.34" like in the example above. Run GHCi,
+import one of the *curlhs* modules, load *libcurl*, and finally check
+its version:
+
+```hs
+ghci> :m Network.CURL720
+ghci> loadlib CURL720
+ghci> curl_version
+"libcurl/7.34.0 OpenSSL/1.0.0k zlib/1.2.8 libidn/1.18 libssh2/1.4.3 librtmp/2.3"
+```
+
+Excellent! But what if...
+
+```hs
+ghci> freelib CURL720
+ghci> curl_version
+*** Exception: <curlhs> failed to call 'curl_version' (NULL)
+```
+
+Nice.
+
+
+# Hello World!
+
+This is about the file transfer library, so let's try to download something:
+
+```hs
+ghci> :m Network.CURL720
+ghci> loadlib CURL720
+ghci> c <- curl_easy_init
+ghci> curl_easy_setopt c [CURLOPT_URL "http://httpbin.org/get"]
+ghci> curl_easy_perform c
+{
+  "args": {},
+  "headers": {
+    "Accept": "*/*",
+    "Connection": "close",
+    "Host": "httpbin.org",
+    "X-Request-Id": "00000000-0000-0000-0000-000000000000"
+  },
+  "origin": "000.000.000.000",
+  "url": "http://httpbin.org/get"
+}
+```
+
+And maybe simple upload:
+
+```hs
+ghci> curl_easy_setopt c [CURLOPT_URL "http://httpbin.org/post"]
+ghci> curl_easy_setopt c [CURLOPT_COPYPOSTFIELDS "Hello World!"]
+ghci> curl_easy_perform c
+{
+  "args": {},
+  "data": "",
+  "files": {},
+  "form": {
+    "Hello World!": ""
+  },
+  "headers": {
+    "Accept": "*/*",
+    "Connection": "close",
+    "Content-Length": "12",
+    "Content-Type": "application/x-www-form-urlencoded",
+    "Host": "httpbin.org",
+    "X-Request-Id": "00000000-0000-0000-0000-000000000000"
+  },
+  "json": null,
+  "origin": "000.000.000.000",
+  "url": "http://httpbin.org/post"
+}
+```
+
+
+# That's all now
+
+I would be grateful for any comments or concerns you may have.
+
+
+
+[haskell.htm]:  http://www.haskell.org/
+[ghc.htm]:      http://www.haskell.org/ghc/
+[cabal.htm]:    http://www.haskell.org/cabal/
+[platform.htm]: http://www.haskell.org/platform/
+[hackage.htm]:  https://hackage.haskell.org/package/curlhs
+[travis.htm]:   https://travis-ci.org/kkardzis/curlhs
+
+![GA](https://ga-beacon.appspot.com/UA-53767359-1/curlhs/docs/tutorial)
diff --git a/test/Network/CURL000Spec.hs b/test/Network/CURL000Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Network/CURL000Spec.hs
@@ -0,0 +1,17 @@
+module Network.CURL000Spec where
+
+--import Network.CURL000
+
+import Test.Hspec
+
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+
+  describe "RTLD LIBCURL" $ do
+    it "load/free libcurl" $ do
+      pending
+
diff --git a/test/Network/CURL720Spec.hs b/test/Network/CURL720Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Network/CURL720Spec.hs
@@ -0,0 +1,38 @@
+module Network.CURL720Spec where
+
+import Network.CURL720
+
+import Control.Exception (tryJust, ErrorCall (..))
+
+import Text.ParserCombinators.ReadP (ReadP, readP_to_S, string)
+import Text.Read.Lex (readDecP)
+
+import Data.List (isPrefixOf)
+
+import Test.Hspec
+
+
+testlib :: LIBCURL -> IO (Either String ())
+testlib lib =
+  let maybeEx s = if (isPrefixOf "<curlhs>" s) then Just s else Nothing
+  in  tryJust (\(ErrorCall s) -> maybeEx s) (withlib lib (return ()))
+
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = runIO (testlib CURL720) >>= \x -> case x of
+  Left  xs -> it "cannot test this module" (pendingWith xs)
+  Right () -> before (loadlib CURL720) $ after (freelib CURL720) $ do
+
+  ----------------------------
+  describe "curl_version" $ do
+    it "returns libcurl version string: \"libcurl/7.x.x ...\"" $ do
+      curl_version >>= (`shouldContain` "libcurl/7.")
+
+    it "returns libcurl version 7.20 or higher compatible" $ do
+      let readP = readP_to_S (string "libcurl/7." >> (readDecP :: ReadP Int))
+      let check s = case (readP s) of [(v,_)] -> Just (v>=20); _ -> Nothing
+      curl_version >>= (`shouldSatisfy` (\s -> maybe False id (check s)))
+
diff --git a/test/Network/CURL730Spec.hs b/test/Network/CURL730Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Network/CURL730Spec.hs
@@ -0,0 +1,38 @@
+module Network.CURL730Spec where
+
+import Network.CURL730
+
+import Control.Exception (tryJust, ErrorCall (..))
+
+import Text.ParserCombinators.ReadP (ReadP, readP_to_S, string)
+import Text.Read.Lex (readDecP)
+
+import Data.List (isPrefixOf)
+
+import Test.Hspec
+
+
+testlib :: LIBCURL -> IO (Either String ())
+testlib lib =
+  let maybeEx s = if (isPrefixOf "<curlhs>" s) then Just s else Nothing
+  in  tryJust (\(ErrorCall s) -> maybeEx s) (withlib lib (return ()))
+
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = runIO (testlib CURL730) >>= \x -> case x of
+  Left  xs -> it "cannot test this module" (pendingWith xs)
+  Right () -> before (loadlib CURL730) $ after (freelib CURL730) $ do
+
+  ----------------------------
+  describe "curl_version" $ do
+    it "returns libcurl version string: \"libcurl/7.x.x ...\"" $ do
+      curl_version >>= (`shouldContain` "libcurl/7.")
+
+    it "returns libcurl version 7.30 or higher compatible" $ do
+      let readP = readP_to_S (string "libcurl/7." >> (readDecP :: ReadP Int))
+      let check s = case (readP s) of [(v,_)] -> Just (v>=30); _ -> Nothing
+      curl_version >>= (`shouldSatisfy` (\s -> maybe False id (check s)))
+
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
