/** {@inheritDoc} */
  @Override
  public void validateSnapshotCreateRequest(Volume requestedVolume, List<Volume> volumesToSnap) {
    // For VMAX3 you cannot have active snap and full copy sessions,
    // so verify there are no active full copies for the volume.
    for (Volume volumeToSnap : volumesToSnap) {
      // Check if the volume to snap is an active full copy.
      if ((BlockFullCopyUtils.isVolumeFullCopy(volumeToSnap, _dbClient))
          && (!BlockFullCopyUtils.isFullCopyDetached(volumeToSnap, _dbClient))
          && (!BlockFullCopyUtils.isFullCopyInactive(volumeToSnap, _dbClient))) {
        throw APIException.badRequests.noSnapshotsForVMAX3VolumeWithActiveFullCopy();
      }

      // Now check if the volume to be snapped is a full copy source
      // that has active full copies.
      StringSet fullCopyIds = volumeToSnap.getFullCopies();
      if ((fullCopyIds != null) && (!fullCopyIds.isEmpty())) {
        Iterator<String> fullCopyIdsIter = fullCopyIds.iterator();
        while (fullCopyIdsIter.hasNext()) {
          URI fullCopyURI = URI.create(fullCopyIdsIter.next());
          Volume fullCopyVolume = _dbClient.queryObject(Volume.class, fullCopyURI);
          if ((fullCopyVolume != null)
              && (!fullCopyVolume.getInactive())
              && (!BlockFullCopyUtils.isFullCopyDetached(fullCopyVolume, _dbClient))
              && (!BlockFullCopyUtils.isFullCopyInactive(fullCopyVolume, _dbClient))) {
            throw APIException.badRequests.noSnapshotsForVMAX3VolumeWithActiveFullCopy();
          }
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void validateFullCopyCreateRequest(List<BlockObject> fcSourceObjList, int count) {
    if (fcSourceObjList.size() > 0) {
      URI fcSourceObjURI = fcSourceObjList.get(0).getId();
      if (URIUtil.isType(fcSourceObjURI, BlockSnapshot.class)) {
        // Currently you cannot create a full copy of a VPLEX snapshot.
        throw APIException.badRequests.cantCreateFullCopyForVPlexSnapshot();
      } else {
        // Call super first.
        super.validateFullCopyCreateRequest(fcSourceObjList, count);

        // Platform specific checks.
        for (BlockObject fcSourceObj : fcSourceObjList) {
          Volume fcSourceVolume = (Volume) fcSourceObj;
          StorageSystem system =
              _dbClient.queryObject(StorageSystem.class, fcSourceVolume.getStorageController());
          if (DiscoveredDataObject.Type.vplex.name().equals(system.getSystemType())) {
            // If the volume is a VPLEX volume, then we need to be sure that
            // storage pool of the source backend volume of the VPLEX volume,
            // which is volume used to create the native full copy, supports
            // full copy.
            Volume srcBackendVolume =
                VPlexUtil.getVPLEXBackendVolume(fcSourceVolume, true, _dbClient, true);
            StoragePool storagePool =
                _dbClient.queryObject(StoragePool.class, srcBackendVolume.getPool());
            verifyFullCopySupportedForStoragePool(storagePool);

            // If the full copy source is itself a full copy, it is not
            // detached, and the native full copy i.e., the source side
            // backend volume, is VNX, then creating a full copy of the
            // volume will fail. As such, we prevent it.
            if ((BlockFullCopyUtils.isVolumeFullCopy(fcSourceVolume, _dbClient))
                && (!BlockFullCopyUtils.isFullCopyDetached(fcSourceVolume, _dbClient))) {
              URI backendSystemURI = srcBackendVolume.getStorageController();
              StorageSystem backendSystem =
                  _dbClient.queryObject(StorageSystem.class, backendSystemURI);
              if (DiscoveredDataObject.Type.vnxblock.name().equals(backendSystem.getSystemType())) {
                throw APIException.badRequests.cantCreateFullCopyOfVPlexFullCopyUsingVNX();
              }
            }
          }
        }
      }
    }
  }