/**
  * Validate the SourceVolume VArray details with ingested target volumes VArray.
  *
  * @param unManagedVolume
  * @param VirtualPool
  * @return
  */
 private void validateSourceVolumeVarrayWithTargetVPool(
     UnManagedVolume unManagedVolume, VirtualPool sourceVPool) {
   StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation();
   // find whether all targets are ingested
   StringSet targetUnManagedVolumeGuids =
       unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_MIRRORS.toString());
   if (null != targetUnManagedVolumeGuids && !targetUnManagedVolumeGuids.isEmpty()) {
     StringSet targetVolumeNativeGuids =
         VolumeIngestionUtil.getListofVolumeIds(targetUnManagedVolumeGuids);
     // check whether target exists
     List<URI> targetUris = VolumeIngestionUtil.getVolumeUris(targetVolumeNativeGuids, _dbClient);
     if (null == targetUris || targetUris.isEmpty()) {
       _logger.info(
           "None of the targets ingested for source volume: {}", unManagedVolume.getNativeGuid());
     } else {
       List<Volume> targetVolumes = _dbClient.queryObject(Volume.class, targetUris);
       for (Volume targetVolume : targetVolumes) {
         Map<URI, VpoolRemoteCopyProtectionSettings> settings =
             sourceVPool.getRemoteProtectionSettings(sourceVPool, _dbClient);
         if (null == settings
             || settings.size() == 0
             || !settings.containsKey(targetVolume.getVirtualArray())) {
           _logger.info(
               "Target Volume's VArray {} is not matching already ingested source volume virtual pool's remote VArray {}",
               targetVolume.getVirtualArray(),
               Joiner.on(",").join(settings.keySet()));
           throw IngestionException.exceptions.unmanagedSRDFSourceVolumeVArrayMismatch(
               unManagedVolume.getLabel(), targetVolume.getVirtualArray().toString());
         }
       }
     }
   }
 }
  /**
   * Return the rdfGroupId based on the personality. For source volume, we will not have RDFGroup
   * hence we should get it from its targets.
   *
   * @param unManagedVolumeInformation
   * @return
   */
  private URI getRDFGroupBasedOnPersonality(StringSetMap unManagedVolumeInformation) {
    String type =
        PropertySetterUtil.extractValueFromStringSet(
            SupportedVolumeInformation.REMOTE_VOLUME_TYPE.toString(), unManagedVolumeInformation);
    URI rdfGroupId = null;
    if (RemoteMirrorObject.Types.SOURCE.toString().equalsIgnoreCase(type)) {
      StringSet targetUnManagedVolumeGuids =
          unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_MIRRORS.toString());
      if (null != targetUnManagedVolumeGuids && !targetUnManagedVolumeGuids.isEmpty()) {
        StringSet targetVolumeNativeGuids =
            VolumeIngestionUtil.getListofVolumeIds(targetUnManagedVolumeGuids);
        List<URI> targetUris =
            VolumeIngestionUtil.getVolumeUris(targetVolumeNativeGuids, _dbClient);
        if (null == targetUris || targetUris.isEmpty()) {
          List<URI> unmanagedTargetVolumes =
              VolumeIngestionUtil.getUnManagedVolumeUris(targetUnManagedVolumeGuids, _dbClient);
          for (URI targetUmv : unmanagedTargetVolumes) {
            _logger.info("RDFGroup Found using unmanaged Target volume {}", targetUmv);
            UnManagedVolume umv = _dbClient.queryObject(UnManagedVolume.class, targetUmv);
            rdfGroupId =
                URI.create(
                    PropertySetterUtil.extractValueFromStringSet(
                        SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(),
                        umv.getVolumeInformation()));
            break;
          }
        } else {
          // If targets are already ingested.
          List<Volume> targetVolumes = _dbClient.queryObject(Volume.class, targetUris);
          if (null != targetVolumes && !targetVolumes.isEmpty()) {
            for (Volume targetVolume : targetVolumes) {
              _logger.info(
                  "RDFGroup Found for using ingested Target volumes {}.",
                  targetVolume.getNativeGuid());
              rdfGroupId = targetVolume.getSrdfGroup();
              break;
            }
          }
        }
      }

    } else if (RemoteMirrorObject.Types.TARGET.toString().equalsIgnoreCase(type)) {
      rdfGroupId =
          URI.create(
              PropertySetterUtil.extractValueFromStringSet(
                  SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(),
                  unManagedVolumeInformation));
    }

    return rdfGroupId;
  }
  /**
   * create StorageVolume Info Object
   *
   * @param unManagedVolume
   * @param volumeInstance
   * @param unManagedVolumeNativeGuid
   * @param pool
   * @return
   */
  private UnManagedVolume createUnManagedVolume(
      UnManagedVolume unManagedVolume,
      CIMInstance volumeInstance,
      String unManagedVolumeNativeGuid,
      StoragePool pool,
      StorageSystem system,
      String volumeNativeGuid,
      // to make the code uniform, passed in all the below sets as
      // arguments
      Map<String, VolHostIOObject> exportedVolumes,
      Set<String> existingVolumesInCG,
      Map<String, RemoteMirrorObject> volumeToRAGroupMap,
      Map<String, LocalReplicaObject> volumeToLocalReplicaMap,
      Set<String> poolSupportedSLONames,
      Map<String, Object> keyMap) {
    _logger.info("Process UnManagedVolume {}", unManagedVolumeNativeGuid);
    try {
      boolean created = false;
      if (null == unManagedVolume) {
        unManagedVolume = new UnManagedVolume();
        unManagedVolume.setId(URIUtil.createId(UnManagedVolume.class));
        unManagedVolume.setNativeGuid(unManagedVolumeNativeGuid);
        unManagedVolume.setStorageSystemUri(system.getId());
        created = true;
      }

      // reset the auto-tiering info for unmanaged volumes already present
      // in db
      // so that the tiering info is updated correctly later
      if (!created) {
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.AUTO_TIERING_POLICIES.toString(), "");
        unManagedVolume.putVolumeCharacterstics(
            SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(), "false");

        // reset local replica info
        unManagedVolume.putVolumeCharacterstics(
            SupportedVolumeCharacterstics.IS_FULL_COPY.name(), FALSE);
        unManagedVolume.putVolumeCharacterstics(
            SupportedVolumeCharacterstics.IS_LOCAL_MIRROR.name(), FALSE);
        unManagedVolume.putVolumeCharacterstics(
            SupportedVolumeCharacterstics.IS_SNAP_SHOT.name(), FALSE);
        unManagedVolume.putVolumeCharacterstics(
            SupportedVolumeCharacterstics.HAS_REPLICAS.name(), FALSE);

        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.REPLICA_STATE.name(), new StringSet());

        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.SYNC_STATE.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.SYNC_TYPE.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.SYNCHRONIZED_INSTANCE.name(), new StringSet());

        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.NEEDS_COPY_TO_TARGET.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.TECHNOLOGY_TYPE.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.SETTINGS_INSTANCE.name(), new StringSet());

        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.FULL_COPIES.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.MIRRORS.name(), new StringSet());
        unManagedVolume
            .getVolumeInformation()
            .put(SupportedVolumeInformation.SNAPSHOTS.name(), new StringSet());
      }

      Map<String, StringSet> unManagedVolumeInformation = new HashMap<String, StringSet>();
      Map<String, String> unManagedVolumeCharacteristics = new HashMap<String, String>();

      if (null != system) {
        StringSet systemTypes = new StringSet();
        systemTypes.add(system.getSystemType());
        unManagedVolumeInformation.put(
            SupportedVolumeInformation.SYSTEM_TYPE.toString(), systemTypes);
      }

      if (exportedVolumes != null && exportedVolumes.containsKey(volumeNativeGuid)) {
        VolHostIOObject obj = exportedVolumes.get(volumeNativeGuid);
        if (null != obj) {
          StringSet bwValues = new StringSet();
          bwValues.add(obj.getHostIoBw());
          if (unManagedVolumeInformation.get(
                  SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString())
              == null) {
            unManagedVolumeInformation.put(
                SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString(), bwValues);
          } else {
            unManagedVolumeInformation
                .get(SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString())
                .replace(bwValues);
          }

          StringSet iopsVal = new StringSet();
          iopsVal.add(obj.getHostIops());

          if (unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString())
              == null) {
            unManagedVolumeInformation.put(
                SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString(), iopsVal);
          } else {
            unManagedVolumeInformation
                .get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString())
                .replace(iopsVal);
          }
        }
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), TRUE);

      } else {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), FALSE);
        StringSet bwValues = new StringSet();
        bwValues.add("0");

        if (unManagedVolumeInformation.get(
                SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString())
            == null) {
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString(), bwValues);
        } else {
          unManagedVolumeInformation
              .get(SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString())
              .replace(bwValues);
        }

        StringSet iopsVal = new StringSet();
        iopsVal.add("0");

        if (unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString())
            == null) {
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString(), iopsVal);
        } else {
          unManagedVolumeInformation
              .get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString())
              .replace(iopsVal);
        }
      }

      // Set SLOName only for VMAX3 exported volumes
      if (system.checkIfVmax3()) {
        // If there are no slonames defined for a pool or no slo
        // set for a volume, update the tiering_enabled to false.
        if (poolSupportedSLONames.isEmpty() || !keyMap.containsKey(Constants.VOLUMES_WITH_SLOS)) {
          unManagedVolumeCharacteristics.put(
              SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(),
              Boolean.FALSE.toString());
        } else {
          Map<String, String> volumesWithSLO =
              (Map<String, String>) keyMap.get(Constants.VOLUMES_WITH_SLOS);
          if (volumesWithSLO.containsKey(volumeNativeGuid)) {
            String sloName = volumesWithSLO.get(volumeNativeGuid);
            _logger.debug("formattedSLOName: {}", sloName);
            updateSLOPolicies(
                poolSupportedSLONames,
                unManagedVolumeInformation,
                unManagedVolumeCharacteristics,
                sloName);
          } else {
            unManagedVolumeCharacteristics.put(
                SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(),
                Boolean.FALSE.toString());
          }
        }
      }

      if (existingVolumesInCG != null && existingVolumesInCG.contains(volumeNativeGuid)) {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), TRUE);
      } else {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), FALSE);
      }

      Object raidLevelObj;
      boolean isIngestable;
      String isBound;
      String isThinlyProvisioned;
      String isMetaVolume;
      String allocCapacity;
      // Set the attributes for new smis version.
      if (keyMap.containsKey(Constants.IS_NEW_SMIS_PROVIDER)
          && Boolean.valueOf(keyMap.get(Constants.IS_NEW_SMIS_PROVIDER).toString())) {
        unManagedVolume.setLabel(getCIMPropertyValue(volumeInstance, NAME));
        raidLevelObj =
            volumeInstance.getPropertyValue(
                SupportedVolumeInformation.RAID_LEVEL.getAlternateKey());
        isBound =
            getCIMPropertyValue(
                volumeInstance, SupportedVolumeCharacterstics.IS_BOUND.getAlterCharacterstic());
        isIngestable = isVolumeIngestable(volumeInstance, isBound, USAGE);
        isThinlyProvisioned = getCIMPropertyValue(volumeInstance, THINLY_PROVISIONED);
        isMetaVolume =
            getCIMPropertyValue(
                volumeInstance,
                SupportedVolumeCharacterstics.IS_METAVOLUME.getAlterCharacterstic());
        allocCapacity =
            getAllocatedCapacity(volumeInstance, _volumeToSpaceConsumedMap, system.checkIfVmax3());
      } else {
        unManagedVolume.setLabel(getCIMPropertyValue(volumeInstance, SVELEMENT_NAME));
        isBound =
            getCIMPropertyValue(
                volumeInstance, SupportedVolumeCharacterstics.IS_BOUND.getCharacterstic());
        raidLevelObj =
            volumeInstance.getPropertyValue(SupportedVolumeInformation.RAID_LEVEL.getInfoKey());
        isIngestable = isVolumeIngestable(volumeInstance, isBound, SVUSAGE);
        isThinlyProvisioned = getCIMPropertyValue(volumeInstance, EMC_THINLY_PROVISIONED);
        isMetaVolume =
            getCIMPropertyValue(
                volumeInstance, SupportedVolumeCharacterstics.IS_METAVOLUME.getCharacterstic());
        allocCapacity = getCIMPropertyValue(volumeInstance, EMC_ALLOCATED_CAPACITY);
      }

      if (null != raidLevelObj) {
        StringSet raidLevels = new StringSet();
        raidLevels.add(raidLevelObj.toString());
        unManagedVolumeInformation.put(
            SupportedVolumeInformation.RAID_LEVEL.toString(), raidLevels);
      }

      if (null != isBound) {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_BOUND.toString(), isBound);
      }
      if (null != isThinlyProvisioned) {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), isThinlyProvisioned);
      }

      if (null != isMetaVolume) {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_METAVOLUME.toString(), isMetaVolume);
      }

      // only Volumes with Usage 2 can be ingestable, other volumes
      // [SAVE,VAULT...] apart from replicas have usage other than 2
      // Volumes which are set EMCIsBound as false cannot be ingested
      if (isIngestable) {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), TRUE);
      } else {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), FALSE);
      }

      if (volumeToRAGroupMap.containsKey(unManagedVolume.getNativeGuid())) {
        RemoteMirrorObject rmObj = volumeToRAGroupMap.get(unManagedVolume.getNativeGuid());
        _logger.info("Found RA Object {}", rmObj.toString());
        if (RemoteMirrorObject.Types.SOURCE.toString().equalsIgnoreCase(rmObj.getType())) {
          _logger.info("Found Source, updating targets {}", rmObj.getTargetVolumenativeGuids());
          // setting target Volumes
          if (unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_MIRRORS.toString())
              == null) {
            unManagedVolumeInformation.put(
                SupportedVolumeInformation.REMOTE_MIRRORS.toString(),
                rmObj.getTargetVolumenativeGuids());
          } else {
            if (null == rmObj.getTargetVolumenativeGuids()
                || rmObj.getTargetVolumenativeGuids().size() == 0) {
              unManagedVolumeInformation
                  .get(SupportedVolumeInformation.REMOTE_MIRRORS.toString())
                  .clear();
            } else {
              unManagedVolumeInformation
                  .get(SupportedVolumeInformation.REMOTE_MIRRORS.toString())
                  .replace(rmObj.getTargetVolumenativeGuids());
            }
          }
        } else if (RemoteMirrorObject.Types.TARGET.toString().equalsIgnoreCase(rmObj.getType())) {

          _logger.info(
              "Found Target {}, updating copyMode {}, RA Group",
              unManagedVolume.getNativeGuid(),
              rmObj.getCopyMode());
          // setting srdfParent
          StringSet parentVolume = new StringSet();
          parentVolume.add(rmObj.getSourceVolumeNativeGuid());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.REMOTE_MIRROR_SOURCE_VOLUME.toString(), parentVolume);

          // setting RAGroup
          StringSet raGroup = new StringSet();
          raGroup.add(rmObj.getRaGroupUri().toString());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(), raGroup);
        }
        // setting Copy Modes
        StringSet copyModes = new StringSet();
        copyModes.add(rmObj.getCopyMode());
        if (unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_COPY_MODE.toString())
            == null) {
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.REMOTE_COPY_MODE.toString(), copyModes);
        } else {
          unManagedVolumeInformation
              .get(SupportedVolumeInformation.REMOTE_COPY_MODE.toString())
              .replace(copyModes);
        }
        // setting Volume Type

        StringSet volumeType = new StringSet();
        volumeType.add(rmObj.getType());
        unManagedVolumeInformation.put(
            SupportedVolumeInformation.REMOTE_VOLUME_TYPE.toString(), volumeType);

        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.REMOTE_MIRRORING.toString(), TRUE);
      } else {
        unManagedVolumeCharacteristics.put(
            SupportedVolumeCharacterstics.REMOTE_MIRRORING.toString(), FALSE);
      }

      // handle clones, local mirrors and snapshots
      boolean isLocalReplica = false;
      if (volumeToLocalReplicaMap.containsKey(unManagedVolume.getNativeGuid())) {
        _logger.info("Found in localReplicaMap {}", unManagedVolume.getNativeGuid());
        LocalReplicaObject lrObj = volumeToLocalReplicaMap.get(unManagedVolume.getNativeGuid());
        isLocalReplica = lrObj.isReplica();

        // setting targets
        StringSet fullCopies = lrObj.getFullCopies();
        if (fullCopies != null && !fullCopies.isEmpty()) {
          unManagedVolumeInformation.put(SupportedVolumeInformation.FULL_COPIES.name(), fullCopies);
        }

        StringSet mirrors = lrObj.getMirrors();
        if (mirrors != null && !mirrors.isEmpty()) {
          unManagedVolumeInformation.put(SupportedVolumeInformation.MIRRORS.name(), mirrors);
        }

        StringSet snapshots = lrObj.getSnapshots();
        if (snapshots != null && !snapshots.isEmpty()) {
          unManagedVolumeInformation.put(SupportedVolumeInformation.SNAPSHOTS.name(), snapshots);
        }

        if (lrObj.hasReplica()) {
          // set the HAS_REPLICAS property
          unManagedVolumeCharacteristics.put(
              SupportedVolumeCharacterstics.HAS_REPLICAS.name(), TRUE);
        }

        if (LocalReplicaObject.Types.FullCopy.equals(lrObj.getType())) {
          _logger.info("Found Clone {}", unManagedVolume.getNativeGuid());
          // setting clone specific info
          unManagedVolumeCharacteristics.put(
              SupportedVolumeCharacterstics.IS_FULL_COPY.name(), TRUE);
          StringSet sourceVolume = new StringSet();
          sourceVolume.add(lrObj.getSourceNativeGuid());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), sourceVolume);

          StringSet isSyncActive = new StringSet();
          isSyncActive.add(new Boolean(lrObj.isSyncActive()).toString());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), isSyncActive);

          StringSet replicaState = new StringSet();
          replicaState.add(lrObj.getReplicaState());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.REPLICA_STATE.name(), replicaState);
        } else if (LocalReplicaObject.Types.BlockMirror.equals(lrObj.getType())) {
          _logger.info("Found Local Mirror {}", unManagedVolume.getNativeGuid());
          // setting local mirror specific info
          unManagedVolumeCharacteristics.put(
              SupportedVolumeCharacterstics.IS_LOCAL_MIRROR.name(), TRUE);
          StringSet sourceVolume = new StringSet();
          sourceVolume.add(lrObj.getSourceNativeGuid());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), sourceVolume);

          StringSet syncState = new StringSet();
          syncState.add(lrObj.getSyncState());
          unManagedVolumeInformation.put(SupportedVolumeInformation.SYNC_STATE.name(), syncState);

          StringSet syncType = new StringSet();
          syncType.add(lrObj.getSyncType());
          unManagedVolumeInformation.put(SupportedVolumeInformation.SYNC_TYPE.name(), syncType);

          String syncedInst = lrObj.getSynchronizedInstance();
          if (syncedInst != null) {
            StringSet synchronizedInstance = new StringSet();
            synchronizedInstance.add(syncedInst);
            unManagedVolumeInformation.put(
                SupportedVolumeInformation.SYNCHRONIZED_INSTANCE.name(), synchronizedInstance);
          }
        } else if (LocalReplicaObject.Types.BlockSnapshot.equals(lrObj.getType())) {
          _logger.info("Found Snapshot {}", unManagedVolume.getNativeGuid());
          // setting snapshot specific info
          unManagedVolumeCharacteristics.put(
              SupportedVolumeCharacterstics.IS_SNAP_SHOT.name(), TRUE);
          StringSet sourceVolume = new StringSet();
          sourceVolume.add(lrObj.getSourceNativeGuid());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), sourceVolume);

          StringSet isSyncActive = new StringSet();
          isSyncActive.add(new Boolean(lrObj.isSyncActive()).toString());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), isSyncActive);

          StringSet needsCopyToTarget = new StringSet();
          needsCopyToTarget.add(new Boolean(lrObj.isNeedsCopyToTarget()).toString());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.NEEDS_COPY_TO_TARGET.name(), needsCopyToTarget);

          StringSet technologyType = new StringSet();
          technologyType.add(lrObj.getTechnologyType());
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.TECHNOLOGY_TYPE.name(), technologyType);

          String settingsInst = lrObj.getSettingsInstance();
          if (settingsInst != null) {
            StringSet settingsInstance = new StringSet();
            settingsInstance.add(settingsInst);
            unManagedVolumeInformation.put(
                SupportedVolumeInformation.SETTINGS_INSTANCE.name(), settingsInstance);
          }
        }
      }

      // set volume's isSyncActive
      if (!isLocalReplica) {
        StringSet isSyncActive = new StringSet();
        isSyncActive.add(TRUE);
        unManagedVolumeInformation.put(
            SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), isSyncActive);
      }

      if (null != pool) {
        unManagedVolume.setStoragePoolUri(pool.getId());
        StringSet pools = new StringSet();
        pools.add(pool.getId().toString());
        unManagedVolumeInformation.put(SupportedVolumeInformation.STORAGE_POOL.toString(), pools);
        StringSet driveTypes = pool.getSupportedDriveTypes();
        if (null != driveTypes) {
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.DISK_TECHNOLOGY.toString(), driveTypes);
        }
        StringSet matchedVPools =
            DiscoveryUtils.getMatchedVirtualPoolsForPool(
                _dbClient,
                pool.getId(),
                unManagedVolumeCharacteristics.get(
                    SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString()));
        if (unManagedVolumeInformation.containsKey(
            SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString())) {

          _logger.debug("Matched Pools :" + Joiner.on("\t").join(matchedVPools));
          if (null != matchedVPools && matchedVPools.size() == 0) {
            // replace with empty string set doesn't work, hence
            // added explicit code to remove all
            unManagedVolumeInformation
                .get(SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString())
                .clear();
          } else {
            // replace with new StringSet
            unManagedVolumeInformation
                .get(SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString())
                .replace(matchedVPools);
            _logger.info(
                "Replaced Pools :"
                    + Joiner.on("\t")
                        .join(
                            unManagedVolumeInformation.get(
                                SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString())));
          }
        } else {
          unManagedVolumeInformation.put(
              SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString(), matchedVPools);
        }
      }

      // set allocated capacity
      if (allocCapacity != null) {
        StringSet allocCapacitySet = new StringSet();
        allocCapacitySet.add(allocCapacity);
        unManagedVolumeInformation.put(
            SupportedVolumeInformation.ALLOCATED_CAPACITY.toString(), allocCapacitySet);
      }

      StringSet provCapacity = new StringSet();
      provCapacity.add(String.valueOf(returnProvisionedCapacity(volumeInstance, keyMap)));
      unManagedVolumeInformation.put(
          SupportedVolumeInformation.PROVISIONED_CAPACITY.toString(), provCapacity);
      injectVolumeInformation(unManagedVolume, volumeInstance, unManagedVolumeInformation);
      injectVolumeCharacterstics(unManagedVolume, volumeInstance, unManagedVolumeCharacteristics);
      unManagedVolume.getUnmanagedExportMasks().clear();
      unManagedVolume.getInitiatorUris().clear();
      unManagedVolume.getInitiatorNetworkIds().clear();
      if (created) {
        _unManagedVolumesInsert.add(unManagedVolume);
      } else {
        _unManagedVolumesUpdate.add(unManagedVolume);
      }

    } catch (Exception e) {
      _logger.error("Exception: ", e);
    }
    return unManagedVolume;
  }