diff --git a/Codec/ActivityStream.hs b/Codec/ActivityStream.hs
new file mode 100644
--- /dev/null
+++ b/Codec/ActivityStream.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+{-|
+Module      : Codec.ActivityStream
+Description : The basic Activity Streams structures
+Copyright   : (c) Getty Ritter, 2014
+Maintainer  : gdritter@galois.com
+
+This is an interface to ActivityStreams that simply wraps an underlying
+@aeson@ Object, and exposes a set of convenient lenses to access the
+values inside. If an @aeson@ object appears wrapped in some respective wrapper,
+it will necessarily contain the obligatory values for that type
+(e.g. an 'Activity' is guaranteed to have a @published@ date.)
+
+Most of the inline documentation is drawn directly from the
+<http://activitystrea.ms/specs/json/1.0/ JSON Activity Streams 1.0>
+specification, with minor modifications
+to refer to the corresponding data types in this module and to clarify
+certain aspects.
+-}
+
+module Codec.ActivityStream
+  ( module Codec.ActivityStream.Representation
+  ) where
+
+import Codec.ActivityStream.Representation
diff --git a/Codec/ActivityStream/Internal.hs b/Codec/ActivityStream/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Codec/ActivityStream/Internal.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE ViewPatterns #-}
+
+module Codec.ActivityStream.Internal (commonOpts, commonOptsCC, ensure) where
+
+import Control.Monad (mzero)
+import Data.Aeson
+import Data.Aeson.TH
+import Data.Char
+import Data.HashMap.Strict (HashMap, member)
+import Data.Monoid ((<>))
+import Data.Text (Text, pack, unpack)
+
+ensure :: Monad m => String -> HashMap Text Value -> [Text] -> m ()
+ensure objName obj keys = mapM_ go keys
+  where go k
+          | member k obj = return ()
+          | otherwise = fail ("Object \"" <> objName <>
+                              "\" does not contain property \"" <>
+                              unpack k <> "\"")
+
+toCamelCaseUpper :: String -> String
+toCamelCaseUpper = toCamelCase True
+
+toCamelCaseLower :: String -> String
+toCamelCaseLower = toCamelCase False
+
+toCamelCase :: Bool -> String -> String
+toCamelCase = go
+  where go _ ""    = ""
+        go _ ('-':cs)   = go True cs
+        go True (c:cs)  = toUpper c : go False cs
+        go False (c:cs) = c : go False cs
+
+fromCamelCase :: String -> String
+fromCamelCase (c:cs)
+  | isUpper c = toLower c : go cs
+  | otherwise = go (c:cs)
+  where go "" = ""
+        go (c:cs)
+          | c == ' '  = go cs
+          | isUpper c = '-' : toLower c : go cs
+          | otherwise = c : go cs
+
+commonOpts :: String -> Options
+commonOpts prefix = defaultOptions
+  { fieldLabelModifier = drop (length prefix)
+  , omitNothingFields  = True
+  }
+
+commonOptsCC :: String -> Options
+commonOptsCC prefix = defaultOptions
+  { fieldLabelModifier     = fromCamelCase . drop (length prefix)
+  , constructorTagModifier = fromCamelCase
+  , omitNothingFields      = True
+
+  }
diff --git a/Codec/ActivityStream/LensInternal.hs b/Codec/ActivityStream/LensInternal.hs
new file mode 100644
--- /dev/null
+++ b/Codec/ActivityStream/LensInternal.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE DeriveFunctor #-}
+
+-- Okay, I'm gonna justify this in a comment: I will never, under any
+-- circumstances, build a library that has an explicit `lens` dependency.
+-- I think `lens` is awesome, but it is also a giant package, and I
+-- don't want to inflict it on end-users who might not want it.
+
+-- I am more okay with lens-family-core, but in this case, all I need
+-- is really the `makeLens` function, which (not counting whitespace
+-- and comments) is three lines of code. Three lines! And it doesn't make
+-- sense to drag in a whole extra package when I can just copy this
+-- in.
+
+-- There's also reimplementations of `get` and `set` for possible internal
+-- use---three lines each, for a total of nine. Nine lines of
+-- easily-copyable, verifiable boilerplate. Instead of another dependency
+-- that must be downloaded and installed and managed by Cabal and
+-- addressed in constraint-solving...
+
+-- And that is why this module reimplement a few `lens` functions.
+
+module Codec.ActivityStream.LensInternal
+         ( get
+         , set
+         , Lens'
+         , makeLens
+         , makeAesonLensMb
+         , makeAesonLens
+         ) where
+
+import           Data.Aeson as Aeson
+import qualified Data.HashMap.Strict as HM
+import           Data.Maybe (fromJust)
+import           Data.Text (Text)
+
+-- We need these to write get and set
+newtype C a b = C { fromC :: a } deriving (Functor)
+newtype I a   = I { fromI :: a } deriving (Functor)
+
+-- This is the same type alias as in @Control.Lens@, and so can be used
+-- anywhere lenses are needed.
+type Lens' a b = forall f. Functor f => (b -> f b) -> (a -> f a)
+
+get :: Lens' a b -> a -> b
+get lens a = fromC (lens C a)
+
+set :: Lens' a b -> b -> a -> a
+set lens x a = fromI (lens (const I x) a)
+
+makeLens :: (a -> b) -> (b -> a -> a) -> Lens' a b
+makeLens get set f a = (`set` a) `fmap` f (get a)
+
+-- This is necessary because of the way we store values as Aeson
+-- values underneath.
+fromJSON' :: FromJSON a => Aeson.Value -> Maybe a
+fromJSON' v = case fromJSON v of
+  Success a -> Just a
+  Error _   -> Nothing
+
+-- Create a lens into an Aeson object wrapper that takes and
+-- returns a Maybe value. When used as a setter, it can either
+-- insert a value in, or delete it from the object (if it is
+-- used with Nothing.)
+makeAesonLensMb :: (FromJSON v, ToJSON v)
+                => Text -> Lens' c Aeson.Object -> Lens' c (Maybe v)
+makeAesonLensMb key fromObj = fromObj . makeLens g s
+  where g o = HM.lookup key o >>= fromJSON'
+        s (Just v) o = HM.insert key (toJSON v) o
+        s Nothing  o = HM.delete key o
+
+
+-- Create a lens into an Aeson object wrapper. This will fail if
+-- the object does not contain the relevant key.
+makeAesonLens :: (FromJSON v, ToJSON v)
+              => Text -> Lens' c Aeson.Object -> Lens' c v
+makeAesonLens key fromObj = fromObj . makeLens g s
+  where g o   = fromJust (HM.lookup key o >>= fromJSON')
+        s v o = HM.insert key (toJSON v) o
diff --git a/Codec/ActivityStream/Representation.hs b/Codec/ActivityStream/Representation.hs
new file mode 100644
--- /dev/null
+++ b/Codec/ActivityStream/Representation.hs
@@ -0,0 +1,449 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+
+{-|
+Module      : Codec.ActivityStream.Representation
+Description : A (more dynamic) interface to Activity Streams
+Copyright   : (c) Getty Ritter, 2014
+Maintainer  : gdritter@galois.com
+
+This is an interface to ActivityStreams that simply wraps an underlying
+@aeson@ Object, and exposes a set of (convenient) lenses to access the
+values inside. If an @aeson@ object is wrapped in the respective wrapper,
+it will contain the obligatory values for that type (e.g. an 'Activity'
+is guaranteed to have a @published@ date.)
+
+Most of the inline documentation is drawn directly from the
+<http://activitystrea.ms/specs/json/1.0/ JSON Activity Streams 1.0>
+specification, with minor modifications
+to refer to the corresponding data types in this module and to clarify
+certain aspects.
+-}
+
+module Codec.ActivityStream.Representation
+       ( Lens'
+         -- * Object
+       , Object
+       , emptyObject
+         -- ** Object Lenses
+       , oAttachments
+       , oAuthor
+       , oContent
+       , oDisplayName
+       , oDownstreamDuplicates
+       , oId
+       , oImage
+       , oObjectType
+       , oPublished
+       , oSummary
+       , oUpdated
+       , oUpstreamDuplicates
+       , oURL
+       , oRest
+         -- * Activity
+       , Activity
+       , makeActivity
+       , asObject
+         -- ** Activity Lenses
+       , acActor
+       , acContent
+       , acGenerator
+       , acIcon
+       , acId
+       , acObject
+       , acPublished
+       , acProvider
+       , acTarget
+       , acTitle
+       , acUpdated
+       , acURL
+       , acVerb
+       , acRest
+         -- * MediaLink
+       , MediaLink
+       , makeMediaLink
+         -- ** MediaLink Lenses
+       , mlDuration
+       , mlHeight
+       , mlWidth
+       , mlURL
+       , mlRest
+         -- * Collection
+       , Collection
+       , makeCollection
+         -- ** Collection Lenses
+       , cTotalItems
+       , cItems
+       , cURL
+       , cRest
+       ) where
+
+import           Data.Aeson ( FromJSON(..)
+                            , ToJSON(..)
+                            , Result(..)
+                            , fromJSON
+                            )
+import qualified Data.Aeson as A
+import           Data.DateTime (DateTime)
+import qualified Data.HashMap.Strict as HM
+import           Data.Text (Text)
+
+import Codec.ActivityStream.Internal (ensure)
+import Codec.ActivityStream.LensInternal
+
+-- | Some types of objects may have an alternative visual representation in
+--   the form of an image, video or embedded HTML fragments. A 'MediaLink'
+--   represents a hyperlink to such resources.
+newtype MediaLink = MediaLink { fromMediaLink :: A.Object } deriving (Eq, Show)
+
+instance FromJSON MediaLink where
+  parseJSON (A.Object o) = do
+    ensure "MediaLink" o ["url"]
+    return (MediaLink o)
+  parseJSON _ = fail "MediaLink not an object"
+
+instance ToJSON MediaLink where
+  toJSON (MediaLink o) = A.Object o
+
+-- | Access the underlying JSON object that represents a Media Link
+mlRest :: Lens' MediaLink A.Object
+mlRest = makeLens fromMediaLink (\ o' m -> m { fromMediaLink = o' })
+
+-- | A hint to the consumer about the length, in seconds, of the media
+--   resource identified by the url property. A media link MAY contain
+--   a "duration" property when the target resource is a time-based
+--   media item such as an audio or video.
+mlDuration :: Lens' MediaLink (Maybe Int)
+mlDuration = makeAesonLensMb "duration" mlRest
+
+-- | A hint to the consumer about the height, in pixels, of the media
+--   resource identified by the url property. A media link MAY contain
+--   a @height@ property when the target resource is a visual media item
+--   such as an image, video or embeddable HTML page.
+mlHeight :: Lens' MediaLink (Maybe Int)
+mlHeight = makeAesonLensMb "height" mlRest
+
+-- | A hint to the consumer about the width, in pixels, of the media
+--   resource identified by the url property. A media link MAY contain
+--   a @width@ property when the target resource is a visual media item
+--   such as an image, video or embeddable HTML page.
+mlWidth :: Lens' MediaLink (Maybe Int)
+mlWidth = makeAesonLensMb "width" mlRest
+
+-- | The IRI of the media resource being linked. A media link MUST have a
+--   @url@ property.
+mlURL :: Lens' MediaLink Text
+mlURL = makeAesonLens "url" mlRest
+
+-- | Create a @MediaLink@ with just a @url@ property, and all other
+--   properties undefined.
+makeMediaLink :: Text -> MediaLink
+makeMediaLink url = MediaLink (HM.insert "url" (toJSON url) HM.empty)
+
+-- | Within the specification, an 'Object' is a thing, real or
+--   imaginary, which participates in an activity. It may be the
+--   entity performing the activity, or the entity on which the
+--   activity was performed. An object consists of properties
+--   defined below. Certain object types may
+--   further refine the meaning of these properties, or they may
+--   define additional properties.
+--
+--   To maintain this flexibility in the Haskell environment, an
+--   'Object' is an opaque wrapper over an underlying JSON value,
+--   and the 'oRest' accessor can be used to access that underlying
+--   value.
+
+newtype Object = Object { fromObject :: A.Object } deriving (Eq, Show)
+
+instance FromJSON Object where
+  parseJSON (A.Object o) = return (Object o)
+  parseJSON _            = fail "Object not an object"
+
+instance ToJSON Object where
+  toJSON (Object o) = A.Object o
+
+-- | Access the underlying JSON object that represents an 'Object'
+oRest :: Lens' Object A.Object
+oRest = makeLens fromObject (\ o' m -> m { fromObject = o' })
+
+-- | A collection of one or more additional, associated objects, similar
+--   to the concept of attached files in an email message. An object MAY
+--   have an attachments property whose value is a JSON Array of 'Object's.
+oAttachments :: Lens' Object (Maybe [Object])
+oAttachments = makeAesonLensMb "attachments" oRest
+
+-- | Describes the entity that created or authored the object. An object
+--   MAY contain a single author property whose value is an 'Object' of any
+--   type. Note that the author field identifies the entity that created
+--   the object and does not necessarily identify the entity that
+--   published the object. For instance, it may be the case that an
+--   object created by one person is posted and published to a system by
+--   an entirely different entity.
+oAuthor :: Lens' Object (Maybe Object)
+oAuthor = makeAesonLensMb "author" oRest
+
+-- | Natural-language description of the object encoded as a single JSON
+--   String containing HTML markup. Visual elements such as thumbnail
+--   images MAY be included. An object MAY contain a @content@ property.
+oContent :: Lens' Object (Maybe Text)
+oContent = makeAesonLensMb "content" oRest
+
+-- | A natural-language, human-readable and plain-text name for the
+--   object. HTML markup MUST NOT be included. An object MAY contain
+--   a @displayName@ property. If the object does not specify an @objectType@
+--   property, the object SHOULD specify a @displayName@.
+oDisplayName :: Lens' Object (Maybe Text)
+oDisplayName = makeAesonLensMb "displayName" oRest
+
+-- | A JSON Array of one or more absolute IRI's
+--   <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]> identifying
+--   objects that duplicate this object's content. An object SHOULD
+--   contain a @downstreamDuplicates@ property when there are known objects,
+--   possibly in a different system, that duplicate the content in this
+--   object. This MAY be used as a hint for consumers to use when
+--   resolving duplicates between objects received from different sources.
+oDownstreamDuplicates :: Lens' Object (Maybe [Text])
+oDownstreamDuplicates = makeAesonLensMb "downstreamDuplicates" oRest
+
+-- | Provides a permanent, universally unique identifier for the object in
+--   the form of an absolute IRI
+--   <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. An
+--   object SHOULD contain a single @id@ property. If an object does not
+--   contain an @id@ property, consumers MAY use the value of the @url@
+--   property as a less-reliable, non-unique identifier.
+
+oId :: Lens' Object (Maybe Text)
+oId = makeAesonLensMb "id" oRest
+
+-- | Description of a resource providing a visual representation of the
+--   object, intended for human consumption. An object MAY contain an
+--   @image@ property whose value is a 'MediaLink'.
+oImage :: Lens' Object (Maybe MediaLink)
+oImage = makeAesonLensMb "image" oRest
+
+-- | Identifies the type of object. An object MAY contain an @objectType@
+--   property whose value is a JSON String that is non-empty and matches
+--   either the "isegment-nz-nc" or the \"IRI\" production in
+--   <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. Note
+--   that the use of a relative reference other than a simple name is
+--   not allowed. If no @objectType@ property is contained, the object has
+--   no specific type.
+oObjectType :: (FromJSON o, ToJSON o) => Lens' Object (Maybe o)
+oObjectType = makeAesonLensMb "objectType" oRest
+
+-- | The date and time at which the object was published. An object MAY
+--   contain a @published@ property.
+oPublished :: Lens' Object (Maybe DateTime)
+oPublished = makeAesonLensMb "published" oRest
+
+-- | Natural-language summarization of the object encoded as a single
+--   JSON String containing HTML markup. Visual elements such as thumbnail
+--   images MAY be included. An activity MAY contain a @summary@ property.
+oSummary :: Lens' Object (Maybe Text)
+oSummary = makeAesonLensMb "summary" oRest
+
+-- | The date and time at which a previously published object has been
+--   modified. An Object MAY contain an @updated@ property.
+oUpdated :: Lens' Object (Maybe DateTime)
+oUpdated = makeAesonLensMb "updated" oRest
+
+-- | A JSON Array of one or more absolute IRI's
+--   <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]> identifying
+--   objects that duplicate this object's content. An object SHOULD contain
+--   an @upstreamDuplicates@ property when a publisher is knowingly
+--   duplicating with a new ID the content from another object. This MAY be
+--   used as a hint for consumers to use when resolving duplicates between
+--   objects received from different sources.
+oUpstreamDuplicates :: Lens' Object (Maybe [Text])
+oUpstreamDuplicates = makeAesonLensMb "upstreamDuplicates" oRest
+
+-- | An IRI <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>
+--   identifying a resource providing an HTML representation of the
+--   object. An object MAY contain a url property
+oURL :: Lens' Object (Maybe Text)
+oURL = makeAesonLensMb "url" oRest
+
+-- | Create an @Object@ with no fields.
+emptyObject :: Object
+emptyObject = Object HM.empty
+
+-- | In its simplest form, an 'Activity' consists of an @actor@, a @verb@, an
+--   @object@, and a @target@. It tells the story of a person performing an
+--   action on or with an object -- "Geraldine posted a photo to her
+--   album" or "John shared a video". In most cases these components
+--   will be explicit, but they may also be implied.
+
+newtype Activity = Activity { fromActivity :: A.Object } deriving (Eq, Show)
+
+instance FromJSON Activity where
+  parseJSON (A.Object o) = do
+    ensure "Activity" o ["published", "provider"]
+    return (Activity o)
+  parseJSON _ = fail "\"Activity\" not an object"
+
+instance ToJSON Activity where
+  toJSON (Activity o) = A.Object o
+
+-- | Access the underlying JSON object that represents an 'Activity'
+acRest :: Lens' Activity A.Object
+acRest = makeLens fromActivity (\ o' m -> m { fromActivity = o' })
+
+-- | Describes the entity that performed the activity. An activity MUST
+--   contain one @actor@ property whose value is a single 'Object'.
+acActor :: Lens' Activity Object
+acActor = makeAesonLens "actor" acRest
+
+-- | Natural-language description of the activity encoded as a single
+--   JSON String containing HTML markup. Visual elements such as
+--   thumbnail images MAY be included. An activity MAY contain a
+--   @content@ property.
+acContent :: Lens' Activity (Maybe Text)
+acContent = makeAesonLensMb "content" acRest
+
+-- | Describes the application that generated the activity. An activity
+--   MAY contain a @generator@ property whose value is a single 'Object'.
+acGenerator :: Lens' Activity (Maybe Object)
+acGenerator = makeAesonLens "generator" acRest
+
+-- | Description of a resource providing a visual representation of the
+--   object, intended for human consumption. The image SHOULD have an
+--   aspect ratio of one (horizontal) to one (vertical) and SHOULD be
+--   suitable for presentation at a small size. An activity MAY have
+--   an @icon@ property.
+acIcon :: Lens' Activity (Maybe MediaLink)
+acIcon = makeAesonLensMb "icon" acRest
+
+-- | Provides a permanent, universally unique identifier for the activity
+--   in the form of an absolute IRI
+--   <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. An
+--   activity SHOULD contain a single @id@ property. If an activity does
+--   not contain an @id@ property, consumers MAY use the value of the
+--   @url@ property as a less-reliable, non-unique identifier.
+acId :: Lens' Activity (Maybe Text)
+acId = makeAesonLensMb "id" acRest
+
+-- | Describes the primary object of the activity. For instance, in the
+--   activity, "John saved a movie to his wishlist", the object of the
+--   activity is "movie". An activity SHOULD contain an @object@ property
+--   whose value is a single 'Object'. If the @object@ property is not
+--   contained, the primary object of the activity MAY be implied by
+--   context.
+acObject :: Lens' Activity (Maybe Object)
+acObject = makeAesonLensMb "object" acRest
+
+-- | The date and time at which the activity was published. An activity
+--   MUST contain a @published@ property.
+acPublished :: Lens' Activity DateTime
+acPublished = makeAesonLens "published" acRest
+
+-- | Describes the application that published the activity. Note that this
+--   is not necessarily the same entity that generated the activity. An
+--   activity MAY contain a @provider@ property whose value is a
+--   single 'Object'.
+acProvider :: Lens' Activity (Maybe Object)
+acProvider = makeAesonLensMb "provider" acRest
+
+-- | Describes the target of the activity. The precise meaning of the
+--   activity's target is dependent on the activities verb, but will
+--   often be the object the English preposition "to". For instance, in
+--   the activity, "John saved a movie to his wishlist", the target of
+--   the activity is "wishlist". The activity target MUST NOT be used
+--   to identity an indirect object that is not a target of the
+--   activity. An activity MAY contain a @target@ property whose value
+--   is a single 'Object'.
+acTarget :: Lens' Activity (Maybe Object)
+acTarget = makeAesonLensMb "target" acRest
+
+-- | Natural-language title or headline for the activity encoded as a
+--  single JSON String containing HTML markup. An activity MAY contain
+--  a @title@ property.
+acTitle :: Lens' Activity (Maybe Text)
+acTitle = makeAesonLensMb "title" acRest
+
+-- | The date and time at which a previously published activity has
+--   been modified. An Activity MAY contain an @updated@ property.
+acUpdated :: Lens' Activity (Maybe DateTime)
+acUpdated = makeAesonLensMb "updated" acRest
+
+-- | An IRI <http://www.ietf.org/rfc/rfc3987.txt RFC3987>
+--   identifying a resource providing an HTML representation of the
+--   activity. An activity MAY contain a @url@ property.
+acURL :: Lens' Activity (Maybe Text)
+acURL = makeAesonLensMb "url" acRest
+
+-- | Identifies the action that the activity describes. An activity SHOULD
+--   contain a verb property whose value is a JSON String that is
+--   non-empty and matches either the \"isegment-nz-nc\" or the
+--   \"IRI\" production in <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>.
+--   Note that the use of a relative
+--   reference other than a simple name is not allowed. If the @verb@ is
+--   not specified, or if the value is null, the @verb@ is
+--   assumed to be \"post\".
+acVerb :: (FromJSON v, ToJSON v) => Lens' Activity (Maybe v)
+acVerb = makeAesonLensMb "verb" acRest
+
+-- | Create an @Activity@ with an @actor@, @published@, and
+--   @provider@ property.
+makeActivity :: Object -> DateTime -> Activity
+makeActivity actor published = Activity
+  $ HM.insert "actor"     (toJSON actor)
+  $ HM.insert "published" (toJSON published)
+  $ HM.empty
+
+-- | JSON Activity Streams 1.0 specificies that an @Activity@ may be used as an
+--   @Object@. In such a case, the object may have fields permitted on either an
+--   @Activity@ or an @Object@
+asObject :: Activity -> Object
+asObject act = Object (fromActivity act)
+
+-- | A "collection" is a generic list of 'Object's of any object type.
+--   The @objectType@ of each item in the collection MAY be omitted if
+--   the type of object can be established through context. The collection
+--   is used primarily as the root of an Activity Streams document as described
+--   in Section 4,
+--   but can be used as the value of extension properties in a variety of
+--   situations.
+
+newtype Collection = Collection { fromCollection :: A.Object } deriving (Eq, Show)
+
+instance FromJSON Collection where
+  parseJSON (A.Object o) = return (Collection o)
+  parseJSON _            = fail "\"Collection\" not an object"
+
+instance ToJSON Collection where
+  toJSON (Collection o) = A.Object o
+
+-- | Access the underlying JSON object that represents a 'Collection'
+cRest :: Lens' Collection A.Object
+cRest = makeLens fromCollection (\ o' m -> m { fromCollection = o' })
+
+-- | Non-negative integer specifying the total number of activities
+--   within the stream. The Stream serialization MAY contain a
+--   @totalItems@ property. (NOTE: there is a typo in the original
+--   specification, in which it inconsistently refers to this as
+--   either @totalItems@ or @count@.)
+cTotalItems :: Lens' Collection (Maybe Int)
+cTotalItems = makeAesonLensMb "totalItems" cRest
+
+-- | An array containing a listing of 'Object's of any object type.
+--   If used in combination with the @url@ property, the @items@ array
+--   can be used to provide a subset of the objects that may be
+--   found in the resource identified by the @url@.
+cItems :: Lens' Collection (Maybe [Object])
+cItems = makeAesonLensMb "items" cRest
+
+-- | An IRI <http://activitystrea.ms/specs/json/1.0/#RFC3987 [RFC3987]>
+--   referencing a JSON document containing the full
+--   listing of objects in the collection.
+cURL :: Lens' Collection (Maybe Text)
+cURL = makeAesonLensMb "url" cRest
+
+-- | Create a @Collection@ with an @items@ and a @url@ property
+--   and fill in the corresponding @totalItems@ field with the
+--   length of the @items@ array.
+makeCollection :: [Object] -> Text -> Collection
+makeCollection objs url = Collection
+  $ HM.insert "totalItems" (toJSON (length objs))
+  $ HM.insert "items"      (toJSON objs)
+  $ HM.insert "url"        (toJSON url)
+  $ HM.empty
diff --git a/Codec/ActivityStream/Schema.hs b/Codec/ActivityStream/Schema.hs
new file mode 100644
--- /dev/null
+++ b/Codec/ActivityStream/Schema.hs
@@ -0,0 +1,944 @@
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+{-|
+Module      : Codec.ActivityStream.Schema
+Description : An interface to the Activity Streams Base Schema
+Copyright   : (c) Getty Ritter, 2014
+Maintainer  : gdritter@galois.com
+
+This is an interface to the extended ActivityStreams schema which defines
+an extensive set of @verb@ values, additional @objectType@ values, and a
+set of extended properties for 'Object's.
+
+Most of the inline documentation is drawn directly from the
+<https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md Activity Base Schema draft>
+specification, with minor modifications
+to refer to the corresponding data types in this module and to clarify
+certain aspects. This is not an approved draft, and as such may be
+subject to changes which will be reflected in this module. In contrast to
+"Codec.ActivityStream", the API in this module makes
+__no guarantees about long-term stability__.
+-}
+
+module Codec.ActivityStream.Schema
+  ( module Codec.ActivityStream
+  -- * Verbs
+  , SchemaVerb(..)
+  -- * Object Types
+  , SchemaObjectType(..)
+  -- ** Audio/Video
+  , avEmbedCode
+  , avStream
+  -- ** Binary
+  , bnCompression
+  , bnData
+  , bnFileUrl
+  , bnLength
+  , bnMd5
+  , bnMimeType
+  -- ** Event
+  , evAttendedBy
+  , evAttending
+  , evEndTime
+  , evInvited
+  , evMaybeAttending
+  , evNotAttendedBy
+  , evNotAttending
+  , evStartTime
+  -- ** Issue
+  , isTypes
+  -- ** Permission
+  , pmScope
+  , pmActions
+  -- ** Place
+  , plPosition
+  , plAddress
+  -- *** PlacePosition
+  , PlacePosition
+  -- *** PlaceAddress
+  , PlaceAddress
+  -- ** Role/Group
+  , rlMembers
+  -- ** Task
+  , tsActor
+  , tsBy
+  , tsObject
+  , tsPrerequisites
+  , tsRequired
+  , tsSupersedes
+  , tsVerb
+  -- * Basic Extension Properties
+  , acContext
+  , getLocation
+  , oMood
+  , oRating
+  , acResult
+  , getSource
+  , getStartTime
+  , getEndTime
+  , oTags
+    -- * Mood
+  , Mood
+  , moodRest
+  , moodDisplayName
+  , moodImage
+  ) where
+
+import qualified Data.Aeson as Aeson
+import           Data.Aeson.TH (deriveJSON)
+import           Data.DateTime (DateTime)
+import           Data.Aeson ( FromJSON(..), ToJSON(..) )
+import qualified Data.HashMap.Strict as HM
+import           Data.Text (Text)
+
+import Codec.ActivityStream.Internal
+import Codec.ActivityStream.LensInternal
+import Codec.ActivityStream
+
+-- | The ActivityStreams Base Schema specification defines the
+-- following core verbs in addition to the default post verb that is
+-- defined in Section 6 of activitystreams:
+data SchemaVerb
+  = Accept
+    -- ^ Indicates that that the actor has accepted the object.
+    -- For instance, a person accepting an award, or accepting an assignment.
+  | Access
+    -- ^ Indicates that the actor has accessed the object. For
+    -- instance, a person accessing a room, or accessing a file.
+  | Acknowledge
+    -- ^ Indicates that the actor has acknowledged the object.
+    -- This effectively signals that the actor is aware of the
+    -- object's existence.
+  | Add
+    -- ^ Indicates that the actor has added the object to the target.
+    -- For instance, adding a photo to an album.
+  | Agree
+    -- ^ Indicates that the actor agrees with the object. For example,
+    -- a person agreeing with an argument, or expressing agreement
+    -- with a particular issue.
+  | Append
+    -- ^ Indicates that the actor has appended the object to the
+    -- target. For instance, a person appending a new record
+    -- to a database.
+  | Approve
+    -- ^ Indicates that the actor has approved the object. For
+    -- instance, a manager might approve a travel request.
+  | Archive
+    -- ^ Indicates that the actor has archived the object.
+  | Assign
+    -- ^ Indicates that the actor has assigned the object to the target.
+  | At
+    -- ^ Indicates that the actor is currently located at the object.
+    -- For instance, a person being at a specific physical location.
+  | Attach
+    -- ^ Indicates that the actor has attached the object to the
+    -- target. For instance, a person attaching a file to a wiki
+    -- page or an email.
+  | Attend
+    -- ^ Indicates that the actor has attended the object. For
+    -- instance, a person attending a meeting.
+  | Author
+    -- ^ Indicates that the actor has authored the object. Note that
+    -- this is a more specific form of the verb \"create\".
+  | Authorize
+    -- ^ Indicates that the actor has authorized the object. If
+    -- a target is specified, it means that the authorization is specifically
+    -- in regards to the target. For instance, a service can authorize a
+    -- person to access a given application; in which case the actor is
+    -- the service, the object is the person, and the target is the
+    -- application. In contrast, a person can authorize a request; in
+    -- which case the actor is the person and the object is the request
+    -- and there might be no explicit target.
+  | Borrow
+    -- ^ Indicates that the actor has borrowed the object. If a target
+    -- is specified, it identifies the entity from which the object was
+    -- borrowed. For instance, if a person borrows a book from a library,
+    -- the person is the actor, the book is the object and the library is
+    -- the target.
+  | Build
+    -- ^ Indicates that the actor has built the object. For example, if a
+    -- person builds a model or compiles code.
+  | Cancel
+    -- ^ Indicates that the actor has canceled the object. For instance,
+    -- canceling a calendar event.
+  | Close
+    -- ^ Indicates that the actor has closed the object. For instance, the
+    -- object could represent a ticket being tracked in an issue management
+    -- system.
+  | Complete
+    -- ^ Indicates that the actor has completed the object.
+  | Confirm
+    -- ^ Indicates that the actor has confirmed or agrees with the object.
+    -- For instance, a software developer might confirm an issue reported
+    -- against a product.
+  | Consume
+    -- ^ Indicates that the actor has consumed the object. The specific
+    -- meaning is dependent largely on the object's type. For instance,
+    -- an actor may \"consume\" an audio object, indicating that the actor
+    -- has listened to it; or an actor may \"consume\" a book, indicating
+    -- that the book has been read. As such, the \"consume\" verb is a
+    -- more generic form of other more specific verbs such as \"read\" and
+    -- \"play\".
+  | Checkin
+    -- ^ Indicates that the actor has checked-in to the object. For
+    -- instance, a person checking-in to a Place.
+  | Create
+    -- ^ Indicates that the actor has created the object.
+  | Delete
+    -- ^ Indicates that the actor has deleted the object. This implies,
+    -- but does not require, the permanent destruction of the object.
+  | Deliver
+    -- ^ Indicates that the actor has delivered the object. For example,
+    -- delivering a package.
+  | Deny
+    -- ^ Indicates that the actor has denied the object. For example, a
+    -- manager may deny a travel request.
+  | Disagree
+    -- ^ Indicates that the actor disagrees with the object.
+  | Dislike
+    -- ^ Indicates that the actor dislikes the object. Note that the
+    -- \"dislike\" verb is distinct from the \"unlike\" verb which assumes
+    -- that the object had been previously \"liked\".
+  | Experience
+    -- ^ Indicates that the actor has experienced the object in some
+    -- manner. Note that, depending on the specific object types used for
+    -- both the actor and object, the meaning of this verb can overlap
+    -- that of the \"consume\" and \"play\" verbs. For instance, a person
+    -- might \"experience\" a movie; or \"play\" the movie; or \"consume\"
+    -- the movie. The \"experience\" verb can be considered a more generic
+    -- form of other more specific verbs as \"consume\", \"play\", \"watch\",
+    -- \"listen\", and \"read\"
+  | Favorite
+    -- ^ Indicates that the actor marked the object as an item of special
+    -- interest.
+  | Find
+    -- ^ Indicates that the actor has found the object.
+  | FlagAsInappropriate
+    -- ^ Indicates that the actor has flagged the object as being
+    -- inappropriate for some reason. When using this verb, the context
+    -- property can be used to provide additional detail about why the
+    -- object has been flagged.
+  | Follow
+    -- ^ Indicates that the actor began following the activity of the
+    -- object. In most cases, the objectType will be a \"person\", but it
+    -- can potentially be of any type that can sensibly generate activity.
+    -- Processors MAY ignore (silently drop) successive identical \"follow\"
+    -- activities.
+  | Give -- ^ Indicates that the actor is giving an object to the
+    -- target. Examples include one person giving a badge object to another
+    -- person. The object identifies the object being given. The target
+    -- identifies the receiver.
+  | Host
+    -- ^ Indicates that the actor is hosting the object. As in hosting
+    -- an event, or hosting a service.
+  | Ignore
+    -- ^ Indicates that the actor has ignored the object. For
+    -- instance, this verb may be used when an actor has ignored a friend
+    -- request, in which case the object may be the request-friend activity.
+  | Insert
+    -- ^ Indicates that the actor has inserted the object into the target.
+  | Install
+    -- ^ Indicates that the actor has installed the object, as in installing
+    -- an application.
+  | Interact
+    -- ^ Indicates that the actor has interacted with the object. For
+    -- instance, when one person interacts with another.
+  | Invite
+    -- ^ Indicates that the actor has invited the object, typically a
+    -- person object, to join or participate in the object described
+    -- by the target. The target could, for instance, be an event,
+    -- group or a service.
+  | Join
+    -- ^ Indicates that the actor has become a member of the
+    -- object. This specification only defines the meaning of this
+    -- verb when the object of the Activity has an objectType of
+    -- group, though implementors need to be prepared to handle other
+    -- types of objects.
+  | Leave
+    -- ^ Indicates that the actor has left the object. For instance, a
+    -- Person leaving a Group or checking-out of a Place.
+  | Like
+    -- ^ Indicates that the actor marked the object as an item of
+    -- special interest. The \"like\" verb is considered to be an alias
+    -- of \"favorite\". The two verb are semantically identical.
+  | Listen
+    -- ^ Indicates that the actor has listened to the object. This is
+    -- typically only applicable for objects representing audio
+    -- content, such as music, an audio-book, or a radio
+    -- broadcast. The \"listen\" verb is a more specific form of the
+    -- \"consume\", \"experience\" and \"play\" verbs.
+  | Lose
+    -- ^ Indicates that the actor has lost the object. For instance,
+    -- if a person loses a game.
+  | MakeFriend
+    -- ^ Indicates the creation of a friendship that is reciprocated
+    -- by the object. Since this verb implies an activity on the part
+    -- of its object, processors MUST NOT accept activities with this
+    -- verb unless they are able to verify through some external means
+    -- that there is in fact a reciprocated connection. For example, a
+    -- processor may have received a guarantee from a particular
+    -- publisher that the publisher will only use this Verb in cases
+    -- where a reciprocal relationship exists.
+  | Open
+    -- ^ Indicates that the actor has opened the object. For instance,
+    -- the object could represent a ticket being tracked in an issue
+    -- management system.
+  | Play
+    -- ^ Indicates that the actor spent some time enjoying the
+    -- object. For example, if the object is a video this indicates
+    -- that the subject watched all or part of the video. The \"play\"
+    -- verb is a more specific form of the \"consume\" verb.
+  | Post
+    -- ^ The default action.
+  | Present
+    -- ^ Indicates that the actor has presented the object. For
+    -- instance, when a person gives a presentation at a conference.
+  | Purchase
+    -- ^ Indicates that the actor has purchased the object. If a
+    -- target is specified, in indicates the entity from which the
+    -- object was purchased.
+  | Qualify
+    -- ^ Indicates that the actor has qualified for the object. If a
+    -- target is specified, it indicates the context within which the
+    -- qualification applies.
+  | Read
+    -- ^ Indicates that the actor read the object. This is typically
+    -- only applicable for objects representing printed or written
+    -- content, such as a book, a message or a comment. The \"read\"
+    -- verb is a more specific form of the \"consume\", \"experience\" and
+    -- \"play\" verbs.
+  | Receive
+    -- ^ Indicates that the actor is receiving an object. Examples
+    -- include a person receiving a badge object. The object
+    -- identifies the object being received.
+  | Reject
+    -- ^ Indicates that the actor has rejected the object.
+  | Remove
+    -- ^ Indicates that the actor has removed the object from the target.
+  | RemoveFriend
+    -- ^ Indicates that the actor has removed the object from the
+    -- collection of friends.
+  | Replace
+    -- ^ Indicates that the actor has replaced the target with the object.
+  | Request
+    -- ^ Indicates that the actor has requested the object. If a
+    -- target is specified, it indicates the entity from which the
+    -- object is being requested.
+  | RequestFriend
+    -- ^ Indicates the creation of a friendship that has not yet been
+    -- reciprocated by the object.
+  | Resolve
+    -- ^ Indicates that the actor has resolved the object. For
+    -- instance, the object could represent a ticket being tracked in
+    -- an issue management system.
+  | Return
+    -- ^ Indicates that the actor has returned the object. If a target
+    -- is specified, it indicates the entity to which the object was
+    -- returned.
+  | Retract
+    -- ^ Indicates that the actor has retracted the object. For
+    -- instance, if an actor wishes to retract a previously published
+    -- activity, the object would be the previously published activity
+    -- that is being retracted.
+  | RsvpMaybe
+    -- ^ The \"possible RSVP\" verb indicates that the actor has made a
+    -- possible RSVP for the object. This specification only defines
+    -- the meaning of this verb when its object is an event, though
+    -- implementors need to be prepared to handle other object
+    -- types. The use of this verb is only appropriate when the RSVP
+    -- was created by an explicit action by the actor. It is not
+    -- appropriate to use this verb when a user has been added as an
+    -- attendee by an event organiser or administrator.
+  | RsvpNo
+    -- ^ The \"negative RSVP\" verb indicates that the actor has made a
+    -- negative RSVP for the object. This specification only defines
+    -- the meaning of this verb when its object is an event, though
+    -- implementors need to be prepared to handle other object
+    -- types. The use of this verb is only appropriate when the RSVP
+    -- was created by an explicit action by the actor. It is not
+    -- appropriate to use this verb when a user has been added as an
+    -- attendee by an event organiser or administrator.
+  | RsvpYes
+    -- ^ The \"positive RSVP\" verb indicates that the actor has made a
+    -- positive RSVP for an object. This specification only defines
+    -- the meaning of this verb when its object is an event, though
+    -- implementors need to be prepared to handle other object
+    -- types. The use of this verb is only appropriate when the RSVP
+    -- was created by an explicit action by the actor. It is not
+    -- appropriate to use this verb when a user has been added as an
+    -- attendee by an event organiser or administrator.
+  | Satisfy
+    -- ^ Indicates that the actor has satisfied the object. If a
+    -- target is specified, it indicate the context within which the
+    -- object was satisfied. For instance, if a person satisfies the
+    -- requirements for a particular challenge, the person is the
+    -- actor; the requirement is the object; and the challenge is the
+    -- target.
+  | Save
+    -- ^ Indicates that the actor has called out the object as being
+    -- of interest primarily to him- or herself. Though this action
+    -- MAY be shared publicly, the implication is that the object has
+    -- been saved primarily for the actor's own benefit rather than to
+    -- show it to others as would be indicated by the \"share\" verb.
+  | Schedule
+    -- ^ Indicates that the actor has scheduled the object. For
+    -- instance, scheduling a meeting.
+  | Search
+    -- ^ Indicates that the actor is or has searched for the
+    -- object. If a target is specified, it indicates the context
+    -- within which the search is or has been conducted.
+  | Sell
+    -- ^ Indicates that the actor has sold the object. If a target is
+    -- specified, it indicates the entity to which the object was
+    -- sold.
+  | Send
+    -- ^ Indicates that the actor has sent the object. If a target is
+    -- specified, it indicates the entity to which the object was
+    -- sent.
+  | Share
+    -- ^ Indicates that the actor has called out the object to
+    -- readers. In most cases, the actor did not create the object
+    -- being shared, but is instead drawing attention to it.
+  | Sponsor
+    -- ^ Indicates that the actor has sponsored the object. If a
+    -- target is specified, it indicates the context within which the
+    -- sponsorship is offered. For instance, a company can sponsor an
+    -- event; or an individual can sponsor a project; etc.
+  | Start
+    -- ^ Indicates that the actor has started the object. For
+    -- instance, when a person starts a project.
+  | StopFollowing
+    -- ^ Indicates that the actor has stopped following the object.
+  | Submit
+    -- ^ Indicates that the actor has submitted the object. If a
+    -- target is specified, it indicates the entity to which the
+    -- object was submitted.
+  | Tag
+    -- ^ Indicates that the actor has associated the object with the
+    -- target. For example, if the actor specifies that a particular
+    -- user appears in a photo. the object is the user and the target
+    -- is the photo.
+  | Terminate
+    -- ^ Indicates that the actor has terminated the object.
+  | Tie
+    -- ^ Indicates that the actor has neither won or lost the
+    -- object. This verb is generally only applicable when the object
+    -- represents some form of competition, such as a game.
+  | Unfavorite
+    -- ^ Indicates that the actor has removed the object from the
+    -- collection of favorited items.
+  | Unlike
+    -- ^ Indicates that the actor has removed the object from the
+    -- collection of liked items.
+  | Unsatisfy
+    -- ^ Indicates that the actor has not satisfied the object. If a
+    -- target is specified, it indicates the context within which the
+    -- object was not satisfied. For instance, if a person fails to
+    -- satisfy the requirements of some particular challenge, the
+    -- person is the actor; the requirement is the object and the
+    -- challenge is the target.
+  | Unsave
+    -- ^ Indicates that the actor has removed the object from the
+    -- collection of saved items.
+  | Unshare
+    -- ^ Indicates that the actor is no longer sharing the object. If
+    -- a target is specified, it indicates the entity with whom the
+    -- object is no longer being shared.
+  | Update
+    -- ^ The \"update\" verb indicates that the actor has modified the
+    -- object. Use of the \"update\" verb is generally reserved to
+    -- indicate modifications to existing objects or data such as
+    -- changing an existing user's profile information.
+  | Use
+    -- ^ Indicates that the actor has used the object in some manner.
+  | Watch
+    -- ^ Indicates that the actor has watched the object. This verb is
+    -- typically applicable only when the object represents dynamic,
+    -- visible content such as a movie, a television show or a public
+    -- performance. This verb is a more specific form of the verbs
+    -- \"experience\", \"play\" and \"consume\".
+  | Win
+    -- ^ Indicates that the actor has won the object. This verb is
+    -- typically applicable only when the object represents some form
+    -- of competition, such as a game.
+    deriving (Eq, Show, Read)
+
+deriveJSON (commonOptsCC "") ''SchemaVerb
+
+-- | This data type contains the core set of common objectTypes in addition
+-- to the "activity" objectType defined in Section 7 of
+-- activitystreams.
+--
+-- All Activity Stream Objects inherit the same
+-- fundamental set of basic properties as defined in section 3.4 of
+-- activitystreams. In addition to these, objects of any specific type
+-- are permitted to introduce additional optional or required
+-- properties that are meaningful to objects of that type.
+data SchemaObjectType
+  = Alert
+    -- ^ Represents any kind of significant notification.
+  | Application
+    -- ^ Represents any kind of software application.
+  | Article
+    -- ^ Represents objects such as news articles, knowledge base
+    -- entries, or other similar construct. Such objects generally
+    -- consist of paragraphs of text, in some cases incorporating
+    -- embedded media such as photos and inline hyperlinks to other
+    -- resources.
+  | Audio
+    -- ^ Represents audio content of any kind. Objects of this type
+    -- MAY contain an additional property as specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#audio-video here>.
+  | Badge
+    -- ^ Represents a badge or award granted to an object (typically a
+    -- @person@ object)
+  | Binary
+    -- ^ Objects of this type are used to carry arbirary
+    -- Base64-encoded binary data within an Activity Stream object. It
+    -- is primarily intended to attach binary data to other types of
+    -- objects through the use of the @attachments@ property. Objects
+    -- of this type will contain the additional properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#binary here>.
+  | Bookmark
+    -- ^ Represents a pointer to some URL -- typically a web page. In
+    -- most cases, bookmarks are specific to a given user and contain
+    -- metadata chosen by that user. Bookmark Objects are similar in
+    -- principle to the concept of bookmarks or favorites in a web
+    -- browser. A bookmark represents a pointer to the URL, not the
+    -- URL or the associated resource itself. Objects of this type
+    -- SHOULD contain an additional @targetUrl@ property whose value
+    -- is a String containing the IRI of the target of the bookmark.
+  | Collection
+    -- ^ Represents a generic collection of objects of any type. This
+    -- object type can be used, for instance, to represent a
+    -- collection of files like a folder; a collection of photos like
+    -- an album; and so forth. Objects of this type MAY contain an
+    -- additional @objectTypes@ property whose value is an Array of
+    -- Strings specifying the expected objectType of objects contained
+    -- within the collection.
+  | Comment
+    -- ^ Represents a textual response to another object. Objects of
+    -- this type MAY contain an additional @inReplyTo@ property whose
+    -- value is an Array of one or more other Activity Stream Objects
+    -- for which the object is to be considered a response.
+  | Device
+    -- ^ Represents a device of any type.
+  | Event
+    -- ^ Represents an event that occurs at a certain location during
+    -- a particular period of time. Objects of this type MAY contain
+    -- the additional properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#event here>.
+  | File
+    -- ^ Represents any form of document or file. Objects of this type
+    -- MAY contain an additional @fileUrl@ property whose value a
+    -- dereferenceable IRI that can be used to retrieve the file; and
+    -- an additional @mimeType@ property whose value is the MIME type
+    -- of the file described by the object.
+  | Game
+    -- ^ Represents a game or competition of any kind.
+  | Group
+    -- ^ Represents a grouping of objects in which member objects can
+    -- join or leave. Objects of this type MAY contain the additional
+    -- properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#roleGroup here>.
+  | Image
+    -- ^ Represents a graphical image. Objects of this type MAY
+    -- contain an additional @fullImage@ property whose value is an
+    -- Activity Streams Media Link to a "full-sized" representation of
+    -- the image.
+  | Issue
+    -- ^ Represents a report about a problem or situation that needs
+    -- to be resolved. For instance, the @issue@ object can be used to
+    -- represent reports detailing software defects, or reports of
+    -- acceptable use violations, and so forth. Objects of this type
+    -- MAY contain the additional properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#issue here>.
+  | Job
+    -- ^ Represents information about a job or a job posting.
+  | Note
+    -- ^ Represents a short-form text message. This object is intended
+    -- primarily for use in "micro-blogging" scenarios and in systems
+    -- where users are invited to publish short, often plain-text
+    -- messages whose useful lifespan is generally shorter than that
+    -- of an article of weblog entry. A note is similar in structure
+    -- to an article, but typically does not have a title or distinct
+    -- paragraphs and tends to be much shorter in length.
+  | Offer
+    -- ^ Represents an offer of any kind.
+  | Organization
+    -- ^ Represents an organization of any kind.
+  | Page
+    -- ^ Represents an area, typically a web page, that is
+    -- representative of, and generally managed by a particular
+    -- entity. Such areas are usually dedicated to displaying
+    -- descriptive information about the entity and showcasing recent
+    -- content such as articles, photographs and videos. Most social
+    -- networking applications, for example, provide individual users
+    -- with their own dedicated "profile" pages. Several allow similar
+    -- types of pages to be created for commercial entities,
+    -- organizations or events. While the specific details of how
+    -- pages are implemented, their characteristics and use may vary,
+    -- the one unifying property is that they are typically "owned" by
+    -- a single entity that is represented by the content provided by
+    -- the page itself.
+  | Permission
+    -- ^ Represents a permission that can be granted to an
+    -- individual. For instance, a person can be granted permission to
+    -- modify a file. Objects of this type MAY contain the additional
+    -- properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#permissions here>.
+  | Person
+    -- ^ Represents an individual person.
+  | Place
+    -- ^ Represents a physical location. Locations can be represented
+    -- using geographic coordinates, a physical address, a free-form
+    -- location name, or any combination of these. Objects of this
+    -- type MAY contain the additional properties specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#place here>.
+  | Process
+    -- ^ Represents any form of process. For instance, a long-running
+    -- task that is started and expected to continue operating for a
+    -- period of time.
+  | Product
+    -- ^ Represents a commercial good or service. Objects of this type
+    -- MAY contain an additional @fullImage@ property whose value is
+    -- an Activity Streams Media Link to an image resource
+    -- representative of the product.
+  | Question
+    -- ^ Represents a question or a poll. Objects of this type MAY
+    -- contain an additional @options@ property whose value is an
+    -- Array of possible answers to the question in the form of
+    -- Activity Stream objects of any type.
+  | Review
+    -- ^ Represents a primarily prose-based commentary on another
+    -- object. Objects of this type MAY contain a @rating@ property as
+    -- specified
+    -- <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md#rating-property here>.
+  | Service
+    -- ^ Represents any form of hosted or consumable service that
+    -- performs some kind of work or benefit for other
+    -- entities. Examples of such objects include websites,
+    -- businesses, etc.
+  | Task
+    -- ^ Represents an activity that has yet to be completed. Objects
+    -- of this type can contain additional properties as specified
+    -- here.
+  | Team
+    -- ^ Represents a team of any type.
+  | Video
+    -- ^ Represents video content of any kind. Objects of this type
+    -- MAY contain additional properties as specified here.
+    deriving (Eq, Show, Read)
+
+deriveJSON (commonOptsCC "") ''SchemaObjectType
+
+
+-- audio/video
+
+-- | A fragment of HTML markup that, when embedded within another HTML
+--   page, provides an interactive user-interface for viewing or listening
+--   to the video or audio stream.
+avEmbedCode :: Lens' Object (Maybe Text)
+avEmbedCode = makeAesonLensMb "embedCode" oRest
+
+-- | An Activity Streams Media Link to the video or audio content itself.
+avStream :: Lens' Object (Maybe MediaLink)
+avStream = makeAesonLensMb "stream" oRest
+
+-- binary
+
+-- | An optional token identifying a compression algorithm applied to
+--   the binary data prior to Base64-encoding. Possible algorithms
+--   are "deflate" and "gzip", respectively indicating the use of
+--   the compression mechanisms defined by RFC 1951 and RFC 1952.
+--   Additional compression algorithms MAY be used but are not defined
+--   by this specification. Note that previous versions of this
+--   specification allowed for multiple compression algorithms to be
+--   applied and listed using a comma-separated format. The use of
+--   multiple compressions is no longer permitted.
+bnCompression :: Lens' Object (Maybe Text)
+bnCompression = makeAesonLensMb "compression" oRest
+
+-- | The URL-Safe Base64-encoded representation of the binary data
+bnData :: Lens' Object (Maybe Text)
+bnData = makeAesonLensMb "data" oRest
+-- | An optional IRI for the binary data described by this object.
+bnFileUrl :: Lens' Object (Maybe Text)
+bnFileUrl = makeAesonLensMb "fileUrl" oRest
+
+-- | The total number of unencoded, uncompressed octets contained
+-- within the "data" field.
+bnLength :: Lens' Object (Maybe Text)
+bnLength = makeAesonLensMb "length" oRest
+
+-- | An optional MD5 checksum calculated over the unencoded,
+-- uncompressed octets contained within the "data" field
+bnMd5 :: Lens' Object (Maybe Text)
+bnMd5 = makeAesonLensMb "md5" oRest
+
+-- | The MIME Media Type of the binary data contained within the object.
+bnMimeType :: Lens' Object (Maybe Text)
+bnMimeType = makeAesonLensMb "mimeType" oRest
+
+-- event
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that attended the event.
+evAttendedBy :: Lens' Object (Maybe Collection)
+evAttendedBy = makeAesonLensMb "attendedBy" oRest
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that intend to attend the event.
+evAttending :: Lens' Object (Maybe Collection)
+evAttending = makeAesonLensMb "attending" oRest
+
+-- | The date and time that the event ends represented as a String
+-- conforming to the "date-time" production in [RFC3339].
+evEndTime :: Lens' Object (Maybe DateTime)
+evEndTime = makeAesonLensMb "endTime" oRest
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that have been invited to the event.
+evInvited :: Lens' Object (Maybe Collection)
+evInvited = makeAesonLensMb "invited" oRest
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that possibly may attend the event.
+evMaybeAttending :: Lens' Object (Maybe Collection)
+evMaybeAttending = makeAesonLensMb "maybeAttending" oRest
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that did not attend the event.
+evNotAttendedBy :: Lens' Object (Maybe Collection)
+evNotAttendedBy = makeAesonLensMb "notAttendedBy" oRest
+
+-- | A collection object as defined in Section 3.5 of the JSON
+-- Activity Streams specification that provides information about
+-- entities that do not intend to attend the event.
+evNotAttending :: Lens' Object (Maybe Collection)
+evNotAttending = makeAesonLensMb "notAttending" oRest
+
+-- | The date and time that the event begins represented as a String
+-- confirming to the "date-time" production in RFC 3339.
+evStartTime :: Lens' Object (Maybe DateTime)
+evStartTime = makeAesonLensMb "startTime" oRest
+
+-- issue
+
+-- | An array of one or more absolute IRI's that describe the type of
+-- issue represented by the object. Note that the IRI's are intended
+-- for use as identifiers and MAY or MAY NOT be dereferenceable.
+isTypes :: Lens' Object (Maybe [Text])
+isTypes = makeAesonLensMb "types" oRest
+
+-- permission
+
+-- | A single Activity Streams Object, of any objectType, that
+-- identifies the scope of the permission. For example, if the
+-- permission objects describes write permissions for a given file,
+-- the scope property would be a file object describing that file.
+pmScope :: Lens' Object (Maybe Object)
+pmScope = makeAesonLensMb "scope" oRest
+
+-- | An array of Strings that identify the specific actions associated
+-- with the permission. The actions are application and scope
+-- specific. No common, core set of actions is defined by this
+-- specification.
+pmActions :: Lens' Object (Maybe [Text])
+pmActions = makeAesonLensMb "actions" oRest
+
+-- place
+
+-- | The latitude, longitude and altitude of the place as a point on
+-- Earth. Represented as a JSON Object as described below.
+plPosition :: Lens' Object (Maybe PlacePosition)
+plPosition = makeAesonLensMb "position" oRest
+
+-- | A physical address represented as a JSON object as described below.
+plAddress :: Lens' Object (Maybe PlaceAddress)
+plAddress = makeAesonLensMb "address" oRest
+
+newtype PlacePosition = PPO { fromPPO :: Aeson.Object } deriving (Eq, Show)
+
+instance FromJSON PlacePosition where
+  parseJSON (Aeson.Object o) = do
+    ensure "Position" o
+      ["altitude", "latitude", "longitude"]
+    return (PPO o)
+  parseJSON _ = fail "\"Position\" not an object"
+
+instance ToJSON PlacePosition where
+  toJSON = Aeson.Object . fromPPO
+
+newtype PlaceAddress = PAO { fromPAO :: Aeson.Object } deriving (Eq, Show)
+
+instance FromJSON PlaceAddress where
+  parseJSON (Aeson.Object o) = do
+    ensure "Address" o
+      [ "formatted"
+      , "streetAddress"
+      , "locality"
+      , "postalCode"
+      , "country"
+      ]
+    return (PAO o)
+  parseJSON _ = fail "Address not an object"
+
+instance ToJSON PlaceAddress where
+  toJSON = Aeson.Object . fromPAO
+
+-- role/group
+
+-- | An optional Activity Streams Collection object listing the
+-- members of a group, or listing the entities assigned to a
+-- particular role.
+rlMembers :: Lens' Object (Maybe [Object])
+rlMembers = makeAesonLensMb "members" oRest
+
+-- Task
+
+-- | An Activity Streams Object that provides information about the
+-- actor that is expected to complete the task.
+tsActor :: Lens' Object (Maybe Object)
+tsActor = makeAesonLensMb "actor" oRest
+
+-- | A RFC 3339 date-time specifying the date and time by which the
+-- task is to be completed.
+tsBy :: Lens' Object (Maybe DateTime)
+tsBy = makeAesonLensMb "by" oRest
+
+-- | An Activity Streams object describing the object of the task.
+tsObject :: Lens' Object (Maybe Object)
+tsObject = makeAesonLensMb "object" oRest
+
+-- | An Array of other Task objects that are to be completed before
+-- this task can be completed.
+tsPrerequisites :: Lens' Object (Maybe [Object])
+tsPrerequisites = makeAesonLensMb "prerequisites" oRest
+
+-- | A boolean value indicating whether completion of this task is
+-- considered to be mandatory.
+tsRequired :: Lens' Object (Maybe Bool)
+tsRequired = makeAesonLensMb "required" oRest
+
+-- | An Array of other Task objects that are superseded by this task object.
+tsSupersedes :: Lens' Object (Maybe [Object])
+tsSupersedes = makeAesonLensMb "supersedes" oRest
+
+-- | A string indicating the verb for this task as defined in Section
+-- 3.2 of [activitystreams].
+tsVerb :: Lens' Object (Maybe SchemaVerb)
+tsVerb = makeAesonLensMb "verb" oRest
+
+-- extra properties
+
+-- | The additional @context@ property allows an 'Activity' to further
+-- include information about why a particular action occurred by
+-- providing details about the context within which a particular
+-- Activity was performed. The value of the @context@ property is an
+-- 'Object' of any @objectType@. The meaning of the @context@ property is
+-- only defined when used within an 'Activity' object.
+acContext :: Lens' Activity (Maybe Object)
+acContext = makeAesonLensMb "context" acRest
+
+-- | When appearing within an activity, the location data indicates
+-- the location where the activity occurred. When appearing within an
+-- object, the location data indicates the location of that object at
+-- the time the activity occurred.
+getLocation :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
+getLocation = makeAesonLensMb "location"
+
+-- | Mood describes the mood of the user when the activity was
+-- performed. This is usually collected via an extra field in the user
+-- interface used to perform the activity. For the purpose of the
+-- schema, a mood is a freeform, short mood keyword or phrase along
+-- with an optional mood icon image.
+oMood :: Lens' Object (Maybe Mood)
+oMood = makeAesonLensMb "mood" oRest
+
+-- | A rating given as a number between 1.0 and 5.0 inclusive with one
+-- decimal place of precision. Represented in JSON as a property
+-- called @rating@ whose value is a JSON number giving the rating.
+oRating :: Lens' Object (Maybe Double)
+oRating = makeAesonLensMb "rating" oRest
+
+-- | The @result@ provides a description of the result of any particular
+-- activity. The value of the @result@ property is an Object of any
+-- objectType. The meaning of the @result@ property is only defined when
+-- used within an 'Activity' object.
+acResult :: Lens' Activity (Maybe Object)
+acResult = makeAesonLensMb "result" acRest
+
+-- | The @source@ property provides a reference to the original source of
+-- an object or activity. The value of the @source@ property is an
+-- Object of any objectType.
+--
+-- The @source@ property is closely related to
+-- the @generator@ and @provider@ properties but serves the distinct
+-- purpose of identifying where the activity or object was originally
+-- published as opposed to identifying the applications that generated
+-- or published it.
+getSource :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
+getSource = makeAesonLensMb "source"
+
+-- | When an long running Activity occurs over a distinct period of
+-- time, or when an Object represents a long-running process or event,
+-- the @startTime@ propertiy can be used to specify the
+-- date and time at which the activity or object begins.
+-- The values for each are represented as JSON Strings
+-- conforming to the "date-time" production in RFC3339.
+getStartTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
+getStartTime = makeAesonLensMb "startTime"
+
+-- | When an long running Activity occurs over a distinct period of
+-- time, or when an Object represents a long-running process or event,
+-- the @endTime@ propertiy can be used to specify the
+-- date and time at which the activity or object concludes.
+-- The values for each are represented as JSON Strings
+-- conforming to the "date-time" production in RFC3339.
+getEndTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
+getEndTime = makeAesonLensMb "endTime"
+
+-- | A listing of the objects that have been associated with a
+-- particular object. Represented in JSON using a property named @tags@
+-- whose value is an Array of objects.
+oTags :: Lens' Object (Maybe [Object])
+oTags = makeAesonLensMb "tags" oRest
+
+-- mood
+
+-- | Mood describes the mood of the user when the activity was
+-- performed. This is usually collected via an extra field in the user
+-- interface used to perform the activity. For the purpose of this
+-- schema, a mood is a freeform, short mood keyword or phrase along
+-- with an optional mood icon image.
+newtype Mood = Mood { fromMood :: Aeson.Object } deriving (Eq, Show)
+
+instance FromJSON Mood where
+  parseJSON (Aeson.Object o) = do
+    ensure "Mood" o ["displayname", "image"]
+    return (Mood o)
+  parseJSON _ = fail "Mood not an object"
+
+instance ToJSON Mood where
+  toJSON = Aeson.Object . fromMood
+
+-- | Access to the underlying JSON object of a 'Mood'
+moodRest :: Lens' Mood Aeson.Object
+moodRest = makeLens fromMood (\ o' m -> m { fromMood = o' })
+
+-- | The natural-language, human-readable and plain-text keyword or
+-- phrase describing the mood. HTML markup MUST NOT be included.
+moodDisplayName :: Lens' Mood Text
+moodDisplayName = makeAesonLens "displayName" moodRest
+
+-- | An optional image that provides a visual representation of the mood.
+moodImage :: Lens' Mood MediaLink
+moodImage = makeAesonLens "image" moodRest
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Getty Ritter
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Getty Ritter nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/activitystreams-aeson.cabal b/activitystreams-aeson.cabal
new file mode 100644
--- /dev/null
+++ b/activitystreams-aeson.cabal
@@ -0,0 +1,37 @@
+name:                activitystreams-aeson
+version:             0.2.0.0
+synopsis:            An interface to the ActivityStreams specification
+description:         An interface to the
+                     <http://activitystrea.ms/ Activity Streams>
+                     specifications, using an @aeson@-based representation
+                     of the underlying ActivityStream structures.
+
+                     An ActivityStream is a representation of social
+                     activities in JSON format, using a standard set of
+                     structures. The specification is very flexible in
+                     allowing most fields to be omitted, while also
+                     allowing arbitrary new fields to be created when
+                     necessary. This library attempts to maximize
+                     type safety while retaining the flexibility present
+                     in the specification.
+license:             BSD3
+license-file:        LICENSE
+author:              Getty Ritter
+maintainer:          gettylefou@gmail.com
+copyright:           (c) 2014 Getty Ritter
+category:            Codec
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Codec.ActivityStream
+                       Codec.ActivityStream.Schema
+  other-modules:       Codec.ActivityStream.Internal,
+                       Codec.ActivityStream.Representation,
+                       Codec.ActivityStream.LensInternal
+  build-depends:       base                 >=4.7 && <4.8,
+                       aeson                ==0.8.*,
+                       text                 >=1.1,
+                       datetime             ==0.2.*,
+                       unordered-containers >=0.2.5
+  default-language:    Haskell2010
