private void releaseNetworkServices(
      final VmInstanceSpec spec,
      NetworkServiceExtensionPosition position,
      final NoErrorCompletion completion) {
    if (!spec.getVmInventory().getType().equals(VmInstanceConstant.USER_VM_TYPE)) {
      completion.done();
      return;
    }

    if (nsExts.isEmpty()) {
      completion.done();
      return;
    }

    // we run into this situation when VM nics are all detached and the
    // VM is being rebooted
    if (spec.getDestNics().isEmpty()) {
      completion.done();
      return;
    }

    List<String> nsTypes = spec.getRequiredNetworkServiceTypes();

    FlowChain schain =
        FlowChainBuilder.newSimpleFlowChain()
            .setName(
                String.format(
                    "release-network-services-from-vm-%s", spec.getVmInventory().getUuid()));
    schain.allowEmptyFlow();

    for (final NetworkServiceExtensionPoint ns : nsExts) {
      if (position != null && ns.getNetworkServiceExtensionPosition() != position) {
        continue;
      }

      if (!nsTypes.contains(ns.getNetworkServiceType().toString())) {
        continue;
      }

      NoRollbackFlow flow =
          new NoRollbackFlow() {
            String __name__ =
                String.format("release-network-service-%s", ns.getNetworkServiceType());

            @Override
            public void run(final FlowTrigger chain, Map data) {
              logger.debug(
                  String.format(
                      "NetworkServiceExtensionPoint[%s] is asking back ends to release network service[%s] if needed",
                      ns.getClass().getName(), ns.getNetworkServiceType()));
              ns.releaseNetworkService(
                  spec,
                  data,
                  new NoErrorCompletion() {
                    @Override
                    public void done() {
                      chain.next();
                    }
                  });
            }
          };

      schain.then(flow);
    }

    schain
        .done(
            new FlowDoneHandler(completion) {
              @Override
              public void handle(Map data) {
                logger.debug(
                    String.format(
                        "successfully released network services for vm[uuid:%s,  name:%s]",
                        spec.getVmInventory().getUuid(), spec.getVmInventory().getName()));
                completion.done();
              }
            })
        .start();
  }