diff --git a/cmd/ldif2html.hs b/cmd/ldif2html.hs
new file mode 100644
--- /dev/null
+++ b/cmd/ldif2html.hs
@@ -0,0 +1,88 @@
+{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+-- | Make Change LDIF based on two Content LDIFs
+import Data.List
+import Data.Either
+import Data.Maybe
+import Control.Monad 
+import System.FilePath 
+import System.Environment
+import Text.LDIF
+import qualified Data.Set as Set
+import qualified Data.ByteString.Char8 as BC
+
+-- | Serialize DN to LDIF Format
+dn2html :: DN -> BC.ByteString
+dn2html ys@(DN xs) = BC.concat [ "<div id=\"abc" 
+                               , nm 
+                               , "\"></div><b>dn:</b> <font color=\"green\"><b>" 
+                               , dnstr 
+                               , "</b></font>" ]
+      where
+        dnstr = BC.intercalate "," $ map (\((Attribute n),v) -> n `BC.append` "=" `BC.append` (aVal v)) xs
+        nm = aVal $ dn2last ys
+
+-- | Serialize Change Record in LDIF Format
+record2html :: Set.Set Value -> LDIFRecord -> BC.ByteString
+record2html idx (ChangeRecord dn (ChangeDelete))     = BC.unlines   [ (dn2str dn), "changetype: delete" ]
+record2html idx (ChangeRecord dn (ChangeAdd xs))     = BC.unlines $ [ (dn2html dn), "changetype: add"    ] ++ (attrVals2Ln idx xs)
+record2html idx (ChangeRecord dn (ChangeModify xs))  = BC.unlines $ [ (dn2str dn), "changetype: modify" ] ++ (mods2Ln idx xs)
+record2html idx (ChangeRecord dn (ChangeModDN))      = BC.unlines $ [ (dn2str dn), "changetype: moddn"  ]
+record2html idx (ContentRecord dn xs) = BC.unlines $ [ (dn2html dn) ] ++ (attrVals2Ln idx xs)
+
+attrVals2Ln :: Set.Set Value -> [AttrValue] -> [BC.ByteString]
+attrVals2Ln idx xs = map (attrVal2Ln idx) xs
+
+attrVal2Ln :: Set.Set Value -> AttrValue -> BC.ByteString
+attrVal2Ln idx ((Attribute n),v) = if Set.member v idx then BC.concat [ "<b>"
+                                                                      , n 
+                                                                      , "</b> : <a href=\"#abc"
+                                                                      , aVal v
+                                                                      , "\">" 
+                                                                      , aVal v
+                                                                      , "</a>"]
+                          else BC.concat [ "<b>",n,"</b> : ",aVal v]
+
+mods2Ln :: Set.Set Value -> [Modify] -> [BC.ByteString]
+mods2Ln idx xs = intercalate ["-"] $ map (mod2Ln idx) xs
+
+mod2Ln :: Set.Set Value -> Modify -> [BC.ByteString]
+mod2Ln idx mod = [ attrVal2Ln idx (modName,attrName) ] ++ valLst
+  where
+    attrName = Value $ aName $ modAttr mod
+    valLst = map (\v -> attrVal2Ln idx (modAttr mod,v)) $ modAttrVals mod
+    modName = case mod of 
+      (ModAdd _ _)     -> Attribute "add"
+      (ModDelete _ _)  -> Attribute "delete"
+      (ModReplace _ _) -> Attribute "replace"
+
+dns :: LDIF -> Set.Set Value
+dns (LDIF _ xs) = Set.fromList $ nub $ map (dn2last . reDN) xs
+
+dn2last (DN xs) = snd $ head xs
+
+main = do
+  args <- getArgs
+  case args of 
+     []         -> putStrLn "Usage: ldif2html <input.ldif> [<input2.ldif> <input3.ldif> ... <inputN.ldif> <output.ldif>]"
+     [inp]      -> do
+                      doLDIF2HTML [inp] (BC.putStrLn)
+                      putStrLn "# Done."
+     xs         -> do
+                      doLDIF2HTML (init xs) (BC.writeFile (last xs)) 
+                      putStrLn $ "## Processed : " ++ (unlines $ init xs)
+                      putStrLn $ "## Written   : " ++ (last xs)
+  where
+    doLDIF2HTML names outF = do
+      mls <- mapM (parseLDIFFile defaulLDIFConf) names
+      case lefts mls of 
+        []   -> do
+                let idx = Set.unions $ map dns $ rights mls
+                outF $ BC.concat [ "<html><body bgcolor=lightyellow><pre>"
+                                 , BC.concat $ map (ldif2html idx) (rights mls) 
+                                 , "</pre></body></html>" ]
+        xs  -> mapM_ print xs
+      -- | Serialize LDIF to HTML
+    ldif2html :: Set.Set Value -> LDIF -> BC.ByteString
+    ldif2html idx (LDIF v xs) = BC.unlines $ (ver2str v) ++ (map (record2html idx) xs)
+
+
diff --git a/cmd/ldifdiff.hs b/cmd/ldifdiff.hs
new file mode 100644
--- /dev/null
+++ b/cmd/ldifdiff.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+-- | Make Change LDIF based on two Content LDIFs
+import Data.List
+import Data.Either
+import Data.Maybe
+import Control.Monad 
+import System.FilePath 
+import System.Environment
+import Text.LDIF
+import System.Console.CmdArgs
+import qualified Data.ByteString.Char8 as BC
+
+progDesc = "Create delta LDIF between Source LDIF and Target LDIF"
+
+data LdifDiff = LdifDiff { srcFile :: FilePath
+                         , dstFile :: FilePath } deriving (Show, Data, Typeable)
+
+defaultCfg = LdifDiff { srcFile = def &= typFile &= name "s" &= help "Source LDIF File"
+                      , dstFile = def &= typFile &= name "t" &= help "Target LDIF File" }
+
+main = do
+  cfg <- cmdArgs defaultCfg
+  execute cfg
+
+execute (LdifDiff []  _  ) = putStrLn "Error: -s source file is mandatory" 
+execute (LdifDiff _ []   ) = putStrLn "Error: -t target file is mandatory"
+execute (LdifDiff src dst) = do
+  ml1 <- parseLDIFFile defaulLDIFConf src
+  ml2 <- parseLDIFFile defaulLDIFConf dst
+  case rights [ml1,ml2] of 
+       [l1,l2] -> case diffLDIF l1 l2 of
+                    Left err -> putStrLn err
+                    Right delta -> BC.putStrLn $ ldif2str delta
+       _       -> print $ lefts [ml1,ml2] 
diff --git a/cmd/ldifmodify.hs b/cmd/ldifmodify.hs
new file mode 100644
--- /dev/null
+++ b/cmd/ldifmodify.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
+-- | Apply LDAP operations within LDIF on another LDIF.
+-- | Without schema related verification like syntax, cardinality etc.
+import Data.List
+import Data.Either
+import Data.Maybe
+import Control.Monad 
+import System.FilePath 
+import System.Environment
+import Text.LDIF
+import System.Console.CmdArgs
+import qualified Data.ByteString.Char8 as BC
+
+progDesc = "Apply LDAP operations from LDIF to LDIF (like ldapmodify)"
+
+data LdifModify = LdifModify { baseFile :: FilePath
+                             , modFiles  :: [FilePath]
+                             , outFile  :: FilePath } deriving (Show, Data, Typeable)
+
+defaultCfg = LdifModify { baseFile = def &= typFile &= name "f" &= help "Base LDIF File"
+                        , modFiles = def &= args &= typ "LDIF Files for applying"
+                        , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }
+
+main = do
+  cfg <- cmdArgs defaultCfg
+  execute cfg
+
+execute (LdifModify [] _ _) = putStrLn "Error: -f base LDIF File is mandatory"
+execute (LdifModify _ [] _) = putStrLn "Error: no LDIF Files for applying provided"
+execute (LdifModify _ _ []) = putStrLn "Error: -o output LDIF File is mandatory"
+execute cfg = do
+  baseLDIF <- safeParseLDIFFile (baseFile cfg)
+  modLDIFs <- mapM (safeParseLDIFFile) (modFiles cfg)
+  let outLDIF = foldr (flip applyLDIF) baseLDIF modLDIFs
+  if length (outFile cfg) == 0 then do
+      BC.putStrLn (ldif2str outLDIF)
+    else do
+      BC.writeFile (outFile cfg) (ldif2str outLDIF)
+      putStrLn $ (outFile cfg) ++ " written."
+
+safeParseLDIFFile :: FilePath -> IO LDIF
+safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
diff --git a/cmd/ldifparse.hs b/cmd/ldifparse.hs
new file mode 100644
--- /dev/null
+++ b/cmd/ldifparse.hs
@@ -0,0 +1,17 @@
+-- | Make Change LDIF based on two Content LDIFs
+import Data.List
+import Data.Either
+import Data.Maybe
+import Control.Monad 
+import System.FilePath 
+import System.Environment
+import Text.LDIF
+import qualified Data.ByteString.Char8 as BC
+
+main = do
+  args <- getArgs
+  let name = args !! 0
+  ml1 <- parseLDIFFile defaulLDIFConf name
+  case ml1 of 
+       Right l1 -> BC.putStrLn $ ldif2str l1
+       Left err -> print err
diff --git a/cmd/ldifundo.hs b/cmd/ldifundo.hs
new file mode 100644
--- /dev/null
+++ b/cmd/ldifundo.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
+import Data.List
+import Data.Either
+import Data.Maybe
+import Control.Monad
+import System.FilePath
+import System.Environment
+import Text.LDIF
+import System.Console.CmdArgs
+import qualified Data.ByteString.Char8 as BC
+
+progDesc = "Calculate undo LDIF (rollback LDIF)"
+
+data LdifUndo = LdifUndo { inFile   :: FilePath
+                         , outFile  :: FilePath } deriving (Show, Data, Typeable)
+
+defaultCfg = LdifUndo { inFile = def &= typFile &= name "f" &= help "Input LDIF File"
+                      , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }
+
+main = do
+  cfg <- cmdArgs defaultCfg
+  execute cfg
+
+execute (LdifUndo [] _) = putStrLn "Error: -f base LDIF File is mandatory"
+execute cfg = do
+  inLDIF <- safeParseLDIFFile (inFile cfg)
+  let (outLDIF, wrn) = undoLDIF inLDIF
+  when (not $ null wrn) (putStrLn $ "Finished with warnings: " ++ (unlines $ map unlines wrn))
+  if length (outFile cfg) == 0 then do
+      BC.putStrLn (ldif2str outLDIF)
+    else do
+      BC.writeFile (outFile cfg) (ldif2str outLDIF)
+      putStrLn $ (outFile cfg) ++ " written."
+
+safeParseLDIFFile :: FilePath -> IO LDIF
+safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
diff --git a/ldif.cabal b/ldif.cabal
--- a/ldif.cabal
+++ b/ldif.cabal
@@ -1,5 +1,5 @@
 Name:            ldif
-Version:         0.0.12
+Version:         0.0.13
 License:         BSD3
 License-File:    LICENSE
 Synopsis:        The LDAP Data Interchange Format (LDIF) tools 
@@ -20,6 +20,8 @@
  .
  - ldifmodify - replays delta LDIF operations on content LDIF (similar to ldapmodify).
  .
+ - ldifundo - produces delta LDIF which rollbacks operations in input LDIF.
+ .
 Category:        Text
 Stability:       experimental
 Build-Type:      Simple
@@ -50,7 +52,7 @@
 
 flag cmd
   description: Build command line programs.
-  default:     False
+  default:     True
 
 Library
   Build-Depends:   base         < 5,
@@ -79,7 +81,12 @@
         Text.LDIF.Undo
 
 Executable ldifdiff
-  Hs-Source-Dirs:  src
+  Hs-Source-Dirs:  cmd
+  Build-Depends:   base         < 5,
+                   ldif,
+                   cmdargs,
+                   filepath,
+                   bytestring
   Main-Is:         ldifdiff.hs
   if flag(cmd)
     Buildable:     True
@@ -89,7 +96,13 @@
     Buildable:     False
 
 Executable ldif2html
-  Hs-Source-Dirs:  src
+  Hs-Source-Dirs:  cmd
+  Build-Depends:   base         < 5,
+                   ldif,
+                   containers,
+                   cmdargs,
+                   filepath,
+                   bytestring
   Main-Is:         ldif2html.hs
   if flag(cmd)
     Buildable:     True
@@ -99,7 +112,12 @@
     Buildable:     False
 
 Executable ldifmodify
-  Hs-Source-Dirs:  src
+  Hs-Source-Dirs:  cmd
+  Build-Depends:   base         < 5,
+                   ldif,
+                   cmdargs,
+                   filepath,
+                   bytestring
   Main-Is:         ldifmodify.hs
   if flag(cmd)
     Buildable:     True
@@ -109,7 +127,12 @@
     Buildable:     False
 
 Executable ldifundo
-  Hs-Source-Dirs:  src
+  Hs-Source-Dirs:  cmd
+  Build-Depends:   base         < 5,
+                   ldif,
+                   cmdargs,
+                   filepath,
+                   bytestring
   Main-Is:         ldifundo.hs
   if flag(cmd)
     Buildable:     True
@@ -119,7 +142,7 @@
     Buildable:     False
 
 Executable ldifparse
-  Hs-Source-Dirs:  src
+  Hs-Source-Dirs:  cmd
   Main-Is:         ldifparse.hs
   if !flag(test)
     Buildable:     False
diff --git a/src/ldif2html.hs b/src/ldif2html.hs
deleted file mode 100644
--- a/src/ldif2html.hs
+++ /dev/null
@@ -1,88 +0,0 @@
-{-# LANGUAGE BangPatterns, OverloadedStrings #-}
--- | Make Change LDIF based on two Content LDIFs
-import Data.List
-import Data.Either
-import Data.Maybe
-import Control.Monad 
-import System.FilePath 
-import System.Environment
-import Text.LDIF
-import qualified Data.Set as Set
-import qualified Data.ByteString.Char8 as BC
-
--- | Serialize DN to LDIF Format
-dn2html :: DN -> BC.ByteString
-dn2html ys@(DN xs) = BC.concat [ "<div id=\"abc" 
-                               , nm 
-                               , "\"></div><b>dn:</b> <font color=\"green\"><b>" 
-                               , dnstr 
-                               , "</b></font>" ]
-      where
-        dnstr = BC.intercalate "," $ map (\((Attribute n),v) -> n `BC.append` "=" `BC.append` (aVal v)) xs
-        nm = aVal $ dn2last ys
-
--- | Serialize Change Record in LDIF Format
-record2html :: Set.Set Value -> LDIFRecord -> BC.ByteString
-record2html idx (ChangeRecord dn (ChangeDelete))     = BC.unlines   [ (dn2str dn), "changetype: delete" ]
-record2html idx (ChangeRecord dn (ChangeAdd xs))     = BC.unlines $ [ (dn2html dn), "changetype: add"    ] ++ (attrVals2Ln idx xs)
-record2html idx (ChangeRecord dn (ChangeModify xs))  = BC.unlines $ [ (dn2str dn), "changetype: modify" ] ++ (mods2Ln idx xs)
-record2html idx (ChangeRecord dn (ChangeModDN))      = BC.unlines $ [ (dn2str dn), "changetype: moddn"  ]
-record2html idx (ContentRecord dn xs) = BC.unlines $ [ (dn2html dn) ] ++ (attrVals2Ln idx xs)
-
-attrVals2Ln :: Set.Set Value -> [AttrValue] -> [BC.ByteString]
-attrVals2Ln idx xs = map (attrVal2Ln idx) xs
-
-attrVal2Ln :: Set.Set Value -> AttrValue -> BC.ByteString
-attrVal2Ln idx ((Attribute n),v) = if Set.member v idx then BC.concat [ "<b>"
-                                                                      , n 
-                                                                      , "</b> : <a href=\"#abc"
-                                                                      , aVal v
-                                                                      , "\">" 
-                                                                      , aVal v
-                                                                      , "</a>"]
-                          else BC.concat [ "<b>",n,"</b> : ",aVal v]
-
-mods2Ln :: Set.Set Value -> [Modify] -> [BC.ByteString]
-mods2Ln idx xs = intercalate ["-"] $ map (mod2Ln idx) xs
-
-mod2Ln :: Set.Set Value -> Modify -> [BC.ByteString]
-mod2Ln idx mod = [ attrVal2Ln idx (modName,attrName) ] ++ valLst
-  where
-    attrName = Value $ aName $ modAttr mod
-    valLst = map (\v -> attrVal2Ln idx (modAttr mod,v)) $ modAttrVals mod
-    modName = case mod of 
-      (ModAdd _ _)     -> Attribute "add"
-      (ModDelete _ _)  -> Attribute "delete"
-      (ModReplace _ _) -> Attribute "replace"
-
-dns :: LDIF -> Set.Set Value
-dns (LDIF _ xs) = Set.fromList $ nub $ map (dn2last . reDN) xs
-
-dn2last (DN xs) = snd $ head xs
-
-main = do
-  args <- getArgs
-  case args of 
-     []         -> putStrLn "Usage: ldif2html <input.ldif> [<input2.ldif> <input3.ldif> ... <inputN.ldif> <output.ldif>]"
-     [inp]      -> do
-                      doLDIF2HTML [inp] (BC.putStrLn)
-                      putStrLn "# Done."
-     xs         -> do
-                      doLDIF2HTML (init xs) (BC.writeFile (last xs)) 
-                      putStrLn $ "## Processed : " ++ (unlines $ init xs)
-                      putStrLn $ "## Written   : " ++ (last xs)
-  where
-    doLDIF2HTML names outF = do
-      mls <- mapM (parseLDIFFile defaulLDIFConf) names
-      case lefts mls of 
-        []   -> do
-                let idx = Set.unions $ map dns $ rights mls
-                outF $ BC.concat [ "<html><body bgcolor=lightyellow><pre>"
-                                 , BC.concat $ map (ldif2html idx) (rights mls) 
-                                 , "</pre></body></html>" ]
-        xs  -> mapM_ print xs
-      -- | Serialize LDIF to HTML
-    ldif2html :: Set.Set Value -> LDIF -> BC.ByteString
-    ldif2html idx (LDIF v xs) = BC.unlines $ (ver2str v) ++ (map (record2html idx) xs)
-
-
diff --git a/src/ldifdiff.hs b/src/ldifdiff.hs
deleted file mode 100644
--- a/src/ldifdiff.hs
+++ /dev/null
@@ -1,34 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
--- | Make Change LDIF based on two Content LDIFs
-import Data.List
-import Data.Either
-import Data.Maybe
-import Control.Monad 
-import System.FilePath 
-import System.Environment
-import Text.LDIF
-import System.Console.CmdArgs
-import qualified Data.ByteString.Char8 as BC
-
-progDesc = "Create delta LDIF between Source LDIF and Target LDIF"
-
-data LdifDiff = LdifDiff { srcFile :: FilePath
-                         , dstFile :: FilePath } deriving (Show, Data, Typeable)
-
-defaultCfg = LdifDiff { srcFile = def &= typFile &= name "s" &= help "Source LDIF File"
-                      , dstFile = def &= typFile &= name "t" &= help "Target LDIF File" }
-
-main = do
-  cfg <- cmdArgs defaultCfg
-  execute cfg
-
-execute (LdifDiff []  _  ) = putStrLn "Error: -s source file is mandatory" 
-execute (LdifDiff _ []   ) = putStrLn "Error: -t target file is mandatory"
-execute (LdifDiff src dst) = do
-  ml1 <- parseLDIFFile defaulLDIFConf src
-  ml2 <- parseLDIFFile defaulLDIFConf dst
-  case rights [ml1,ml2] of 
-       [l1,l2] -> case diffLDIF l1 l2 of
-                    Left err -> putStrLn err
-                    Right delta -> BC.putStrLn $ ldif2str delta
-       _       -> print $ lefts [ml1,ml2] 
diff --git a/src/ldifmodify.hs b/src/ldifmodify.hs
deleted file mode 100644
--- a/src/ldifmodify.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
--- | Apply LDAP operations within LDIF on another LDIF.
--- | Without schema related verification like syntax, cardinality etc.
-import Data.List
-import Data.Either
-import Data.Maybe
-import Control.Monad 
-import System.FilePath 
-import System.Environment
-import Text.LDIF
-import System.Console.CmdArgs
-import qualified Data.ByteString.Char8 as BC
-
-progDesc = "Apply LDAP operations from LDIF to LDIF (like ldapmodify)"
-
-data LdifModify = LdifModify { baseFile :: FilePath
-                             , modFiles  :: [FilePath]
-                             , outFile  :: FilePath } deriving (Show, Data, Typeable)
-
-defaultCfg = LdifModify { baseFile = def &= typFile &= name "f" &= help "Base LDIF File"
-                        , modFiles = def &= args &= typ "LDIF Files for applying"
-                        , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }
-
-main = do
-  cfg <- cmdArgs defaultCfg
-  execute cfg
-
-execute (LdifModify [] _ _) = putStrLn "Error: -f base LDIF File is mandatory"
-execute (LdifModify _ [] _) = putStrLn "Error: no LDIF Files for applying provided"
-execute (LdifModify _ _ []) = putStrLn "Error: -o output LDIF File is mandatory"
-execute cfg = do
-  baseLDIF <- safeParseLDIFFile (baseFile cfg)
-  modLDIFs <- mapM (safeParseLDIFFile) (modFiles cfg)
-  let outLDIF = foldr (flip applyLDIF) baseLDIF modLDIFs
-  if length (outFile cfg) == 0 then do
-      BC.putStrLn (ldif2str outLDIF)
-    else do
-      BC.writeFile (outFile cfg) (ldif2str outLDIF)
-      putStrLn $ (outFile cfg) ++ " written."
-
-safeParseLDIFFile :: FilePath -> IO LDIF
-safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
diff --git a/src/ldifparse.hs b/src/ldifparse.hs
deleted file mode 100644
--- a/src/ldifparse.hs
+++ /dev/null
@@ -1,17 +0,0 @@
--- | Make Change LDIF based on two Content LDIFs
-import Data.List
-import Data.Either
-import Data.Maybe
-import Control.Monad 
-import System.FilePath 
-import System.Environment
-import Text.LDIF
-import qualified Data.ByteString.Char8 as BC
-
-main = do
-  args <- getArgs
-  let name = args !! 0
-  ml1 <- parseLDIFFile defaulLDIFConf name
-  case ml1 of 
-       Right l1 -> BC.putStrLn $ ldif2str l1
-       Left err -> print err
diff --git a/src/ldifundo.hs b/src/ldifundo.hs
deleted file mode 100644
--- a/src/ldifundo.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
-import Data.List
-import Data.Either
-import Data.Maybe
-import Control.Monad
-import System.FilePath
-import System.Environment
-import Text.LDIF
-import System.Console.CmdArgs
-import qualified Data.ByteString.Char8 as BC
-
-progDesc = "Calculate undo LDIF (rollback LDIF)"
-
-data LdifUndo = LdifUndo { inFile   :: FilePath
-                         , outFile  :: FilePath } deriving (Show, Data, Typeable)
-
-defaultCfg = LdifUndo { inFile = def &= typFile &= name "f" &= help "Input LDIF File"
-                      , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }
-
-main = do
-  cfg <- cmdArgs defaultCfg
-  execute cfg
-
-execute (LdifUndo [] _) = putStrLn "Error: -f base LDIF File is mandatory"
-execute cfg = do
-  inLDIF <- safeParseLDIFFile (inFile cfg)
-  let (outLDIF, wrn) = undoLDIF inLDIF
-  when (not $ null wrn) (putStrLn $ "Finished with warnings: " ++ (unlines $ map unlines wrn))
-  if length (outFile cfg) == 0 then do
-      BC.putStrLn (ldif2str outLDIF)
-    else do
-      BC.writeFile (outFile cfg) (ldif2str outLDIF)
-      putStrLn $ (outFile cfg) ++ " written."
-
-safeParseLDIFFile :: FilePath -> IO LDIF
-safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
