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

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

Introduction

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

Prototype

boolean containsKey(@Nullable Object key);

Source Link

Document

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

Usage

From source file:com.facebook.buck.cli.FineGrainedJavaDependencySuggester.java

/**
 * Suggests a refactoring by printing it to stdout (with warnings printed to stderr).
 * @throws IllegalArgumentException// www  .  ja va  2  s .c  o m
 */
void suggestRefactoring() {
    final TargetNode<?, ?> suggestedNode = graph.get(suggestedTarget);
    if (!(suggestedNode.getConstructorArg() instanceof JavaLibraryDescription.Arg)) {
        console.printErrorText(String.format("'%s' does not correspond to a Java rule", suggestedTarget));
        throw new IllegalArgumentException();
    }

    JavaLibraryDescription.Arg arg = (JavaLibraryDescription.Arg) suggestedNode.getConstructorArg();
    JavaFileParser javaFileParser = javaDepsFinder.getJavaFileParser();
    Multimap<String, String> providedSymbolToRequiredSymbols = HashMultimap.create();
    Map<String, PathSourcePath> providedSymbolToSrc = new HashMap<>();
    for (SourcePath src : arg.srcs) {
        extractProvidedSymbolInfoFromSourceFile(src, javaFileParser, providedSymbolToRequiredSymbols,
                providedSymbolToSrc);
    }

    // Create a MutableDirectedGraph from the providedSymbolToRequiredSymbols.
    MutableDirectedGraph<String> symbolsDependencies = new MutableDirectedGraph<>();
    // Iterate the keys of providedSymbolToSrc rather than providedSymbolToRequiredSymbols because
    // providedSymbolToRequiredSymbols will not have any entries for providedSymbols with no
    // dependencies.
    for (String providedSymbol : providedSymbolToSrc.keySet()) {
        // Add a node for the providedSymbol in case it has no edges.
        symbolsDependencies.addNode(providedSymbol);
        for (String requiredSymbol : providedSymbolToRequiredSymbols.get(providedSymbol)) {
            if (providedSymbolToRequiredSymbols.containsKey(requiredSymbol)
                    && !providedSymbol.equals(requiredSymbol)) {
                symbolsDependencies.addEdge(providedSymbol, requiredSymbol);
            }
        }
    }

    // Determine the strongly connected components.
    Set<Set<String>> stronglyConnectedComponents = symbolsDependencies.findStronglyConnectedComponents();
    // Maps a providedSymbol to the component that contains it.
    Map<String, NamedStronglyConnectedComponent> namedComponentsIndex = new TreeMap<>();
    Set<NamedStronglyConnectedComponent> namedComponents = new TreeSet<>();
    for (Set<String> stronglyConnectedComponent : stronglyConnectedComponents) {
        // We just use the first provided symbol in the strongly connected component as the canonical
        // name for the component. Maybe not the best name, but certainly not the worst.
        String name = Iterables.getFirst(stronglyConnectedComponent, /* defaultValue */ null);
        if (name == null) {
            throw new IllegalStateException("A strongly connected component was created with zero nodes.");
        }

        NamedStronglyConnectedComponent namedComponent = new NamedStronglyConnectedComponent(name,
                stronglyConnectedComponent);
        namedComponents.add(namedComponent);
        for (String providedSymbol : stronglyConnectedComponent) {
            namedComponentsIndex.put(providedSymbol, namedComponent);
        }
    }

    // Visibility argument.
    StringBuilder visibilityBuilder = new StringBuilder("  visibility = [\n");
    SortedSet<String> visibilities = FluentIterable.from(suggestedNode.getVisibilityPatterns())
            .transform(VisibilityPattern::getRepresentation).toSortedSet(Ordering.natural());
    for (String visibility : visibilities) {
        visibilityBuilder.append("    '" + visibility + "',\n");
    }
    visibilityBuilder.append("  ],\n");
    String visibilityArg = visibilityBuilder.toString();

    // Print out the new version of the original rule.
    console.getStdOut().printf("java_library(\n" + "  name = '%s',\n" + "  exported_deps = [\n",
            suggestedTarget.getShortName());
    for (NamedStronglyConnectedComponent namedComponent : namedComponents) {
        console.getStdOut().printf("    ':%s',\n", namedComponent.name);
    }
    console.getStdOut().print("  ],\n" + visibilityArg + ")\n");

    // Print out a rule for each of the strongly connected components.
    JavaDepsFinder.DependencyInfo dependencyInfo = javaDepsFinder.findDependencyInfoForGraph(graph);
    for (NamedStronglyConnectedComponent namedComponent : namedComponents) {
        String buildRuleDefinition = createBuildRuleDefinition(namedComponent, providedSymbolToSrc,
                providedSymbolToRequiredSymbols, namedComponentsIndex, dependencyInfo, symbolsDependencies,
                visibilityArg);
        console.getStdOut().print(buildRuleDefinition);
    }
}

