@Override
  public boolean deleteNetworkACL(NetworkACL acl) {
    List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
    if (aclItems.size() > 0) {
      throw new CloudRuntimeException(
          "ACL is not empty. Cannot delete network ACL: " + acl.getUuid());
    }

    List<NetworkVO> networks = _networkDao.listByAclId(acl.getId());
    if (networks != null && networks.size() > 0) {
      throw new CloudRuntimeException(
          "ACL is still associated with "
              + networks.size()
              + " tier(s). Cannot delete network ACL: "
              + acl.getUuid());
    }

    List<VpcGatewayVO> pvtGateways =
        _vpcGatewayDao.listByAclIdAndType(acl.getId(), VpcGateway.Type.Private);

    if (pvtGateways != null && pvtGateways.size() > 0) {
      throw new CloudRuntimeException(
          "ACL is still associated with "
              + pvtGateways.size()
              + " private gateway(s). Cannot delete network ACL: "
              + acl.getUuid());
    }

    return _networkACLDao.remove(acl.getId());
  }
  @Override
  public boolean applyNetworkACL(long aclId) throws ResourceUnavailableException {
    boolean handled = true;
    boolean aclApplyStatus = true;

    List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(aclId);
    // Find all networks using this ACL and apply the ACL
    List<NetworkVO> networks = _networkDao.listByAclId(aclId);
    for (NetworkVO network : networks) {
      if (!applyACLItemsToNetwork(network.getId(), rules)) {
        handled = false;
        break;
      }
    }

    List<VpcGatewayVO> vpcGateways =
        _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
    for (VpcGatewayVO vpcGateway : vpcGateways) {
      PrivateGateway privateGateway = _vpcMgr.getVpcPrivateGateway(vpcGateway.getId());
      if (!applyACLToPrivateGw(privateGateway)) {
        aclApplyStatus = false;
        s_logger.debug(
            "failed to apply network acl item on private gateway "
                + privateGateway.getId()
                + "acl id "
                + aclId);
        break;
      }
    }

    if (handled && aclApplyStatus) {
      for (NetworkACLItem rule : rules) {
        if (rule.getState() == NetworkACLItem.State.Revoke) {
          removeRule(rule);
        } else if (rule.getState() == NetworkACLItem.State.Add) {
          NetworkACLItemVO ruleVO = _networkACLItemDao.findById(rule.getId());
          ruleVO.setState(NetworkACLItem.State.Active);
          _networkACLItemDao.update(ruleVO.getId(), ruleVO);
        }
      }
    }
    return handled && aclApplyStatus;
  }