module Language.Haskell.Refact.Utils.Variables
  (
  
    isFieldName
  , isClassName
  , isInstanceName
  , isDeclaredInRdr
  , FreeNames(..),DeclaredNames(..)
  , hsFreeAndDeclaredRdr
  , hsFreeAndDeclaredNameStrings
  , hsFreeAndDeclaredPNs
  , getDeclaredTypesRdr
  , getDeclaredVarsRdr
  , hsVisibleNamesRdr, hsVisibleDsRdr
  , hsFDsFromInsideRdr, hsFDNamesFromInsideRdr, hsFDNamesFromInsideRdrPure
  , rdrName2Name, rdrName2NamePure
  , eqRdrNamePure
  
  , sameNameSpace
  
  , FindEntity(..)
  , findNameInRdr
  , findNamesRdr
  , sameOccurrence
  , definedPNsRdr,definedNamesRdr
  , definingDeclsRdrNames,definingDeclsRdrNames',definingSigsRdrNames
  , definingTyClDeclsNames
  , definesRdr,definesDeclRdr,definesNameRdr
  , definesTypeSigRdr,definesSigDRdr
  , hsTypeVbls
  , hsNamessRdr
  , findLRdrName
  , locToNameRdr, locToNameRdrPure
  , locToRdrName
  ) where
import Control.Monad.State
import Data.List
import Data.Maybe
import Data.Monoid
import Language.Haskell.Refact.Utils.GhcVersionSpecific
import Language.Haskell.Refact.Utils.LocUtils
import Language.Haskell.Refact.Utils.Monad
import Language.Haskell.Refact.Utils.MonadFunctions
import Language.Haskell.Refact.Utils.Types
import Language.Haskell.GHC.ExactPrint.Types
import Language.Haskell.GHC.ExactPrint
import Language.Haskell.GHC.ExactPrint.Utils
import qualified Bag           as GHC
import qualified GHC           as GHC
import qualified Name          as GHC
import qualified RdrName       as GHC
import qualified Data.Generics as SYB
import qualified GHC.SYB.Utils as SYB
import qualified Data.Map as Map
import Data.Generics.Strafunski.StrategyLib.StrategyLib hiding (liftIO,MonadPlus,mzero)
class (SYB.Data a, SYB.Typeable a) => FindEntity a where
  
  
  
  findEntity:: (SYB.Data b) => a -> b -> Bool
instance FindEntity GHC.Name where
  findEntity n t = fromMaybe False res
   where
    res = SYB.somethingStaged SYB.Renamer Nothing (Nothing `SYB.mkQ` worker) t
    worker (name::GHC.Name)
      | n == name = Just True
    worker _ = Nothing
instance FindEntity (GHC.Located GHC.RdrName) where
  findEntity ln t =
    case SYB.something (nameSybQuery checkRdr) t of
      Nothing -> False
      _       -> True
    where
      checkRdr :: GHC.Located GHC.RdrName -> Maybe Bool
      checkRdr n
        | sameOccurrence n ln = Just True
        | otherwise = Nothing
instance FindEntity (GHC.Located GHC.Name) where
  findEntity n t = fromMaybe False res
   where
    res = SYB.somethingStaged SYB.Renamer Nothing (Nothing `SYB.mkQ` worker) t
    worker (name::GHC.Located GHC.Name)
      | n == name = Just True
    worker _ = Nothing
instance FindEntity (GHC.LHsExpr GHC.RdrName) where
  findEntity e t = fromMaybe False res
   where
    res = SYB.something (Nothing `SYB.mkQ` worker) t
    worker (expr :: GHC.LHsExpr GHC.RdrName)
      | sameOccurrence e expr = Just True
    worker _ = Nothing
instance FindEntity (GHC.LHsExpr GHC.Name) where
  findEntity e t = fromMaybe False res
   where
    res = SYB.something (Nothing `SYB.mkQ` worker) t
    worker (expr :: GHC.LHsExpr GHC.Name)
      | sameOccurrence e expr = Just True
    worker _ = Nothing
instance FindEntity (GHC.Located (GHC.HsBindLR GHC.Name GHC.Name)) where
  findEntity e t = fromMaybe False res
   where
    res = SYB.somethingStaged SYB.Renamer Nothing (Nothing `SYB.mkQ` worker) t
    worker (expr::(GHC.Located (GHC.HsBindLR GHC.Name GHC.Name)))
      | sameOccurrence e expr = Just True
    worker _ = Nothing
instance FindEntity (GHC.Located (GHC.HsDecl GHC.Name)) where
  findEntity d t = fromMaybe False res
   where
    res = SYB.somethingStaged SYB.Renamer Nothing (Nothing `SYB.mkQ` worker) t
    worker (decl::(GHC.Located (GHC.HsDecl GHC.Name)))
      | sameOccurrence d decl = Just True
    worker _ = Nothing
sameOccurrence :: (GHC.Located t) -> (GHC.Located t) -> Bool
sameOccurrence (GHC.L l1 _) (GHC.L l2 _)
 = l1 == l2
data FreeNames = FN { fn :: [GHC.Name] }
data DeclaredNames = DN { dn :: [GHC.Name] }
instance Show FreeNames where
  show (FN ls) = "FN " ++ showGhcQual ls
instance Show DeclaredNames where
  show (DN ls) = "DN " ++ showGhcQual ls
instance Monoid FreeNames where
  mempty = FN []
  mappend (FN a) (FN b) = FN (a `mappend` b)
instance Monoid DeclaredNames where
  mempty = DN []
  mappend (DN a) (DN b) = DN (a `mappend` b)
emptyFD :: (FreeNames,DeclaredNames)
emptyFD = (FN [], DN [])
isFieldName :: GHC.Name -> Bool
isFieldName _n = error "undefined isFieldName"
isClassName :: GHC.Name -> Bool
isClassName _n = error "undefined isClassName"
isInstanceName :: GHC.Name -> Bool
isInstanceName _n = error "undefined isInstanceName"
hsTypeVbls::(SYB.Data t) => t -> ([GHC.RdrName],[GHC.RdrName])
hsTypeVbls =ghead "hsTypeVbls".(applyTU (stop_tdTU (failTU `adhocTU` pnt)))
  where
    
    pnt n | GHC.rdrNameSpace n == GHC.tvName = return ([], [n])
    pnt _ = mzero
isDeclaredInRdr :: NameMap -> GHC.Name -> [GHC.LHsDecl GHC.RdrName] -> Bool
isDeclaredInRdr nm name decls = nonEmptyList $ definingDeclsRdrNames nm [name] decls False True
hsFreeAndDeclaredNameStrings :: (SYB.Data t)
  => t -> RefactGhc ([String],[String])
hsFreeAndDeclaredNameStrings t = do
  (f,d) <- hsFreeAndDeclaredPNs t
  return ((nub.map showGhc) f, (nub.map showGhc) d)
hsFreeAndDeclaredPNs :: (SYB.Data t) => t -> RefactGhc ([GHC.Name],[GHC.Name])
hsFreeAndDeclaredPNs t = do
  nm <- getRefactNameMap
  
  let (FN f,DN d) = hsFreeAndDeclaredRdr nm t
  return (f,d)
hsFreeAndDeclaredRdr :: (SYB.Data t) => NameMap -> t -> (FreeNames,DeclaredNames)
hsFreeAndDeclaredRdr nm t = res
  where
    fd = hsFreeAndDeclaredRdr' nm t
    (FN f,DN d) = case fd of
      Left _err -> mempty
      Right v -> v
    res = (FN (f \\ d),DN d)
hsFreeAndDeclaredRdr':: (SYB.Data t) => NameMap -> t -> Either String (FreeNames,DeclaredNames)
hsFreeAndDeclaredRdr' nm t = do
      (FN f,DN d) <- hsFreeAndDeclared'
      
      
      let (f',d') = ( nub f
                    , nub d)
      return (FN f',DN d')
   where
          hsFreeAndDeclared' :: Either String (FreeNames,DeclaredNames)
          hsFreeAndDeclared'  = applyTU (stop_tdTU (failTU
                                                      `adhocTU` expr
                                                      `adhocTU` pat
                                                      `adhocTU` bndrs
                                                      `adhocTU` binds
                                                      `adhocTU` bindList
                                                      `adhocTU` match
                                                      `adhocTU` stmtlist
                                                      `adhocTU` stmts
                                                      `adhocTU` rhs
                                                      `adhocTU` ltydecl
                                                      `adhocTU` tyvarbndrs
                                                      `adhocTU` lhstyvarbndr
#if __GLASGOW_HASKELL__ > 710
                                                      `adhocTU` lsigtype
#endif
                                                      `adhocTU` sig
                                                      `adhocTU` datadefn
                                                      `adhocTU` condecl
                                                      `adhocTU` condetails
                                                      `adhocTU` condeclfield
                                                      `adhocTU` hstype
                                                       )) t
          
#if __GLASGOW_HASKELL__ <= 710
          expr (GHC.L l (GHC.HsVar n))
#else
          expr (GHC.L l (GHC.HsVar (GHC.L _ n)))
#endif
            = return (FN [rdrName2NamePure nm (GHC.L l n)],DN [])
#if __GLASGOW_HASKELL__ <= 710
          expr (GHC.L _ (GHC.OpApp e1 (GHC.L l (GHC.HsVar n)) _ e2)) = do
#else
          expr (GHC.L _ (GHC.OpApp e1 (GHC.L l (GHC.HsVar (GHC.L _ n))) _ e2)) = do