From source file:org.jboss.errai.ioc.rebind.ioc.graph.impl.DependencyGraphBuilderImpl.java

private Injectable resolveDependency(final BaseDependency dep, final Injectable concrete,
        final Collection<String> problems, final Map<String, Injectable> customProvidedInjectables) {
    if (dep.injectable.resolution != null) {
        return dep.injectable.resolution;
    }/*  ww  w  . ja v  a2  s  . c om*/

    final Multimap<ResolutionPriority, ConcreteInjectable> resolvedByPriority = HashMultimap.create();
    final Queue<AbstractInjectable> resolutionQueue = new LinkedList<AbstractInjectable>();
    resolutionQueue.add(dep.injectable);
    resolutionQueue.add(addMatchingExactTypeInjectables(dep.injectable));

    processResolutionQueue(resolutionQueue, resolvedByPriority);

    // Iterates through priorities from highest to lowest.
    for (final ResolutionPriority priority : ResolutionPriority.values()) {
        if (resolvedByPriority.containsKey(priority)) {
            final Collection<ConcreteInjectable> resolved = resolvedByPriority.get(priority);
            if (resolved.size() > 1) {
                problems.add(
                        ambiguousDependencyMessage(dep, concrete, new ArrayList<ConcreteInjectable>(resolved)));
                return null;
            } else {
                Injectable injectable = resolved.iterator().next();
                if (injectable.isExtension()) {
                    final ExtensionInjectable providedInjectable = (ExtensionInjectable) injectable;
                    final Collection<Injectable> otherResolvedInjectables = new ArrayList<Injectable>(
                            resolvedByPriority.values());
                    otherResolvedInjectables.remove(injectable);

                    final InjectionSite site = new InjectionSite(concrete.getInjectedType(), getAnnotated(dep),
                            otherResolvedInjectables);
                    injectable = providedInjectable.provider.getInjectable(site, nameGenerator);
                    customProvidedInjectables.put(injectable.getFactoryName(), injectable);
                    dep.injectable = copyAbstractInjectable(dep.injectable);
                }
                return (dep.injectable.resolution = injectable);
            }
        }
    }

    problems.add(unsatisfiedDependencyMessage(dep, concrete));
    return null;
}

From source file:net.diogobohm.timed.impl.hamster.migration.HamsterMigration.java

private Map<Integer, Task> loadTasks(SqlJetDb hamsterDb, Map<Integer, Activity> activityMap,
        Map<Activity, Project> activityProjects, Multimap<Integer, Tag> taskTags) throws SqlJetException {
    Map<Integer, Task> tasks = Maps.newHashMap();
    ISqlJetTable tasksTable = hamsterDb.getTable("facts");
    ISqlJetCursor tasksCursor = tasksTable.order(tasksTable.getPrimaryKeyIndexName());

    if (!tasksCursor.eof()) {
        do {/*from  w  ww  .  ja  v a2 s  . com*/
            Integer activityId = fromLong(tasksCursor.getInteger("activity_id"));
            Activity activity = activityMap.get(activityId);
            Project project = activityProjects.get(activity);

            Integer id = fromLong(tasksCursor.getInteger("id"));
            String description = tasksCursor.getString("description");
            String start = tasksCursor.getString("start_time");
            String end = tasksCursor.getString("end_time");

            Date startTime = parseTime(start);
            Optional<Date> endTime = Optional.absent();
            if (!tasksCursor.isNull("end_time")) {
                if (start.equals(end)) {
                    System.out.println("BAAAAD");
                }
                endTime = Optional.of(parseTime(end));
            }

            Set<Tag> tags = Sets.newHashSet();
            if (taskTags.containsKey(id)) {
                tags.addAll(taskTags.get(id));
            }

            tasks.put(id, new Task(activity, project, startTime, endTime, description, tags));
        } while (tasksCursor.next());
    }

    return tasks;
}

