diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+tests/
+dist/
+.nix
+tmp/
diff --git a/Changelog b/Changelog
new file mode 100644
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,7 @@
+0.0.4 - 2012-04-05
+- change function name mangling algorithm (parameter types are now appended
+to the function name)
+- fix bug where a type declaration might be output twice
+
+0.0.3 - 2011-01-09
+- add dummy library for dependency checks
diff --git a/TODO b/TODO
new file mode 100644
--- /dev/null
+++ b/TODO
@@ -0,0 +1,12 @@
+C++ parsing:
+-
+
+C/C++ generation:
+- functions returning a reference are filtered out
+- Static member functions have this pointer
+- try-catch handling is missing
+
+Haskell generation:
+- Enums must be improved
+- Out-params
+
diff --git a/cgen.cabal b/cgen.cabal
--- a/cgen.cabal
+++ b/cgen.cabal
@@ -2,7 +2,7 @@
 -- see
 -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
 Name:                cgen
-Version:             0.0.3
+Version:             0.0.4
 Synopsis:            generates Haskell bindings and C wrappers for C++ libraries
 Description:         cgen parses C++ headers and generates C wrappers and 
                      Haskell bindings to a C++ library.
diff --git a/src/CppGen.hs b/src/CppGen.hs
--- a/src/CppGen.hs
+++ b/src/CppGen.hs
@@ -373,13 +373,19 @@
 correctFuncRetType n = n
 
 -- o(n^2).
--- simply adds a number at the end of the overloaded function name.
+-- adds cleaned up type names at the end of the overloaded function name.
 mangle :: [Object] -> [Object]
 mangle []     = []
 mangle (n:ns) = 
-  let num = length $ filter (== funname n) $ map funname ns
-      m   = n{funname = funname n ++ show num}
-  in if num == 0
+  let m   = n{funname = funname n ++ functionMangleSuffix n}
+  in if null $ filter (== funname n) $ map funname ns
        then n : mangle ns
        else m : mangle ns
 
+functionMangleSuffix :: Object -> String
+functionMangleSuffix (FunDecl _ _ [] _ _ _ _) = "_void"
+functionMangleSuffix (FunDecl _ _ ps _ _ _ _) = '_' : concatMap (mangleType . vartype) ps
+functionMangleSuffix _ = ""
+
+mangleType :: String -> String
+mangleType = filter (`notElem` ": <>") . map (\c -> if c == '*' then 'P' else if c == '&' then 'R' else c) . replace "::type" "" . stripConst
diff --git a/src/CppUtils.hs b/src/CppUtils.hs
--- a/src/CppUtils.hs
+++ b/src/CppUtils.hs
@@ -149,3 +149,12 @@
   any isAbstractFun (map snd objs)
 abstractClass _ = False
 
+removeNamespace :: String -> String
+removeNamespace = map (\c -> if c == ':' then '_' else c)
+
+stripNamespace :: String -> String
+stripNamespace = last . takeWhile (not . null) . iterate (dropWhile (==':') . snd . break (== ':'))
+
+fixNamespace :: [String] -> String -> String
+fixNamespace enums n = (if (stripNamespace n) `elem` enums then stripNamespace else removeNamespace) n
+
diff --git a/src/HaskellGen.hs b/src/HaskellGen.hs
--- a/src/HaskellGen.hs
+++ b/src/HaskellGen.hs
@@ -85,7 +85,7 @@
     hPutStrLn stderr $ "Rejected types: "
     forM_ (S.toList rejtypes) print
     hPutStrLn stderr $ "Used types: "
-    let hstypes = nub $ filter (not . isStdType . stripPtr) (S.toList cpptypes)
+    let hstypes = nubBy (\x y -> hstypify x == hstypify y) $ filter (not . isStdType . stripPtr) (S.toList cpptypes)
         typefile = outdir </> "Types.hs"
         hstypify = capitalize . stripPtr . removeNamespace
 
@@ -151,7 +151,7 @@
                       (intercalate ", \n" $ withfunnames ++ map hsfunname allgenfuns)
                       modprefix
             hPutStrLn h importForeign
-            mapM_ (addWithFun h) $ filter isConstructor allgenfuns
+            mapM_ (addWithFun h) constructors
             forM_ allgenfuns $ addFun h
             return $ withfunnames ++ map hsfunname allgenfuns
 
@@ -175,7 +175,7 @@
               fname 
               (map (cTypeToHsCType enumnames) pts)
               (cTypeToHsCType enumnames rt) 
-              (decapitalize $ dropWhile (== '_') $ dropWhile (/= '_') fname)
+              (decapitalize $ if '_' `elem` fname then dropWhile (== '_') $ dropWhile (/= '_') fname else fname)
               (map (cTypeToHsType enumnames) pts)
               ([(cTypeToHsType enumnames rt, convRevFunc enumnames rt)])
     l  -> Left (intercalate "\n" l)
@@ -334,7 +334,7 @@
 destructor fn = fn =~ ".*_delete$"
 
 constructor :: String -> Bool
-constructor fn = fn =~ ".*_new[0-9]*$"
+constructor fn = fn =~ ".*_new($|_.*$)"
 
 importForeign :: String
 importForeign = "import Foreign\nimport Foreign.C.String\nimport Foreign.C.Types\n"
@@ -452,12 +452,4 @@
 printHsParams types = 
   intercalate " -> " types ++ " -> " 
 
-removeNamespace :: String -> String
-removeNamespace = map (\c -> if c == ':' then '_' else c)
-
-stripNamespace :: String -> String
-stripNamespace = last . takeWhile (not . null) . iterate (dropWhile (==':') . snd . break (== ':'))
-
-fixNamespace :: [String] -> String -> String
-fixNamespace enums n = (if (stripNamespace n) `elem` enums then stripNamespace else removeNamespace) n
 
diff --git a/src/HeaderData.hs b/src/HeaderData.hs
--- a/src/HeaderData.hs
+++ b/src/HeaderData.hs
@@ -11,7 +11,7 @@
   , varvalue  :: Maybe String
   , vararray  :: Maybe String
   }
-  deriving (Eq, Read, Show)
+  deriving (Eq, Read, Show, Ord)
 
 data Object = FunDecl {
                 funname      :: String
@@ -39,22 +39,22 @@
               }
             | ExternDecl String [Object]
             | Using Bool String
-    deriving (Eq, Read, Show)
+    deriving (Eq, Read, Show, Ord)
 
 data InheritDecl = InheritDecl {
     inheritname  :: String
   , inheritlevel :: InheritLevel
   }
-  deriving (Eq, Read, Show)
+  deriving (Eq, Read, Show, Ord)
 
 data InheritLevel = Public | Protected | Private
-  deriving (Eq, Read, Show, Enum, Bounded)
+  deriving (Eq, Read, Show, Enum, Bounded, Ord)
 
 data EnumVal = EnumVal {
     enumvaluename :: String
   , enumvalue     :: Maybe String
   }
-  deriving (Eq, Read, Show)
+  deriving (Eq, Read, Show, Ord)
 
 type Header = [Object]
 
