Example usage for com.google.common.collect Multimap containsValue

List of usage examples for com.google.common.collect Multimap containsValue

Introduction

In this page you can find the example usage for com.google.common.collect Multimap containsValue.

Prototype

boolean containsValue(@Nullable Object value);

Source Link

Document

Returns true if this multimap contains at least one key-value pair with the value value .

Usage

From source file:com.google.devtools.build.xcode.util.Containing.java

public static <V> boolean value(Multimap<?, V> map, V value) {
    checkNotNull(value);/*from   www .  j  a va 2 s. c  om*/
    return map.containsValue(value);
}

From source file:com.google.devtools.j2objc.translate.TypeSorter.java

public static void sortTypes(CompilationUnit unit) {
    List<AbstractTypeDeclaration> typeNodes = unit.getTypes();
    Map<String, AbstractTypeDeclaration> nodeMap = Maps.newHashMap();
    LinkedHashMap<String, ITypeBinding> bindingMap = Maps.newLinkedHashMap();
    for (AbstractTypeDeclaration node : typeNodes) {
        ITypeBinding typeBinding = node.getTypeBinding();
        String key = typeBinding.getKey();
        nodeMap.put(key, node);/*from  ww  w. j av a 2  s. c  o m*/
        bindingMap.put(key, typeBinding);
    }
    Multimap<String, String> superTypes = findSuperTypes(bindingMap);

    ArrayList<String> rootTypes = Lists.newArrayListWithCapacity(typeNodes.size());
    for (String type : bindingMap.keySet()) {
        if (!superTypes.containsValue(type)) {
            rootTypes.add(type);
        }
    }

    typeNodes.clear();
    while (!rootTypes.isEmpty()) {
        String nextType = rootTypes.remove(rootTypes.size() - 1);
        typeNodes.add(0, nodeMap.get(nextType));
        for (String superType : superTypes.removeAll(nextType)) {
            if (!superTypes.containsValue(superType)) {
                rootTypes.add(superType);
            }
        }
    }
}

From source file:com.b2international.snowowl.snomed.reasoner.server.classification.EquivalentConceptMerger.java

private void removeDeprecatedRelationships(final Concept conceptToKeep,
        final Collection<Concept> conceptsToRemove,
        final Multimap<String, Relationship> inboundRelationshipMap) {
    for (final Relationship inboundRelationship : Sets
            .newHashSet(inboundRelationshipMap.get(conceptToKeep.getId()))) {
        if (conceptsToRemove.contains(inboundRelationship.getSource())) {
            if (inboundRelationshipMap.containsValue(inboundRelationship)) {
                inboundRelationshipMap.remove(inboundRelationship.getDestination().getId(),
                        inboundRelationship);
            }/*  ww  w  .java  2 s  .co  m*/
            SnomedModelExtensions.removeOrDeactivate(inboundRelationship);
        }
    }

    for (final Relationship outboundRelationship : newArrayList(conceptToKeep.getOutboundRelationships())) {
        if (conceptsToRemove.contains(outboundRelationship.getDestination())) {
            if (inboundRelationshipMap.containsValue(outboundRelationship)) {
                inboundRelationshipMap.remove(outboundRelationship.getDestination().getId(),
                        outboundRelationship);
            }
            SnomedModelExtensions.removeOrDeactivate(outboundRelationship);
        }
    }
}

From source file:com.zyxist.dirtyplayground.core.svc.ServiceComposer.java

public List<StartableService> compose(Set<StartableService> unorderedServices) {
    Multimap<Class<?>, StartableService> servicesReachableFrom = findServiceReachabilityGraph(
            unorderedServices);//  w  ww.  j  a  v a 2 s.co m
    Deque<StartableService> toProcess = findRoots(unorderedServices);
    List<StartableService> output = new ArrayList<>(unorderedServices.size());

    while (!toProcess.isEmpty()) {
        StartableService svc = toProcess.poll();
        output.add(svc);

        findProvidedService(svc).ifPresent((provided) -> {
            Iterator<StartableService> reachableServices = servicesReachableFrom.get(provided).iterator();
            while (reachableServices.hasNext()) {
                StartableService reachable = reachableServices.next();
                reachableServices.remove();
                if (!servicesReachableFrom.containsValue(reachable)) {
                    toProcess.add(reachable);
                }
            }
        });
    }
    if (!servicesReachableFrom.isEmpty()) {
        throw new RuntimeException("Cycle detected in services!");
    }
    return output;
}