From source file:org.dllearner.utilities.QueryUtils.java

public Query removeUnboundObjectVarTriples(Query query) {
    QueryUtils queryUtils = new QueryUtils();

    Var rootVar = query.getProjectVars().get(0);

    // 1. outgoing triple paths pruning
    Set<Triple> outgoingTriplePatterns = queryUtils.extractOutgoingTriplePatternsTrans(query, rootVar);
    Multimap<Var, Triple> var2OutgoingTriplePatterns = HashMultimap.create();

    // mapping from variable to triple pattern
    for (Triple tp : outgoingTriplePatterns) {
        var2OutgoingTriplePatterns.put(Var.alloc(tp.getSubject()), tp);
    }/*from   w w w.ja v a  2 s . c  o  m*/

    // remove triple patterns with object is var node and leaf node
    Iterator<Triple> iterator = outgoingTriplePatterns.iterator();
    while (iterator.hasNext()) {
        Triple triple = iterator.next();
        Node object = triple.getObject();
        if (object.isVariable() && !var2OutgoingTriplePatterns.containsKey(Var.alloc(object))) {
            iterator.remove();
        }
    }

    // 2. incoming triple paths pruning
    Set<Triple> incomingTriplePatterns = queryUtils.extractIncomingTriplePatternsTrans(query, rootVar);
    Multimap<Var, Triple> var2IncomingTriplePatterns = HashMultimap.create();

    // mapping from variable to triple pattern
    for (Triple tp : incomingTriplePatterns) {
        var2IncomingTriplePatterns.put(Var.alloc(tp.getObject()), tp);
    }

    // remove triple patterns with object is var node and leaf node
    iterator = incomingTriplePatterns.iterator();
    while (iterator.hasNext()) {
        Triple triple = iterator.next();
        Node s = triple.getSubject();
        if (s.isVariable() && !var2IncomingTriplePatterns.containsKey(Var.alloc(s))) {
            iterator.remove();
        }
    }

    Query newQuery = new Query();
    newQuery.addProjectVars(query.getProjectVars());
    ElementTriplesBlock el = new ElementTriplesBlock();
    for (Triple triple : Sets.union(outgoingTriplePatterns, incomingTriplePatterns)) {
        el.addTriple(triple);
    }
    newQuery.setQuerySelectType();
    newQuery.setDistinct(true);
    newQuery.setQueryPattern(el);

    return newQuery;
}

From source file:uk.ac.ebi.intact.editor.services.curate.cvobject.CvObjectService.java

public List<IntactCvTerm> getSortedList(String key, Multimap<String, IntactCvTerm> classMultimap) {
    if (classMultimap.containsKey(key)) {
        List<IntactCvTerm> list = new ArrayList<IntactCvTerm>(classMultimap.get(key));
        Collections.sort(list, new CvObjectComparator());
        return list;
    } else {/*from www .j ava  2s .  c o  m*/
        return new ArrayList<IntactCvTerm>();
    }
}

From source file:uk.ac.ebi.intact.editor.services.curate.cvobject.CvObjectService.java

public List<IntactCvTerm> getSortedTopicList(String key, Multimap<String, IntactCvTerm> topicMultimap) {
    if (topicMultimap.containsKey(key)) {
        List<IntactCvTerm> list = new ArrayList<IntactCvTerm>(topicMultimap.get(key));

        Collections.sort(list, new CvObjectComparator());
        return list;
    } else {/*from w w w .  j  a va  2s  . c o m*/
        return new ArrayList<IntactCvTerm>();
    }
}

From source file:com.google.auto.value.processor.BuilderMethodClassifier.java

/**
 * Classifies the given methods and sets the state of this object based on what is found.
 *///w  w  w .ja v  a 2  s .c  o  m
