@WebMethod("friend/usersset")
  public boolean setFriends(QueryParams qp, HttpServletRequest req)
      throws UnsupportedEncodingException {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);

    try {
      List<String> l = StringUtils2.splitList(qp.checkGetString("friendIds"), ",", true);
      MessageDelayCombineUtils.sendEmailCombineAndDelayNewFollower(ctx, ctx.getViewerIdString(), l);
    } catch (Exception e) {
      L.error(ctx, e, "delay and combine new follower email error!@@@@");
    }

    String viewerId = ctx.getViewerIdString();
    String friendIds = qp.checkGetString("friendIds");
    String circleId = qp.checkGetString("circleId");
    ConversationLogic c = GlobalLogics.getConversation();
    if (c.getEnabled(ctx, Constants.LOCAL_CIRCLE_OBJECT, circleId) == 1) {
      Set<String> friends = StringUtils2.splitSet(friendIds, ",", true);
      for (String friend : friends) {
        c.createConversationP(
            ctx, Constants.USER_OBJECT, friend, Constants.C_SUBSCRIBE_LOCAL_CIRCLE, viewerId);
      }
    }
    return fs.setFriendsP(
        ctx,
        viewerId,
        friendIds,
        circleId,
        Constants.FRIEND_REASON_MANUALSELECT,
        qp.getBoolean("isadd", true));
  }
  @WebMethod("circle/update")
  public boolean updateCircleName(QueryParams qp) {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    return fs.updateCircleName(
        ctx, ctx.getViewerIdString(), qp.checkGetString("circle"), qp.checkGetString("name"));
  }
  @WebMethod("friend/circlesset")
  public NoResponse setCircles(QueryParams qp, HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    String viewerId = ctx.getViewerIdString();
    String friendId = qp.checkGetString("friendId");
    String circleIds = qp.checkGetString("circleIds");
    ConversationLogic c = GlobalLogics.getConversation();
    Map<String, Integer> map = c.getEnabledByTargetIds(ctx, circleIds);
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
      String circleId = entry.getKey();
      int enabled = entry.getValue();
      if (enabled == 1) {
        c.createConversationP(
            ctx, Constants.USER_OBJECT, friendId, Constants.C_SUBSCRIBE_LOCAL_CIRCLE, viewerId);
      }
    }
    Record rec =
        fs.setFriendP(ctx, viewerId, friendId, circleIds, Constants.FRIEND_REASON_MANUALSELECT);

    if (qp.containsKey("from_email")) {
      String notice = "Operate Success!";
      String html =
          pageTemplate.merge(
              "notice.ftl",
              new Object[][] {
                {"host", serverHost},
                {"notice", notice}
              });

      resp.setContentType("text/html");
      resp.getWriter().print(html);
    } else {
      output(qp, req, resp, rec.toString(false, false), 200, "text/plain");
    }
    // add by wangpeng for delay and combine email

    try {
      List list = new ArrayList<String>();
      list.add(qp.checkGetString("friendId"));
      MessageDelayCombineUtils.sendEmailCombineAndDelayNewFollower(
          ctx, ctx.getViewerIdString(), list);
    } catch (Exception e) {
      L.error(ctx, e, "delay and combine new follower email error!@@@@");
    }
    return NoResponse.get();
  }
  @WebMethod("friend/exchange_vcard")
  public Record exchangeVcard(QueryParams qp, HttpServletRequest req)
      throws UnsupportedEncodingException {
    FriendshipLogic fs = GlobalLogics.getFriendship();
    Context ctx = WutongContext.getContext(qp, true);

    boolean send_request = qp.getBoolean("send_request", false);
    return fs.exchangeVcardP(
        ctx,
        ctx.getViewerIdString(),
        qp.checkGetString("friendId"),
        qp.checkGetString("circleIds"),
        Constants.FRIEND_REASON_MANUALSELECT,
        send_request);
  }
  @WebMethod("circle/destroy")
  public boolean destroyCircle(QueryParams qp) {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    return fs.destroyCircleP(ctx, ctx.getViewerIdString(), qp.checkGetString("circles"));
  }
  @WebMethod("circle/create")
  public int createCircle(QueryParams qp) {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    return Integer.parseInt(
        fs.createCircle(ctx, ctx.getViewerIdString(), qp.checkGetString("name")));
  }
  @WebMethod("remark/set")
  public boolean setUserRemark(QueryParams qp) {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    return fs.setRemark(
        ctx, ctx.getViewerIdString(), qp.checkGetString("friend"), qp.getString("remark", ""));
  }
  @WebMethod("relation/bidi")
  public Record getBidiRelation(QueryParams qp) {
    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, true);
    String userId = qp.getString("source", ctx.getViewerIdString());
    return fs.getBidiRelation(
        ctx,
        userId,
        qp.checkGetString("target"),
        qp.getString("circle", Integer.toString(FRIENDS_CIRCLE)));
  }
  @WebMethod("friend/contactset")
  public Record setContactFriends(QueryParams qp, HttpServletRequest req)
      throws UnsupportedEncodingException {
    FriendshipLogic fs = GlobalLogics.getFriendship();
    AccountLogic account = GlobalLogics.getAccount();

    Context ctx = WutongContext.getContext(qp, true);

    Record rec = account.findUidLoginNameNotInID(ctx, qp.checkGetString("content"));
    String fid = "";
    String hasVirtualFriendId =
        fs.getUserFriendHasVirtualFriendId(
            ctx, ctx.getViewerIdString(), qp.checkGetString("content"));
    if (rec.isEmpty() && hasVirtualFriendId.equals("0")) {
      fid =
          fs.setContactFriendP(
              ctx,
              ctx.getViewerIdString(),
              qp.checkGetString("name"),
              qp.checkGetString("content"),
              qp.checkGetString("circleIds"),
              Constants.FRIEND_REASON_MANUALSELECT);
      return account.getUser(
          ctx,
          ctx.getViewerIdString(),
          fid,
          qp.getString("columns", AccountLogic.USER_LIGHT_COLUMNS));
    } else {
      fid = !rec.isEmpty() ? rec.getString("user_id") : hasVirtualFriendId;
      return fs.setFriendP(
          ctx,
          ctx.getViewerIdString(),
          fid,
          qp.checkGetString("circleIds"),
          Constants.FRIEND_REASON_MANUALSELECT);
    }
  }
  @WebMethod("friend/mutual")
  public NoResponse mutualFriend(QueryParams qp, HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
    final String SERVER_HOST = GlobalConfig.get().getString("server.host", "api.borqs.com");
    ;

    FriendshipLogic fs = GlobalLogics.getFriendship();

    Context ctx = WutongContext.getContext(qp, false);
    String userId = qp.checkGetString("user_id");
    String fromId = qp.checkGetString("from_id");
    try {
      fs.setFriendsP(
          ctx,
          userId,
          fromId,
          String.valueOf(Constants.ACQUAINTANCE_CIRCLE),
          Constants.FRIEND_REASON_INVITE,
          true);
      fs.setFriendsP(
          ctx,
          fromId,
          userId,
          String.valueOf(Constants.ACQUAINTANCE_CIRCLE),
          Constants.FRIEND_REASON_INVITE,
          true);
      fs.setFriendsP(
          ctx,
          userId,
          fromId,
          String.valueOf(Constants.ADDRESS_BOOK_CIRCLE),
          Constants.FRIEND_REASON_INVITE,
          true);
      fs.setFriendsP(
          ctx,
          fromId,
          userId,
          String.valueOf(Constants.ADDRESS_BOOK_CIRCLE),
          Constants.FRIEND_REASON_INVITE,
          true);
    } catch (Exception e) {
      String html =
          pageTemplate.merge(
              "notice.ftl",
              new Object[][] {
                {"host", SERVER_HOST},
                {"notice", "互相加为好友失败,请稍后再试。"}
              });
      resp.setContentType("text/html");
      resp.getWriter().print(html);

      return NoResponse.get();
    }

    String html =
        pageTemplate.merge(
            "notice.ftl",
            new Object[][] {
              {"host", SERVER_HOST},
              {"notice", "互相加为好友成功!"}
            });
    resp.setContentType("text/html");
    resp.getWriter().print(html);

    return NoResponse.get();
  }