diff --git a/datadir/examples.txt b/datadir/examples.txt
new file mode 100644
--- /dev/null
+++ b/datadir/examples.txt
@@ -0,0 +1,76 @@
+-- these tests use all the databases
+
+-- check ~ is found, bug #280
+~ +keyword -n1
+keyword ~
+
+-- check keywords are including in default
+~ -n1
+keyword ~
+
+-- check that keyword links work, bug #309
+! --link +keyword -n1
+keyword ! -- http://haskell.org/haskellwiki/Keywords#.21
+
+-- check you find forall, bug #235
+forall -n10
+keyword forall
+
+-- check you find MonadWriter, bug #249
+MonadWriter +mtl -n1
+class (Monoid w, Monad m) => MonadWriter w m
+
+module -n10
+keyword module
+
+Prelude -n1
+Prelude
+
+even +base -n1
+even
+
+tan +base -n1
+tan
+
++base log -n1
+log
+
+seq +base -n1
+seq
+
+-- test that the base type String=[Char] alias is known
+"[Char] -> a -> a" -n1
+@now trace
+
+-- test that packages are included
+hlint -n1
+package hlint
+
+-- #146, preserve foralls
+everywhere +syb -n1
+everywhere :: (forall a. Data a => a -> a) -> (forall a. Data a => a -> a)
+
+-- #320, make sure it finds system
+system -n10
+System.Cmd system :: String -> IO ExitCode
+
+-- #187, LT not found
+LT +base -n1
+LT :: Ordering
+
+-- #327, utf8 not found
+utf8 -n1
+utf8
+
+-- check that URL's work
+>>= --link -n1
+http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:-62--62--61-
+
+False --link -n1
+http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:False
+
+Ord --link -n1
+http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:Ord
+
+String --link -n1
+http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:String
diff --git a/datadir/rank.txt b/datadir/rank.txt
new file mode 100644
--- /dev/null
+++ b/datadir/rank.txt
@@ -0,0 +1,66 @@
+-- a list of examples
+-- used to generate a scoring system
+
+@package rank
+module Rank
+type String = [Char]
+type FilePath = String
+
+
+@rank Ord a => [a] -> [a]
+Ord a => a -> [a] -> [a]
+[a] -> [a]
+a -> [a] -> [a]
+
+@rank Ord a => [a] -> [a]
+[a] -> [a]
+Int -> [a] -> [a]
+String -> String
+Int -> [Char] -> [Char]
+
+@rank Ord a => [a] -> [a]
+[a] -> [a]
+Ord a => a -> [a]
+
+@rank [a] -> [b]
+(a -> b) -> [a] -> [b]
+[a] -> [a]
+Eq a => [a] -> [a]
+
+@rank Int -> Bool
+a -> Int -> Bool
+a -> Bool
+
+@rank a -> a
+Int -> a -> a
+a -> m a
+a -> b
+
+@rank a -> b
+a -> b
+a -> b -> a
+a -> a
+Int -> a
+
+@rank [a] -> a
+[a] -> Int -> a
+Ord a => [a] -> a
+[a] -> Bool
+
+@rank a -> b -> c
+a -> b -> c -> d
+Int -> b -> c
+a -> a -> a
+Ord a => a -> a -> a
+
+@rank String
+[Char]
+FilePath
+a -> String
+
+@rank [(a,b)] -> a -> b
+[(a,b)] -> a -> b
+a -> [(a,b)] -> b
+Eq a => [(a,b)] -> a -> b
+[(a,b)] -> a -> Maybe b
+Eq a => a -> [(a,b)] -> Maybe b
diff --git a/datadir/testdata.txt b/datadir/testdata.txt
new file mode 100644
--- /dev/null
+++ b/datadir/testdata.txt
@@ -0,0 +1,58 @@
+-- data for tests.txt
+
+@package testdata
+
+module Testdata
+
+() :: ()
+(,) :: a -> b -> (a,b)
+type FilePath = String
+type String = [Char]
+data Unit
+Unit :: Unit
+data Maybe a
+Just :: a -> Maybe a
+Nothing :: Maybe a
+id :: a -> a
+unsafeCoerce :: a -> b
+map :: (a -> b) -> [a] -> [b]
+flipmap :: [a] -> (a -> b) -> [b]
+fmap :: Functor m => (a -> b) -> m a -> m b
+unfmap :: (a -> b) -> m a -> m b
+eq :: Eq a => (a -> b) -> m a -> m b
+fst :: (a,b) -> a
+snd :: (a,b) -> b
+(==) :: Eq a => a -> a -> Bool
+instance Eq Bool
+instance Functor []
+not :: Bool -> Bool
+string :: String
+chars :: [Char]
+
+int2 :: Char -> Int -> Int
+instance Ord Bar
+ordId :: Ord a => a -> a
+nonId :: Non a => a -> a
+
+-- check bug # 352
+( # ) :: Int
+
+everywhere :: Data a => (forall local. Data local => local -> local) -> a -> a
+class Eq2 a b => Ord2 a b | a -> b
+
+@entry package pkg1
+@entry package pkg2
+
+module Foo.Bar
+
+-- | Documentation for <i>foo_bar</i>
+foo_bar :: Unit
+fst :: (Unit,Unit) -> Unit
+fst2 :: (Unit,Unit) -> Unit
+
+module Bar.Foo
+bar_foo :: Unit
+fst :: (Bar,Bar) -> Bar
+
+type Alias1 a = Alias2 a
+aliases :: Alias1 (Alias1 a) -> a
diff --git a/datadir/tests.txt b/datadir/tests.txt
new file mode 100644
--- /dev/null
+++ b/datadir/tests.txt
@@ -0,0 +1,127 @@
+-- these tests only rely on the testdata database
+
+id +testdata
+id
+
+map +testdata
+map
+fmap
+@reorder unfmap
+
+"(a -> b) -> [a] -> [b]" +testdata
+map
+fmap
+unfmap
+
+"(a -> b) -> [a] -> [b]" +testdata
+map
+flipmap
+
+"a -> b" +testdata
+unsafeCoerce
+
+"(c,d) -> d" +testdata
+snd
+fst
+
+"(c,d) -> c" +testdata
+fst
+snd
+
+"Bool -> Bool -> Bool" +testdata
+(==)
+
+"Bool -> Bool" +testdata
+not
+(==)
+
+:: String +testdata
+string
+chars
+
+[Char] +testdata
+chars
+string
+
+"Functor m => (a -> b) -> m a -> m b" +testdata
+fmap
+unfmap
+eq
+
+-- tests that arguments are not reused
+"Int -> Int -> Int" +testdata
+@not int2
+
+-- test that instances are applied properly
+"Bar -> Bar" +testdata
+ordId
+@reorder id
+nonId
+
+-- test that packages can be searched for
+pkg +testdata
+pkg1
+@reorder pkg2
+
+map --link +testdata
+Testdata map :: (a -> b) -> [a] -> [b] -- http://hackage.haskell.org/packages/archive/testdata/latest/doc/html/Testdata.html#v:map
+
+== --link +testdata
+Testdata (==) :: Eq a => a -> a -> Bool -- http://hackage.haskell.org/packages/archive/testdata/latest/doc/html/Testdata.html#v:-61--61-
+
+-- check for perservation of forall
+everywhere +testdata
+everywhere :: Data a => (forall local. Data local => local -> local) -> a -> a
+
+-- preservation of functional dependencies
+rd2 +testdata
+class Eq2 a b => Ord2 a b | a -> b
+
+:: Just a +testdata
+Did you mean: :: Maybe a +testdata
+
+:: Maybe +testdata
+Did you mean: :: Maybe a +testdata
+
+-- check that () is known, not a warning, and is the first result
+:: () +testdata
+@now () :: ()
+
+to +testdata
+No results
+
+a to b +testdata
+Did you mean: a -> b +testdata
+
+a to to b +testdata
+No results
+
+-- case insensitive module names
+BAR.bar_foo +testdata
+bar_foo
+
+-- lower case module prefixes via .
+bar.bar_foo +testdata
+bar_foo
+
+-- #372, proper searching for modules
+foo.bar_foo +testdata
+bar_foo
+
+bar.foo.bar_foo +testdata
+bar_foo
+
+bar.fo.bar_foo +testdata
+bar_foo
+
+ba.foo.bar_foo +testdata
+@now No results
+
+ar.foo bar_foo +testdata
+@now No results
+
+"Alias1 (Alias1 a) -> a" +testdata
+aliases
+
+"Alias2 (Alias2 a) -> a" +testdata
+aliases
diff --git a/hoogle.cabal b/hoogle.cabal
--- a/hoogle.cabal
+++ b/hoogle.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.10
 build-type:         Simple
 name:               hoogle
-version:            4.2.20
+version:            4.2.21
 license:            BSD3
 license-file:       docs/LICENSE
 category:           Development
@@ -14,8 +14,10 @@
     search many standard Haskell libraries by either function name,
     or by approximate type signature.
 homepage:           http://www.haskell.org/hoogle/
+bug-reports:        https://github.com/ndmitchell/hoogle/issues
 stability:          Beta
 extra-source-files: README.txt
+                    datadir/*.txt
 
 data-dir: datadir
 data-files:
@@ -28,8 +30,8 @@
     resources/search.xml
 
 source-repository head
-    type:     darcs
-    location: http://code.haskell.org/hoogle/
+    type:     git
+    location: https://github.com/ndmitchell/hoogle.git
 
 library
     hs-source-dirs: src
diff --git a/src/General/Base.hs b/src/General/Base.hs
--- a/src/General/Base.hs
+++ b/src/General/Base.hs
@@ -9,7 +9,7 @@
 import Control.Monad as X
 import Data.Char as X
 import Data.Data as X (Data,Typeable)
-import Data.Either as X
+import Data.Either as X (partitionEithers)
 import Data.Function as X
 import Data.List as X
 import Data.Maybe as X
diff --git a/src/Hoogle/DataBase/Aliases.hs b/src/Hoogle/DataBase/Aliases.hs
--- a/src/Hoogle/DataBase/Aliases.hs
+++ b/src/Hoogle/DataBase/Aliases.hs
@@ -95,7 +95,10 @@
 normAliases :: Aliases -> Type -> ([String], Type)
 normAliases as t = first (sort . nub) $ f t
     where
-        f t = case followAlias as t of
-                  Just (s,t) -> ([s],t)
-                  Nothing -> (concat *** gen) $ unzip $ map f cs
-            where (cs, gen) = uniplate t
+        f t = case followAlias as t2 of
+                   Nothing -> (concat ss, t2)
+                   Just (s,t2) -> (s : concat ss, t2)
+            where
+                (cs, gen) = uniplate t
+                (ss, css) = unzip $ map f cs
+                t2 = gen css
