cgTopRhsClosure :: DynFlags
                -> RecFlag              -- member of a recursive group?
                -> Id
                -> StgBinderInfo
                -> UpdateFlag
                -> [Id]                 -- Args
                -> StgExpr
                -> (CgIdInfo, CodeGen ())
cgTopRhsClosure dflags recflag id binderInfo updateFlag args body
  = (cgIdInfo, genCode dflags lfInfo)
  where cgIdInfo = mkCgIdInfo dflags id lfInfo
        lfInfo = mkClosureLFInfo id TopLevel [] updateFlag args
        (modClass, clName, clClass) = getJavaInfo dflags cgIdInfo
        isThunk = isLFThunk lfInfo
        qClName = closure clName
        genCode dflags _
          | StgApp f [] <- body, null args, isNonRec recflag
          = do cgInfo <- getCgIdInfo f
               let loadCode = idInfoLoadCode cgInfo
               defineField $ mkFieldDef [Public, Static] qClName closureType
               let field = mkFieldRef modClass qClName closureType
                   deps = catMaybes [getLocField (cgLocation cgInfo)]
               addInitStep (fold
                 [
                   new indStaticType,
                   dup indStaticType,
                   loadCode,
                   invokespecial $ mkMethodRef stgIndStatic "<init>"
                     [closureType] void,
                   putstatic field
                 ]
                 , field
                 , deps
                 -- TODO: Check this works when f is in external module
                 )
        genCode dflags lf = do
          (_, CgState { cgClassName }) <- forkClosureBody $
            closureCodeBody True id lfInfo
                            (nonVoidIds args) (length args) body [] False []

          let ft = obj cgClassName
          -- NOTE: Don't make thunks final so that they can be
          --       replaced by their values by the GC
          let flags = (if isThunk then [] else [Final]) ++ [Public, Static]
          defineField $ mkFieldDef flags qClName closureType
          let field = mkFieldRef modClass qClName closureType
          addInitStep (fold
            [
              new ft,
              dup ft,
              invokespecial $ mkMethodRef cgClassName "<init>" [] void,
              putstatic field
            ]
            , field
            , []
            )
          return ()

-- Simplifies the code if the mod is associated to the Id
cgTopRhsClosure :: DynFlags
                -> RecFlag              -- member of a recursive group?
                -> Id
                -> StgBinderInfo
                -> UpdateFlag
                -> [Id]                 -- Args
                -> StgExpr
                -> (CgIdInfo, CodeGen ())
cgTopRhsClosure dflags recflag id binderInfo updateFlag args body
  = (cgIdInfo, genCode dflags lfInfo)
  where cgIdInfo = mkCgIdInfo dflags id lfInfo
        lfInfo = mkClosureLFInfo id TopLevel [] updateFlag args
        (modClass, clName, clClass) = getJavaInfo dflags cgIdInfo
        isThunk = isLFThunk lfInfo
        qClName = closure clName
        genCode dflags _
          | StgApp f [] <- body, null args, isNonRec recflag
          = do cgInfo <- getCgIdInfo f
               let loadCode = idInfoLoadCode cgInfo
               defineField $ mkFieldDef [Public, Static] qClName closureType
               let field = mkFieldRef modClass qClName closureType
                   deps = catMaybes [getLocField (cgLocation cgInfo)]
               addInitStep (fold
                 [
                   new indStaticType,
                   dup indStaticType,
                   loadCode,
                   invokespecial $ mkMethodRef stgIndStatic "<init>"
                     [closureType] void,
                   putstatic field
                 ]
                 , field
                 , deps
                 -- TODO: Check this works when f is in external module
                 )
        genCode dflags lf = do
          (_, CgState { cgClassName }) <- forkClosureBody $
            closureCodeBody True id lfInfo
                            (nonVoidIds args) (length args) body [] False []

          let ft = obj cgClassName
          -- NOTE: Don't make thunks final so that they can be
          --       replaced by their values by the GC
          let flags = (if isThunk then [] else [Final]) ++ [Public, Static]
          defineField $ mkFieldDef flags qClName closureType
          let field = mkFieldRef modClass qClName closureType
          addInitStep (fold
            [
              new ft,
              dup ft,
              invokespecial $ mkMethodRef cgClassName "<init>" [] void,
              putstatic field
            ]
            , field
            , []
            )
          return ()

-- Simplifies the code if the mod is associated to the Id
cgTopRhsClosure dflags recflag id binderInfo updateFlag args body
  = (cgIdInfo, genCode dflags lfInfo)
  where cgIdInfo = mkCgIdInfo dflags id lfInfo
        lfInfo = mkClosureLFInfo id TopLevel [] updateFlag args
        (modClass, clName, clClass) = getJavaInfo dflags cgIdInfo
        isThunk = isLFThunk lfInfo
        qClName = closure clName
        genCode dflags _
          | StgApp f [] <- body, null args, isNonRec recflag
          = do cgInfo <- getCgIdInfo f
               let loadCode = idInfoLoadCode cgInfo
               defineField $ mkFieldDef [Public, Static] qClName closureType
               let field = mkFieldRef modClass qClName closureType
                   deps = catMaybes [getLocField (cgLocation cgInfo)]
               addInitStep (fold
                 [
                   new indStaticType,
                   dup indStaticType,
                   loadCode,
                   invokespecial $ mkMethodRef stgIndStatic "<init>"
                     [closureType] void,
                   putstatic field
                 ]
                 , field
                 , deps
                 -- TODO: Check this works when f is in external module
                 )
        genCode dflags lf = do
          (_, CgState { cgClassName }) <- forkClosureBody $
            closureCodeBody True id lfInfo
                            (nonVoidIds args) (length args) body [] False []

          let ft = obj cgClassName
          -- NOTE: Don't make thunks final so that they can be
          --       replaced by their values by the GC
          let flags = (if isThunk then [] else [Final]) ++ [Public, Static]
          defineField $ mkFieldDef flags qClName closureType
          let field = mkFieldRef modClass qClName closureType
          addInitStep (fold
            [
              new ft,
              dup ft,
              invokespecial $ mkMethodRef cgClassName "<init>" [] void,
              putstatic field
            ]
            , field
            , []
            )
          return ()

-- Simplifies the code if the mod is associated to the Id