           callback( ret.retcode == 0, e || 'retcode isnot 0' ) if callback
 
     # 获取好友列表
+    # @callback (ret:bool, error)
     update_buddy_list: (callback)->
         @api.get_buddy_list @auth , (ret,e)=>
             @save_buddy_info ret.result if ret.retcode == 0
             callback( ret.retcode == 0, e || 'retcode isnot 0' ) if callback
-    
+
     # 更新群成员， 似乎获取不到群ID
-    # @options {key:value} 
-    # @callback (true/false , error)
+    # @options {key:value} or group obj
+    # @callback (ret:bool , error)
     update_group_member: (options, callback)->
-        group = @get_group(options)
+        group = if options.code then options else @get_group(options)
         api.get_group_member group.code , @auth , (ret,e)=>
             if ret.retcode == 0
                 @save_group_member(group,ret.result)
             callback(ret.retcode == 0 , e) if callback
-    
-    
+
+    # 更新所有群成员
+    # @callback (success,total_count,success_count)
+    update_all_group_member: (callback)->
+      finished = successed = 0
+      groups = @group_info.gnamelist || []
+      all = groups.length
+      for group in groups
+        @update_group_member group , (ret,error)->
+          finished += 1; successed += ret
+          log.debug "groupmember all#{all} fin#{finished} succ#{successed}"
+          callback(successed == all, finished ,successed) if finished == all
+
+    # 更新好友和群成员
+    # @callback (ret?,actions) 是否全部更新成功 , actions每个状态
+    update_all_members: (callback)->
+      # [0,0] -> [finished,success]
+      actions= buddy:[0,0],group:[0,0],groupmember:[0,0]
+      check = ->
+        finished = successed = 0 ; all = Object.keys(actions).length
+        stats = (value for key,value of actions)
+        for item in stats
+          finished += item[0] ; successed += item[1]
+        log.debug("updating all: all #{all} finished #{finished} success #{successed}")
+        callback(successed==all) if finished == all
+
+      # fetching...
+      log.info 'fetching buddy list...'
+      @update_buddy_list (ret)->
+        actions.buddy = [1, ret]
+        check()
+
+      log.info 'fetching group list...'
+      @update_group_list (ret)=>
+        actions.group = [1, ret]
+        unless ret
+          callback(false)
+          return
+
+        log.info 'fetching all groupmember...'
+        @update_all_group_member (ret,all,successed)->
+          actions.groupmember = [1,ret]
+          check()
+
+
     # 长轮训
-    # @callback 
+    # @callback
     runloop: (callback)->
       @api.long_poll @auth , (ret,e)=>
           @handle_poll_responce ret
           callback(ret,e) if callback
-    
+
     # 回复消息
     # @param message 收到的message
     # @param content:string 回复信息

            msg.from_user = @get_user( msg.from_uin )
        msg

        
    # 监听特定群并返回群对象
    # @callback (group对象, error = null)
    
    listen_group : (name , callback) ->
      log.info 'fetching group list'
      @update_group_list (ret, e) =>
          log.info '√ group list fetched'
                    
          @update_buddy_list (ret,error)->
              log.info '√ buddy list fetched' if ret

          
          log.info "fetching groupmember #{name}"
          @update_group_member {name:name} ,(ret,error)=>
              log.info '√ group memeber fetched'
                
              groupinfo = @get_group {name:name} 
              group = new Group(@, groupinfo.gid)
              @dispatcher.add_listener [group,"dispatch"]
              callback group

        else if message.type == 'buddy'
            @api.send_msg_2buddy message.from_uin , content , @auth , (ret,e)->
                callback(ret,e) if callback

    # 发送群消息
    send_message_to_group: (gid, content, callback)->
      log.info "send msg #{content} to group#{gid}"
      api.send_msg_2group  gid , content , @auth, (ret,e)->
        callback(ret,e) if callback

    # 自杀
    die: (message,info)->
        log.error "QQBot die! message: #{message}" if message
        log.error "QQBot die! info #{JSON.stringify info}" if info
        process.exit(1)

    # 处理poll返回的内容
    handle_poll_responce: (resp)->
        code = resp.retcode
