@Override
  public boolean replaceNetworkACL(NetworkACL acl, NetworkVO network)
      throws ResourceUnavailableException {

    NetworkOffering guestNtwkOff =
        _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());

    if (guestNtwkOff == null) {
      throw new InvalidParameterValueException(
          "Can't find network offering associated with network: " + network.getUuid());
    }

    // verify that ACLProvider is supported by network offering
    if (!_ntwkModel.areServicesSupportedByNetworkOffering(
        guestNtwkOff.getId(), Service.NetworkACL)) {
      throw new InvalidParameterValueException(
          "Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
    }

    if (network.getNetworkACLId() != null) {
      // Revoke ACL Items of the existing ACL if the new ACL is empty
      // Existing rules won't be removed otherwise
      List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
      if (aclItems == null || aclItems.isEmpty()) {
        s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
        if (!revokeACLItemsForNetwork(network.getId())) {
          throw new CloudRuntimeException(
              "Failed to replace network ACL. Error while removing existing ACL items for network: "
                  + network.getId());
        }
      }
    }

    network.setNetworkACLId(acl.getId());
    // Update Network ACL
    if (_networkDao.update(network.getId(), network)) {
      s_logger.debug(
          "Updated network: "
              + network.getId()
              + " with Network ACL Id: "
              + acl.getId()
              + ", Applying ACL items");
      // Apply ACL to network
      return applyACLToNetwork(network.getId());
    }
    return false;
  }
  @Override
  public Network implement(
      final Network network,
      final NetworkOffering offering,
      final DeployDestination dest,
      final ReservationContext context)
      throws InsufficientVirtualNetworkCapacityException {
    assert network.getState() == State.Implementing : "Why are we implementing " + network;

    final long dcId = dest.getDataCenter().getId();

    Long physicalNetworkId = network.getPhysicalNetworkId();

    // physical network id can be null in Guest Network in Basic zone, so locate the physical
    // network
    if (physicalNetworkId == null) {
      physicalNetworkId =
          networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
    }

    final NetworkVO implemented =
        new NetworkVO(
            network.getTrafficType(),
            network.getMode(),
            network.getBroadcastDomainType(),
            network.getNetworkOfferingId(),
            State.Allocated,
            network.getDataCenterId(),
            physicalNetworkId,
            offering.getRedundantRouter());

    if (network.getGateway() != null) {
      implemented.setGateway(network.getGateway());
    }

    if (network.getCidr() != null) {
      implemented.setCidr(network.getCidr());
    }

    // Name is either the given name or the uuid
    String name = network.getName();
    if (name == null || name.isEmpty()) {
      name = ((NetworkVO) network).getUuid();
    }
    if (name.length() > MAX_NAME_LENGTH) {
      name = name.substring(0, MAX_NAME_LENGTH - 1);
    }

    final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physicalNetworkId);
    if (devices.isEmpty()) {
      s_logger.error("No NiciraNvp Controller on physical network " + physicalNetworkId);
      return null;
    }
    final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
    final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId());
    hostDao.loadDetails(niciraNvpHost);
    final String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid");
    final String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype");

    final CreateLogicalSwitchCommand cmd =
        new CreateLogicalSwitchCommand(
            transportzoneuuid,
            transportzoneisotype,
            name,
            context.getDomain().getName() + "-" + context.getAccount().getAccountName());
    final CreateLogicalSwitchAnswer answer =
        (CreateLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd);

    if (answer == null || !answer.getResult()) {
      s_logger.error("CreateLogicalSwitchCommand failed");
      return null;
    }

    try {
      implemented.setBroadcastUri(new URI("lswitch", answer.getLogicalSwitchUuid(), null));
      implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch);
      s_logger.info(
          "Implemented OK, network linked to  = " + implemented.getBroadcastUri().toString());
    } catch (final URISyntaxException e) {
      s_logger.error(
          "Unable to store logical switch id in broadcast uri, uuid = " + implemented.getUuid(), e);
      return null;
    }

    return implemented;
  }