-- Add the definition to the client module, and modify the import/export if necessary.
addCodeToMod  pns destFileName (origMod, origToks) (destInscps,destModName, destMod, destToks) usedByClients  
 = do let -- get the declaraion. False means not spliting the type signature.
          decl  = definingDecls pns (hsDecls origMod) True False
           --get the fun binding.
          funBinding = ghead "addCodeToMod" $ filter isFunOrPatBind decl  -- shoudn't be empty.
           --get the type signature if there is any.
          typeSig    = filter isTypeSig decl 
          decl' = if typeSig==[]
                    then [funBinding]
                    else [ghead "addCodeToMod" (getTypeSig pns (head typeSig)),funBinding]
          
          toksTobeAdded =getDeclToks (ghead "addCodeToMod" pns) True decl origToks 
      (decl'', toksTobeAdded') <- if isDirectRecursiveDef funBinding &&
                                     sameNameInScope (ghead "addCodeToMod" pns) destInscps
                                  then do (t,((toks',_), m))<-runStateT (addQualifier pns modName decl)
                                                             ((toksTobeAdded,unmodified),(-1000,0))
                                          return (t, toks')
                                  else return (decl', toksTobeAdded)
      (decl''',((toksTobeAdded'',_),_)) <-runStateT (replaceQualifier pns destModName decl'')
                                          ((toksTobeAdded',unmodified),(-1000,0))  --destFileName)
      runStateT ( do  destMod'<-resolveAmbiguity pns destInscps destMod
                      mod'<-replaceQualifier pns destModName destMod'
                      mod''<- addDecl mod' Nothing (decl''', Just toksTobeAdded'') True
                      mod''' <- rmItemsFromImport mod'' pns                            
                      if usedByClients && not (modIsExported destMod) 
                          -- The definition name is used by other modules, but it is
                         then addItemsToExport mod''' Nothing False (Right (map pnToEnt pns))   --so make it exported.
                         else return mod'''      -- Do nothing.                            
                ) ((destToks,unmodified), (-1000,0)) --destFileName)

   where 
        -- Get the type signatures defines the type of pns. 
       getTypeSig pns (Dec (HsTypeSig loc is c tp))
         =[(Dec (HsTypeSig loc (filter (\x->isJust (find (==pNTtoPN x) pns)) is) c tp))]
       getTypeSig pns _ = []
  
       modName = modNameToStr destModName

       pnToEnt pn = EntE (Var (pNtoPNT pn Value))


-- |Returns True if another identifier which has the same name but different meaning is in scope.
-- NOTE: The name space should be taken into account as well.
addCodeToMod  pns destFileName (origMod, origToks) (destInscps,destModName, destMod, destToks) usedByClients  
 = do let -- get the declaraion. False means not spliting the type signature.
          decl  = definingDecls pns (hsDecls origMod) True False
           --get the fun binding.
          funBinding = ghead "addCodeToMod" $ filter isFunOrPatBind decl  -- shoudn't be empty.
           --get the type signature if there is any.
          typeSig    = filter isTypeSig decl 
          decl' = if typeSig==[]
                    then [funBinding]
                    else [ghead "addCodeToMod" (getTypeSig pns (head typeSig)),funBinding]
          
          toksTobeAdded =getDeclToks (ghead "addCodeToMod" pns) True decl origToks 
      (decl'', toksTobeAdded') <- if isDirectRecursiveDef funBinding &&
                                     sameNameInScope (ghead "addCodeToMod" pns) destInscps
                                  then do (t,((toks',_), m))<-runStateT (addQualifier pns modName decl)
                                                             ((toksTobeAdded,unmodified),(-1000,0))
                                          return (t, toks')
                                  else return (decl', toksTobeAdded)
      (decl''',((toksTobeAdded'',_),_)) <-runStateT (replaceQualifier pns destModName decl'')
                                          ((toksTobeAdded',unmodified),(-1000,0))  --destFileName)
      runStateT ( do  destMod'<-resolveAmbiguity pns destInscps destMod
                      mod'<-replaceQualifier pns destModName destMod'
                      mod''<- addDecl mod' Nothing (decl''', Just toksTobeAdded'') True
                      mod''' <- rmItemsFromImport mod'' pns                            
                      if usedByClients && not (modIsExported destMod) 
                          -- The definition name is used by other modules, but it is
                         then addItemsToExport mod''' Nothing False (Right (map pnToEnt pns))   --so make it exported.
                         else return mod'''      -- Do nothing.                            
                ) ((destToks,unmodified), (-1000,0)) --destFileName)

   where 
        -- Get the type signatures defines the type of pns. 
       getTypeSig pns (Dec (HsTypeSig loc is c tp))
         =[(Dec (HsTypeSig loc (filter (\x->isJust (find (==pNTtoPN x) pns)) is) c tp))]
       getTypeSig pns _ = []
  
       modName = modNameToStr destModName

       pnToEnt pn = EntE (Var (pNtoPNT pn Value))


-- |Returns True if another identifier which has the same name but different meaning is in scope.
-- NOTE: The name space should be taken into account as well.
addCodeToMod  pns destFileName (origMod, origToks) (destInscps,destModName, destMod, destToks) usedByClients  
 = do let -- get the declaraion. False means not spliting the type signature.
          decl  = definingDecls pns (hsDecls origMod) True False
           --get the fun binding.
          funBinding = ghead "addCodeToMod" $ filter isFunOrPatBind decl  -- shoudn't be empty.
           --get the type signature if there is any.
          typeSig    = filter isTypeSig decl 
          decl' = if typeSig==[]
                    then [funBinding]
                    else [ghead "addCodeToMod" (getTypeSig pns (head typeSig)),funBinding]
          
          toksTobeAdded =getDeclToks (ghead "addCodeToMod" pns) True decl origToks 
      (decl'', toksTobeAdded') <- if isDirectRecursiveDef funBinding &&
                                     sameNameInScope (ghead "addCodeToMod" pns) destInscps
                                  then do (t,((toks',_), m))<-runStateT (addQualifier pns modName decl)
                                                             ((toksTobeAdded,unmodified),(-1000,0))
                                          return (t, toks')
                                  else return (decl', toksTobeAdded)
      (decl''',((toksTobeAdded'',_),_)) <-runStateT (replaceQualifier pns destModName decl'')
                                          ((toksTobeAdded',unmodified),(-1000,0))  --destFileName)
      runStateT ( do  destMod'<-resolveAmbiguity pns destInscps destMod
                      mod'<-replaceQualifier pns destModName destMod'
                      mod''<- addDecl mod' Nothing (decl''', Just toksTobeAdded'') True
                      mod''' <- rmItemsFromImport mod'' pns                            
                      if usedByClients && not (modIsExported destMod) 
                          -- The definition name is used by other modules, but it is
                         then addItemsToExport mod''' Nothing False (Right (map pnToEnt pns))   --so make it exported.
                         else return mod'''      -- Do nothing.                            
                ) ((destToks,unmodified), (-1000,0)) --destFileName)

   where 
        -- Get the type signatures defines the type of pns. 
       getTypeSig pns (Dec (HsTypeSig loc is c tp))
         =[(Dec (HsTypeSig loc (filter (\x->isJust (find (==pNTtoPN x) pns)) is) c tp))]
       getTypeSig pns _ = []
  
       modName = modNameToStr destModName

       pnToEnt pn = EntE (Var (pNtoPNT pn Value))


-- |Returns True if another identifier which has the same name but different meaning is in scope.
-- NOTE: The name space should be taken into account as well.