From source file:com.haulmont.cuba.core.app.importexport.EntityImportExport.java

protected void importOneToManyCollectionAttribute(Entity srcEntity, Entity dstEntity,
        EntityImportViewProperty importViewProperty, View regularView, CommitContext commitContext,
        Collection<ReferenceInfo> referenceInfoList) {
    String propertyName = importViewProperty.getName();
    MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(propertyName);
    MetaProperty inverseMetaProperty = metaProperty.getInverse();

    //filteredItems collection will contain entities filtered by the row-level security
    Multimap<String, Object> filteredItems = ArrayListMultimap.create();
    if (srcEntity instanceof BaseGenericIdEntity) {
        String storeName = metadata.getTools().getStoreName(srcEntity.getMetaClass());
        DataStore dataStore = storeFactory.get(storeName);
        //row-level security works only for entities from RdbmsStore
        if (dataStore instanceof RdbmsStore) {
            filteredItems = BaseEntityInternalAccess.getFilteredData(srcEntity);
        }/*  w w w  . j a  v  a2 s .com*/
    }

    Collection<Entity> srcPropertyValue = srcEntity.getValue(propertyName);
    Collection<Entity> dstPropertyValue = dstEntity.getValue(propertyName);
    if (dstPropertyValue == null)
        dstPropertyValue = new ArrayList<>();
    Collection<Entity> collection;
    try {
        collection = srcPropertyValue.getClass().newInstance();
    } catch (Exception e) {
        throw new RuntimeException("Error on import entities", e);
    }

    if (srcPropertyValue != null) {
        for (Entity srcChildEntity : srcPropertyValue) {
            if (importViewProperty.getView() != null) {
                //create new referenced entity
                Entity dstChildEntity = null;
                for (Entity _entity : dstPropertyValue) {
                    if (_entity.equals(srcChildEntity)) {
                        dstChildEntity = _entity;
                        break;
                    }
                }
                dstChildEntity = importEntity(srcChildEntity, dstChildEntity, importViewProperty.getView(),
                        regularView, commitContext, referenceInfoList);
                if (inverseMetaProperty != null) {
                    dstChildEntity.setValue(inverseMetaProperty.getName(), dstEntity);
                }
                collection.add(dstChildEntity);
            }
        }
    }

    if (importViewProperty.getCollectionImportPolicy() == CollectionImportPolicy.REMOVE_ABSENT_ITEMS) {
        Collection<? extends Entity> dstValue = dstEntity.getValue(propertyName);
        if (dstValue != null) {
            Multimap<String, Object> finalFilteredItems = filteredItems;
            List<? extends Entity> collectionItemsToRemove = dstValue.stream().filter(
                    entity -> !collection.contains(entity) && (finalFilteredItems == null || !finalFilteredItems
                            .containsValue(referenceToEntitySupport.getReferenceId(entity))))
                    .collect(Collectors.toList());
            for (Entity _entity : collectionItemsToRemove) {
                commitContext.addInstanceToRemove(_entity);
            }
        }
    }

    dstEntity.setValue(propertyName, collection);
}

From source file:com.b2international.snowowl.snomed.reasoner.server.classification.EquivalentConceptMerger.java