private boolean classifyMethods(Iterable<ExecutableElement> methods, boolean autoValueHasToBuilder) {
    boolean ok = true;
    for (ExecutableElement method : methods) {
        ok &= classifyMethod(method);
    }
    if (!ok) {
        return false;
    }
    Multimap<String, ExecutableElement> propertyNameToSetter;
    if (propertyNameToPrefixedSetters.isEmpty()) {
        propertyNameToSetter = propertyNameToUnprefixedSetters;
        this.settersPrefixed = false;
    } else if (propertyNameToUnprefixedSetters.isEmpty()) {
        propertyNameToSetter = propertyNameToPrefixedSetters;
        this.settersPrefixed = true;
    } else {
        errorReporter.reportError("If any setter methods use the setFoo convention then all must",
                propertyNameToUnprefixedSetters.values().iterator().next());
        return false;
    }
    for (Map.Entry<ExecutableElement, String> getterEntry : getterToPropertyName.entrySet()) {
        String property = getterEntry.getValue();
        String propertyType = typeSimplifier.simplify(getterEntry.getKey().getReturnType());
        boolean hasSetter = propertyNameToSetter.containsKey(property);
        PropertyBuilder propertyBuilder = propertyNameToPropertyBuilder.get(property);
        boolean hasBuilder = propertyBuilder != null;
        if (hasBuilder) {
            // If property bar of type Bar has a barBuilder() that returns BarBuilder, then it must be
            // possible to make a BarBuilder from a Bar if either (1) the @AutoValue class has a
            // toBuilder() or (2) there is also a setBar(Bar). Making BarBuilder from Bar is possible
            // if Bar either has a toBuilder() method or is a Guava immutable collection (in which case
            // we can use addAll or putAll).
            boolean canMakeBarBuilder = (propertyBuilder.getBuiltToBuilder() != null
                    || propertyBuilder.getCopyAll() != null);
            boolean needToMakeBarBuilder = (autoValueHasToBuilder || hasSetter);
            if (needToMakeBarBuilder && !canMakeBarBuilder) {
                String error = String.format(
                        "Property builder method returns %1$s but there is no way to make that type from "
                                + "%2$s: %2$s does not have a non-static toBuilder() method that returns %1$s",
                        propertyBuilder.getBuilderType(), propertyType);
                errorReporter.reportError(error, propertyBuilder.getPropertyBuilderMethod());
            }
        } else if (!hasSetter) {
            // We have neither barBuilder() nor setBar(Bar), so we should complain.
            String setterName = settersPrefixed ? prefixWithSet(property) : property;
            String error = String.format(
                    "Expected a method with this signature: %s%s %s(%s), or a %sBuilder() method", builderType,
                    typeParamsString(), setterName, propertyType, property);
            errorReporter.reportError(error, builderType);
            ok = false;
        }
    }
    return ok;
}

From source file:org.apache.s4.edsl.AppBuilder.java

private void setStreamField(ProcessingElement pe, Collection<StreamBuilder<? extends Event>> streams)
        throws Exception {

    /*/*from w  w w . j a v  a  2 s .c o  m*/
     * Create a map of the stream fields to the corresponding generic type. We will use this info to assign the
     * streams. If the field type matches the stream type and there is no ambiguity, then the assignment is easy. If
     * more than one field has the same type, then then we need to do more work.
     */
    Field[] fields = pe.getClass().getDeclaredFields();
    Multimap<String, Field> typeMap = LinkedListMultimap.create();
    logger.debug("Analyzing PE [{}].", pe.getClass().getName());
    for (Field field : fields) {
        logger.trace("Field [{}] is of generic type [{}].", field.getName(), field.getGenericType());

        if (field.getType() == Stream[].class) {
            logger.debug("Found stream field: {}", field.getGenericType());

            /* Track what fields have streams with the same event type. */
            String key = field.getGenericType().toString();
            typeMap.put(key, field);
        }
    }

    /* Assign streams to stream fields. */
    Multimap<Field, Stream<? extends Event>> assignment = LinkedListMultimap.create();
    for (StreamBuilder<? extends Event> sm : streams) {

        Stream<? extends Event> stream = sm.stream;
        Class<? extends Event> eventType = sm.type;
        String key = Stream.class.getCanonicalName() + "<" + eventType.getCanonicalName() + ">[]";
        if (typeMap.containsKey(key)) {
            String fieldName;
            Field field;
            Collection<Field> streamFields = typeMap.get(key);
            int numStreamFields = streamFields.size();
            logger.debug("Found [{}] stream fields for type [{}].", numStreamFields, key);

            if (numStreamFields > 1) {

                /*
                 * There is more than one field that can be used for this stream type. To resolve the ambiguity we
                 * need additional information. The app graph should include the name of the field that should be
                 * used to assign this stream. If the name is missing we bail out.
                 */
                fieldName = sm.fieldName;

                /* Bail out. */
                if (fieldName == null) {
                    String msg = String.format(
                            "There are [%d] stream fields in PE [%s]. To assign stream [%s] you need to provide the field name in the application graph using the method withFiled(). See Javadocs for an example.",
                            numStreamFields, pe.getClass().getName(), stream.getName());
                    logger.error(msg);
                    throw new Exception(msg);
                }

                /* Use the provided field name to choose the PE field. */
                field = pe.getClass().getDeclaredField(fieldName);

            } else {

                /*
                 * The easy case, no ambiguity, we don't need an explicit field name to be provided. We have the
                 * field that matches the stream type.
                 */
                Iterator<Field> iter = streamFields.iterator();
                field = iter.next(); // Note that numStreamFields == 1, the size of this collection is 1.
                logger.debug("Using field [{}].", field.getName());
            }

            /*
             * By now, we found the field to use for this stream or we bailed out. We are not ready to finish yet.
             * There may be more than one stream that needs to be assigned to this field. The stream fields must be
             * arrays by convention and there may be more than one stream assigned to this fields. For now we create
             * a multimap from field to streams so we can construct the array in the next step.
             */
            assignment.put(field, stream);

        } else {

            /* We couldn't find a match. Tell user to fix the EDSL code. */
            String msg = String.format(
                    "There is no stream of type [%s] in PE [%s]. I was unable to assign stream [%s].", key,
                    pe.getClass().getName(), stream.getName());
            logger.error(msg);
            throw new Exception(msg);

        }
    }
    /* Now we construct the array and do the final assignment. */

    Map<Field, Collection<Stream<? extends Event>>> assignmentMap = assignment.asMap();
    for (Map.Entry<Field, Collection<Stream<? extends Event>>> entry : assignmentMap.entrySet()) {
        Field f = entry.getKey();

        int arraySize = entry.getValue().size();
        @SuppressWarnings("unchecked")
        Stream<? extends Event> streamArray[] = (Stream<? extends Event>[]) Array.newInstance(Stream.class,
                arraySize);
        int i = 0;
        for (Stream<? extends Event> s : entry.getValue()) {
            streamArray[i++] = s;

            f.setAccessible(true);
            f.set(pe, streamArray);
            logger.debug("Assigned [{}] streams to field [{}].", streamArray.length, f.getName());
        }
    }
}