#endif
              efed <- hsFreeAndDeclaredRdr' nm [e1,e2]
              fd   <- addFree (rdrName2NamePure nm (GHC.L l n)) efed
              return fd
          expr (GHC.L _ ((GHC.HsLam (GHC.MG matches _ _ _))) :: GHC.LHsExpr GHC.RdrName) =
             hsFreeAndDeclaredRdr' nm matches
          expr (GHC.L _ ((GHC.HsLet decls e)) :: GHC.LHsExpr GHC.RdrName) =
            do
              (FN df,DN dd) <- hsFreeAndDeclaredRdr' nm decls
              (FN ef,_)  <- hsFreeAndDeclaredRdr' nm e
              return (FN (df `union` (ef \\ dd)),DN [])
#if __GLASGOW_HASKELL__ <= 710
          expr (GHC.L _ (GHC.RecordCon ln _ e)) = do
#else
          expr (GHC.L _ (GHC.RecordCon ln _ _ e)) = do
#endif
            fd <- hsFreeAndDeclaredRdr' nm e
            addFree (rdrName2NamePure nm ln) fd   
          expr (GHC.L _ (GHC.EAsPat ln e)) = do
            fd <- (hsFreeAndDeclaredRdr' nm e)
            addFree (rdrName2NamePure nm ln) fd
          expr _ = mzero
          
          rhs ((GHC.GRHSs g ds) :: GHC.GRHSs GHC.RdrName (GHC.LHsExpr GHC.RdrName))
            = do (FN df,DN dd) <- hsFreeAndDeclaredRdr' nm g
                 (FN ef,DN ed) <- hsFreeAndDeclaredRdr' nm ds
                 return (FN $ df ++ ef, DN $ dd ++ ed)
          
          pat :: GHC.LPat GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          pat (GHC.L _ (GHC.WildPat _)) = mzero
#if __GLASGOW_HASKELL__ <= 710
          pat (GHC.L l (GHC.VarPat n))
#else
          pat (GHC.L l (GHC.VarPat (GHC.L _ n)))
#endif
            = return (FN [],DN [rdrName2NamePure nm (GHC.L l n)])
          pat (GHC.L _ (GHC.AsPat ln p)) = do
            (f,DN d) <- hsFreeAndDeclaredRdr' nm p
            return (f,DN (rdrName2NamePure nm ln:d))
          pat (GHC.L _ (GHC.ParPat p)) = pat p
          pat (GHC.L _ (GHC.BangPat p)) = pat p
          pat (GHC.L _ (GHC.ListPat ps _ _)) = do
            fds <- mapM pat ps
            return $ mconcat fds
          pat (GHC.L _ (GHC.TuplePat ps _ _)) = do
            fds <- mapM pat ps
            return $ mconcat fds
          pat (GHC.L _ (GHC.PArrPat ps _)) = do
            fds <- mapM pat ps
            return $ mconcat fds
          pat (GHC.L _ (GHC.ConPatIn n det)) = do
            (FN f,DN d) <- details det
            return $ (FN [rdrName2NamePure nm n],DN d) <> (FN [],DN f)
          pat (GHC.L _ (GHC.ViewPat e p _)) = do
            fde <- hsFreeAndDeclaredRdr' nm e
            fdp <- pat p
            return $ fde <> fdp
          
          pat (GHC.L _ (GHC.LitPat _)) = return emptyFD
#if __GLASGOW_HASKELL__ <= 710
          pat (GHC.L _ (GHC.NPat _ _ _)) = return emptyFD
          pat (GHC.L _ (GHC.NPlusKPat n _ _ _)) = return (FN [],DN [rdrName2NamePure nm n])
#else
          pat (GHC.L _ (GHC.NPat _ _ _ _)) = return emptyFD
          pat (GHC.L _ (GHC.NPlusKPat n _ _ _ _ _)) = return (FN [],DN [rdrName2NamePure nm n])
#endif
          pat (GHC.L _ _p@(GHC.SigPatIn p b)) = do
            fdp <- pat p
            (FN fb,DN _db) <- hsFreeAndDeclaredRdr' nm b
            
            return $ fdp <> (FN fb,DN [])
          pat (GHC.L _ (GHC.SigPatOut p _)) = pat p
          pat (GHC.L l (GHC.CoPat _ p _)) = pat (GHC.L l p)
          pat (GHC.L _ (GHC.LazyPat p)) = pat p
          pat (GHC.L _ (GHC.ConPatOut {})) = error $ "hsFreeAndDeclaredRdr'.pat:impossible: ConPatOut"
#if __GLASGOW_HASKELL__ <= 710
          pat (GHC.L _ (GHC.SplicePat (GHC.HsSplice _ e))) = hsFreeAndDeclaredRdr' nm e
#else
          pat (GHC.L _ (GHC.SplicePat (GHC.HsQuasiQuote {})))     = return (FN [], DN [])
          pat (GHC.L _ (GHC.SplicePat (GHC.HsTypedSplice _ e)))   = hsFreeAndDeclaredRdr' nm e
          pat (GHC.L _ (GHC.SplicePat (GHC.HsUntypedSplice _ e))) = hsFreeAndDeclaredRdr' nm e
#endif
#if __GLASGOW_HASKELL__ <= 710
          pat (GHC.L _ (GHC.QuasiQuotePat _)) = return (FN [], DN [])
#endif
          
          
          details :: GHC.HsConPatDetails GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          details (GHC.PrefixCon  args) = do
            fds <- mapM pat args
            return $ mconcat fds
          details (GHC.RecCon recf) =
            recfields recf
          details (GHC.InfixCon arg1 arg2) = do
            fds <- mapM pat [arg1,arg2]
            return $ mconcat fds
          
          recfields :: (GHC.HsRecFields GHC.RdrName (GHC.LPat GHC.RdrName)) -> Either String (FreeNames,DeclaredNames)
          recfields (GHC.HsRecFields fields _) = do
            let args = map (\(GHC.L _ (GHC.HsRecField _ arg _)) -> arg) fields
            fds <- mapM pat args
            return $ mconcat fds
          
#if __GLASGOW_HASKELL__ <= 710
          bndrs :: GHC.HsWithBndrs GHC.RdrName (GHC.LHsType GHC.RdrName) -> Either String (FreeNames,DeclaredNames)
          bndrs (GHC.HsWB thing _ _ _) = do
            (FN ft,DN _dt) <- hsFreeAndDeclaredRdr' nm thing
            return (FN ft,DN [])
#else
          bndrs :: GHC.LHsSigWcType GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          bndrs (GHC.HsIB _ (GHC.HsWC _ _ ty)) = do
            (FN ft,DN _dt) <- hsFreeAndDeclaredRdr' nm ty
            
            return (FN ft,DN [])
#endif
          
          bindList (ds :: [GHC.LHsBind GHC.RdrName])
            =do (FN f,DN d) <- recurseList ds
                return (FN (f\\d),DN d)
          
#if __GLASGOW_HASKELL__ <= 710
          binds ((GHC.FunBind ln _ (GHC.MG matches _ _ _) _ _fvs _) :: GHC.HsBind GHC.RdrName)
#else
          binds ((GHC.FunBind ln (GHC.MG matches _ _ _) _ _fvs _) :: GHC.HsBind GHC.RdrName)
#endif
            = do
                (FN pf,_pd) <- hsFreeAndDeclaredRdr' nm matches
                let n = rdrName2NamePure nm ln
                return (FN (pf \\ [n]) ,DN [n])
          
          binds (GHC.PatBind pat' prhs _ _ds _) =
            do
              (FN pf,DN pd) <- hsFreeAndDeclaredRdr' nm pat'
              (FN rf,DN rd) <- hsFreeAndDeclaredRdr' nm prhs
              return (FN $ pf `union` (rf \\ pd),DN $ pd ++ rd)
          binds _ = mzero
          match ((GHC.Match _fn pats _mtype mrhs) :: GHC.Match GHC.RdrName (GHC.LHsExpr GHC.RdrName))
            = do
              (FN pf,DN pd) <- hsFreeAndDeclaredRdr' nm pats
              (FN rf,DN rd) <- hsFreeAndDeclaredRdr' nm mrhs
              return (FN (pf `union` (rf \\ (pd `union` rd))),DN [])
          stmtlist (ds :: [GHC.ExprLStmt GHC.RdrName]) = do
            (FN f,DN d) <- recurseList ds
            
            
            
            return (FN (f\\d),DN d)
          
#if __GLASGOW_HASKELL__ <= 710
          stmts ((GHC.BindStmt pat' expre _bindOp _failOp) :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) = do
#else
          stmts ((GHC.BindStmt pat' expre _bindOp _failOp _) :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) = do
#endif
            
            
            (FN pf,DN pd)  <- hsFreeAndDeclaredRdr' nm pat'
            
            (FN ef,_ed) <- hsFreeAndDeclaredRdr' nm expre
            let sf1 = []
            return (FN $ pf `union` ef `union` (sf1\\pd),DN pd) 
          stmts ((GHC.LetStmt binds') :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) =
            hsFreeAndDeclaredRdr' nm binds'
          stmts _ = mzero
          
          ltydecl :: GHC.TyClDecl GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          ltydecl (GHC.FamDecl fd) = hsFreeAndDeclaredRdr' nm fd
          ltydecl (GHC.SynDecl ln _bndrs _rhs _fvs)
              = return (FN [],DN [rdrName2NamePure nm ln])
#if __GLASGOW_HASKELL__ <= 710
          ltydecl (GHC.DataDecl ln tyvars defn _fvs) = do
              
#else
          ltydecl (GHC.DataDecl ln tyvars defn _c _fvs) = do
#endif
              (FN fs,DN dds) <- hsFreeAndDeclaredRdr' nm  defn
              (FN _ft,DN dt) <- hsFreeAndDeclaredRdr' nm  tyvars
              return (FN (fs \\ dt),DN (rdrName2NamePure nm ln:dds))
          ltydecl (GHC.ClassDecl ctx ln tyvars
                           _fds sigs meths ats atds _docs _fvs) = do
             ct  <- hsFreeAndDeclaredRdr' nm ctx
             (_,DN tv)  <- hsFreeAndDeclaredRdr' nm tyvars
             ss  <- recurseList sigs
             md  <- hsFreeAndDeclaredRdr' nm meths
             ad  <- hsFreeAndDeclaredRdr' nm ats
             atd <- hsFreeAndDeclaredRdr' nm atds
             let (FN ff,DN df) = ((FN [],DN [rdrName2NamePure nm ln]) <> md <> ad <> atd <> ct <> ss)
             return (FN (nub ff \\ tv), DN df)
          
#if __GLASGOW_HASKELL__ <= 710
          tyvarbndrs :: GHC.LHsTyVarBndrs GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          tyvarbndrs (GHC.HsQTvs _implicit explicit) = do
            recurseList explicit
#else
          tyvarbndrs :: GHC.LHsQTyVars GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          tyvarbndrs (GHC.HsQTvs _implicit explicit _dependent ) = recurseList explicit
#endif
          lhstyvarbndr :: GHC.LHsTyVarBndr GHC.RdrName -> Either String (FreeNames,DeclaredNames)
#if __GLASGOW_HASKELL__ <= 710
          lhstyvarbndr (GHC.L l (GHC.UserTyVar n)) = return (FN [], DN [rdrName2NamePure nm (GHC.L l n)])
#else
          lhstyvarbndr (GHC.L _ (GHC.UserTyVar ln)) = return (FN [], DN [rdrName2NamePure nm ln])
#endif
          lhstyvarbndr (GHC.L _ (GHC.KindedTyVar ln lk)) = do
            ks <- hsFreeAndDeclaredRdr' nm lk
            return ((FN [], DN [rdrName2NamePure nm ln]) <> ks)
          
#if __GLASGOW_HASKELL__ > 710
          lsigtype :: GHC.LHsSigType GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          lsigtype (GHC.HsIB _ typ) = do
            hsFreeAndDeclaredRdr' nm typ
#endif
          
          sig :: GHC.Sig GHC.RdrName -> Either String (FreeNames,DeclaredNames)
#if __GLASGOW_HASKELL__ <= 710
          sig (GHC.TypeSig lns typ _) = do
#else
          sig (GHC.TypeSig lns typ) = do
#endif
            (FN ft, dt) <- hsFreeAndDeclaredRdr' nm typ
            
            return ((FN [],DN (map (rdrName2NamePure nm ) lns))
                     <> (FN (filter (not . GHC.isTyVarName) ft), dt))
#if __GLASGOW_HASKELL__ <= 710
          sig (GHC.PatSynSig ln (_ef,GHC.HsQTvs _ns bndrs) ctx1 ctx2 typ) = do
            (_, DN bs) <- hsFreeAndDeclaredRdr' nm bndrs
            c1s <- hsFreeAndDeclaredRdr' nm ctx1
            c2s <- hsFreeAndDeclaredRdr' nm ctx2
            ts  <- hsFreeAndDeclaredRdr' nm typ
            let (FN f,DN d) = c1s <> c2s <> ts
                fd = (FN (f \\ bs), DN d )
            return ((FN [],DN [rdrName2NamePure nm ln]) <> fd)
#else
          sig (GHC.PatSynSig ln typ) = do
            ts <- hsFreeAndDeclaredRdr' nm typ
            return ((FN [],DN [rdrName2NamePure nm ln]) <> ts)
#endif
#if __GLASGOW_HASKELL__ <= 710
          sig (GHC.GenericSig lns typ) = do
#else
          sig (GHC.ClassOpSig _ lns typ) = do
#endif
            ts <- hsFreeAndDeclaredRdr' nm typ
            return ((FN [],DN (map (rdrName2NamePure nm) lns)) <> ts)
          sig (GHC.IdSig _ ) = error $ "hsFreeAndDeclaredRdr:IdSig should not occur"
          sig (GHC.FixSig fsig) = hsFreeAndDeclaredRdr' nm fsig
          sig (GHC.InlineSig ln _) = do
            return ((FN [],DN [rdrName2NamePure nm ln]) )
          sig (GHC.SpecSig ln typs _) = do
            ts <- recurseList typs
            return ((FN [rdrName2NamePure nm ln],DN []) <> ts)
          sig (GHC.SpecInstSig _ ssig) = hsFreeAndDeclaredRdr' nm ssig
          sig (GHC.MinimalSig _ _) = return mempty
          
          datadefn :: GHC.HsDataDefn GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          datadefn (GHC.HsDataDefn _ ctxt mtyp mkind cons mderivs) = do
             cts <- mapM (hsFreeAndDeclaredRdr' nm) $ GHC.unLoc ctxt
             ts  <- maybeHelper mtyp
             ks  <- maybeHelper mkind
             cs  <- mapM (hsFreeAndDeclaredRdr' nm) cons
             ds  <- case mderivs of
                      Nothing           -> return (FN [],DN [])
                      Just (GHC.L _ ds) -> recurseList ds
             
             return $ mconcat [mconcat cts,ts,ks,mconcat cs,ds]
          
          condecl :: GHC.LConDecl GHC.RdrName -> Either String (FreeNames,DeclaredNames)
#if __GLASGOW_HASKELL__ <= 710
          condecl (GHC.L _ (GHC.ConDecl ns _expr (GHC.HsQTvs _ns bndrs) ctxt
                                        dets res _ depc_syntax)) =
            case res of
              GHC.ResTyGADT ls typ -> do
                (ft,_) <- hsFreeAndDeclaredRdr' nm typ
                return (ft,DN (map (rdrName2NamePure nm) ns))
              GHC.ResTyH98 -> do
                cs <- hsFreeAndDeclaredRdr' nm ctxt
                ds <- hsFreeAndDeclaredRdr' nm dets
                return ((FN [], DN (map (rdrName2NamePure nm) ns)) <> cs <> ds)
#else
          condecl (GHC.L _ (GHC.ConDeclGADT ns typ _)) = do
            (ft,_) <- hsFreeAndDeclaredRdr' nm typ
            return (ft,DN (map (rdrName2NamePure nm) ns))
          condecl (GHC.L _ (GHC.ConDeclH98 n _ mctxt dets _)) = do
             cs <- maybeHelper mctxt
             ds <- hsFreeAndDeclaredRdr' nm dets
             return ((FN [], DN ([rdrName2NamePure nm n])) <> cs <> ds)
#endif
          
          
          condetails :: GHC.HsConDeclDetails GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          condetails (GHC.PrefixCon args)      = do
            
            (FN fs,d) <- recurseList args
            return (FN (filter (not . GHC.isTyVarName) fs),d)
          condetails (GHC.RecCon (GHC.L _ fs)) = recurseList fs
          condetails (GHC.InfixCon a1 a2)      = do
            
            (FN fs,d) <- recurseList [a1,a2]
            return (FN (filter (not . GHC.isTyVarName) fs),d)
          
          condeclfield :: GHC.LConDeclField GHC.RdrName -> Either String (FreeNames,DeclaredNames)
          condeclfield (GHC.L _ (GHC.ConDeclField fns typ _)) = do
#if __GLASGOW_HASKELL__ <= 710
            let ns = fns
#else
            let ns = map (GHC.rdrNameFieldOcc . GHC.unLoc) fns
#endif
            dt <- hsFreeAndDeclaredRdr' nm typ
            return ((FN [],DN (map (rdrName2NamePure nm) ns)) <> dt)
          
          hstype :: GHC.LHsType GHC.RdrName -> Either String (FreeNames,DeclaredNames)
#if __GLASGOW_HASKELL__ <= 710
          hstype (GHC.L _ (GHC.HsForAllTy _ _ _ _ typ)) = hsFreeAndDeclaredRdr' nm typ
#else
          hstype (GHC.L _ (GHC.HsForAllTy _ typ)) = hsFreeAndDeclaredRdr' nm typ
#endif
#if __GLASGOW_HASKELL__ <= 710
          hstype (GHC.L l (GHC.HsTyVar n)) = return (FN [rdrName2NamePure nm (GHC.L l n)],DN [])
#else
          hstype (GHC.L _ (GHC.HsTyVar n)) = return (FN [rdrName2NamePure nm n],DN [])
#endif
          hstype (GHC.L _ (GHC.HsAppTy t1 t2)) = recurseList [t1,t2]
          hstype (GHC.L _ (GHC.HsFunTy t1 t2)) = recurseList [t1,t2]
          hstype (GHC.L _ (GHC.HsListTy typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsPArrTy typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsTupleTy _ typs)) = recurseList typs
          hstype (GHC.L _ (GHC.HsOpTy t1 _ t2)) = recurseList [t1,t2]
          hstype (GHC.L _ (GHC.HsParTy typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsIParamTy _ typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsEqTy t1 t2)) = recurseList [t1,t2]
          hstype (GHC.L _ (GHC.HsKindSig t1 t2)) = recurseList [t1,t2]
#if __GLASGOW_HASKELL__ <= 710
          hstype (GHC.L _ (GHC.HsQuasiQuoteTy _)) = return emptyFD
#endif
          hstype (GHC.L _ (GHC.HsSpliceTy _ _)) = return (FN [],DN [])
          hstype (GHC.L _ (GHC.HsDocTy _ typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsBangTy _ typ)) = hsFreeAndDeclaredRdr' nm typ
          hstype (GHC.L _ (GHC.HsRecTy cons)) = recurseList cons
          hstype (GHC.L _ (GHC.HsCoreTy _)) = return emptyFD
          hstype (GHC.L _ (GHC.HsExplicitListTy _ typs)) = recurseList typs
          hstype (GHC.L _ (GHC.HsExplicitTupleTy _ typs)) = recurseList typs
          hstype (GHC.L _ (GHC.HsTyLit _)) = return emptyFD
#if __GLASGOW_HASKELL__ <= 710
          hstype (GHC.L _ (GHC.HsWrapTy _ typ)) = hsFreeAndDeclaredRdr' nm typ
#endif
#if __GLASGOW_HASKELL__ <= 710
          hstype (GHC.L _ (GHC.HsWildcardTy)) = return (FN [],DN [])
          hstype (GHC.L l (GHC.HsNamedWildcardTy n)) = return (FN [rdrName2NamePure nm (GHC.L l n)],DN [])
#else
          hstype (GHC.L _ (GHC.HsWildCardTy _)) = return (FN [],DN [])
#endif
#if __GLASGOW_HASKELL__ > 710
          hstype (GHC.L _ (GHC.HsQualTy (GHC.L _ ctxt) ty)) = recurseList (ty:ctxt)
          hstype (GHC.L _ (GHC.HsAppsTy as)) = do
            fds <- mapM doApp as
            return $ mconcat fds
            where
              doApp (GHC.L _ (GHC.HsAppInfix n)) = return (FN [rdrName2NamePure nm n],DN [])
              doApp (GHC.L _ (GHC.HsAppPrefix ty)) = hstype ty
#endif
          
          recurseList xs = do
            fds <- mapM (hsFreeAndDeclaredRdr' nm) xs
            return $ mconcat fds
          maybeHelper mv = case mv of
            Nothing -> return (FN [], DN [])
            Just v -> hsFreeAndDeclaredRdr' nm v
          
          addFree :: GHC.Name -> (FreeNames,DeclaredNames)
                  -> Either String (FreeNames,DeclaredNames)
          addFree free (FN fr,de) = return (FN $ [free] `union` fr, de)
getDeclaredTypesRdr :: GHC.LHsDecl GHC.RdrName -> RefactGhc [GHC.Name]
getDeclaredTypesRdr (GHC.L _ (GHC.TyClD decl)) = do
  nm <- getRefactNameMap
  case decl of
#if __GLASGOW_HASKELL__ <= 710
    (GHC.FamDecl (GHC.FamilyDecl _ ln _ _)) -> return [rdrName2NamePure nm ln]
#else
    (GHC.FamDecl (GHC.FamilyDecl _ ln _ _ _)) -> return [rdrName2NamePure nm ln]
#endif
    (GHC.SynDecl ln  _ _ _) -> return [rdrName2NamePure nm ln]
#if __GLASGOW_HASKELL__ <= 710
    (GHC.DataDecl ln _ defn _) -> do
      let dds = concatMap (GHC.con_names . GHC.unLoc) $ GHC.dd_cons defn
#else
    (GHC.DataDecl ln _ defn _ _) -> do
      let dds = concatMap (GHC.getConNames . GHC.unLoc) $ GHC.dd_cons defn
#endif
      let ddns = map (rdrName2NamePure nm) dds
      return $ [rdrName2NamePure nm ln] ++ ddns
    (GHC.ClassDecl _ ln _vars _fds sigs meths ats _atdefs _ _fvs) -> do
      
      let msn = getDeclaredVarsRdr nm (map wrapDecl $ GHC.bagToList meths)
      let fds = map (GHC.fdLName . GHC.unLoc) ats
          fds' = map (rdrName2NamePure nm) fds
      return $ nub $ [rdrName2NamePure nm ln] ++ ssn ++ msn ++ fds' 
      where
        getLSig :: GHC.LSig GHC.RdrName -> [GHC.Name]
#if __GLASGOW_HASKELL__ <= 710
        getLSig (GHC.L _ (GHC.TypeSig ns _ _))  = map (rdrName2NamePure nm) ns
#else
        getLSig (GHC.L _ (GHC.TypeSig ns _))  = map (rdrName2NamePure nm) ns
#endif
#if __GLASGOW_HASKELL__ <= 710
        getLSig (GHC.L _ (GHC.GenericSig ns _)) = map (rdrName2NamePure nm) ns
#else
        getLSig (GHC.L _ (GHC.ClassOpSig _ ns _)) = map (rdrName2NamePure nm) ns
#endif
        getLSig (GHC.L _ (GHC.IdSig _n)) = []
        getLSig (GHC.L _ (GHC.InlineSig ln2 _)) = [rdrName2NamePure nm ln2]
        getLSig (GHC.L _ (GHC.SpecSig ln2 _ _)) = [rdrName2NamePure nm ln2]
        getLSig (GHC.L _ (GHC.SpecInstSig _ _)) = []
        getLSig (GHC.L _ (GHC.FixSig _)) = []
#if __GLASGOW_HASKELL__ <= 710
        getLSig (GHC.L _ (GHC.PatSynSig _ _ _ _ _)) = error "To implement: getLSig PatSynSig"
#else
        getLSig (GHC.L _ (GHC.PatSynSig _ _)) = error "To implement: getLSig PatSynSig"
#endif
        getLSig (GHC.L _ (GHC.MinimalSig _ _)) = error "To implement: getLSig PatSynSig"
        ssn = concatMap getLSig sigs
getDeclaredTypesRdr _ = return []
findNameInRdr :: (SYB.Data t) => NameMap -> GHC.Name -> t -> Bool
findNameInRdr nm pn t = findNamesRdr nm [pn] t
findNamesRdr :: (SYB.Data t) => NameMap -> [GHC.Name] -> t -> Bool
findNamesRdr nm pns t =
  isJust $ SYB.something (inName) t
    where
      
      checker :: GHC.Located GHC.RdrName -> Maybe Bool
      checker ln
         | elem (GHC.nameUnique (rdrName2NamePure nm ln)) uns = Just True
      checker _ = Nothing
      inName :: (SYB.Typeable a) => a -> Maybe Bool
      inName = nameSybQuery checker
      uns = map GHC.nameUnique pns
definedPNsRdr :: GHC.LHsDecl GHC.RdrName -> [GHC.Located GHC.RdrName]
#if __GLASGOW_HASKELL__ <= 710
definedPNsRdr (GHC.L _ (GHC.ValD (GHC.FunBind pname _ _ _ _ _)))   = [pname]
#else
definedPNsRdr (GHC.L _ (GHC.ValD (GHC.FunBind pname _ _ _ _)))   = [pname]
#endif
definedPNsRdr (GHC.L _ (GHC.ValD (GHC.PatBind p _rhs _ty _fvs _))) = (hsNamessRdr p)
definedPNsRdr  _ = []
definedNamesRdr :: NameMap -> GHC.LHsDecl GHC.RdrName -> [GHC.Name]
definedNamesRdr nameMap bind = map (rdrName2NamePure nameMap) (definedPNsRdr bind)
definingDeclsRdrNames ::
            NameMap
            -> [GHC.Name]   
            -> [GHC.LHsDecl GHC.RdrName] 
            -> Bool       
            -> Bool       
            -> [GHC.LHsDecl GHC.RdrName]  
definingDeclsRdrNames nameMap pns ds incTypeSig recursive = concatMap defining ds
  where
   defining decl
     = if recursive
        then SYB.everything  (++) ([]  `SYB.mkQ` definesDecl `SYB.extQ` definesBind)  decl
        else definesDecl decl
     where
      definesDecl :: (GHC.LHsDecl GHC.RdrName) -> [GHC.LHsDecl GHC.RdrName]
#if __GLASGOW_HASKELL__ <= 710
      definesDecl decl'@(GHC.L _ (GHC.ValD (GHC.FunBind _ _ _ _ _ _)))
#else
      definesDecl decl'@(GHC.L _ (GHC.ValD (GHC.FunBind _ _ _ _ _)))
#endif
        | any (\n -> definesDeclRdr nameMap n decl') pns = [decl']
      definesDecl decl'@(GHC.L _l (GHC.ValD (GHC.PatBind _p _rhs _ty _fvs _)))
        | any (\n -> definesDeclRdr nameMap n decl') pns = [decl']
      definesDecl decl'@(GHC.L _l (GHC.TyClD _))
        | any (\n -> definesNameRdr nameMap n decl') pns = [decl']
      definesDecl decl'@(GHC.L _l (GHC.SigD _))
        | incTypeSig && any (\n -> definesNameRdr nameMap n decl') pns = [decl']
      definesDecl _ = []
      definesBind :: (GHC.LHsBind GHC.RdrName) -> [GHC.LHsDecl GHC.RdrName]
      definesBind (GHC.L l b) = definesDecl (GHC.L l (GHC.ValD b))
definingDeclsRdrNames' :: (SYB.Data t)
            => NameMap
            -> [GHC.Name]   
            -> t            
            -> [GHC.LHsDecl GHC.RdrName]  
definingDeclsRdrNames' nameMap pns ds = defining ds
  where
   defining decl
     = SYB.everythingStaged SYB.Renamer (++) [] ([]  `SYB.mkQ` defines' `SYB.extQ` definesBind) decl
     where
      defines' :: (GHC.LHsDecl GHC.RdrName) -> [GHC.LHsDecl GHC.RdrName]
      defines' decl'@(GHC.L _ (GHC.ValD (GHC.FunBind{})))
        | any (\n -> definesDeclRdr nameMap n decl') pns = [decl']
      defines' decl'@(GHC.L _l (GHC.ValD (GHC.PatBind _p _rhs _ty _fvs _)))
        | any (\n -> definesDeclRdr nameMap n decl') pns = [decl']
      defines' decl'@(GHC.L _l (GHC.TyClD _))
        | any (\n -> definesDeclRdr nameMap n decl') pns = [decl']
      defines' _ = []
      definesBind :: (GHC.LHsBind GHC.RdrName) -> [GHC.LHsDecl GHC.RdrName]
      definesBind (GHC.L l b) = defines' (GHC.L l (GHC.ValD b))
definingSigsRdrNames :: (SYB.Data t) =>
            NameMap
            ->[GHC.Name] 
            ->t        
            ->[GHC.LSig GHC.RdrName]  
definingSigsRdrNames nameMap pns ds = def ds
  where
   def decl
     
     = SYB.everything (++) ([]  `SYB.mkQ` inSig `SYB.extQ` inSigDecl) decl
     where
      inSigDecl :: GHC.LHsDecl GHC.RdrName -> [GHC.LSig GHC.RdrName]
      inSigDecl (GHC.L l (GHC.SigD s)) = inSig (GHC.L l s)
      inSigDecl _ = []
      inSig :: (GHC.LSig GHC.RdrName) -> [GHC.LSig GHC.RdrName]
#if __GLASGOW_HASKELL__ <= 710
      inSig (GHC.L l (GHC.TypeSig ns t p))
       | defines' ns /= [] = [(GHC.L l (GHC.TypeSig (defines' ns) t p))]
#else
      inSig (GHC.L l (GHC.TypeSig ns t))
       | defines' ns /= [] = [(GHC.L l (GHC.TypeSig (defines' ns) t))]
#endif
      inSig _ = []
      defines' :: [GHC.Located GHC.RdrName] -> [GHC.Located GHC.RdrName]
      defines' p
        
        = let
             isDefined :: GHC.Located GHC.RdrName -> [GHC.Located GHC.RdrName]
             isDefined ln = if (rdrName2NamePure nameMap ln) `elem` pns
                              then [ln]
                              else []
          in concatMap isDefined p
definingTyClDeclsNames:: (SYB.Data t)
            => NameMap
            -> [GHC.Name]   
            -> t 
            -> [GHC.LTyClDecl GHC.RdrName]  
definingTyClDeclsNames nm pns t = defining t
  where
   defining decl
     = SYB.everythingStaged SYB.Parser (++) []
                   ([]  `SYB.mkQ` defines'
                        `SYB.extQ` definesDecl) decl
     where
      defines' :: (GHC.LTyClDecl GHC.RdrName) -> [GHC.LTyClDecl GHC.RdrName]
#if __GLASGOW_HASKELL__ <= 710
      defines' decl'@(GHC.L _ (GHC.FamDecl (GHC.FamilyDecl _ pname _ _)))
#else
      defines' decl'@(GHC.L _ (GHC.FamDecl (GHC.FamilyDecl _ pname _ _ _)))
#endif
        | elem (GHC.nameUnique $ rdrName2NamePure nm pname) uns = [decl']
        | otherwise = []
      defines' decl'@(GHC.L _ (GHC.SynDecl pname _ _ _))
        | elem (GHC.nameUnique $ rdrName2NamePure nm pname) uns = [decl']
        | otherwise = []
#if __GLASGOW_HASKELL__ <= 710
      defines' decl'@(GHC.L _ (GHC.DataDecl _ _ _ _))
#else
      defines' decl'@(GHC.L _ (GHC.DataDecl _ _ _ _ _))
#endif
        
        | not $ null (dus `intersect` uns) = [decl']
        | otherwise = []
        where
          (_,DN ds) = hsFreeAndDeclaredRdr nm decl'
          dus = map GHC.nameUnique ds
      defines' decl'@(GHC.L _ (GHC.ClassDecl _ pname _ _ _ _ _ _ _ _))
        | elem (GHC.nameUnique $ rdrName2NamePure nm pname) uns = [decl']
        | otherwise = []
      definesDecl (GHC.L l (GHC.TyClD d)) = defines' (GHC.L l d)
      definesDecl _ = []
      uns = map (\n -> GHC.nameUnique n) pns
definesRdr :: NameMap -> GHC.Name -> GHC.LHsBind GHC.RdrName -> Bool
#if __GLASGOW_HASKELL__ <= 710
definesRdr nm  nin (GHC.L _ (GHC.FunBind ln _ _ _ _ _))
#else
definesRdr nm nin (GHC.L _ (GHC.FunBind ln _ _ _ _))
#endif
  = GHC.nameUnique (rdrName2NamePure nm ln) == GHC.nameUnique nin
definesRdr nm n (GHC.L _ (GHC.PatBind p _rhs _ty _fvs _))
  = elem n (map (rdrName2NamePure nm) (hsNamessRdr p))
definesRdr _ _ _= False
definesDeclRdr :: NameMap -> GHC.Name -> GHC.LHsDecl GHC.RdrName -> Bool
definesDeclRdr nameMap nin (GHC.L l (GHC.ValD d)) = definesRdr nameMap nin (GHC.L l d)
definesDeclRdr nameMap nin (GHC.L _ (GHC.TyClD ty)) = clsDeclDefinesRdr nameMap nin ty
definesDeclRdr _ _ _ = False
clsDeclDefinesRdr :: NameMap -> GHC.Name -> GHC.TyClDecl GHC.RdrName -> Bool
clsDeclDefinesRdr nameMap nin (GHC.SynDecl (GHC.L ln _nm) _ty _rhs _) =
  case Map.lookup ln nameMap of
    Nothing -> False
    Just n  -> GHC.nameUnique n == GHC.nameUnique nin
clsDeclDefinesRdr _ _ _ = False
definesNameRdr :: NameMap -> GHC.Name -> GHC.LHsDecl GHC.RdrName -> Bool
definesNameRdr nameMap nin (GHC.L l (GHC.ValD d))  = definesRdr nameMap nin (GHC.L l d)
definesNameRdr nameMap nin d = nin `elem` declared
  where
    (_,DN declared) = hsFreeAndDeclaredRdr nameMap d
definesTypeSigRdr :: NameMap -> GHC.Name -> GHC.Sig GHC.RdrName -> Bool
#if __GLASGOW_HASKELL__ <= 710
definesTypeSigRdr nameMap pn (GHC.TypeSig names _typ _)
#else
definesTypeSigRdr nameMap pn (GHC.TypeSig names _typ)
#endif
  = elem (GHC.nameUnique pn) (map (GHC.nameUnique . rdrName2NamePure nameMap) names)
definesTypeSigRdr _ _  x = error $ "definesTypeSigRdr : got " ++ SYB.showData SYB.Parser 0 x
definesSigDRdr :: NameMap -> GHC.Name -> GHC.LHsDecl GHC.RdrName -> Bool
definesSigDRdr nameMap nin (GHC.L _ (GHC.SigD d)) = definesTypeSigRdr nameMap nin d
definesSigDRdr _ _ _ = False
hsNamessRdr :: (SYB.Data t) => t -> [GHC.Located GHC.RdrName]
hsNamessRdr t = nub $ fromMaybe [] r
  where
     r = (SYB.everythingStaged SYB.Parser mappend mempty (inName) t)
     checker :: GHC.Located GHC.RdrName -> Maybe [GHC.Located GHC.RdrName]
     checker x = Just [x]
     inName :: (SYB.Typeable a) => a -> Maybe [GHC.Located GHC.RdrName]
     inName = nameSybQuery checker
findLRdrName :: (SYB.Data t) => NameMap -> GHC.Name -> t -> Bool
findLRdrName nm n t = isJust $ SYB.something isMatch t
  where
    checker :: GHC.Located GHC.RdrName -> Maybe Bool
    checker x
      | GHC.nameUnique (rdrName2NamePure nm x) == GHC.nameUnique n = Just True
      | otherwise = Nothing
    isMatch :: (SYB.Typeable a) => a -> Maybe Bool
    isMatch = nameSybQuery checker
getDeclaredVarsRdr :: NameMap -> [GHC.LHsDecl GHC.RdrName] -> [GHC.Name]
getDeclaredVarsRdr nm bs = concatMap vars bs
  where
      vars :: (GHC.LHsDecl GHC.RdrName) -> [GHC.Name]
#if __GLASGOW_HASKELL__ <= 710
      vars (GHC.L _ (GHC.ValD (GHC.FunBind ln _ _ _ _fvs _)))   = [rdrName2NamePure nm ln]
#else
      vars (GHC.L _ (GHC.ValD (GHC.FunBind ln _ _ _ _fvs)))   = [rdrName2NamePure nm ln]
#endif
      vars (GHC.L _ (GHC.ValD (GHC.PatBind p _rhs _ty _fvs _))) = (map (rdrName2NamePure nm) $ hsNamessRdr p)
      vars _ = []
hsVisibleNamesRdr:: (SYB.Data t2)
  => GHC.Name -> t2 -> RefactGhc [String]
hsVisibleNamesRdr e t = do
    nm <- getRefactNameMap
    (DN d) <- hsVisibleDsRdr nm e t
    return ((nub . map showGhc) d)
hsVisibleDsRdr :: (SYB.Data t)
             => NameMap -> GHC.Name -> t -> RefactGhc DeclaredNames
hsVisibleDsRdr nm e t = do
  
  (DN d) <- res
  return (DN (nub d))
  where
    
    
    
    
    
    
    res = (const err 
          `SYB.extQ` parsed
          `SYB.extQ` lvalbinds
          `SYB.extQ` valbinds
          `SYB.extQ` lhsdecls
          `SYB.extQ` lhsdecl
          `SYB.extQ` lhsbindslr
          `SYB.extQ` hsbinds
          `SYB.extQ` hsbind
          `SYB.extQ` hslocalbinds
          `SYB.extQ` lmatch
          `SYB.extQ` match
          `SYB.extQ` grhss
          `SYB.extQ` lgrhs
          `SYB.extQ` lexpr
          `SYB.extQ` tyclgroups
          `SYB.extQ` tyclgroup
          `SYB.extQ` tycldeclss
          `SYB.extQ` tycldecls
          `SYB.extQ` ltycldecl
          `SYB.extQ` tycldecl
          `SYB.extQ` hsdatadefn
          `SYB.extQ` condecl
          `SYB.extQ` instdecls
          `SYB.extQ` instdecl
          `SYB.extQ` lhstype
          `SYB.extQ` lsigs
          `SYB.extQ` lsig
          `SYB.extQ` lstmts
          `SYB.extQ` lstmt
          `SYB.extQ` lpats
          `SYB.extQ` lpat
#if __GLASGOW_HASKELL__ > 710
          `SYB.extQ` ibndrs
          `SYB.extQ` lsigty
#endif
          `SYB.extQ` lanndecl
          ) t
    
    parsed :: GHC.ParsedSource -> RefactGhc DeclaredNames
    parsed p
      | findNameInRdr nm e p = do
         
         
         dfds <- mapM (declFun ( hsVisibleDsRdr nm e) ) $ GHC.hsmodDecls $ GHC.unLoc p
         
         return $ mconcat dfds
    parsed _ = return (DN [])
    lvalbinds :: (GHC.Located (GHC.HsLocalBinds GHC.RdrName)) -> RefactGhc DeclaredNames
    lvalbinds (GHC.L _ (GHC.HsValBinds vb)) = valbinds vb
    lvalbinds (GHC.L _ (GHC.HsIPBinds _))   = return (DN [])
    lvalbinds (GHC.L _ GHC.EmptyLocalBinds) = return (DN [])
    valbinds :: (GHC.HsValBinds GHC.RdrName) -> RefactGhc DeclaredNames
    valbinds vb@(GHC.ValBindsIn bindsBag sigs)
      | findNameInRdr nm e vb = do
          fdsb <- mapM (hsVisibleDsRdr nm e) $ GHC.bagToList bindsBag
          fdss <- mapM (hsVisibleDsRdr nm e) sigs
          return $ mconcat fdss <> mconcat fdsb
    valbinds vb@(GHC.ValBindsOut _binds _sigs)
      | findNameInRdr nm e vb = do
          
          return (DN [])
    valbinds _ = do
      
      return (DN [])
    lhsdecls :: [GHC.LHsDecl GHC.RdrName] -> RefactGhc DeclaredNames
    lhsdecls ds
      | findNameInRdr nm e ds = do
         dfds <- mapM (declFun ( hsVisibleDsRdr nm e) ) ds
         return $ mconcat dfds
    lhsdecls _ = return (DN [])
    lhsdecl :: GHC.LHsDecl GHC.RdrName -> RefactGhc DeclaredNames
    lhsdecl (GHC.L l dd) = do
        
        case dd of
            GHC.TyClD d       -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.InstD d       -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.DerivD d      -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.ValD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.SigD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.DefD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.ForD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.WarningD d    -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.AnnD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.RuleD d       -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.VectD d       -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.SpliceD d     -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.DocD d        -> hsVisibleDsRdr nm e (GHC.L l d)
            GHC.RoleAnnotD d  -> hsVisibleDsRdr nm e (GHC.L l d)
#if __GLASGOW_HASKELL__ < 711
            GHC.QuasiQuoteD d -> hsVisibleDsRdr nm e (GHC.L l d)
#endif
    lhsbindslr :: GHC.LHsBinds GHC.RdrName -> RefactGhc DeclaredNames
    lhsbindslr bs = do
      fds <- mapM (hsVisibleDsRdr nm e) $ GHC.bagToList bs
      return $ mconcat fds
    hsbinds :: [GHC.LHsBind GHC.RdrName] -> RefactGhc DeclaredNames
    hsbinds ds
      | findNameInRdr nm e ds = do
        fds <- mapM (hsVisibleDsRdr nm e) ds
        return $ mconcat fds
    hsbinds _ = return (DN [])
    hsbind :: (GHC.LHsBind GHC.RdrName) -> RefactGhc DeclaredNames
#if __GLASGOW_HASKELL__ <= 710
    hsbind ((GHC.L _ (GHC.FunBind _n _ (GHC.MG matches _ _ _) _ _ _)))
#else
    hsbind ((GHC.L _ (GHC.FunBind _n (GHC.MG (GHC.L _ matches) _ _ _) _ _ _)))
#endif
      | findNameInRdr nm e matches = do
          fds <- mapM (hsVisibleDsRdr nm e) matches
          return $ mconcat fds
    hsbind _ = do
      return (DN [])
    hslocalbinds :: (GHC.HsLocalBinds GHC.RdrName) -> RefactGhc DeclaredNames
    hslocalbinds (GHC.HsValBinds binds)
      | findNameInRdr nm e binds = hsVisibleDsRdr nm e binds
    hslocalbinds (GHC.HsIPBinds binds)
      | findNameInRdr nm e binds = hsVisibleDsRdr nm e binds
    hslocalbinds (GHC.EmptyLocalBinds) = return (DN [])
    hslocalbinds _ = return (DN [])
    lmatch :: (GHC.LMatch GHC.RdrName (GHC.LHsExpr GHC.RdrName)) -> RefactGhc DeclaredNames
    lmatch (GHC.L _ m) = match m
    match :: (GHC.Match GHC.RdrName (GHC.LHsExpr GHC.RdrName)) -> RefactGhc DeclaredNames
    match (GHC.Match _fn pats _mtyp rhs)
      | findNameInRdr nm e rhs || findNameInRdr nm e pats = do
           
           let (_pf,pd) = hsFreeAndDeclaredRdr nm pats
           
           rd <- hsVisibleDsRdr nm e rhs
           
           return (pd <> rd)
    match _ =return  (DN [])
    grhss :: (GHC.GRHSs GHC.RdrName (GHC.LHsExpr GHC.RdrName)) -> RefactGhc DeclaredNames
    grhss (GHC.GRHSs guardedRhss lstmts')
      | findNameInRdr nm e guardedRhss || findNameInRdr nm e lstmts' = do
          
          fds <- mapM (hsVisibleDsRdr nm e) guardedRhss
          
          let (_,sfds) = hsFreeAndDeclaredRdr nm lstmts'
          return $ mconcat (sfds:fds)
    grhss _ = do
      
      return (DN [])
    lgrhs :: GHC.LGRHS GHC.RdrName (GHC.LHsExpr GHC.RdrName) -> RefactGhc DeclaredNames
    lgrhs (GHC.L _ (GHC.GRHS guards ex))
      | findNameInRdr nm e guards = hsVisibleDsRdr nm e guards
      | findNameInRdr nm e ex     = do
        r <- hsVisibleDsRdr nm e ex
        
        return r
    lgrhs _ = do
      
      return (DN [])
    lexpr :: GHC.LHsExpr GHC.RdrName -> RefactGhc DeclaredNames
#if __GLASGOW_HASKELL__ <= 710
    lexpr (GHC.L l (GHC.HsVar n))
#else
    lexpr (GHC.L l (GHC.HsVar (GHC.L _ n)))
#endif
      | findNameInRdr nm e n  = do
        
        return (DN [rdrName2NamePure nm (GHC.L l n)])
    lexpr (GHC.L _ (GHC.HsLet lbinds expr))
      | findNameInRdr nm e lbinds || findNameInRdr nm e expr  = do
        
        let (_,lds) = hsFreeAndDeclaredRdr nm lbinds
        let (_,eds) = hsFreeAndDeclaredRdr nm expr
        return $ lds <> eds
    lexpr expr
      | findNameInRdr nm e expr = do
        
        let (FN efs,eds)         = hsFreeAndDeclaredRdr nm expr
        let (FN _eefs,DN eeds) = hsFreeAndDeclaredRdr nm e
        
        return (DN (efs \\ eeds) <> eds)
    lexpr x = do
      
      return (DN [])
    
    tyclgroups :: [GHC.TyClGroup GHC.RdrName] -> RefactGhc DeclaredNames
    tyclgroups tgrps
      | findNameInRdr nm e tgrps = do
        fds <- mapM (hsVisibleDsRdr nm e) tgrps
        return $ mconcat fds
    tyclgroups _ = return (DN [])
    tyclgroup :: GHC.TyClGroup GHC.RdrName -> RefactGhc DeclaredNames
    tyclgroup (GHC.TyClGroup tyclds _roles)
      | findNameInRdr nm e tyclds = do
        fds <- mapM (hsVisibleDsRdr nm e) tyclds
        return $ mconcat fds
    tyclgroup _ = return (DN [])
    tycldeclss :: [[GHC.LTyClDecl GHC.RdrName]] -> RefactGhc DeclaredNames
    tycldeclss tcds
      | findNameInRdr nm e tcds = do
        fds <- mapM (hsVisibleDsRdr nm e) tcds
        return $ mconcat fds
    tycldeclss _ = return (DN [])
    tycldecls :: [GHC.LTyClDecl GHC.RdrName] -> RefactGhc DeclaredNames
    tycldecls tcds
      | findNameInRdr nm e tcds = do
        fds <- mapM (hsVisibleDsRdr nm e) tcds
        return $ mconcat fds
    tycldecls _ = return (DN [])
    ltycldecl :: GHC.LTyClDecl GHC.RdrName -> RefactGhc DeclaredNames
    ltycldecl tcd
      | findNameInRdr nm e tcd = do
        let (_,ds) = hsFreeAndDeclaredRdr nm tcd
        return ds
    ltycldecl _ = return (DN [])
    tycldecl :: GHC.TyClDecl GHC.RdrName -> RefactGhc DeclaredNames
    tycldecl tcd
      | findNameInRdr nm e tcd = do
        let (_,ds) = hsFreeAndDeclaredRdr nm tcd
        return ds
    tycldecl _ = return (DN [])
    hsdatadefn :: GHC.HsDataDefn GHC.RdrName -> RefactGhc DeclaredNames
    hsdatadefn tcd
      | findNameInRdr nm e tcd = do
        let (_,ds) = hsFreeAndDeclaredRdr nm tcd
        return ds
    hsdatadefn _ = return (DN [])
    condecl :: GHC.ConDecl GHC.RdrName -> RefactGhc DeclaredNames
    condecl tcd
      | findNameInRdr nm e tcd = do
        let (_,ds) = hsFreeAndDeclaredRdr nm tcd
        return ds
    condecl _ = return (DN [])
    
    instdecls :: [GHC.LInstDecl GHC.RdrName] -> RefactGhc DeclaredNames
    instdecls ds
      | findNameInRdr nm e ds = do
        fds <- mapM (hsVisibleDsRdr nm e) ds
        return $ mconcat fds
    instdecls _ = return (DN [])
    instdecl :: GHC.LInstDecl GHC.RdrName -> RefactGhc DeclaredNames
    instdecl (GHC.L _ (GHC.ClsInstD (GHC.ClsInstDecl polytyp binds sigs tyfaminsts dfaminsts _)))
      | findNameInRdr nm e polytyp    = hsVisibleDsRdr nm e polytyp
      | findNameInRdr nm e binds      = hsVisibleDsRdr nm e binds
      | findNameInRdr nm e sigs       = hsVisibleDsRdr nm e sigs
      | findNameInRdr nm e tyfaminsts = hsVisibleDsRdr nm e tyfaminsts
      | findNameInRdr nm e dfaminsts  = hsVisibleDsRdr nm e dfaminsts
      | otherwise = return (DN [])
    instdecl (GHC.L _ (GHC.DataFamInstD (GHC.DataFamInstDecl _ln pats defn _)))
      | findNameInRdr nm e pats = hsVisibleDsRdr nm e pats
      | findNameInRdr nm e defn = hsVisibleDsRdr nm e defn
      | otherwise = return (DN [])
    instdecl (GHC.L _ (GHC.TyFamInstD (GHC.TyFamInstDecl eqn _)))
      | findNameInRdr nm e eqn = hsVisibleDsRdr nm e eqn
      | otherwise = return (DN [])
    lhstype :: GHC.LHsType GHC.RdrName -> RefactGhc DeclaredNames
#if __GLASGOW_HASKELL__ <= 710
    lhstype tv@(GHC.L l (GHC.HsTyVar n))
#else
    lhstype tv@(GHC.L l (GHC.HsTyVar (GHC.L _ n)))
#endif
      | findNameInRdr nm e tv = return (DN [rdrName2NamePure nm (GHC.L l n)])
      | otherwise       = return (DN [])
    lhstype (GHC.L _ (GHC.HsForAllTy {}))
        = return (DN [])
    lhstype (GHC.L _ (GHC.HsFunTy{})) = return (DN [])
    lhstype ty = do
      
      return (DN [])
    
    lsigs :: [GHC.LSig GHC.RdrName] -> RefactGhc DeclaredNames
    lsigs ss = do
      fds <- mapM (hsVisibleDsRdr nm e) ss
      return $ mconcat fds
    
    lsig :: GHC.LSig GHC.RdrName -> RefactGhc DeclaredNames
#if __GLASGOW_HASKELL__ <= 710
    lsig (GHC.L _ (GHC.TypeSig _ns typ _))
#else
    lsig (GHC.L _ (GHC.TypeSig _ns typ))
#endif
      | findNameInRdr nm e typ = hsVisibleDsRdr nm e typ
#if __GLASGOW_HASKELL__ <= 710
    lsig (GHC.L _ (GHC.GenericSig _n typ))
#else
    lsig (GHC.L _ (GHC.ClassOpSig _ _n (GHC.HsIB _ typ)))
#endif
      | findNameInRdr nm e typ = hsVisibleDsRdr nm e typ
    lsig (GHC.L _ (GHC.IdSig _)) = return (DN [])
    lsig (GHC.L _ (GHC.InlineSig _ _)) = return (DN [])
    lsig (GHC.L _ (GHC.SpecSig _n typ _))
      | findNameInRdr nm e typ = hsVisibleDsRdr nm e typ
    lsig (GHC.L _ (GHC.SpecInstSig _ _)) = return (DN [])
    lsig _ = return (DN [])
    
    lstmts :: [GHC.LStmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)] -> RefactGhc DeclaredNames
    lstmts ds
      | findNameInRdr nm e ds = do
        fds <- mapM (hsVisibleDsRdr nm e) ds
        return $ mconcat fds
    lstmts _ = return (DN [])
    
    lstmt :: GHC.LStmt GHC.RdrName (GHC.LHsExpr GHC.RdrName) -> RefactGhc DeclaredNames
#if __GLASGOW_HASKELL__ <= 710
    lstmt (GHC.L _ (GHC.LastStmt ex _)) = hsVisibleDsRdr nm e ex
#else
    lstmt (GHC.L _ (GHC.LastStmt ex _ _)) = hsVisibleDsRdr nm e ex
#endif
#if __GLASGOW_HASKELL__ <= 710
    lstmt (GHC.L _ (GHC.BindStmt pa ex _ _)) = do
#else
    lstmt (GHC.L _ (GHC.BindStmt pa ex _ _ _)) = do
#endif
      fdp <- hsVisibleDsRdr nm e pa
      fde <- hsVisibleDsRdr nm e ex
      return (fdp <> fde)
    lstmt (GHC.L _ (GHC.BodyStmt ex _ _ _)) = hsVisibleDsRdr nm e ex
    lstmt (GHC.L _ (GHC.LetStmt bs)) = hsVisibleDsRdr nm e bs
#if __GLASGOW_HASKELL__ <= 710
    lstmt (GHC.L _ (GHC.ParStmt ps _ _)) = hsVisibleDsRdr nm e ps
#else
    lstmt (GHC.L _ (GHC.ParStmt ps _ _ _)) = hsVisibleDsRdr nm e ps
#endif
#if __GLASGOW_HASKELL__ <= 710
    lstmt (GHC.L _ (GHC.TransStmt _ stmts _ using mby _ _ _)) = do
#else
    lstmt (GHC.L _ (GHC.TransStmt _ stmts _ using mby _ _ _ _)) = do
#endif
      fds <- hsVisibleDsRdr nm e stmts
      fdu <- hsVisibleDsRdr nm e using
      fdb <- case mby of
        Nothing -> return (DN [])
        Just ex -> hsVisibleDsRdr nm e ex
      return $ fds <> fdu <> fdb
#if __GLASGOW_HASKELL__ <= 710
    lstmt (GHC.L _ (GHC.RecStmt stmts _ _ _ _ _ _ _ _)) = hsVisibleDsRdr nm e stmts
#else
    lstmt (GHC.L _ (GHC.RecStmt stmts _ _ _ _ _ _ _ _ _)) = hsVisibleDsRdr nm e stmts
#endif
#if __GLASGOW_HASKELL__ > 710
    lstmt (GHC.L _ (GHC.ApplicativeStmt {})) = return mempty
#endif
    
    
    lpats :: [GHC.LPat GHC.RdrName] -> RefactGhc DeclaredNames
    lpats ps
      | findNameInRdr nm e ps = do
        fds <- mapM (hsVisibleDsRdr nm e) ps
        return $ mconcat fds
    lpats _ = return (DN [])
    
    lpat :: GHC.LPat GHC.RdrName -> RefactGhc DeclaredNames
    lpat (GHC.L _ (GHC.WildPat _)) = return (DN [])
#if __GLASGOW_HASKELL__ <= 710
    lpat (GHC.L l (GHC.VarPat n))
#else
    lpat (GHC.L l (GHC.VarPat (GHC.L _ n)))
#endif
      = return (DN [rdrName2NamePure nm (GHC.L l n)])
    lpat (GHC.L _ (GHC.AsPat ln p)) = do
      (DN dp) <- lpat p
      return (DN (rdrName2NamePure nm ln:dp))
    lpat (GHC.L _ (GHC.ParPat p)) = lpat p
    lpat (GHC.L _ (GHC.BangPat p)) = lpat p
    lpat (GHC.L _ (GHC.ListPat ps _ _)) = do
      fds <- mapM lpat ps
      return $ mconcat fds
    lpat (GHC.L _ (GHC.TuplePat ps _ _)) = do
      fds <- mapM lpat ps
      return $ mconcat fds
    lpat (GHC.L _ (GHC.PArrPat ps _)) = do
      fds <- mapM lpat ps
      return $ mconcat fds
    lpat (GHC.L _ (GHC.ConPatIn n det)) = do
      (DN d) <- details det
      return $ (DN (rdrName2NamePure nm n:d))
    
    lpat (GHC.L _ (GHC.ViewPat ex p _)) = do
      fde <- hsVisibleDsRdr nm e ex
      fdp <- lpat p
      return $ fde <> fdp
    
    lpat (GHC.L _ (GHC.LitPat _)) = return (DN [])
#if __GLASGOW_HASKELL__ <= 710
    lpat (GHC.L _ (GHC.NPat _ _ _)) = return (DN [])
    lpat (GHC.L _ (GHC.NPlusKPat n _ _ _)) = return (DN [rdrName2NamePure nm n])
#else
    lpat (GHC.L _ (GHC.NPat _ _ _ _)) = return (DN [])
    lpat (GHC.L _ (GHC.NPlusKPat n _ _ _ _ _)) = return (DN [rdrName2NamePure nm n])
#endif
    lpat (GHC.L _ _p@(GHC.SigPatIn p b)) = do
      dp <- lpat p
      db <- hsVisibleDsRdr nm e b
      
      return $ dp <> db
    lpat (GHC.L _ (GHC.SigPatOut p _)) = lpat p
    lpat (GHC.L l (GHC.CoPat _ p _)) = lpat (GHC.L l p)
    lpat (GHC.L _ (GHC.LazyPat p)) = lpat p
    lpat (GHC.L _ (GHC.ConPatOut {})) = error $ "hsFreeAndDeclared.lpat:impossible GHC.ConPatOut"
#if __GLASGOW_HASKELL__ <= 710
    lpat (GHC.L _ (GHC.QuasiQuotePat _)) = return mempty
    lpat (GHC.L _ (GHC.SplicePat (GHC.HsSplice _ expr))) = hsVisibleDsRdr nm e expr
#else
    lpat (GHC.L _ (GHC.SplicePat (GHC.HsTypedSplice _ expr)))   = hsVisibleDsRdr nm e expr
    lpat (GHC.L _ (GHC.SplicePat (GHC.HsUntypedSplice _ expr))) = hsVisibleDsRdr nm e expr
    lpat (GHC.L _ (GHC.SplicePat (GHC.HsQuasiQuote {})))        = return mempty
#endif
    
    details :: GHC.HsConPatDetails GHC.RdrName -> RefactGhc DeclaredNames
    details (GHC.PrefixCon  args) = do
      fds <- mapM lpat args
      return $ mconcat fds
    details (GHC.RecCon recf) =
      recfields recf
    details (GHC.InfixCon arg1 arg2) = do
      fds <- mapM lpat [arg1,arg2]
      return $ mconcat fds
    
    recfields :: (GHC.HsRecFields GHC.RdrName (GHC.LPat GHC.RdrName)) -> RefactGhc DeclaredNames
    recfields (GHC.HsRecFields fields _) = do
      let args = map (\(GHC.L _ (GHC.HsRecField _ arg _)) -> arg) fields
      fds <- mapM lpat args
      return $ mconcat fds
    
#if __GLASGOW_HASKELL__ > 710
    ibndrs :: GHC.LHsSigWcType GHC.RdrName -> RefactGhc DeclaredNames
    ibndrs (GHC.HsIB _ (GHC.HsWC _ _ ty)) = hsVisibleDsRdr nm e ty
    lsigty :: GHC.LHsSigType GHC.RdrName -> RefactGhc DeclaredNames
    lsigty (GHC.HsIB _ ty) = hsVisibleDsRdr nm e ty
#endif
    
    lanndecl :: GHC.LAnnDecl GHC.RdrName -> RefactGhc DeclaredNames
    lanndecl (GHC.L _ (GHC.HsAnnotation _ _ expr)) = hsVisibleDsRdr nm e expr
    
    err = error $ "hsVisibleDsRdr nm:no match for:" ++ (SYB.showData SYB.Parser 0 t)
hsFDsFromInsideRdr :: (SYB.Data t)
                  => NameMap ->  t -> (FreeNames,DeclaredNames)
hsFDsFromInsideRdr nm t = hsFDsFromInsideRdr' t
   where
     hsFDsFromInsideRdr' :: (SYB.Data t) => t -> (FreeNames,DeclaredNames)
     hsFDsFromInsideRdr' t1 = (FN $ nub f', DN $ nub d')
       where
          r1 = applyTU (once_tdTU (failTU  `adhocTU` parsed
                                           `adhocTU` decl
                                           `adhocTU` match
                                           `adhocTU` expr
                                           `adhocTU` stmts )) t1
          
          (FN f',DN d') = fromMaybe (FN [],DN []) r1
          
     parsed :: GHC.ParsedSource -> Maybe (FreeNames,DeclaredNames)
     parsed p = return $ hsFreeAndDeclaredRdr nm p
     
     match :: GHC.Match GHC.RdrName (GHC.LHsExpr GHC.RdrName) -> Maybe (FreeNames,DeclaredNames)
     match (GHC.Match _fn pats _type rhs) = do
       let (FN pf, DN pd) = hsFreeAndDeclaredRdr nm pats
           (FN rf, DN rd) = hsFreeAndDeclaredRdr nm rhs
       return (FN $ nub (pf `union` (rf \\ pd)),
               DN $ nub (pd `union` rd))
     
     decl :: GHC.HsBind GHC.RdrName -> Maybe (FreeNames,DeclaredNames)
#if __GLASGOW_HASKELL__ <= 710
     decl (GHC.FunBind (GHC.L _ _) _ (GHC.MG matches _ _ _) _ _ _) = do
#else
     decl (GHC.FunBind (GHC.L _ _) (GHC.MG (GHC.L _ matches) _ _ _) _ _ _) = do
#endif
       let
         fds = map hsFDsFromInsideRdr' matches
         
       return (FN $ nub (concat $ map (fn . fst) fds), DN $ nub (concat $ map (dn . snd) fds))
     decl ((GHC.PatBind p rhs _ _ _) :: GHC.HsBind GHC.RdrName) = do
       let
         (FN pf, DN pd) = hsFreeAndDeclaredRdr nm p
         (FN rf, DN rd) = hsFreeAndDeclaredRdr nm rhs
       return
           (FN $ nub (pf `union` (rf \\ pd)),
            DN $ nub (pd `union` rd))
     decl ((GHC.VarBind p rhs _) :: GHC.HsBind GHC.RdrName) = do
       let
         (FN pf, DN pd) = hsFreeAndDeclaredRdr nm p
         (FN rf, DN rd) = hsFreeAndDeclaredRdr nm rhs
       return
           (FN $ nub (pf `union` (rf \\ pd)),
            DN $ nub (pd `union` rd))
     decl _ = mzero
     
     expr ((GHC.HsLet decls e) :: GHC.HsExpr GHC.RdrName) = do
       let
         (FN df,DN dd) = hsFreeAndDeclaredRdr nm decls
         (FN ef,_)     = hsFreeAndDeclaredRdr nm e
       return (FN $ nub (df `union` (ef \\ dd)), DN $ nub dd)
     expr ((GHC.HsLam (GHC.MG matches _ _ _)) :: GHC.HsExpr GHC.RdrName) =
       return $ hsFreeAndDeclaredRdr nm matches
     expr ((GHC.HsCase e (GHC.MG matches _ _ _)) :: GHC.HsExpr GHC.RdrName) = do
       let
         (FN ef,_)     = hsFreeAndDeclaredRdr nm e
         (FN df,DN dd) = hsFreeAndDeclaredRdr nm matches
       return (FN $ nub (df `union` (ef \\ dd)), DN $ nub dd)
     expr _ = return (FN [],DN [])
#if __GLASGOW_HASKELL__ <= 710
     stmts ((GHC.BindStmt pat e1 e2 e3) :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) = do
#else
     stmts ((GHC.BindStmt pat e1 e2 e3 _) :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) = do
#endif
       let
         (FN pf,DN pd)  = hsFreeAndDeclaredRdr nm pat
         (FN ef,DN _ed) = hsFreeAndDeclaredRdr nm e1
         (FN df,DN dd)  = hsFreeAndDeclaredRdr nm [e2,e3]
       return
           (FN $ nub (pf `union` (((ef \\ dd) `union` df) \\ pd)), DN $ nub (pd `union` dd))
     stmts ((GHC.LetStmt binds) :: GHC.Stmt GHC.RdrName (GHC.LHsExpr GHC.RdrName)) =
       return $ hsFreeAndDeclaredRdr nm binds
     stmts _ = return (FN [],DN [])
hsFDNamesFromInsideRdr ::(SYB.Data t) => t -> RefactGhc ([String],[String])
hsFDNamesFromInsideRdr t = do
  nm <- getRefactNameMap
  return (hsFDNamesFromInsideRdrPure nm t)
  
  
hsFDNamesFromInsideRdrPure :: (SYB.Data t) => NameMap -> t -> ([String],[String])
hsFDNamesFromInsideRdrPure nm t = ((nub.map showGhc) f, (nub.map showGhc) d)
  where
    (FN f,DN d) = hsFDsFromInsideRdr nm t
rdrName2Name :: GHC.Located GHC.RdrName -> RefactGhc GHC.Name
rdrName2Name ln = do
  nameMap <- getRefactNameMap
  return (rdrName2NamePure nameMap ln)
rdrName2NamePure :: NameMap -> GHC.Located GHC.RdrName -> GHC.Name
rdrName2NamePure _nameMap (GHC.L _ (GHC.Exact n)) = n
rdrName2NamePure nameMap (GHC.L lrn _) =
  fromMaybe (error $ "rdrName2NamePure: no name found for" ++ showGhc lrn)
  
             (Map.lookup lrn nameMap)
eqRdrNamePure :: NameMap -> GHC.Located GHC.RdrName -> GHC.Name -> Bool
eqRdrNamePure nameMap rn n
  = GHC.nameUnique (rdrName2NamePure nameMap rn) == GHC.nameUnique n
sameNameSpace :: GHC.Name -> GHC.Name -> Bool
sameNameSpace n1 n2
  = (GHC.occNameSpace $ GHC.nameOccName n1) == (GHC.occNameSpace $ GHC.nameOccName n2)
locToNameRdr :: (SYB.Data t)
                     => SimpPos          
                     -> t                
                     -> RefactGhc (Maybe GHC.Name)  
locToNameRdr pos t = do
   nm <- getRefactNameMap
   let mn = locToRdrName pos t
   return $ fmap (rdrName2NamePure nm) mn
locToNameRdrPure :: (SYB.Data t)
                    => NameMap
                    -> SimpPos         
                    -> t               
                    -> Maybe GHC.Name  
locToNameRdrPure nm pos t =
  let mn = locToRdrName pos t
  in fmap (rdrName2NamePure nm) mn
locToRdrName::(SYB.Data t)
                    =>SimpPos          
                    ->t                
                    -> Maybe (GHC.Located GHC.RdrName)  
locToRdrName (row,col) t = locToName' (row,col) t
locToName':: forall a t.(SYB.Data t, SYB.Data a)
                    =>SimpPos          
                    ->t                
                    -> Maybe (GHC.Located a)  
locToName' (row,col) t = res1
     where
        res1 :: Maybe (GHC.Located a)
        res1 = SYB.something (nameSybQuery checker) t
        checker pnt =
          
          if inScope pnt
             then Just pnt
             else Nothing
        
        inScope :: GHC.Located e -> Bool
        inScope (GHC.L l _) =
          case l of
            (GHC.UnhelpfulSpan _) -> False
            (GHC.RealSrcSpan ss)  ->
              
              (GHC.srcSpanStartLine ss <= row) &&
              (GHC.srcSpanEndLine ss   >= row) &&
              (col >= (GHC.srcSpanStartCol ss)) &&
              (col <= (GHC.srcSpanEndCol   ss))