diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,11 +1,73 @@
 # ble - Bluetooth Low Energy for Haskell
 
-*ble* is a Haskell library for writing Bluetooth Low Energy peripherals. It
-currently only supports Linux, and requires Bluez versions 5.41 and up. To see
-what version you are running, type:
+*ble* is a Haskell library for writing Bluetooth Low Energy peripherals (and
+soon centrals).
 
+For usage, see the  [haddocks](https://hackage.haskell.org/package/ble). There
+are also examples in
+[`examples`](https://github.com/plow-technologies/ble/tree/master/examples)
+directory.
+
+## Example
+
+The code below is a simple example of a complete Bluetooth Low Energy
+application. The application allows a counter to be read, and adds one to the
+value of the counter, as well as allowing the counter to be set to any value.
+
+~~~ {.haskell}
+module Main (main) where
+
+import Bluetooth
+import Control.Concurrent     (threadDelay)
+import Control.Concurrent.STM
+import Control.Monad.IO.Class
+
+main :: IO ()
+main = do
+  ref <- newTVarIO 0
+  conn <- connect
+  x <- runBluetoothM (registerAndAdvertiseApplication $ app ref) conn
+  case x of
+    Right _ -> putStrLn "Started BLE counter application!"
+    Left e -> error $ "Error starting application " ++ show e
+  threadDelay maxBound
+
+app :: TVar Int -> Application
+app ref
+  = "/com/turingjump/example/counter"
+     & services .~ [counter ref]
+
+counter :: TVar Int -> Service
+counter ref
+  = "4f1f704f-0a0b-49e4-bd27-6368f27697a7"
+     & characteristics .~ [getCounter ref]
+
+getCounter :: TVar Int -> CharacteristicBS
+getCounter ref
+  = "90874979-563e-4224-9da6-3b1a6c03e97d"
+      & readValue  ?~ encodeRead readV
+      & writeValue ?~ encodeWrite writeV
+      & properties .~ [CPRead, CPWrite]
+  where
+    readV :: Handler Int
+    readV = liftIO $ do
+      v <- atomically $ modifyTVar' ref succ >> readTVar ref
+      putStrLn $ "Value requested. New value: " ++ show v
+      return v
+
+    writeV :: Int -> Handler Bool
+    writeV i = liftIO $ do
+      v <- atomically $ swapTVar ref i
+      putStrLn $ "Value changed to: " ++ show i
+      putStrLn $ "Old value: " ++ show v
+      return True
+~~~
+
+## Requirements
+
+`ble` currently only supports Linux, and requires Bluez versions 5.41 and up.
+To see what version you are running, type:
+
 ``` bash
 bluetoothd --version
 ```
-
-For usage, see the haddocks. There are also examples in 'examples' directory.
diff --git a/ble.cabal b/ble.cabal
--- a/ble.cabal
+++ b/ble.cabal
@@ -1,9 +1,9 @@
--- This file has been generated from package.yaml by hpack version 0.15.0.
+-- This file has been generated from package.yaml by hpack version 0.17.0.
 --
 -- see: https://github.com/sol/hpack
 
 name:           ble
-version:        0.3.3.0
+version:        0.3.4.0
 synopsis:       Bluetooth Low Energy (BLE) peripherals
 description:    This package provides a Haskell API for writing Bluetooth Low Energy peripherals.
 stability:      alpha
@@ -62,10 +62,10 @@
   exposed-modules:
       Bluetooth
       Bluetooth.Internal.DBus
-      Bluetooth.Internal.Descriptors
       Bluetooth.Internal.Errors
       Bluetooth.Internal.HasInterface
       Bluetooth.Internal.Interfaces
+      Bluetooth.Internal.Lenses
       Bluetooth.Internal.Serialize
       Bluetooth.Internal.Types
       Bluetooth.Internal.Utils
@@ -96,12 +96,12 @@
   if flag(hasBluez)
     cpp-options: -DBluez
   other-modules:
-      Counter
       HeartRate
+      README
   default-language: Haskell2010
 
-executable counter
-  main-is: Counter.hs
+executable hrs
+  main-is: HeartRate.hs
   hs-source-dirs:
       examples
   default-extensions: AutoDeriveTypeable ConstraintKinds DataKinds DefaultSignatures DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable FlexibleContexts FlexibleInstances FunctionalDependencies GADTs KindSignatures MultiParamTypeClasses OverloadedStrings RankNTypes ScopedTypeVariables TypeFamilies TypeOperators
@@ -122,20 +122,20 @@
     , cereal >= 0.4 && < 0.6
     , data-default-class >= 0.0 && < 0.2
     , ble
-    , stm
+    , hslogger
   if flag(hasBluez)
     cpp-options: -DBluez
   other-modules:
       Auth
-      HeartRate
+      README
   default-language: Haskell2010
 
-executable hrs
-  main-is: HeartRate.hs
+executable readme
+  main-is: README.lhs
   hs-source-dirs:
       examples
   default-extensions: AutoDeriveTypeable ConstraintKinds DataKinds DefaultSignatures DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable FlexibleContexts FlexibleInstances FunctionalDependencies GADTs KindSignatures MultiParamTypeClasses OverloadedStrings RankNTypes ScopedTypeVariables TypeFamilies TypeOperators
-  ghc-options: -Wall
+  ghc-options: -Wall -pgmL markdown-unlit
   build-depends:
       base >= 4.8 && < 4.10
     , bytestring >= 0.10 && < 0.11
@@ -152,12 +152,13 @@
     , cereal >= 0.4 && < 0.6
     , data-default-class >= 0.0 && < 0.2
     , ble
-    , hslogger
+    , stm
+    , markdown-unlit
   if flag(hasBluez)
     cpp-options: -DBluez
   other-modules:
       Auth
-      Counter
+      HeartRate
   default-language: Haskell2010
 
 test-suite spec
@@ -184,7 +185,7 @@
     , data-default-class >= 0.0 && < 0.2
     , ble
     , hspec > 2 && < 3
-    , QuickCheck >= 2.8 && < 2.9
+    , QuickCheck >= 2.8 && < 2.10
     , quickcheck-instances >= 0.3 && < 0.4
     , hslogger
   if flag(hasBluez)
diff --git a/examples/Counter.hs b/examples/Counter.hs
deleted file mode 100644
--- a/examples/Counter.hs
+++ /dev/null
@@ -1,50 +0,0 @@
-module Main (main) where
-
--- A simple example of a complete Bluetooth Low Energy application. The
--- application allows a counter to be read, and adds one to the value of the
--- counter, as well as allowing the counter to be set to any value.
-
-import Bluetooth
-import Control.Concurrent     (threadDelay)
-import Control.Concurrent.STM
-import Control.Monad.IO.Class
-
-main :: IO ()
-main = do
-  ref <- newTVarIO 0
-  conn <- connect
-  x <- runBluetoothM (registerAndAdvertiseApplication $ app ref) conn
-  case x of
-    Right _ -> putStrLn "Started BLE counter application!"
-    Left e -> error $ "Error starting application " ++ show e
-  threadDelay maxBound
-
-app :: TVar Int -> Application
-app ref
-  = "/com/turingjump/example/counter"
-     & services .~ [counter ref]
-
-counter :: TVar Int -> Service
-counter ref
-  = "4f1f704f-0a0b-49e4-bd27-6368f27697a7"
-     & characteristics .~ [getCounter ref]
-
-getCounter :: TVar Int -> CharacteristicBS
-getCounter ref
-  = "90874979-563e-4224-9da6-3b1a6c03e97d"
-      & readValue  ?~ encodeRead readV
-      & writeValue ?~ encodeWrite writeV
-      & properties .~ [CPRead, CPWrite]
-  where
-    readV :: Handler Int
-    readV = liftIO $ do
-      v <- atomically $ modifyTVar' ref succ >> readTVar ref
-      putStrLn $ "Value requested. New value: " ++ show v
-      return v
-
-    writeV :: Int -> Handler Bool
-    writeV i = liftIO $ do
-      v <- atomically $ swapTVar ref i
-      putStrLn $ "Value changed to: " ++ show i
-      putStrLn $ "Old value: " ++ show v
-      return True
diff --git a/examples/README.lhs b/examples/README.lhs
new file mode 100644
--- /dev/null
+++ b/examples/README.lhs
@@ -0,0 +1,73 @@
+# ble - Bluetooth Low Energy for Haskell
+
+*ble* is a Haskell library for writing Bluetooth Low Energy peripherals (and
+soon centrals).
+
+For usage, see the  [haddocks](https://hackage.haskell.org/package/ble). There
+are also examples in
+[`examples`](https://github.com/plow-technologies/ble/tree/master/examples)
+directory.
+
+## Example
+
+The code below is a simple example of a complete Bluetooth Low Energy
+application. The application allows a counter to be read, and adds one to the
+value of the counter, as well as allowing the counter to be set to any value.
+
+~~~ {.haskell}
+module Main (main) where
+
+import Bluetooth
+import Control.Concurrent     (threadDelay)
+import Control.Concurrent.STM
+import Control.Monad.IO.Class
+
+main :: IO ()
+main = do
+  ref <- newTVarIO 0
+  conn <- connect
+  x <- runBluetoothM (registerAndAdvertiseApplication $ app ref) conn
+  case x of
+    Right _ -> putStrLn "Started BLE counter application!"
+    Left e -> error $ "Error starting application " ++ show e
+  threadDelay maxBound
+
+app :: TVar Int -> Application
+app ref
+  = "/com/turingjump/example/counter"
+     & services .~ [counter ref]
+
+counter :: TVar Int -> Service
+counter ref
+  = "4f1f704f-0a0b-49e4-bd27-6368f27697a7"
+     & characteristics .~ [getCounter ref]
+
+getCounter :: TVar Int -> CharacteristicBS
+getCounter ref
+  = "90874979-563e-4224-9da6-3b1a6c03e97d"
+      & readValue  ?~ encodeRead readV
+      & writeValue ?~ encodeWrite writeV
+      & properties .~ [CPRead, CPWrite]
+  where
+    readV :: Handler Int
+    readV = liftIO $ do
+      v <- atomically $ modifyTVar' ref succ >> readTVar ref
+      putStrLn $ "Value requested. New value: " ++ show v
+      return v
+
+    writeV :: Int -> Handler Bool
+    writeV i = liftIO $ do
+      v <- atomically $ swapTVar ref i
+      putStrLn $ "Value changed to: " ++ show i
+      putStrLn $ "Old value: " ++ show v
+      return True
+~~~
+
+## Requirements
+
+`ble` currently only supports Linux, and requires Bluez versions 5.41 and up.
+To see what version you are running, type:
+
+``` bash
+bluetoothd --version
+```
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name:                ble
-version:             0.3.3.0
+version:             0.3.4.0
 synopsis:            Bluetooth Low Energy (BLE) peripherals
 description:         >
     This package provides a Haskell API for writing Bluetooth Low Energy
@@ -88,7 +88,7 @@
     dependencies:
       - ble
       - hspec > 2 && < 3
-      - QuickCheck >= 2.8 && < 2.9
+      - QuickCheck >= 2.8 && < 2.10
       - quickcheck-instances >= 0.3 && < 0.4
       - hslogger
 #   doctest:
@@ -100,12 +100,14 @@
 #       - yaml == 0.8.*
 
 executables:
-  counter:
-    main:            Counter.hs
+  readme:
+    main:            README.lhs
     source-dirs:     examples
+    ghc-options:    -pgmL markdown-unlit
     dependencies:
       - ble
       - stm
+      - markdown-unlit
   hrs:
     main:            HeartRate.hs
     source-dirs:     examples
diff --git a/src/Bluetooth.hs b/src/Bluetooth.hs
--- a/src/Bluetooth.hs
+++ b/src/Bluetooth.hs
@@ -1,4 +1,3 @@
-
 -- | This module exports all you should need to build a Bluetooth Low Energy
 --  (BLE) peripheral.
 --
@@ -20,7 +19,7 @@
 -- All three have @IsString@ instances and lens field accessors.  The
 -- recommended way of using this library is by using the @OverloadedStrings@
 -- pragma and lenses. A complete example can be found
--- <https://github.com/plow-technologies/ble/blob/master/examples/Counter.hs here>.
+-- <https://github.com/plow-technologies/ble/blob/master/examples/README.lhs here>.
 --
 -- > {-# LANGUAGE OverloadedStrings #-}
 -- > import Bluetooth
@@ -118,6 +117,7 @@
 import Bluetooth.Internal.Types as X
 import Bluetooth.Internal.Serialize as X
 import Bluetooth.Internal.Errors as X
+import Bluetooth.Internal.Lenses as X
 
 import Lens.Micro
 import Lens.Micro.GHC
diff --git a/src/Bluetooth/Internal/DBus.hs b/src/Bluetooth/Internal/DBus.hs
--- a/src/Bluetooth/Internal/DBus.hs
+++ b/src/Bluetooth/Internal/DBus.hs
@@ -16,6 +16,7 @@
 import Bluetooth.Internal.Types
 import Bluetooth.Internal.Utils
 import Bluetooth.Internal.Errors
+import Bluetooth.Internal.Lenses
 
 -- | Registers an application and advertises it. If you would like to have
 -- finer-grained control of the advertisement, use @registerApplication@ and
diff --git a/src/Bluetooth/Internal/Descriptors.hs b/src/Bluetooth/Internal/Descriptors.hs
deleted file mode 100644
--- a/src/Bluetooth/Internal/Descriptors.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Bluetooth.Internal.Descriptors where
-
--- This modules defines some commonly used GATT descriptors.
-
-
-
diff --git a/src/Bluetooth/Internal/HasInterface.hs b/src/Bluetooth/Internal/HasInterface.hs
--- a/src/Bluetooth/Internal/HasInterface.hs
+++ b/src/Bluetooth/Internal/HasInterface.hs
@@ -20,6 +20,7 @@
 import Bluetooth.Internal.Interfaces
 import Bluetooth.Internal.Types
 import Bluetooth.Internal.Utils
+import Bluetooth.Internal.Lenses
 
 -- The Bluez DBus API makes certain requirements about the interfaces
 -- that objects must meet. These requirements are outlined in:
diff --git a/src/Bluetooth/Internal/Lenses.hs b/src/Bluetooth/Internal/Lenses.hs
new file mode 100644
--- /dev/null
+++ b/src/Bluetooth/Internal/Lenses.hs
@@ -0,0 +1,51 @@
+module Bluetooth.Internal.Lenses where
+
+import Lens.Micro
+
+class HasPath s a | s -> a where
+  -- | Returns the `ObjectPath` of an entity.
+  path :: Lens' s a
+class HasValue s a | s -> a where
+  -- | Returns the actual value of an entity that is wrapped in an
+  value :: Lens' s a
+class HasOffset s a | s -> a where
+  -- | A `Word16` data offset.
+  offset :: Lens' s a
+class HasProperties s a | s -> a where
+  -- | The properties of e.g. a characteristic.
+  properties :: Lens' s a
+class HasReadValue s a | s -> a where
+  -- | Access the handler for reading a value, if there is one.
+  readValue :: Lens' s a
+class HasWriteValue s a | s -> a where
+  -- | Access the handler for writing a value, if there is one. The handler
+  -- should return `True` if the value was successfully update.
+  writeValue :: Lens' s a
+class HasUuid s a | s -> a where
+  -- | The `UUID` of an entity
+  uuid :: Lens' s a
+class HasCharacteristics s a | s -> a where
+  -- | An access for the list of characteristics.
+  characteristics :: Lens' s a
+class HasServices s a | s -> a where
+  -- | An access for the list of services.
+  services :: Lens' s a
+class HasIncludeTxPower s a | s -> a where
+  -- | Accessor for indicating whether an `Advertisement` announces TX power
+  -- (transmission power).
+  includeTxPower :: Lens' s a
+class HasManufacturerData s a | s -> a where
+  -- | Accessor for manufacting data.
+  manufacturerData :: Lens' s a
+class HasServiceData s a | s -> a where
+  -- | Accessor for manufacting data.
+  serviceData :: Lens' s a
+class HasServiceUUIDs s a | s -> a where
+  -- | Accessor for service UUIDs
+  serviceUUIDs :: Lens' s a
+class HasSolicitUUIDs s a | s -> a where
+  -- | Accessor for solicit UUIDs. These are UUIDs that an application or
+  -- service expects to be available.
+  solicitUUIDs :: Lens' s a
+class HasType_ s a | s -> a where
+  type_ :: Lens' s a
diff --git a/src/Bluetooth/Internal/Types.hs b/src/Bluetooth/Internal/Types.hs
--- a/src/Bluetooth/Internal/Types.hs
+++ b/src/Bluetooth/Internal/Types.hs
@@ -42,6 +42,7 @@
 import Bluetooth.Internal.Errors
 import Bluetooth.Internal.Interfaces
 import Bluetooth.Internal.Utils
+import Bluetooth.Internal.Lenses
 
 -- | Append two Texts, keeping exactly one slash between them.
 (</>) :: T.Text -> T.Text -> T.Text
