diff --git a/Data/Generic/Diff.hs b/Data/Generic/Diff.hs
new file mode 100644
--- /dev/null
+++ b/Data/Generic/Diff.hs
@@ -0,0 +1,533 @@
+{-#  LANGUAGE GADTs  #-}
+{-#  LANGUAGE KindSignatures  #-}
+{-#  LANGUAGE TypeFamilies  #-}
+{-#  LANGUAGE TypeOperators  #-}
+{-#  LANGUAGE MultiParamTypeClasses  #-}
+{-#  LANGUAGE FunctionalDependencies  #-}
+{-#  LANGUAGE FlexibleInstances  #-}
+{-#  LANGUAGE RankNTypes  #-}
+{-#  LANGUAGE ScopedTypeVariables  #-}
+{-#  LANGUAGE OverlappingInstances  #-} --  Only for the Show
+
+{- |
+
+Use this library to get an efficient, optimal, type-safe 'diff' and
+'patch' function for your datatypes of choice by defining a simple GADT and
+some class instances.  The process is explained in the documentation of the
+'Family' type class.
+
+The result of 'diff' is an optimal 'EditScript' that contains the operations
+that need to be performed to get from the /source/ value to the /destination/
+value. The edit script can be used by 'patch', inspected with 'show' and used
+for all kinds of interesting stuff /you/ come up with.
+
+The library has been extracted from Eelco Lempsink's Master's Thesis 
+/Generic type-safe diff and patch for families of datatypes/ (available online:
+<http://eelco.lempsink.nl/thesis.pdf>).  See Appendix C for a large example.
+Note that some types and functions have been renamed for the benefit of the API
+(e.g., @diff@ to @diffL@, @diff1@ to @diff@, @Diff@ to @EditScriptL@).
+
+-}
+module Data.Generic.Diff (
+    -- * Diffing and patchLing
+    diff,
+    patch,  
+    -- ** For multiple datatypes 
+    diffL,
+    patchL, 
+    -- ** Patch compression
+    compress,
+    -- * Patch datatype
+    EditScriptL(..),
+    EditScript,
+    -- * Type classes
+    Family(..),
+    Type(..),
+    -- ** Supporting datatypes 
+    (:=:)(..),
+    Con(..),
+    Nil(..), 
+    Cons(..),
+) where
+
+-- | Edit script type for two single values.
+type EditScript f x y = EditScriptL f (Cons x Nil) (Cons y Nil)
+
+-- | Apply the edit script to value.
+patch :: EditScript f x y -> x -> y
+patch d x = case patchL d (CCons x CNil) of
+               CCons y CNil -> y
+
+-- | Calculate the difference between two values in the form of an edit script.
+--
+-- See the documentation for 'Family' for how to make your own data types work
+-- with this function.
+diff :: (Type f x, Type f y) => x -> y -> EditScript f x y
+diff x y = diffL (CCons x CNil) (CCons y CNil)
+
+-- | Underlying implementation of 'patch', works with (heterogeneous) lists of
+-- values.
+patchL :: forall f txs tys . EditScriptL f txs tys -> txs -> tys
+patchL (Ins  c   d) = insert c .  patchL d
+patchL (Del  c   d) =             patchL d . delete c
+patchL (Cpy  c   d) = insert c .  patchL d . delete c
+patchL (CpyTree  d) = \(CCons x xs) -> CCons x . patchL d $ xs 
+
+-- | Underlying implementation of 'diff', works with (heterogeneous) lists of
+-- values.
+diffL :: (Family f, List f txs, List f tys) => txs -> tys -> EditScriptL f txs tys
+diffL x y = getEditScriptL $ diffLMemo x y
+
+
+-- | Datatype for type level lists, corresponding to '[]'.  Use when creating
+-- your 'Family' instance.
+data Nil        = CNil
+-- | Datatype for type level lists, corresponding to '(:)'.  Use when creating
+-- your 'Family' instance.
+data Cons x xs  = CCons x xs
+
+{- | 
+
+To use 'diff' and 'patch' on your datatypes, you must create an instance of
+'Family'.  
+
+There are four steps to set up everything for 'diff' and 'patch'.
+
+(1) Define your datatypes.  (Presumable, you already have done this.)
+
+(2) Create a family datatype, grouping your datatypes together.
+
+(3) Make the family datatype an instance of 'Family'
+
+(4) Create 'Type' instances for each member of the family.
+
+Steps 1-3 are explained below, step 4 is explained in the documentation for
+'Type'.
+
+As a running example, we create a simple family of datatypes (step 1):
+
+> data Expr  =  Min Expr Term
+> data Term  =  Parens Expr
+>            |  Number Int
+
+The second step is creating the family datatype.  Each constructor in the
+datatypes above gets a constructor in a family GADT:
+
+> data ExprTermFamily :: * -> * -> * where
+>     Min'     ::          ExprTermFamily Expr (Cons Expr (Cons Term Nil)) 
+>     Parens'  ::          ExprTermFamily Term (Cons Expr Nil)
+>     Number'  ::          ExprTermFamily Term (Cons Int Nil)
+>     Int'     ::  Int ->  ExprTermFamily Int  Nil
+
+The first type argument of the datatype must be the resulting type of the
+constructor.  The second argument captures the types of the arguments the
+constructor expects.  Note how to use 'Cons' and 'Nil' to create type level
+lists.
+
+The @Int'@ constructor is special, in the sense that it captures the 'Int' type
+abstractly (listing all 'Int''s constructors would be quite impossible).
+
+/Caveat emptor/: polymorphic datatypes (like lists) are ill-supported and
+require family constructors for each instance.  It might require another master
+thesis project to solve this.
+
+Step 3 is to create the instance for the 'Family' class.  For each function you
+will have to implement four functions.  It's straightforward albeit a bit
+boring.
+
+> instance Family ExprTermFamily where
+>     decEq Min'      Min'      =              Just (Refl, Refl)
+>     decEq Parens'   Parens'   =              Just (Refl, Refl)
+>     decEq Number'   Number'   =              Just (Refl, Refl)
+>     decEq (Int' x)  (Int' y)  | x == y     = Just (Refl, Refl)
+>                               | otherwise  = Nothing
+>     decEq _        _          = Nothing
+> 
+>     fields Min'      (Min e t)   = Just (CCons e (CCons t CNil))
+>     fields Parens'   (Parens e)  = Just (CCons e CNil)
+>     fields Number'   (Number i)  = Just (CCons i CNil)
+>     fields (Int' _)  _           = Just CNil
+>     fields _         _           = Nothing
+> 
+>     apply Min'      (CCons e (CCons t CNil))  = Min e t
+>     apply Parens'   (CCons e CNil)            = Parens e
+>     apply Number'   (CCons i CNil)            = Number i
+>     apply (Int' i)  CNil                      = i
+> 
+>     string Min'      = "Min"
+>     string Parens'   = "Parens"
+>     string Number'   = "Number"
+>     string (Int' i)  = show i
+
+-}
+
+class Family f where
+    -- | Return an instance of the equality GADT ('Refl') of the type and
+    -- constructor arguments are equal, else return 'Nothing'.
+    decEq     ::                f tx txs -> f ty tys -> Maybe (tx :=: ty, txs :=: tys)
+    -- | When the constructor from the family matches the 'real' constructor,
+    -- return the arguments in a heterogeneous list, else return 'Nothing'.
+    fields    ::                f t ts -> t -> Maybe ts
+    -- | When the constructor from the family and the heterogeneous list of
+    -- arguments match, apply the 'real' constructor.  For abstract
+    -- constructors, the list of arguments should be 'CNil', but you project
+    -- out the value saved with the family constructor.
+    apply     ::                f t ts -> ts -> t
+    -- | For 'show'ing the constructors from the family.
+    string    ::                f t ts -> String
+
+-- | Equality GADT, see the documentation for 'Family' for an example of its use.
+data a :=: b where
+  Refl :: a :=: a
+
+{- |
+
+For each type in the family, you need to create an instance of 'Type', listing
+all the members of the family GADT which belong to one type.
+
+This is step 4 of the four steps needed to be able to use 'diff' and 'patch'.
+Steps 1-3 are explained in the documentation for 'Family'.
+
+Continuing the example from the 'Family' documentation, the instances for
+'Type' are:
+
+> instance Type ExprTermFamily Term where
+>     constructors = [Concr Number', Concr Parens']
+> 
+> instance Type ExprTermFamily Expr where
+>     constructors = [Concr Min']
+> 
+> instance Type ExprTermFamily Int where
+>     constructors = [Abstr Int']
+
+-} 
+
+class (Family f) => Type f t where
+    -- | List of constructors from the family GADT for one type in your family
+    constructors :: [Con f t]
+
+-- | 'Con' wraps both concrete and abstract constructors to a simple type so
+-- constructors for a single type can be put together in a list, see 'Type' for
+-- more information and an example. 
+--
+-- Use 'Concr' for concrete constructors (e.g., for simple abstract datatypes).
+--
+-- Use 'Abstr' for abstract constructors (e.g., for build-in types or types with many
+-- (or infinite) constructors)
+data Con :: (* -> * -> *) -> * -> * where
+    Concr   :: (List f ts)        =>        f t ts   -> Con f t
+    Abstr   :: (Eq t, List f ts)  => (t ->  f t ts)  -> Con f t
+
+class List f ts where
+  list :: IsList f ts
+
+data IsList :: (* -> * -> *) -> * -> * where
+  IsNil   ::                               IsList f Nil
+  IsCons  :: (Type f t) => IsList f ts ->  IsList f (Cons t ts)
+
+instance List f Nil where
+  list = IsNil
+
+instance (Type f t, List f ts) => List f (Cons t ts) where
+  list = IsCons list
+
+{- |
+
+The 'EditScriptL' datatype captures the result of 'diffL' and can be used as the input
+to 'patchL' (and 'compress').
+
+The 'diffL' function use a depth-first preorder traversal to traverse the
+expression trees.  The edit script it outputs contains the operation that must
+be applied to the constructor at that point: either keeping it ('Cpy'),
+removing it ('Del', which does not remove the complete subtree, but /contracts/
+the edge of the removed node) or inserting a new constructor ('Ins', which can
+only be done if the available subtrees at that point correspond to the types
+the constructor expects). (The 'CpyTree' is only used when running 'compress'
+over an existing edit script.)
+
+For more information about this datatype, you're advised to look at Eelco
+Lempsink's thesis at <http://eelco.lempsink.nl/thesis.pdf>.
+
+-}
+data EditScriptL :: (* -> * -> *) -> * -> * -> * where
+  Ins      ::  (Type f t, List f ts,              List f tys)  => f t ts  ->
+               EditScriptL f               txs   (Append ts    tys)              ->
+               EditScriptL f               txs   (Cons t       tys)
+  Del      ::  (Type f t, List f ts, List f txs)               => f t ts  ->
+               EditScriptL f (Append ts    txs)                tys               ->
+               EditScriptL f (Cons t       txs)                tys
+  Cpy      ::  (Type f t, List f ts, List f txs,  List f tys)  => f t ts  ->
+               EditScriptL f (Append ts    txs)  (Append ts    tys)              ->
+               EditScriptL f (Cons t       txs)  (Cons t       tys)
+
+  CpyTree  ::  (Type f t, List f txs, List f tys) =>
+               EditScriptL f txs tys                                             -> 
+               EditScriptL f (Cons t txs) (Cons t tys)
+
+  End      ::  EditScriptL f Nil                 Nil
+
+type family    Append txs tys :: *
+type instance  Append Nil            tys = tys
+type instance  Append (Cons tx txs)  tys = Cons tx (Append txs tys)
+
+appendList :: IsList f txs -> IsList f tys -> IsList f (Append txs tys)
+appendList IsNil         isys = isys
+appendList (IsCons isxs) isys = IsCons (appendList isxs isys)
+
+append :: IsList f txs -> IsList f tys -> txs -> tys -> Append txs tys
+append IsNil         _    CNil         ys = ys
+append (IsCons isxs) isys (CCons x xs) ys = CCons x (append isxs isys xs ys)
+
+instance Show (EditScriptL f txs tys) where
+  show (Ins  c   d)  = "Ins "  ++ string c  ++ " $ " ++ show d
+  show (Del  c   d)  = "Del "  ++ string c  ++ " $ " ++ show d
+  show (Cpy  c   d)  = "Cpy "  ++ string c  ++ " $ " ++ show d
+  show (CpyTree  d)  = "CpyTree"            ++ " $ " ++ show d
+  show End           = "End"
+
+delete :: (Type f t, List f ts, List f txs) => f t ts -> Cons t txs -> Append ts txs
+delete c (CCons x xs) =
+  case fields c x of
+    Nothing  -> error "Patching failed"
+    Just ts  -> append (isList c) list ts xs
+
+isList :: (Family f, List f ts) => f t ts -> IsList f ts
+isList _ = list
+
+insert :: (Type f t, List f ts, List f txs) => f t ts -> Append ts txs -> Cons t txs
+insert c xs = CCons (apply c txs) tys
+  where (txs, tys) = split (isList c) xs
+
+split :: IsList f txs -> Append txs tys -> (txs, tys)
+split IsNil         ys              = (CNil, ys)
+split (IsCons isxs) (CCons x xsys)  =  let  (xs, ys) = split isxs xsys
+                                       in   (CCons x xs, ys)
+
+matchConstructor ::  (Type f t) => t ->
+                     (forall ts. f t ts -> IsList f ts -> ts -> r) -> r
+matchConstructor = tryEach constructors
+  where
+    tryEach :: (Type f t) => [Con f t] -> t -> 
+      (forall ts. f t ts -> IsList f ts -> ts -> r) -> r
+    tryEach (Concr c  : cs)  x  k  = matchOrRetry c      cs x k
+    tryEach (Abstr c  : cs)  x  k  = matchOrRetry (c x)  cs x k
+    tryEach [] _ _ = error "Incorrect Family or Type instance."
+
+    matchOrRetry :: (List f ts, Type f t) => f t ts -> [Con f t] -> t -> 
+      (forall ts'. f t ts' -> IsList f ts' -> ts' -> r) -> r
+    matchOrRetry c cs x k = case fields c x of
+      Just ts  -> k c (isList c) ts
+      Nothing  -> tryEach cs x k
+
+best :: EditScriptL f txs tys -> EditScriptL f txs tys -> EditScriptL f txs tys
+best dx dy = bestSteps (steps dx) dx (steps dy) dy
+
+data Nat = Zero | Succ Nat
+  deriving (Eq, Show)
+
+steps :: EditScriptL f txs tys -> Nat
+steps (Ins  _ d)  = Succ $ steps d
+steps (Del  _ d)  = Succ $ steps d
+steps (Cpy  _ d)  = Succ $ steps d
+steps End         = Zero
+
+bestSteps :: Nat -> d -> Nat -> d -> d
+bestSteps Zero      x _         _ = x
+bestSteps _         _ Zero      y = y
+bestSteps (Succ nx) x (Succ ny) y = bestSteps nx x ny y
+
+data RListT :: (* -> * -> *) -> * -> * where
+  RList :: List f ts => RListT f ts
+
+reify :: IsList f ts -> RListT f ts
+reify IsNil          = RList
+reify (IsCons ists)  = case reify ists of
+                         RList -> RList
+
+ins :: (Type f t) => IsList f ts -> IsList f tys -> 
+      f t ts -> EditScriptL f txs (Append ts tys) -> EditScriptL f txs (Cons t tys)
+ins ists isys =
+  case (reify ists, reify isys) of
+    (RList, RList) -> Ins
+
+del :: (Type f t) => IsList f ts -> IsList f txs ->
+      f t ts -> EditScriptL f (Append ts txs) tys -> EditScriptL f (Cons t txs) tys 
+del ists isxs =
+  case (reify ists, reify isxs) of
+    (RList, RList) -> Del
+
+cpy :: (Type f t) => IsList f ts -> IsList f txs -> IsList f tys ->
+      f t ts -> EditScriptL f (Append ts txs) (Append ts tys) -> 
+      EditScriptL f (Cons t txs) (Cons t tys)
+cpy ists isxs isys =
+  case (reify ists, reify isxs, reify isys) of
+    (RList, RList, RList) -> Cpy
+
+compress :: (Family f) => EditScriptL f txs tys -> EditScriptL f txs tys
+compress End           = End 
+compress (Ins  c   d)  = Ins  c   (compress d)
+compress (Del  c   d)  = Del  c   (compress d)
+compress (CpyTree  d)  = CpyTree  (compress d) 
+compress (Cpy  c   d)  = let d' = compress d in
+  case copied (isList c) d' of
+    Just d''  -> CpyTree d''
+    Nothing   -> Cpy c d'
+
+copied :: (Family f) => IsList f ts -> 
+             EditScriptL f (Append ts txs) (Append ts tys) -> Maybe (EditScriptL f txs tys)
+copied IsNil                  d   = Just d
+copied (IsCons xs)  (CpyTree  d)  = copied xs d
+copied (IsCons _)   _             = Nothing 
+
+data EditScriptLMemo :: (* -> * -> *) -> * -> * -> * where
+  CC :: (Type f tx, Type f ty, List f txs', List f tys') => 
+        f tx txs' -> f ty tys' ->
+        EditScriptL f (Cons tx txs) (Cons ty tys) ->
+        EditScriptLMemo f (Cons tx txs)      (Append tys' tys)  -> 
+        EditScriptLMemo f (Append txs' txs)  (Cons ty tys)      ->
+        EditScriptLMemo f (Append txs' txs)  (Append tys' tys)  ->
+        EditScriptLMemo f (Cons tx txs)      (Cons ty tys)
+  CN :: (Type f tx, List f txs') => f tx txs' ->
+        EditScriptL f (Cons tx txs) Nil ->
+        EditScriptLMemo f (Append txs' txs)  Nil ->
+        EditScriptLMemo f (Cons tx txs)      Nil
+  NC :: (Type f ty, List f tys') => f ty tys' ->
+        EditScriptL f Nil (Cons ty tys) ->
+        EditScriptLMemo f Nil                (Append tys' tys) ->
+        EditScriptLMemo f Nil                (Cons ty tys)
+  NN :: EditScriptL f Nil Nil ->
+        EditScriptLMemo f Nil                Nil
+
+diffLMemo :: (Family f, List f txs, List f tys) => txs -> tys -> EditScriptLMemo f txs tys
+diffLMemo = diffLMemo' list list
+
+diffLMemo' :: (Family f) => forall txs tys. IsList f txs -> IsList f tys -> 
+        txs -> tys -> EditScriptLMemo f txs tys
+diffLMemo' IsNil          IsNil          CNil          CNil          = 
+  NN End
+diffLMemo' (IsCons isxs)  IsNil          (CCons x xs)  CNil          =
+  matchConstructor x
+    (\ cx isxs' xs' ->
+       let d = diffLMemo'  (appendList isxs' isxs)     IsNil
+                       (append isxs' isxs xs' xs)  CNil
+       in  cn isxs' isxs cx (del isxs' isxs cx (getEditScriptL d)) d)
+diffLMemo' IsNil          (IsCons isys)  CNil          (CCons y ys)  =
+  matchConstructor y
+    (\ cy isys' ys' ->
+       let i = diffLMemo'  IsNil  (appendList isys' isys)
+                       CNil   (append isys' isys ys' ys)
+       in  nc isys' isys cy (ins isys' isys cy (getEditScriptL i)) i)
+diffLMemo' (IsCons isxs)  (IsCons isys)  (CCons x xs)  (CCons y ys)  =
+  matchConstructor x
+    (\ cx isxs' xs' ->
+       matchConstructor y
+       (\ cy isys' ys' -> 
+          let  c  = diffLMemo'  (appendList isxs' isxs)     (appendList isys' isys)
+                            (append isxs' isxs xs' xs)  (append isys' isys ys' ys)
+               d  = extendd  isys'  isys  cy  c 
+               i  = extendi  isxs'  isxs  cx  c
+          in cc isxs' isxs isys' isys cx cy 
+               (bestEditScriptLMemo cx cy isxs' isxs isys' isys i d c) i d c))
+
+getEditScriptL :: EditScriptLMemo f txs tys -> EditScriptL f txs tys
+getEditScriptL (CC _ _ d _ _ _) = d
+getEditScriptL (CN _ d _)       = d
+getEditScriptL (NC _ d _)       = d
+getEditScriptL (NN d)           = d
+
+bestEditScriptLMemo ::  (Type f tx, Type f ty) => f tx txs' -> f ty tys' ->
+              IsList f txs' -> IsList f txs -> IsList f tys' -> IsList f tys ->
+              EditScriptLMemo f (Cons tx txs)      (Append tys' tys)  -> 
+              EditScriptLMemo f (Append txs' txs)  (Cons ty tys)      ->
+              EditScriptLMemo f (Append txs' txs)  (Append tys' tys)  ->
+              EditScriptL f (Cons tx txs) (Cons ty tys)
+bestEditScriptLMemo cx cy isxs' isxs isys' isys i d c = case decEq cx cy of
+    Just (Refl, Refl) -> cpy isxs' isxs isys cx (getEditScriptL c)
+    Nothing           -> best  (ins isys' isys cy (getEditScriptL i))
+                               (del isxs' isxs cx (getEditScriptL d))
+
+extendd :: (Type f ty) => IsList f tys' -> IsList f tys -> f ty tys' -> 
+           EditScriptLMemo f txs' (Append tys' tys) ->
+           EditScriptLMemo f txs' (Cons ty tys)
+extendd isys' isys cy dt@(NN d)          = nc isys' isys cy (ins isys' isys cy d) dt
+extendd isys' isys cy dt@(NC _ d _)      = nc isys' isys cy (ins isys' isys cy d) dt
+extendd isys' isys cy dt@(CN _ _ _)        = extendd' isys' isys cy dt
+extendd isys' isys cy dt@(CC _ _ _ _ _ _)  = extendd' isys' isys cy dt
+
+extendd' :: (Type f ty, Type f tx) => IsList f tys' -> IsList f tys -> f ty tys' -> 
+            EditScriptLMemo f (Cons tx txs) (Append tys' tys) ->
+            EditScriptLMemo f (Cons tx txs) (Cons ty tys)
+extendd' isys' isys cy dt =
+  extractd dt (\ isxs' isxs cx dt' -> 
+    let i = dt
+        d = extendd isys' isys cy dt'
+        c = dt'
+    in  cc isxs' isxs isys' isys cx cy (bestEditScriptLMemo cx cy isxs' isxs isys' isys i d c) i d c)
+
+extendi :: (Type f tx) => IsList f txs' -> IsList f txs -> f tx txs' ->
+           EditScriptLMemo f (Append txs' txs)  tys' ->
+           EditScriptLMemo f (Cons tx txs)      tys'
+extendi isxs' isxs cx dt@(NN d)         = cn isxs' isxs cx (del isxs' isxs cx d) dt
+extendi isxs' isxs cx dt@(CN _ d _)     = cn isxs' isxs cx (del isxs' isxs cx d) dt
+extendi isxs' isxs cx dt@(NC _ _ _)       = extendi' isxs' isxs cx dt
+extendi isxs' isxs cx dt@(CC _ _ _ _ _ _) = extendi' isxs' isxs cx dt
+
+extendi' :: (Type f tx, Type f ty) => IsList f txs' -> IsList f txs -> f tx txs' -> 
+            EditScriptLMemo f (Append txs' txs)  (Cons ty tys) ->
+            EditScriptLMemo f (Cons tx txs)      (Cons ty tys)
+extendi' isxs' isxs cx dt =
+  extracti dt (\ isys' isys cy dt' -> 
+    let i = extendi isxs' isxs cx dt'
+        d = dt
+        c = dt'
+    in  cc   isxs' isxs isys' isys cx cy 
+             (bestEditScriptLMemo cx cy isxs' isxs isys' isys i d c) 
+             i d c)
+
+extractd :: (Type f tx) => EditScriptLMemo f (Cons tx txs) tys' ->
+          (forall txs'. IsList f txs' -> IsList f txs -> f tx txs' ->
+          EditScriptLMemo f (Append txs' txs) tys' -> r) -> r
+extractd (CC c _ d' _ d _) k = k (isList c) (sourceTail d') c d
+extractd (CN c d' d)       k = k (isList c) (sourceTail d') c d
+
+sourceTail :: EditScriptL f (Cons tx txs) tys -> IsList f txs
+sourceTail (Ins _ d) = sourceTail d
+sourceTail (Del _ _) = list
+sourceTail (Cpy _ _) = list
+
+extracti :: (Type f ty) => EditScriptLMemo f txs' (Cons ty tys) ->
+          (forall tys'. IsList f tys' -> IsList f tys -> f ty tys' ->
+          EditScriptLMemo f txs' (Append tys' tys) -> r) -> r
+extracti (CC _ c d i _ _) k = k (isList c) (targetTail d) c i 
+extracti (NC c d i)       k = k (isList c) (targetTail d) c i
+
+targetTail :: EditScriptL f txs (Cons ty tys) -> IsList f tys
+targetTail (Ins _ _) = list
+targetTail (Del _ d) = targetTail d
+targetTail (Cpy _ _) = list
+
+nc :: (Type f t) => IsList f ts -> IsList f tys -> 
+      f t ts -> EditScriptL f Nil (Cons t tys) -> 
+      EditScriptLMemo f Nil (Append ts tys) -> EditScriptLMemo f Nil (Cons t tys)
+nc ists isys =
+  case (reify ists, reify isys) of
+    (RList, RList) -> NC
+
+cn :: (Type f t) => IsList f ts -> IsList f txs -> 
+      f t ts -> EditScriptL f (Cons t txs) Nil ->
+      EditScriptLMemo f (Append ts txs) Nil -> EditScriptLMemo f (Cons t txs) Nil
+cn ists isxs =
+  case (reify ists, reify isxs) of
+    (RList, RList) -> CN
+
+cc :: (Type f tx, Type f ty) => 
+      IsList f txs' -> IsList f txs -> IsList f tys' -> IsList f tys ->
+      f tx txs' -> f ty tys' -> EditScriptL f (Cons tx txs) (Cons ty tys) ->
+      EditScriptLMemo f (Cons tx txs)      (Append tys' tys)    -> 
+      EditScriptLMemo f (Append txs' txs)  (Cons ty tys)        ->
+      EditScriptLMemo f (Append txs' txs)  (Append tys' tys)  ->
+      EditScriptLMemo f (Cons tx txs)      (Cons ty tys)
+cc isxs' isxs isys' isys =
+  case (reify isxs', reify isxs, reify isys', reify isys) of
+    (RList, RList, RList, RList) -> CC
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009-2010, Eelco Lempsink
+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 the <ORGANIZATION>  nor the names of its 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 HOLDER 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/gdiff.cabal b/gdiff.cabal
new file mode 100644
--- /dev/null
+++ b/gdiff.cabal
@@ -0,0 +1,19 @@
+Name:                gdiff
+Version:             1.0
+Category:            Data
+License:             BSD3
+License-File:        LICENSE
+Author:              Eelco Lempsink, Andres Löh
+Maintainer:          eelco at lempsink nl
+Synopsis:            Generic diff and patch
+
+Description:         
+  Get an efficient, optimal, type-safe diff and patch function for your
+  datatypes of choice by defining a simple GADT and some class instances.
+  .
+  Extracted from Eelco Lempsink's Thesis (<http://eelco.lempsink.nl/thesis.pdf>).
+
+Build-Depends:       base >= 3 && < 5
+Build-Type:          Simple
+Exposed-Modules:     Data.Generic.Diff
+Tested-With:         GHC == 6.10.4, GHC == 6.12.1
