protected boolean validateSpaceRequirements() {
    int numOfVms = getParameters().getVmsCount();
    Collection<DiskImage> diskDummies =
        ImagesHandler.getDisksDummiesForStorageAllocations(diskInfoDestinationMap.values());
    Collection<DiskImage> disks = new ArrayList<>(numOfVms * diskDummies.size());
    // Number of added disks multiplies by the vms number
    for (int i = 0; i < numOfVms; ++i) {
      disks.addAll(diskDummies);
    }

    Guid spId = getVmTemplate().getStoragePoolId();
    Set<Guid> sdIds = destStorages.keySet();
    MultipleStorageDomainsValidator storageDomainsValidator =
        getStorageDomainsValidator(spId, sdIds);
    return validate(storageDomainsValidator.allDomainsWithinThresholds())
        && validate(storageDomainsValidator.allDomainsHaveSpaceForNewDisks(disks));
  }
  @Override
  protected boolean validate() {
    if (getVm() == null) {
      return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND);
    }

    if (!canRunActionOnNonManagedVm()) {
      return false;
    }

    if (getVm().isDeleteProtected()) {
      return failValidation(EngineMessage.ACTION_TYPE_FAILED_DELETE_PROTECTION_ENABLED);
    }

    vmHandler.updateDisksFromDb(getVm());
    getParameters()
        .setUseCinderCommandCallback(
            getParameters().isRemoveDisks() && !getCinderDisks().isEmpty());

    if (!getParameters().isRemoveDisks() && !canRemoveVmWithDetachDisks()) {
      return false;
    }

    switch (getVm().getStatus()) {
      case Unassigned:
      case Down:
      case ImageIllegal:
      case ImageLocked:
        break;
      case Suspended:
        return failValidation(EngineMessage.VM_CANNOT_REMOVE_VM_WHEN_STATUS_IS_NOT_DOWN);
      default:
        return (getVm().isHostedEngine() && isInternalExecution())
            || failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_IS_RUNNING);
    }

    if (getVm().getVmPoolId() != null) {
      return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_ATTACHED_TO_POOL);
    }

    // enable to remove vms without images
    SnapshotsValidator snapshotsValidator = new SnapshotsValidator();
    if (!validate(snapshotsValidator.vmNotDuringSnapshot(getVmId()))) {
      return false;
    }

    if (!getVm().getDiskMap().isEmpty()
        && !validate(new StoragePoolValidator(getStoragePool()).isUp())) {
      return false;
    }

    Collection<Disk> vmDisks = getVm().getDiskMap().values();
    List<DiskImage> vmImages =
        DisksFilter.filterImageDisks(vmDisks, ONLY_NOT_SHAREABLE, ONLY_ACTIVE);
    vmImages.addAll(DisksFilter.filterCinderDisks(vmDisks));
    if (!vmImages.isEmpty()) {
      Set<Guid> storageIds = ImagesHandler.getAllStorageIdsForImageIds(vmImages);
      MultipleStorageDomainsValidator storageValidator =
          new MultipleStorageDomainsValidator(getVm().getStoragePoolId(), storageIds);
      if (!validate(storageValidator.allDomainsExistAndActive())) {
        return false;
      }

      DiskImagesValidator diskImagesValidator = new DiskImagesValidator(vmImages);
      if (!getParameters().getForce() && !validate(diskImagesValidator.diskImagesNotLocked())) {
        return false;
      }
    }

    // Handle VM status with ImageLocked
    VmValidator vmValidator = new VmValidator(getVm());
    ValidationResult vmLockedValidatorResult = vmValidator.vmNotLocked();
    if (!vmLockedValidatorResult.isValid()) {
      // without force remove, we can't remove the VM
      if (!getParameters().getForce()) {
        return failValidation(vmLockedValidatorResult.getMessages());
      }

      // If it is force, we cannot remove if there are task
      if (CommandCoordinatorUtil.hasTasksByStoragePoolId(getVm().getStoragePoolId())) {
        return failValidation(EngineMessage.VM_CANNOT_REMOVE_HAS_RUNNING_TASKS);
      }
    }

    if (getParameters().isRemoveDisks()
        && !validate(vmValidator.vmNotHavingDeviceSnapshotsAttachedToOtherVms(false))) {
      return false;
    }

    return true;
  }