public static List<StoragePool> checkStoragePoolsNotVisible(
      List<StoragePool> discoveredPools, DbClient dbClient, URI storageSystemId) {
    List<StoragePool> modifiedPools = new ArrayList<StoragePool>();
    // Get the pools previously discovered
    URIQueryResultList storagePoolURIs = new URIQueryResultList();
    dbClient.queryByConstraint(
        ContainmentConstraint.Factory.getStorageDeviceStoragePoolConstraint(storageSystemId),
        storagePoolURIs);
    Iterator<URI> storagePoolIter = storagePoolURIs.iterator();

    List<URI> existingPoolsURI = new ArrayList<URI>();
    while (storagePoolIter.hasNext()) {
      existingPoolsURI.add(storagePoolIter.next());
    }

    List<URI> discoveredPoolsURI = new ArrayList<URI>();
    for (StoragePool pool : discoveredPools) {
      discoveredPoolsURI.add(pool.getId());
    }

    Set<URI> poolDiff =
        Sets.difference(new HashSet<URI>(existingPoolsURI), new HashSet<URI>(discoveredPoolsURI));

    if (!poolDiff.isEmpty()) {
      Iterator<StoragePool> storagePoolIt =
          dbClient.queryIterativeObjects(StoragePool.class, poolDiff, true);
      while (storagePoolIt.hasNext()) {
        StoragePool pool = storagePoolIt.next();
        modifiedPools.add(pool);
        _log.info(
            "Setting discovery status of pool {} : {} as NOTVISIBLE",
            pool.getLabel(),
            pool.getId());
        pool.setDiscoveryStatus(DiscoveredDataObject.DiscoveryStatus.NOTVISIBLE.name());
        dbClient.persistObject(pool);
      }
    }

    return modifiedPools;
  }
  /**
   * Process the volumes to find the unmanaged volumes and populate the volume supported
   * information.
   *
   * @param it
   * @param keyMap
   * @param operation
   * @param pool
   * @param system
   * @param exportedVolumes
   * @param volumesAndReplicas
   * @param existingVolumesInCG
   * @param volumeToRAGroupMap
   * @param poolSupportedSLONames
   * @param boundVolumes
   */
  private void processVolumes(
      Iterator<CIMInstance> it,
      Map<String, Object> keyMap,
      Operation operation,
      StoragePool pool,
      StorageSystem system,
      Map<String, VolHostIOObject> exportedVolumes,
      Set<String> existingVolumesInCG,
      Map<String, RemoteMirrorObject> volumeToRAGroupMap,
      Map<String, LocalReplicaObject> volumeToLocalReplicaMap,
      Set<String> poolSupportedSLONames,
      Set<String> boundVolumes) {

    List<CIMObjectPath> metaVolumes = new ArrayList<CIMObjectPath>();
    List<CIMObjectPath> metaVolumeViews = new ArrayList<CIMObjectPath>();
    while (it.hasNext()) {
      CIMInstance volumeViewInstance = null;
      try {
        volumeViewInstance = it.next();
        String volumeNativeGuid =
            getVolumeViewNativeGuid(volumeViewInstance.getObjectPath(), keyMap);

        Volume volume = checkStorageVolumeExistsInDB(volumeNativeGuid, _dbClient);
        if (null != volume) {
          _logger.debug(
              "Skipping discovery, as this Volume {} is already being managed by ViPR.",
              volumeNativeGuid);
          continue;
        }

        // skip non-bound volumes for this pool
        if (boundVolumes != null) {
          String deviceId = null;
          if (system.getUsingSmis80()) {
            deviceId = volumeViewInstance.getObjectPath().getKey(DEVICE_ID).getValue().toString();
          } else {
            deviceId = volumeViewInstance.getObjectPath().getKey(SVDEVICEID).getValue().toString();
          }
          if (!boundVolumes.contains(deviceId)) {
            _logger.info(
                "Skipping volume, as this Volume {} is not bound to this Thin Storage Pool {}",
                volumeNativeGuid,
                pool.getLabel());
            continue;
          }
        }

        addPath(keyMap, operation.get_result(), volumeViewInstance.getObjectPath());
        String unManagedVolumeNativeGuid =
            getUnManagedVolumeNativeGuid(volumeViewInstance.getObjectPath(), keyMap);

        UnManagedVolume unManagedVolume =
            checkUnManagedVolumeExistsInDB(unManagedVolumeNativeGuid, _dbClient);
        unManagedVolume =
            createUnManagedVolume(
                unManagedVolume,
                volumeViewInstance,
                unManagedVolumeNativeGuid,
                pool,
                system,
                volumeNativeGuid,
                exportedVolumes,
                existingVolumesInCG,
                volumeToRAGroupMap,
                volumeToLocalReplicaMap,
                poolSupportedSLONames,
                keyMap);

        // set up UnManagedExportMask information

        @SuppressWarnings("unchecked")
        Map<String, Set<UnManagedExportMask>> masksMap =
            (Map<String, Set<UnManagedExportMask>>)
                keyMap.get(Constants.UNMANAGED_EXPORT_MASKS_MAP);
        if (masksMap != null) {

          Set<UnManagedExportMask> uems = masksMap.get(unManagedVolume.getNativeGuid());
          if (uems != null) {
            _logger.info(
                "{} UnManagedExportMasks found in the keyMap for volume {}",
                uems.size(),
                unManagedVolume.getNativeGuid());
            for (UnManagedExportMask uem : uems) {
              _logger.info(
                  "   adding UnManagedExportMask {} to UnManagedVolume", uem.getMaskingViewPath());
              unManagedVolume.getUnmanagedExportMasks().add(uem.getId().toString());
              uem.getUnmanagedVolumeUris().add(unManagedVolume.getId().toString());
              _unManagedExportMasksUpdate.add(uem);

              // add the known initiators, too
              for (String initUri : uem.getKnownInitiatorUris()) {
                _logger.info("   adding known Initiator URI {} to UnManagedVolume", initUri);
                unManagedVolume.getInitiatorUris().add(initUri);
                Initiator init = _dbClient.queryObject(Initiator.class, URI.create(initUri));
                unManagedVolume.getInitiatorNetworkIds().add(init.getInitiatorPort());
              }

              // log this info for debugging
              for (String path : uem.getUnmanagedInitiatorNetworkIds()) {
                _logger.info("   UnManagedExportMask has this initiator unknown to ViPR: {}", path);
              }

              // check if this volume is in a vplex backend mask
              // and mark it as such if it is
              Object o = keyMap.get(Constants.UNMANAGED_VPLEX_BACKEND_MASKS_SET);
              if (o != null) {
                Set<String> unmanagedVplexBackendMasks = (Set<String>) o;
                if (unmanagedVplexBackendMasks.size() > 0) {
                  if (unmanagedVplexBackendMasks.contains(uem.getId().toString())) {
                    _logger.info(
                        "unmanaged volume {} is a vplex backend volume",
                        unManagedVolume.getLabel());
                    unManagedVolume.putVolumeCharacterstics(
                        SupportedVolumeCharacterstics.IS_VPLEX_BACKEND_VOLUME.toString(), "true");
                  }
                }
              }
            }
          }
        }
        _logger.debug(
            "Going to check if the volume is meta: {}, volume meta property: {}",
            volumeViewInstance.getObjectPath(),
            unManagedVolume
                .getVolumeCharacterstics()
                .get(SupportedVolumeCharacterstics.IS_METAVOLUME.toString()));
        // Check if the volume is meta volume and add it to the meta
        // volume list
        String isMetaVolume =
            unManagedVolume
                .getVolumeCharacterstics()
                .get(SupportedVolumeCharacterstics.IS_METAVOLUME.toString());
        if (null != isMetaVolume && Boolean.valueOf(isMetaVolume)) {
          if (keyMap.containsKey(Constants.IS_NEW_SMIS_PROVIDER)
              && Boolean.valueOf(keyMap.get(Constants.IS_NEW_SMIS_PROVIDER).toString())) {
            metaVolumes.add(volumeViewInstance.getObjectPath());
          } else {
            metaVolumeViews.add(volumeViewInstance.getObjectPath());
          }

          _logger.info(
              "Found meta volume: {}, name: {}",
              volumeViewInstance.getObjectPath(),
              unManagedVolume.getLabel());
        }

        // if volumes size reaches 200 , then dump to Db.
        if (_unManagedVolumesInsert.size() > BATCH_SIZE) {
          _partitionManager.insertInBatches(
              _unManagedVolumesInsert, getPartitionSize(keyMap), _dbClient, UNMANAGED_VOLUME);
          _unManagedVolumesInsert.clear();
        }

        if (_unManagedVolumesUpdate.size() > BATCH_SIZE) {
          _partitionManager.updateInBatches(
              _unManagedVolumesUpdate, getPartitionSize(keyMap), _dbClient, UNMANAGED_VOLUME);
          _unManagedVolumesUpdate.clear();
        }

        if (_unManagedExportMasksUpdate.size() > BATCH_SIZE) {
          _partitionManager.updateInBatches(
              _unManagedExportMasksUpdate,
              getPartitionSize(keyMap),
              _dbClient,
              UNMANAGED_EXPORT_MASK);
          _unManagedExportMasksUpdate.clear();
        }

        unManagedVolumesReturnedFromProvider.add(unManagedVolume.getId());

      } catch (Exception ex) {
        _logger.error(
            "Processing UnManaged Storage Volume {} ", volumeViewInstance.getObjectPath(), ex);
      }
    }

    // Add meta volumes to the keyMap
    try {
      if (metaVolumes != null && !metaVolumes.isEmpty()) {
        _metaVolumePaths.addAll(metaVolumes);
        _logger.info("Added {} meta volumes.", metaVolumes.size());
      }

      if (metaVolumeViews != null && !metaVolumeViews.isEmpty()) {
        _metaVolumeViewPaths.addAll(metaVolumeViews);
        _logger.info("Added {} meta volume views.", metaVolumeViews.size());
      }
    } catch (Exception ex) {
      _logger.error("Processing UnManaged meta volumes.", ex);
    }
  }