diff --git a/Control/Instances/Morph.hs b/Control/Instances/Morph.hs
new file mode 100644
--- /dev/null
+++ b/Control/Instances/Morph.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, MultiParamTypeClasses, FlexibleInstances, PolyKinds, UndecidableInstances, AllowAmbiguousTypes, RankNTypes, ScopedTypeVariables, FlexibleContexts, OverlappingInstances #-}
+
+module Control.Instances.Morph (GenMorph(..), Morph(..)) where
+
+import Control.Instances.ShortestPath
+
+import Control.Monad.Identity
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.List
+import Control.Monad.State
+import Data.Maybe
+import Data.Proxy
+import GHC.TypeLits
+import Control.Instances.TypeLevelPrelude
+
+-- | States that 'm1' can be represented with 'm2'.
+-- That is because 'm2' contains more infromation than 'm1'.
+--
+-- The 'MMorph' relation defines a natural transformation from 'm1' to 'm2'
+-- that keeps the following laws:
+--
+-- > morph (return x)  =  return x
+-- > morph (m >>= f)   =  morph m >>= morph . f
+-- 
+-- It is a reflexive and transitive relation.
+--
+class Morph (m1 :: * -> *) (m2 :: * -> *) where
+  -- | Lifts the first monad into the second.
+  morph :: m1 a -> m2 a
+  
+instance GenMorph DB m1 m2 => Morph m1 m2 where
+  morph = genMorph db
+  
+-- | A generalized version of 'Morph'. Can work on different
+-- rulesets, so this should be used if the ruleset is to be extended.
+class GenMorph db (m1 :: * -> *) (m2 :: * -> *) where
+  -- | Lifts the first monad into the second.
+  genMorph :: db -> m1 a -> m2 a
+  
+instance ( fl ~ (TransformPath (PathFromList (ShortestPath (ToMorphRepo DB) x y)))
+         , CorrectPath x y fl
+         , GeneratableMorph DB fl
+         , Morph' fl x y
+         ) => GenMorph DB x y where
+  genMorph db = repr (generateMorph db :: fl)
+  
+class Morph' fl x y where
+  repr :: fl -> x a -> y a
+  
+instance Morph' r y z => Morph' (ConnectMorph x y :+: r) x z where
+  repr (ConnectMorph m :+: r) = repr r . m
+ 
+instance (Morph' r m x, Monad m) => Morph' (IdentityMorph m :+: r) Identity x where
+  repr (IdentityMorph :+: r) = (repr r :: forall a . m a -> x a) . return . runIdentity
+  
+instance Morph' (MUMorph m :+: r) m Proxy where
+  repr (MUMorph :+: _) = const Proxy
+ 
+instance Morph' NoMorph x x where
+  repr fl = id
+  
+infixr 6 :+:
+data a :+: r = a :+: r 
+
+data NoMorph = NoMorph
+  
+type family ToMorphRepo db where
+  ToMorphRepo (cm :+: r) = TranslateConn cm ': ToMorphRepo r
+  ToMorphRepo NoMorph = '[]
+   
+type DB = ConnectMorph_2m Maybe MaybeT
+           :+: ConnectMorph_mt MaybeT 
+           :+: ConnectMorph Maybe [] 
+           :+: ConnectMorph_2m [] ListT
+           :+: ConnectMorph (MaybeT IO) (ListT IO)
+           :+: NoMorph
+ 
+db :: DB 
+db = ConnectMorph_2m (MaybeT . return) 
+       :+: ConnectMorph_mt (MaybeT . liftM Just) 
+       :+: ConnectMorph (maybeToList) 
+       :+: ConnectMorph_2m (ListT . return) 
+       :+: ConnectMorph (ListT . liftM maybeToList . runMaybeT) 
+       :+: NoMorph
+  
+-- | This class provides a way to construct the value-level transformations
+-- from the type-level path and a rulebase.
+class GeneratableMorph db ch where
+  generateMorph :: db -> ch
+    
+instance GeneratableMorph db NoMorph where
+  generateMorph _ = NoMorph
+  
+instance GeneratableMorph db r 
+      => GeneratableMorph db ((IdentityMorph m) :+: r) where
+  generateMorph db = IdentityMorph :+: generateMorph db
+  
+instance GeneratableMorph db r 
+      => GeneratableMorph db (MUMorph m :+: r) where
+  generateMorph db = MUMorph :+: generateMorph db
+  
+instance (HasMorph db (ConnectMorph a b), GeneratableMorph db r) 
+      => GeneratableMorph db (ConnectMorph a b :+: r) where
+  generateMorph db = getMorph db :+: generateMorph db
+  
+-- | This class extracts a given morph from the set of rules
+class HasMorph r m where 
+  getMorph :: r -> m
+instance HasMorph (m :+: r) m where
+  getMorph (c :+: r) = c
+instance Monad k => HasMorph (ConnectMorph_2m a b :+: r) (ConnectMorph a (b k)) where
+  getMorph (ConnectMorph_2m f :+: r) = ConnectMorph f
+instance Monad k => HasMorph (ConnectMorph_mt t :+: r) (ConnectMorph k (t k)) where
+  getMorph (ConnectMorph_mt f :+: r) = ConnectMorph f
+instance HasMorph r m => HasMorph (c :+: r) m where
+  getMorph (c :+: r) = getMorph r
+
+-- | Checks if the path is found to provide usable error messages
+class CorrectPath from to path
+
+instance CorrectPath from to (a :+: b)
+instance CorrectPath from to NoMorph
+
+data ConnectMorph m1 m2 = ConnectMorph { fromConnectMorph :: forall a . m1 a -> m2 a }
+data ConnectMorph_2m m1 m2 = ConnectMorph_2m { fromConnectMorph_2m :: forall a k . Monad k => m1 a -> m2 k a }
+data ConnectMorph_mt mt = ConnectMorph_mt { fromConnectMorph_mt :: forall a k . Monad k => k a -> mt k a }
+data IdentityMorph (m :: * -> *) = IdentityMorph
+data MUMorph m = MUMorph
+
+-- | Transforms a path element from the generic format to the specific one
+type family TranslateConn m where
+  TranslateConn (ConnectMorph m1 m2) = Connect m1 m2
+  TranslateConn (ConnectMorph_2m m1 m2) = Connect_2m m1 m2
+  TranslateConn (ConnectMorph_mt mt) = Connect_mt mt
+  
+-- | Transforms the path from the generic format to the specific one
+type family TransformPath m where
+  TransformPath (Connect m1 m2 :+: r) = ConnectMorph m1 m2 :+: TransformPath r
+  TransformPath (Connect_id m :+: r) = IdentityMorph m :+: TransformPath r
+  TransformPath (Connect_MU m :+: r) = MUMorph m :+: TransformPath r
+  TransformPath NoMorph = NoMorph
+  TransformPath NoPathFound = NoPathFound
+  
+type family PathFromList ls where
+  PathFromList '[] = NoMorph
+  PathFromList '[ NoPathFound ] = NoPathFound
+  PathFromList (c ': ls) = c :+: PathFromList ls
+
+
diff --git a/Control/Instances/ShortestPath.hs b/Control/Instances/ShortestPath.hs
new file mode 100644
--- /dev/null
+++ b/Control/Instances/ShortestPath.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, MultiParamTypeClasses, FlexibleInstances, PolyKinds, UndecidableInstances, AllowAmbiguousTypes, RankNTypes, ScopedTypeVariables, FlexibleContexts, OverlappingInstances #-}
+
+module Control.Instances.ShortestPath where
+
+import Control.Monad.Identity
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.List
+import Control.Monad.State
+import Data.Maybe
+import Data.Proxy
+import GHC.TypeLits
+import Control.Instances.TypeLevelPrelude
+
+-- * Generic datatypes to store connections
+  
+data Connect m1 m2
+data Connect_2m m1 m2
+data Connect_mt mt
+data Connect_id m
+data Connect_MU m
+
+-- | Marks that there is no legal path between the two types according
+-- to the rulebase.
+data NoPathFound
+  
+type family ShortestPath (e :: [*]) (s :: * -> *) (t :: * -> *) :: [*] where
+  ShortestPath e t t = '[]
+  ShortestPath e Identity t = '[ Connect_id t ]
+  ShortestPath e s Proxy = '[ Connect_MU s ]
+  ShortestPath e s t = ShortestPath' e s (InitCurrent e t)
+  
+type family ShortestPath' (e :: [*]) (s :: * -> *) (c :: [[*]]) :: [*] where
+  ShortestPath' e s '[] = '[ NoPathFound ]
+  ShortestPath' e s c = FromMaybe (ShortestPath' e s (ApplyEdges e c c))
+                                  (GetFinished s c) 
+                                  
+                                      
+type family GetFinished s c where
+  GetFinished s ((Connect s b ': p) ': lls) 
+    = Just (Connect s b ': p)
+  GetFinished s (p ': lls) = GetFinished s lls
+  GetFinished s '[] = Nothing
+
+type family InitCurrent (e :: [*]) (t :: * -> *) :: [[*]] where
+  InitCurrent '[] t = '[]
+  InitCurrent (e ': es) t = IfJust (ApplyEdge e t)
+                                   ('[ MonomorphEnd e t ] ': InitCurrent es t) 
+                                   (InitCurrent es t)
+  
+type family ApplyEdges (e :: [*]) (co :: [[*]]) (c :: [[*]]) :: [[*]] where
+  ApplyEdges (e ': es) co ((Connect s b ': p) ': cs) 
+    = AppendJust (IfThenJust (IsJust (ApplyEdge e s)) 
+                                (MonomorphEnd e s ': Connect s b ': p)) 
+                 (ApplyEdges (e ': es) co cs)
+  ApplyEdges (e ': es) co '[] = ApplyEdges es co co
+  ApplyEdges '[] co cr = '[]  
+  
+type family ApplyEdge e t :: Maybe (* -> *) where
+  ApplyEdge (Connect ms mr) mr = Just ms
+  ApplyEdge (Connect_2m ms mt) (mt m) = Just ms
+  ApplyEdge (Connect_mt mt) (mt m) = Just m
+  ApplyEdge e t = Nothing
+
+type family MonomorphEnd c v :: * where
+  MonomorphEnd (Connect_2m m m') v = Connect m v
+  MonomorphEnd (Connect_mt t) (t m) = Connect m (t m)
+  MonomorphEnd c v = c
+
+
diff --git a/Control/Instances/TypeLevelPrelude.hs b/Control/Instances/TypeLevelPrelude.hs
new file mode 100644
--- /dev/null
+++ b/Control/Instances/TypeLevelPrelude.hs
@@ -0,0 +1,88 @@
+{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, MultiParamTypeClasses, FlexibleInstances, PolyKinds, UndecidableInstances, AllowAmbiguousTypes, RankNTypes, ScopedTypeVariables, FlexibleContexts #-}
+
+module Control.Instances.TypeLevelPrelude where
+
+import GHC.TypeLits
+
+type family Const a b where
+  Const a b = a
+  
+type family Seq a b where
+  Seq a b = b
+  
+type family LazyIfThenElse p a b where
+  LazyIfThenElse True a b = a
+  LazyIfThenElse False a b = b
+  
+type family Iterate a where
+  Iterate a = a ': Iterate a
+
+type family l1 :++: l2 where
+  '[] :++: l2       = l2
+  (e ': r1) :++: l2 = e ': (r1 :++: l2)
+  
+type family Elem e ls where
+  Elem e '[] = False
+  Elem e (e ': ls) = True
+  Elem e (x ': ls) = Elem e ls
+  
+type family IfThenElse (b :: Bool) (th :: x) (el :: x) :: x where
+  IfThenElse True  th el = th
+  IfThenElse False th el = el
+         
+type family Length ls :: Nat where
+  Length '[] = 0
+  Length (e ': ls) = 1 + Length ls
+           
+type family Head (ls :: [k]) :: k where
+  Head (e ': ls) = e   
+  
+type family HeadMaybe (ls :: [k]) :: Maybe k where
+  HeadMaybe (e ': ls) = Just e
+  HeadMaybe '[] = Nothing
+  
+type family FromMaybe d m where
+  FromMaybe d (Just x) = x
+  FromMaybe d Nothing = d
+  
+type family Same a b where
+  Same a a = True
+  Same a b = False
+  
+type family Null (ls :: [k]) :: Bool where
+  Null '[] = True
+  Null ls = False
+           
+type family MapAppend e lls where
+  MapAppend e (ls ': lls) = (e ': ls) ': MapAppend e lls
+  MapAppend e '[] = '[]
+  
+type family AppendJust m ls where
+  AppendJust (Just x) ls = x ': ls
+  AppendJust Nothing ls = ls
+  
+type family Revert ls where
+  Revert '[] = '[]
+  Revert (e ': ls) = Revert ls :++: '[ e ]
+  
+type family IfThenJust (p :: Bool) (v :: k) :: Maybe k where
+  IfThenJust True v = Just v
+  IfThenJust False v = Nothing  
+  
+type family IfJust (p :: Maybe k) (t :: kr) (e :: kr) :: kr where
+  IfJust (Just x) t e = t
+  IfJust Nothing t e = e
+  
+type family IsJust (p :: Maybe k) :: Bool where
+  IsJust (Just x) = True
+  IsJust Nothing = False    
+  
+type family FromJust (p :: Maybe k) :: k where
+  FromJust (Just x) = x
+  
+type family Cat (f2 :: k2 -> k3) (f1 :: k1 -> k2) (a :: k1) :: k3 where
+  Cat f2 f1 a = f2 (f1 a)
+  
+
+  
+  
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Boldizsar Nemeth
+
+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 Boldizsar Nemeth 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/instance-control.cabal b/instance-control.cabal
new file mode 100644
--- /dev/null
+++ b/instance-control.cabal
@@ -0,0 +1,32 @@
+
+name:                instance-control
+version:             0.1.0.0
+synopsis:            Controls how the compiler searches for instances using type families.
+description:         GHC has no capability to perform graph searches on instance definition. Because of that,
+                     transitive rules for type classes cannot be defined. This package solves the issue with
+                     type functions performing a search on the graph where nodes are types and edges are
+                     rules from a given rule database. After constructing the type-level representation of the
+                     wanted path, the system constructs the needed functions from the value-level representation
+                     of the database.
+homepage:            https://github.com/lazac/instance-control
+license:             BSD3
+license-file:        LICENSE
+author:              Boldizsar Nemeth
+maintainer:          nboldi@caesar.elte.hu
+-- copyright:           
+category:            Control
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+source-repository head
+  type:                git
+  location:            http://github.com/nboldi/instance-control
+
+library
+  exposed-modules:     Control.Instances.Morph
+  other-modules:       Control.Instances.TypeLevelPrelude
+                     , Control.Instances.ShortestPath
+  other-extensions:    TypeFamilies, DataKinds, TypeOperators, MultiParamTypeClasses, FlexibleInstances, PolyKinds, UndecidableInstances, AllowAmbiguousTypes, RankNTypes, ScopedTypeVariables, FlexibleContexts, OverlappingInstances
+  build-depends:       base >=4.7 && <4.9, mtl >=2.2 && <2.3, transformers >=0.4 && <0.5
+  -- hs-source-dirs:      
+  default-language:    Haskell2010