private void switchOutboundRelationships(final Concept conceptToKeep,
        final Collection<Concept> conceptsToRemove, final Concept conceptToRemove,
        Multimap<String, Relationship> inboundRelationshipMap, Multimap<Concept, Concept> equivalentConcepts) {
    for (final Relationship relationshipToRemove : newArrayList(conceptToRemove.getOutboundRelationships())) {
        boolean found = false;
        for (final Relationship replacementOutboundRelationship : conceptToKeep.getOutboundRelationships()) {
            if (isEquivalentOutboundRelationship(equivalentConcepts, relationshipToRemove,
                    replacementOutboundRelationship)) {
                found = true;//from w w  w  . j a  v  a  2  s.co  m
                break;
            }
        }

        if (!found) {
            if (!conceptsToRemove.contains(relationshipToRemove.getSource())) {
                final String namespace = SnomedIdentifiers.create(relationshipToRemove.getId()).getNamespace();
                final Relationship newRelationship = editingContext.buildDefaultRelationship(conceptToKeep,
                        relationshipToRemove.getType(), relationshipToRemove.getDestination(),
                        relationshipToRemove.getCharacteristicType(), relationshipToRemove.getModule(),
                        namespace);

                inboundRelationshipMap.put(newRelationship.getDestination().getId(), newRelationship);
                switchRelationship(newRelationship, relationshipToRemove);
            }
        }
        if (inboundRelationshipMap.containsValue(relationshipToRemove)) {
            inboundRelationshipMap.remove(relationshipToRemove.getDestination().getId(), relationshipToRemove);
        }
        SnomedModelExtensions.removeOrDeactivate(relationshipToRemove);
    }
}

From source file:com.b2international.snowowl.snomed.reasoner.server.classification.EquivalentConceptMerger.java

private void switchInboundRelationships(final Concept conceptToKeep, final Collection<Concept> conceptsToRemove,
        final Concept conceptToRemove, Multimap<String, Relationship> inboundRelationshipMap,
        Multimap<Concept, Concept> equivalentConcepts) {
    for (final Relationship relationshipToRemove : newArrayList(
            inboundRelationshipMap.get(conceptToRemove.getId()))) {
        boolean found = false;
        for (final Relationship replacementInboundRelationship : Sets
                .newHashSet(inboundRelationshipMap.get(conceptToKeep.getId()))) {
            if (isEquivalentInboundRelationship(equivalentConcepts, relationshipToRemove,
                    replacementInboundRelationship)) {
                found = true;/*from w  ww .ja  v a 2  s .c  om*/
                break;
            }
        }
        if (!found) {
            if (!conceptsToRemove.contains(relationshipToRemove.getSource())) {
                final String namespace = SnomedIdentifiers.create(relationshipToRemove.getId()).getNamespace();
                final Relationship newRelationship = editingContext.buildDefaultRelationship(
                        relationshipToRemove.getSource(), relationshipToRemove.getType(), conceptToKeep,
                        relationshipToRemove.getCharacteristicType(), relationshipToRemove.getModule(),
                        namespace);

                inboundRelationshipMap.put(newRelationship.getDestination().getId(), newRelationship);
                switchRelationship(newRelationship, relationshipToRemove);
            }
        }
        if (inboundRelationshipMap.containsValue(relationshipToRemove)) {
            inboundRelationshipMap.remove(relationshipToRemove.getDestination().getId(), relationshipToRemove);
        }
        SnomedModelExtensions.removeOrDeactivate(relationshipToRemove);
    }
}

From source file:com.github.rinde.rinsim.central.arrays.ArraysSolverValidator.java