From source file:org.obeonetwork.m2doc.genconf.TemplateConfigurationServices.java

/**
 * return generation eObject with definitions template information.
 * //w ww  . j a  v a2  s  .c  o m
 * @param generation
 *            Generation
 * @param templateInfo
 *            TemplateInfo
 * @return generation eObject with definitions template information.
 */
public Generation addProperties(Generation generation, TemplateInfo templateInfo) {
    Multimap<String, EPackage> packagesByName = ArrayListMultimap.create();
    for (String uri : templateInfo.getPackagesURIs()) {
        if (EPackage.Registry.INSTANCE.containsKey(uri)) {
            EPackage p = EPackage.Registry.INSTANCE.getEPackage(uri);
            if (p != null && p.getName() != null) {
                packagesByName.put(p.getName(), p);
            }
        }
    }
    for (String key : templateInfo.getVariables().keySet()) {
        String typeName = templateInfo.getVariables().get(key);
        Definition definition = null;
        // The only currently supported scalar type is 'string'
        if (M2DocCustomProperties.STRING_TYPE.equals(typeName)) {
            StringDefinition sdefinition = getConfigurationServices().createStringDefinition(generation);
            sdefinition.setValue(typeName);
            definition = sdefinition;
        } else if (TemplateConfigUtil.isValidClassifierTypeName(typeName)) {
            int index = typeName.indexOf(TemplateConfigUtil.METAMODEL_TYPE_SEPARATOR);
            String packageName = typeName.substring(0, index);
            String classifierName = typeName.substring(index + 2);
            ModelDefinition mdefinition = getConfigurationServices().createModelDefinition(generation);
            if (packagesByName.containsKey(packageName)) {
                Collection<EPackage> packages = packagesByName.get(packageName);
                // We'll use the first matching classifier we find with that name among the packages with this name
                for (EPackage pack : packages) {
                    EClassifier eClassifier = pack.getEClassifier(classifierName);
                    if (eClassifier != null) {
                        mdefinition.setType(eClassifier);
                        break;
                    }
                }
            }
            definition = mdefinition;
        } else {
            // Create untyped definition
            definition = getConfigurationServices().createModelDefinition(generation);
        }
        if (definition != null) {
            definition.setKey(key);
        }
    }
    return generation;
}

