@Override
  public List<LoadBalancerVO> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) {
    Account caller = UserContext.current().getCaller();
    Long ipId = cmd.getPublicIpId();
    Long zoneId = cmd.getZoneId();
    String path = null;

    Pair<String, Long> accountDomainPair =
        _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
    String accountName = accountDomainPair.first();
    Long domainId = accountDomainPair.second();

    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN
        || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
      Domain domain = _domainMgr.getDomain(caller.getDomainId());
      path = domain.getPath();
    }

    Filter searchFilter =
        new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());

    Object id = cmd.getId();
    Object name = cmd.getLoadBalancerRuleName();
    Object keyword = cmd.getKeyword();
    Object instanceId = cmd.getVirtualMachineId();

    SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
    sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
    sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
    sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
    sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
    sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);

    if (instanceId != null) {
      SearchBuilder<LoadBalancerVMMapVO> lbVMSearch = _lb2VmMapDao.createSearchBuilder();
      lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
      sb.join(
          "lbVMSearch",
          lbVMSearch,
          sb.entity().getId(),
          lbVMSearch.entity().getLoadBalancerId(),
          JoinBuilder.JoinType.INNER);
    }

    if (path != null) {
      // for domain admin we should show only subdomains information
      SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
      domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
      sb.join(
          "domainSearch",
          domainSearch,
          sb.entity().getDomainId(),
          domainSearch.entity().getId(),
          JoinBuilder.JoinType.INNER);
    }

    if (zoneId != null) {
      SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
      ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
      sb.join(
          "ipSearch",
          ipSearch,
          sb.entity().getSourceIpAddressId(),
          ipSearch.entity().getId(),
          JoinBuilder.JoinType.INNER);
    }

    SearchCriteria<LoadBalancerVO> sc = sb.create();
    if (keyword != null) {
      SearchCriteria<LoadBalancerVO> ssc = _lbDao.createSearchCriteria();
      ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
      ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");

      sc.addAnd("name", SearchCriteria.Op.SC, ssc);
    }

    if (name != null) {
      sc.setParameters("name", "%" + name + "%");
    }

    if (id != null) {
      sc.setParameters("id", id);
    }

    if (ipId != null) {
      sc.setParameters("sourceIpAddress", ipId);
    }

    if (instanceId != null) {
      sc.setJoinParameters("lbVMSearch", "instanceId", instanceId);
    }

    if (domainId != null) {
      sc.setParameters("domainId", domainId);
      if (accountName != null) {
        Account account = _accountMgr.getActiveAccountByName(accountName, domainId);
        sc.setParameters("accountId", account.getId());
      }
    }

    if (path != null) {
      sc.setJoinParameters("domainSearch", "path", path + "%");
    }

    if (zoneId != null) {
      sc.setJoinParameters("ipSearch", "zoneId", zoneId);
    }

    return _lbDao.search(sc, searchFilter);
  }