/**
 * Validates the inputs for the {@link MultiVehicleArraysSolver}. This method
 * checks all properties as defined in/*  w ww .  j  a v  a2  s .c  o  m*/
 * {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 * . If the inputs are not correct an {@link IllegalArgumentException} is
 * thrown.
 * @param travelTime Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param releaseDates Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param dueDates Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param servicePairs Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param serviceTimes Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param vehicleTravelTimes Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param inventories Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param remainingServiceTimes Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param currentDestinations Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 * @param currentSolutions Parameter as specified by
 *          {@link MultiVehicleArraysSolver#solve(int[][], int[], int[], int[][], int[], int[][], int[][], int[], int[], SolutionObject[])}
 *          .
 */
public static void validateInputs(int[][] travelTime, int[] releaseDates, int[] dueDates, int[][] servicePairs,
        int[] serviceTimes, int[][] vehicleTravelTimes, int[][] inventories, int[] remainingServiceTimes,
        int[] currentDestinations, @Nullable SolutionObject[] currentSolutions) {

    validateInputs(travelTime, releaseDates, dueDates, servicePairs, serviceTimes);

    // number of vehicles v
    final int v = vehicleTravelTimes.length;
    final int n = travelTime.length;
    checkArgument(v > 0, "At least one vehicle is required.");

    checkArgument(v == remainingServiceTimes.length,
            "Expected a remainingServiceTimes array of size %s, but found one with " + "size %s.", v,
            remainingServiceTimes.length);
    checkArgument(currentDestinations.length == v,
            "The currentDestinations array should be of length v=%s, it is %s.", v, currentDestinations.length);

    validateVehicleTravelTimes(v, n, vehicleTravelTimes, currentDestinations);

    final ImmutableSet.Builder<Integer> b = ImmutableSet.builder();
    for (int i = 0; i < servicePairs.length; i++) {
        b.add(servicePairs[i][0]);
        b.add(servicePairs[i][1]);
    }
    final Set<Integer> availLocs = b.build();

    final int m = n - 2 - servicePairs.length * 2;
    checkArgument(inventories.length == m, "Invalid number of inventory entries, must be equal to number of "
            + "delivery locations: %s, found: %s.", m, servicePairs.length);

    final Multimap<Integer, Integer> inventoriesMap = HashMultimap.create();
    final Set<Integer> parcelsInInventory = newHashSet();
    for (int i = 0; i < m; i++) {
        checkArgument(2 == inventories[i].length,
                "We expected inventories matrix of size m x 2, but we found m x %s " + "at index %s.",
                inventories[i].length, i);
        checkArgument(inventories[i][0] >= 0 && inventories[i][0] < v,
                "Found a reference to a non-existing vehicle (%s) in inventories at " + "row %s.",
                inventories[i][0], i);
        checkArgument(inventories[i][1] >= 1 && inventories[i][1] < n - 1,
                "Found a reference to a non-existing location (%s) in inventories at" + " row %s.",
                inventories[i][1], i);
        checkArgument(!availLocs.contains(inventories[i][1]),
                "Found a reference to a location (%s) in inventories at row %s which "
                        + "is available, as such, it can not be in the inventory.",
                inventories[i][1], i);
        checkArgument(!parcelsInInventory.contains(inventories[i][1]),
                "Found a duplicate inventory entry, first duplicate at row %s.", i);
        parcelsInInventory.add(inventories[i][1]);
        inventoriesMap.put(inventories[i][0], inventories[i][1]);
    }

    for (int i = 0; i < v; i++) {
        checkArgument(remainingServiceTimes[i] >= 0, "Remaining service time must be >= 0, found %s.",
                remainingServiceTimes[i]);
    }

    final ImmutableBiMap.Builder<Integer, Integer> servicePairsBuilder = ImmutableBiMap.builder();
    for (int i = 0; i < servicePairs.length; i++) {
        servicePairsBuilder.put(servicePairs[i][0], servicePairs[i][1]);
    }
    final ImmutableBiMap<Integer, Integer> servicePairsMap = servicePairsBuilder.build();

    for (int i = 0; i < v; i++) {
        if (remainingServiceTimes[i] != 0) {
            checkArgument(currentDestinations[i] != 0);
        }

        if (currentDestinations[i] != 0) {
            final int dest = currentDestinations[i];
            checkArgument(dest >= 1 && dest < n - 1,
                    "The destination must be a valid location, it can not be the " + "depot. It is %s.", dest);

            final boolean isAvailablePickupLoc = servicePairsMap.keySet().contains(dest);
            final boolean isInInventory = inventoriesMap.containsValue(dest);
            checkArgument(isAvailablePickupLoc != isInInventory,
                    "The destination location %s must be an available pickup location "
                            + "OR a delivery location which is in the inventory, available "
                            + "pickup loc: %s, in inventory: %s.",
                    dest, isAvailablePickupLoc, isInInventory);

            if (parcelsInInventory.contains(dest)) {
                checkArgument(inventoriesMap.get(i).contains(dest),
                        "When a vehicle is moving towards a destination which is a "
                                + "delivery location, it must contain this parcel in its "
                                + "cargo. Vehicle %s, destination %s.",
                        i, dest);
            }
        }
    }

    if (currentSolutions != null) {
        validateCurrentSolutions(v, n, currentSolutions, currentDestinations, inventoriesMap, servicePairsMap);
    }
}

From source file:brooklyn.entity.nosql.cassandra.CassandraDatacenterImpl.java

@Override
public void init() {
    super.init();

    /*/*from w  w w  .j a  va 2 s  .com*/
     * subscribe to hostname, and keep an accurate set of current seeds in a sensor;
     * then at nodes we set the initial seeds to be the current seeds when ready (non-empty)
     */
    subscribeToMembers(this, Attributes.HOSTNAME, new SensorEventListener<String>() {
        @Override
        public void onEvent(SensorEvent<String> event) {
            seedTracker.onHostnameChanged(event.getSource(), event.getValue());
        }
    });
    subscribe(this, DynamicGroup.MEMBER_REMOVED, new SensorEventListener<Entity>() {
        @Override
        public void onEvent(SensorEvent<Entity> event) {
            seedTracker.onMemberRemoved(event.getValue());
        }
    });
    subscribeToMembers(this, Attributes.SERVICE_UP, new SensorEventListener<Boolean>() {
        @Override
        public void onEvent(SensorEvent<Boolean> event) {
            seedTracker.onServiceUpChanged(event.getSource(), event.getValue());
        }
    });
    subscribeToMembers(this, Attributes.SERVICE_STATE_ACTUAL, new SensorEventListener<Lifecycle>() {
        @Override
        public void onEvent(SensorEvent<Lifecycle> event) {
            // trigger a recomputation also when lifecycle state changes, 
            // because it might not have ruled a seed as inviable when service up went true 
            // because service state was not yet running
            seedTracker.onServiceUpChanged(event.getSource(), Lifecycle.RUNNING == event.getValue());
        }
    });

    // Track the datacenters for this cluster
    subscribeToMembers(this, CassandraNode.DATACENTER_NAME, new SensorEventListener<String>() {
        @Override
        public void onEvent(SensorEvent<String> event) {
            Entity member = event.getSource();
            String dcName = event.getValue();
            if (dcName != null) {
                Multimap<String, Entity> datacenterUsage = getAttribute(DATACENTER_USAGE);
                Multimap<String, Entity> mutableDatacenterUsage = (datacenterUsage == null)
                        ? LinkedHashMultimap.<String, Entity>create()
                        : LinkedHashMultimap.create(datacenterUsage);
                Optional<String> oldDcName = getKeyOfVal(mutableDatacenterUsage, member);
                if (!(oldDcName.isPresent() && dcName.equals(oldDcName.get()))) {
                    mutableDatacenterUsage.values().remove(member);
                    mutableDatacenterUsage.put(dcName, member);
                    setAttribute(DATACENTER_USAGE, mutableDatacenterUsage);
                    setAttribute(DATACENTERS, Sets.newLinkedHashSet(mutableDatacenterUsage.keySet()));
                }
            }
        }

        private <K, V> Optional<K> getKeyOfVal(Multimap<K, V> map, V val) {
            for (Map.Entry<K, V> entry : map.entries()) {
                if (Objects.equal(val, entry.getValue())) {
                    return Optional.of(entry.getKey());
                }
            }
            return Optional.absent();
        }
    });
    subscribe(this, DynamicGroup.MEMBER_REMOVED, new SensorEventListener<Entity>() {
        @Override
        public void onEvent(SensorEvent<Entity> event) {
            Entity entity = event.getSource();
            Multimap<String, Entity> datacenterUsage = getAttribute(DATACENTER_USAGE);
            if (datacenterUsage != null && datacenterUsage.containsValue(entity)) {
                Multimap<String, Entity> mutableDatacenterUsage = LinkedHashMultimap.create(datacenterUsage);
                mutableDatacenterUsage.values().remove(entity);
                setAttribute(DATACENTER_USAGE, mutableDatacenterUsage);
                setAttribute(DATACENTERS, Sets.newLinkedHashSet(mutableDatacenterUsage.keySet()));
            }
        }
    });

    getMutableEntityType().addEffector(EXECUTE_SCRIPT, new EffectorBody<String>() {
        @Override
        public String call(ConfigBag parameters) {
            return executeScript((String) parameters.getStringKey("commands"));
        }
    });
}

From source file:org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenterImpl.java

@Override
public void init() {
    super.init();

    /*// ww  w. j a  va 2s . c  o  m
     * subscribe to hostname, and keep an accurate set of current seeds in a sensor;
     * then at nodes we set the initial seeds to be the current seeds when ready (non-empty)
     */
    subscriptions().subscribeToMembers(this, Attributes.HOSTNAME, new SensorEventListener<String>() {
        @Override
        public void onEvent(SensorEvent<String> event) {
            seedTracker.onHostnameChanged(event.getSource(), event.getValue());
        }
    });
    subscriptions().subscribe(this, DynamicGroup.MEMBER_REMOVED, new SensorEventListener<Entity>() {
        @Override
        public void onEvent(SensorEvent<Entity> event) {
            seedTracker.onMemberRemoved(event.getValue());
        }
    });
    subscriptions().subscribeToMembers(this, Attributes.SERVICE_UP, new SensorEventListener<Boolean>() {
        @Override
        public void onEvent(SensorEvent<Boolean> event) {
            seedTracker.onServiceUpChanged(event.getSource(), event.getValue());
        }
    });
    subscriptions().subscribeToMembers(this, Attributes.SERVICE_STATE_ACTUAL,
            new SensorEventListener<Lifecycle>() {
                @Override
                public void onEvent(SensorEvent<Lifecycle> event) {
                    // trigger a recomputation also when lifecycle state changes, 
                    // because it might not have ruled a seed as inviable when service up went true 
                    // because service state was not yet running
                    seedTracker.onServiceUpChanged(event.getSource(), Lifecycle.RUNNING == event.getValue());
                }
            });

    // Track the datacenters for this cluster
    subscriptions().subscribeToMembers(this, CassandraNode.DATACENTER_NAME, new SensorEventListener<String>() {
        @Override
        public void onEvent(SensorEvent<String> event) {
            Entity member = event.getSource();
            String dcName = event.getValue();
            if (dcName != null) {
                Multimap<String, Entity> datacenterUsage = getAttribute(DATACENTER_USAGE);
                Multimap<String, Entity> mutableDatacenterUsage = (datacenterUsage == null)
                        ? LinkedHashMultimap.<String, Entity>create()
                        : LinkedHashMultimap.create(datacenterUsage);
                Optional<String> oldDcName = getKeyOfVal(mutableDatacenterUsage, member);
                if (!(oldDcName.isPresent() && dcName.equals(oldDcName.get()))) {
                    mutableDatacenterUsage.values().remove(member);
                    mutableDatacenterUsage.put(dcName, member);
                    sensors().set(DATACENTER_USAGE, mutableDatacenterUsage);
                    sensors().set(DATACENTERS, Sets.newLinkedHashSet(mutableDatacenterUsage.keySet()));
                }
            }
        }

        private <K, V> Optional<K> getKeyOfVal(Multimap<K, V> map, V val) {
            for (Map.Entry<K, V> entry : map.entries()) {
                if (Objects.equal(val, entry.getValue())) {
                    return Optional.of(entry.getKey());
                }
            }
            return Optional.absent();
        }
    });
    subscriptions().subscribe(this, DynamicGroup.MEMBER_REMOVED, new SensorEventListener<Entity>() {
        @Override
        public void onEvent(SensorEvent<Entity> event) {
            Entity entity = event.getSource();
            Multimap<String, Entity> datacenterUsage = getAttribute(DATACENTER_USAGE);
            if (datacenterUsage != null && datacenterUsage.containsValue(entity)) {
                Multimap<String, Entity> mutableDatacenterUsage = LinkedHashMultimap.create(datacenterUsage);
                mutableDatacenterUsage.values().remove(entity);
                sensors().set(DATACENTER_USAGE, mutableDatacenterUsage);
                sensors().set(DATACENTERS, Sets.newLinkedHashSet(mutableDatacenterUsage.keySet()));
            }
        }
    });

    getMutableEntityType().addEffector(EXECUTE_SCRIPT, new EffectorBody<String>() {
        @Override
        public String call(ConfigBag parameters) {
            return executeScript((String) parameters.getStringKey("commands"));
        }
    });
}