@Override
 public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap)
     throws BaseCollectionException {
   try {
     CIMInstance modifiedInstance = (CIMInstance) resultObj;
     addInstance(keyMap, operation.getResult(), modifiedInstance);
   } catch (Exception e) {
     _logger.error("Error while modifying Pool Setting", e);
   }
 }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap)
      throws BaseCollectionException {
    try {
      final Iterator<CIMInstance> it = (Iterator<CIMInstance>) resultObj;
      profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE);
      Set<String> protocols = (Set<String>) keyMap.get(Constants.PROTOCOLS);
      _newPortList = new ArrayList<StoragePort>();
      _updatePortList = new ArrayList<StoragePort>();
      _dbClient = (DbClient) keyMap.get(Constants.dbClient);
      CoordinatorClient coordinator = (CoordinatorClient) keyMap.get(Constants.COORDINATOR_CLIENT);
      Map<URI, StoragePool> poolsToMatchWithVpool =
          (Map<URI, StoragePool>) keyMap.get(Constants.MODIFIED_STORAGEPOOLS);
      Set<URI> systemsToRunRPConnectivity =
          (HashSet<URI>) keyMap.get(Constants.SYSTEMS_RUN_RP_CONNECTIVITY);
      StorageSystem device = _dbClient.queryObject(StorageSystem.class, profile.getSystemId());
      CIMObjectPath storageAdapterPath = getObjectPathfromCIMArgument(args);
      Iterable<String> adapterItr =
          Splitter.on(Constants.PATH_DELIMITER_PATTERN)
              .limit(3)
              .split(storageAdapterPath.getKey(Constants.NAME).getValue().toString());
      String adapterNativeGuid =
          NativeGUIDGenerator.generateNativeGuid(
              device, Iterables.getLast(adapterItr), NativeGUIDGenerator.ADAPTER);
      StorageHADomain haDomain = getStorageAdapter(_dbClient, adapterNativeGuid);
      if (null == haDomain) {
        _logger.info("Adapter Not found");
        return;
      }

      while (it.hasNext()) {
        CIMInstance portInstance = null;
        StoragePort port = null;
        try {
          portInstance = it.next();

          // skip back end ports other than RDF Ports
          if (!HADomainType.REMOTE.name().equalsIgnoreCase(haDomain.getAdapterType())
              && "3".equalsIgnoreCase(getCIMPropertyValue(portInstance, USAGERESTRICTION))) {
            continue;
          }
          // only if its an EthernetPort, as protocolEnd point needs
          // to run only for Ethernet
          // Ports , because SCSI address we don't have it in
          // CIM_LogicalPort Class
          // 2 - Ethernet Port 4 - FC Port
          if ("2".equalsIgnoreCase(getCIMPropertyValue(portInstance, LINKTECHNOLOGY))) {
            port = createStoragePort(null, portInstance, profile, haDomain, false, IP, device);
            checkProtocolAlreadyExists(protocols, ISCSI);
            String deviceId = getCIMPropertyValue(portInstance, DEVICEID);
            /*
             * For SMI-S 8.x, While getting the iSCSI Port details, we use SystemName property
             * (Ex. SYMMETRIX-+-<<SERIAL>>-+-SE-1G-+-0)
             * Where this call just add the deviceId to the KeyMap (i.e SE-1G-+-0).
             * Hence manually constructing the key.
             */
            if (device.getUsingSmis80()) {
              String systemName = getCIMPropertyValue(portInstance, SYSTEM_NAME);
              StringBuffer deviceIdStrBuf = new StringBuffer(systemName);
              deviceIdStrBuf.append(Constants.SMIS80_DELIMITER).append(deviceId);
              deviceId = deviceIdStrBuf.toString();
            }
            _logger.debug("Adding iSCSI Port instance {} to keyMap", deviceId);
            keyMap.put(deviceId, port);
            addPath(keyMap, operation.getResult(), portInstance.getObjectPath());
          } else if ("4".equalsIgnoreCase(getCIMPropertyValue(portInstance, LINKTECHNOLOGY))) {
            port = checkStoragePortExistsInDB(portInstance, device, _dbClient);
            checkProtocolAlreadyExists(protocols, FC);
            createStoragePort(port, portInstance, profile, haDomain, true, FC, device);
          } else {
            _logger.debug("Unsupported Port : {}", getCIMPropertyValue(portInstance, DEVICEID));
          }

        } catch (Exception e) {
          _logger.warn(
              "Port Discovery failed for {}", getCIMPropertyValue(portInstance, DEVICEID), e);
        }
      }
      _dbClient.createObject(_newPortList);
      _dbClient.persistObject(_updatePortList);

      // ports used later to run Transport Zone connectivity
      List<List<StoragePort>> portsUsedToRunTZoneConnectivity =
          (List<List<StoragePort>>) keyMap.get(Constants.STORAGE_PORTS);
      portsUsedToRunTZoneConnectivity.add(_newPortList);
      portsUsedToRunTZoneConnectivity.add(_updatePortList);

      List<StoragePool> modifiedPools =
          StoragePoolAssociationHelper.getStoragePoolsFromPorts(
              _dbClient, _newPortList, _updatePortList);
      for (StoragePool pool : modifiedPools) {
        // pool matcher will be invoked on this pool
        if (!poolsToMatchWithVpool.containsKey(pool.getId())) {
          poolsToMatchWithVpool.put(pool.getId(), pool);
        }
      }

      // Systems used to run RP connectivity later after runing pool matcher
      systemsToRunRPConnectivity.addAll(
          StoragePoolAssociationHelper.getStorageSytemsFromPorts(_newPortList, null));
      systemsToRunRPConnectivity.addAll(
          StoragePoolAssociationHelper.getStorageSytemsFromPorts(_updatePortList, null));

      // discovered ports used later to check for not visible ports
      List<StoragePort> discoveredPorts =
          (List<StoragePort>) keyMap.get(Constants.DISCOVERED_PORTS);
      discoveredPorts.addAll(_newPortList);
      discoveredPorts.addAll(_updatePortList);

      _logger.debug(
          "# Pools used in invoking PoolMatcher during StoragePortProcessor {}",
          Joiner.on("\t").join(poolsToMatchWithVpool.keySet()));
    } catch (Exception e) {
      _logger.error("Port Discovery failed -->{}", getMessage(e));
    } finally {
      _newPortList = null;
      _updatePortList = null;
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap)
      throws BaseCollectionException {
    final Iterator<CIMInstance> it = (Iterator<CIMInstance>) resultObj;
    profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE);
    try {
      _newPoolList = new ArrayList<StoragePool>();
      _updatePoolList = new ArrayList<StoragePool>();
      _dbClient = (DbClient) keyMap.get(Constants.dbClient);
      _cimClient = (WBEMClient) keyMap.get(Constants._cimClient);
      _coordinator = (CoordinatorClient) keyMap.get(Constants.COORDINATOR_CLIENT);
      _eventManager = (RecordableEventManager) keyMap.get(Constants.EVENT_MANAGER);
      _logger.info("StoragePoolProcessor --- event manager: " + _eventManager);
      StorageSystem device = getStorageSystem(_dbClient, profile.getSystemId());
      if (SupportedProvisioningTypes.NONE
          .toString()
          .equalsIgnoreCase(device.getSupportedProvisioningType())) {
        _logger.info(
            "Storage System doesn't support volume creations :" + device.getSerialNumber());
        return;
      }
      Set<String> protocols = (Set<String>) keyMap.get(Constants.PROTOCOLS);
      Map<URI, StoragePool> poolsToMatchWithVpool =
          (Map<URI, StoragePool>) keyMap.get(Constants.MODIFIED_STORAGEPOOLS);
      while (it.hasNext()) {
        CIMInstance poolInstance = null;
        try {
          poolInstance = it.next();

          // Supporting both thick and thin pools
          String[] poolClassNameAndSupportedVolumeTypes =
              determinePoolClassNameAndSupportedVolumeTypes(poolInstance, device);
          if (null != poolClassNameAndSupportedVolumeTypes) {
            String instanceID = getCIMPropertyValue(poolInstance, Constants.INSTANCEID);
            addPath(keyMap, operation.getResult(), poolInstance.getObjectPath());
            StoragePool pool =
                checkStoragePoolExistsInDB(getNativeIDFromInstance(instanceID), _dbClient, device);
            createStoragePool(
                pool,
                poolInstance,
                profile,
                poolClassNameAndSupportedVolumeTypes[0],
                poolClassNameAndSupportedVolumeTypes[1],
                protocols,
                poolsToMatchWithVpool,
                device);

            if (DiscoveredDataObject.Type.vnxblock
                .toString()
                .equalsIgnoreCase(device.getSystemType())) {
              addPath(keyMap, Constants.VNXPOOLS, poolInstance.getObjectPath());
            }

            if (DiscoveredDataObject.Type.vmax
                .toString()
                .equalsIgnoreCase(device.getSystemType())) {
              addPath(keyMap, Constants.VMAXPOOLS, poolInstance.getObjectPath());
              if (!device.checkIfVmax3()) {
                addPath(keyMap, Constants.VMAX2POOLS, poolInstance.getObjectPath());
              }
            }
            // This approach deviates from the existing built plugin framework for plugin
            // Discovery
            // To follow the existing pattern, we need to have different SMI-S calls
            // 1st to get Device StoragePools alone ,and 2nd to get Thin Pools.
            // Its a tradeoff between whether to go with the current plugin design or
            // reduce the number of calls to SMI Provider.
            // I chose the 2nd option.
            if (!poolClassNameAndSupportedVolumeTypes[0].contains(DEVICE_STORAGE_POOL)) {
              addPath(keyMap, Constants.THINPOOLS, poolInstance.getObjectPath());
            }

            addPath(keyMap, Constants.DEVICEANDTHINPOOLS, poolInstance.getObjectPath());
          } else {
            _logger.debug(
                "Skipping Pools other than Unified & Virtual & Device : {}",
                poolInstance.getObjectPath().toString());
          }
        } catch (Exception e) {
          _logger.warn(
              "StoragePool Discovery failed for {}",
              getCIMPropertyValue(poolInstance, Constants.INSTANCEID),
              e);
        }
      }

      _dbClient.createObject(_newPoolList);
      _dbClient.updateAndReindexObject(_updatePoolList);

      // find the pools not visible in this discovery
      List<StoragePool> discoveredPools = new ArrayList<StoragePool>(_newPoolList);
      discoveredPools.addAll(_updatePoolList);
      List<StoragePool> notVisiblePools =
          DiscoveryUtils.checkStoragePoolsNotVisible(discoveredPools, _dbClient, device.getId());
      for (StoragePool notVisiblePool : notVisiblePools) {
        poolsToMatchWithVpool.put(notVisiblePool.getId(), notVisiblePool);
      }
      // If any storage ports on the storage system are in a transport
      // zone, there is an implicit connection to the transport zone
      // varray. We need to add these implicit varray
      // connections for the new storage pool.
      StoragePoolAssociationHelper.setStoragePoolVarrays(device.getId(), _newPoolList, _dbClient);
    } catch (Exception e) {
      _logger.error("StoragePool Discovery failed --> {}", getMessage(e));
    } finally {
      _newPoolList = null;
      _updatePoolList = null;
    }
  }