From source file:com.dpbymqn.fsm.manager.FsmManager.java

private String transitAtomic(StatefulObject st, String toState) {
    String currentState = getState(st);
    String nextState = toState;/*w  w  w .j  a v a 2 s.  c om*/
    // do pre-callbacks
    Collection<TransitionCallback> preCallbacks = new ArrayList<TransitionCallback>();
    synchronized (classPreTrCallbackMap) {
        for (Class<?> clz : lazySuper.get(st.getClass())) {
            final Map<String, Multimap<String, TransitionCallback>> clzPreStateFromMap = classPreTrCallbackMap
                    .get(clz);
            if (clzPreStateFromMap != null) {
                if (clzPreStateFromMap.get(null) != null || clzPreStateFromMap.get(currentState) != null) {
                    Multimap<String, TransitionCallback> clzStateToMap = LinkedHashMultimap.create();
                    Multimap<String, TransitionCallback> clzStateToMap1 = clzPreStateFromMap.get(currentState);
                    Multimap<String, TransitionCallback> clzStateToMap0 = clzPreStateFromMap.get(null);
                    if (clzStateToMap1 != null) {
                        clzStateToMap.putAll(clzStateToMap1);
                    }
                    if (clzStateToMap0 != null) {
                        clzStateToMap.putAll(clzStateToMap0);
                    }
                    if (clzStateToMap.containsKey(nextState) && clzStateToMap.get(nextState) != null) {
                        preCallbacks.addAll(clzStateToMap.get(nextState));
                    }
                    if (clzStateToMap.get(null) != null) {
                        preCallbacks.addAll(clzStateToMap.get(null));
                    }
                }
            }
        }
    }
    synchronized (instancePreTrCallbackMap) {
        if (instancePreTrCallbackMap.containsKey(st)) {
            for (final Map<String, Multimap<String, TransitionCallback>> instPreStateFromMap : instancePreTrCallbackMap
                    .get(st).values()) {
                if (instPreStateFromMap != null) {
                    if (instPreStateFromMap.get(null) != null
                            || instPreStateFromMap.get(currentState) != null) {
                        Multimap<String, TransitionCallback> instStateToMap = LinkedHashMultimap.create();
                        Multimap<String, TransitionCallback> instStateToMap1 = instPreStateFromMap
                                .get(currentState);
                        Multimap<String, TransitionCallback> instStateToMap0 = instPreStateFromMap.get(null);
                        if (instStateToMap1 != null) {
                            instStateToMap.putAll(instStateToMap1);
                        }
                        if (instStateToMap0 != null) {
                            instStateToMap.putAll(instStateToMap0);
                        }
                        if (instStateToMap.containsKey(nextState) && instStateToMap.get(nextState) != null) {
                            preCallbacks.addAll(instStateToMap.get(nextState));
                        }
                        if (instStateToMap.get(null) != null) {
                            preCallbacks.addAll(instStateToMap.get(null));
                        }
                    }
                }
            }
        }
    }
    // - call pre callbacks 
    // this "if" would prevent calling Pre methods when the transition is triggered by the newly registered listener(s)
    //        if (currentState == null || !currentState.equals(nextState)) {
    for (TransitionCallback trCallback : preCallbacks) {
        trCallback.onTransition(st, currentState, nextState);
    }
    //        }
    // move to next state

    setState(st, nextState);
    // post-callbacks
    // - collect post callbacks
    Collection<TransitionCallback> postCallbacks = new ArrayList<TransitionCallback>();
    synchronized (classPostTrCallbackMap) {
        for (Class<?> clz : lazySuper.get(st.getClass())) {
            final Map<String, Multimap<String, TransitionCallback>> clzPostStateFromMap = classPostTrCallbackMap
                    .get(clz);
            if (clzPostStateFromMap != null) {
                if (clzPostStateFromMap.get(null) != null || clzPostStateFromMap.get(currentState) != null) {
                    Multimap<String, TransitionCallback> clzStateToMap = LinkedHashMultimap.create();
                    Multimap<String, TransitionCallback> clzStateToMap1 = clzPostStateFromMap.get(currentState);
                    Multimap<String, TransitionCallback> clzStateToMap0 = clzPostStateFromMap.get(null);
                    if (clzStateToMap1 != null) {
                        clzStateToMap.putAll(clzStateToMap1);
                    }
                    if (clzStateToMap0 != null) {
                        clzStateToMap.putAll(clzStateToMap0);
                    }
                    if (clzStateToMap.containsKey(nextState) && clzStateToMap.get(nextState) != null) {
                        postCallbacks.addAll(clzStateToMap.get(nextState));
                    }
                    if (clzStateToMap.get(null) != null) {
                        postCallbacks.addAll(clzStateToMap.get(null));
                    }
                }
            }
        }
    }
    synchronized (instancePostTrCallbackMap) {
        if (instancePostTrCallbackMap.containsKey(st)) {
            for (final Map<String, Multimap<String, TransitionCallback>> instPostStateFromMap : instancePostTrCallbackMap
                    .get(st).values()) {
                if (instPostStateFromMap != null) {
                    if (instPostStateFromMap.get(null) != null
                            || instPostStateFromMap.get(currentState) != null) {
                        Multimap<String, TransitionCallback> instStateToMap = LinkedHashMultimap.create();
                        Multimap<String, TransitionCallback> instStateToMap1 = instPostStateFromMap
                                .get(currentState);
                        Multimap<String, TransitionCallback> instStateToMap0 = instPostStateFromMap.get(null);
                        if (instStateToMap1 != null) {
                            instStateToMap.putAll(instStateToMap1);
                        }
                        if (instStateToMap0 != null) {
                            instStateToMap.putAll(instStateToMap0);
                        }
                        if (instStateToMap.containsKey(nextState) && instStateToMap.get(nextState) != null) {
                            postCallbacks.addAll(instStateToMap.get(nextState));
                        }
                        if (instStateToMap.get(null) != null) {
                            postCallbacks.addAll(instStateToMap.get(null));
                        }
                    }
                }
            }
        }
    }
    // - call post callbacks
    for (TransitionCallback trCallback : postCallbacks) {
        trCallback.onTransition(st, currentState, nextState);
    }
    // check decisions
    Set<String> decisions = new HashSet<String>();
    // collect decision callbacks
    Multimap<String, DecisionCallback> possibleStates = HashMultimap.create();
    synchronized (classDecCallbackMap) {
        for (Class<?> clz : lazySuper.get(st.getClass())) {
            final Map<String, Multimap<String, DecisionCallback>> clzDecStateFromMap = classDecCallbackMap
                    .get(clz);
            if (clzDecStateFromMap != null) {
                if (clzDecStateFromMap.get(null) != null || clzDecStateFromMap.get(nextState) != null) {
                    Multimap<String, DecisionCallback> clzStateToMap1 = clzDecStateFromMap.get(nextState);
                    Multimap<String, DecisionCallback> clzStateToMap0 = clzDecStateFromMap.get(null);
                    if (clzStateToMap1 != null) {
                        possibleStates.putAll(clzStateToMap1);
                    }
                    if (clzStateToMap0 != null) {
                        possibleStates.putAll(clzStateToMap0);
                    }
                }
            }
        }
    }
    synchronized (instanceDecCallbackMap) {
        if (instanceDecCallbackMap.containsKey(st)) {
            for (final Map<String, Multimap<String, DecisionCallback>> instDecStateFromMap : instanceDecCallbackMap
                    .get(st).values()) {
                if (instDecStateFromMap != null) {
                    if (instDecStateFromMap.get(null) != null || instDecStateFromMap.get(nextState) != null) {
                        Multimap<String, DecisionCallback> instStateToMap1 = instDecStateFromMap.get(nextState);
                        Multimap<String, DecisionCallback> instStateToMap0 = instDecStateFromMap.get(null);
                        if (instStateToMap1 != null) {
                            possibleStates.putAll(instStateToMap1);
                        }
                        if (instStateToMap0 != null) {
                            possibleStates.putAll(instStateToMap0);
                        }
                    }
                }
            }
        }
    }
    // - call post callbacks
    for (Map.Entry<String, DecisionCallback> e : possibleStates.entries()) {
        DecisionCallback decCallback = e.getValue();
        String intoState = e.getKey();
        String suggest = decCallback.query(st, nextState);
        if (suggest != null) {
            decisions.add(suggest);
        } else {
            if (intoState != null && !intoState.equals(nextState)) {
                final Boolean query = decCallback.query(st, nextState, intoState);
                if (query != null && query) {
                    decisions.add(intoState);
                }
            }
        }
    }
    if (decisions.size() == 1) {
        return decisions.iterator().next();
    }
    return null;
}