@Override
  public Network design(
      final NetworkOffering offering,
      final DeploymentPlan plan,
      final Network userSpecified,
      final Account owner) {
    // Check of the isolation type of the related physical network is supported
    final PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId());
    final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
    if (!canHandle(offering, dc.getNetworkType(), physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }

    final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physnet.getId());
    if (devices.isEmpty()) {
      s_logger.error("No NiciraNvp Controller on physical network " + physnet.getName());
      return null;
    }
    s_logger.debug(
        "Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());

    s_logger.debug(
        "Physical isolation type is supported, asking GuestNetworkGuru to design this network");
    final NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, owner);
    if (networkObject == null) {
      return null;
    }
    networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch);

    return networkObject;
  }
  @Override
  public Network design(
      NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {

    PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
    DataCenter dc = _dcDao.findById(plan.getDataCenterId());
    if (!canHandle(offering, dc.getNetworkType(), physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }
    NetworkVO config = (NetworkVO) super.design(offering, plan, userSpecified, owner);
    if (config == null) {
      return null;
    }

    config.setBroadcastDomainType(BroadcastDomainType.Vswitch);

    return config;
  }
  @Override
  public Network implement(
      Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
      throws InsufficientVirtualNetworkCapcityException {
    assert (network.getState() == State.Implementing) : "Why are we implementing " + network;

    long dcId = dest.getDataCenter().getId();
    NetworkType nwType = dest.getDataCenter().getNetworkType();
    // get physical network id
    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());
    }
    PhysicalNetworkVO physnet = _physicalNetworkDao.findById(physicalNetworkId);

    if (!canHandle(offering, nwType, physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }
    NetworkVO implemented = (NetworkVO) super.implement(network, offering, dest, context);

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

    if (network.getCidr() != null) {
      implemented.setCidr(network.getCidr());
    }
    String name = network.getName();
    if (name == null || name.isEmpty()) {
      name = ((NetworkVO) network).getUuid();
    }

    // do we need to create switch right now?

    implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);

    return implemented;
  }
  @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;
  }