Example usage for com.google.common.collect ImmutableMap entrySet

List of usage examples for com.google.common.collect ImmutableMap entrySet

Introduction

In this page you can find the example usage for com.google.common.collect ImmutableMap entrySet.

Prototype

public final ImmutableSet<Entry<K, V>> entrySet() 

Source Link

Usage

From source file:com.facebook.buck.apple.WorkspaceAndProjectGenerator.java

private void writeWorkspaceSchemes(String workspaceName, Path outputDirectory,
        ImmutableMap<String, XcodeWorkspaceConfigDescription.Arg> schemeConfigs,
        ImmutableSetMultimap<String, Optional<TargetNode<?>>> schemeNameToSrcTargetNode,
        ImmutableSetMultimap<String, TargetNode<?>> buildForTestNodes,
        ImmutableSetMultimap<String, TargetNode<AppleTestDescription.Arg>> ungroupedTests,
        ImmutableMap<PBXTarget, Path> targetToProjectPathMap,
        Iterable<PBXTarget> synthesizedCombinedTestTargets,
        Function<TargetNode<?>, Collection<PBXTarget>> targetNodeToPBXTargetTransformer,
        Function<BuildTarget, PBXTarget> buildTargetToPBXTargetTransformer) throws IOException {
    for (Map.Entry<String, XcodeWorkspaceConfigDescription.Arg> schemeConfigEntry : schemeConfigs.entrySet()) {
        String schemeName = schemeConfigEntry.getKey();
        boolean isMainScheme = schemeName.equals(workspaceName);
        XcodeWorkspaceConfigDescription.Arg schemeConfigArg = schemeConfigEntry.getValue();
        Iterable<PBXTarget> orderedBuildTargets = FluentIterable
                .from(ImmutableSet.copyOf(Optional.presentInstances(schemeNameToSrcTargetNode.get(schemeName))))
                .transformAndConcat(targetNodeToPBXTargetTransformer).toSet();
        FluentIterable<PBXTarget> orderedBuildTestTargets = FluentIterable
                .from(buildForTestNodes.get(schemeName)).transformAndConcat(targetNodeToPBXTargetTransformer);
        if (isMainScheme) {
            orderedBuildTestTargets = orderedBuildTestTargets.append(synthesizedCombinedTestTargets);
        }/*  ww  w. j a v a2s. co m*/
        FluentIterable<PBXTarget> orderedRunTestTargets = FluentIterable.from(ungroupedTests.get(schemeName))
                .transformAndConcat(targetNodeToPBXTargetTransformer);
        if (isMainScheme) {
            orderedRunTestTargets = orderedRunTestTargets.append(synthesizedCombinedTestTargets);
        }
        Optional<String> runnablePath;
        Optional<BuildTarget> targetToBuildWithBuck = getTargetToBuildWithBuck();
        if (buildWithBuck && targetToBuildWithBuck.isPresent()) {
            Optional<String> productName = getProductName(schemeNameToSrcTargetNode.get(schemeName),
                    targetToBuildWithBuck);
            String binaryName = AppleBundle.getBinaryName(targetToBuildWithBuck.get(), productName);
            runnablePath = Optional.of(projectFilesystem.resolve(
                    ProjectGenerator.getScratchPathForAppBundle(targetToBuildWithBuck.get(), binaryName))
                    .toString());
        } else {
            runnablePath = Optional.absent();
        }
        Optional<String> remoteRunnablePath;
        if (schemeConfigArg.isRemoteRunnable.or(false)) {
            // XXX TODO(bhamiltoncx): Figure out the actual name of the binary to launch
            remoteRunnablePath = Optional.of("/" + workspaceName);
        } else {
            remoteRunnablePath = Optional.absent();
        }
        SchemeGenerator schemeGenerator = new SchemeGenerator(projectFilesystem,
                schemeConfigArg.srcTarget.transform(buildTargetToPBXTargetTransformer), orderedBuildTargets,
                orderedBuildTestTargets, orderedRunTestTargets, schemeName,
                combinedProject ? outputDirectory : outputDirectory.resolve(workspaceName + ".xcworkspace"),
                buildWithBuck, parallelizeBuild, runnablePath, remoteRunnablePath,
                XcodeWorkspaceConfigDescription.getActionConfigNamesFromArg(workspaceArguments),
                targetToProjectPathMap);
        schemeGenerator.writeScheme();
        schemeGenerators.put(schemeName, schemeGenerator);
    }
}

From source file:com.facebook.buck.apple.xcode.ProjectGenerator.java

private String serializeBuildConfiguration(XcodeRuleConfiguration configuration,
        ImmutableList<Path> searchPaths, ImmutableMap<String, String> extra) {

    XcconfigStack.Builder builder = XcconfigStack.builder();
    for (XcodeRuleConfiguration.Layer layer : configuration.getLayers()) {
        switch (layer.getLayerType()) {
        case FILE:
            builder.addSettingsFromFile(projectFilesystem, searchPaths, layer.getPath().get());
            break;
        case INLINE_SETTINGS:
            ImmutableMap<String, String> entries = layer.getInlineSettings().get();
            for (ImmutableMap.Entry<String, String> entry : entries.entrySet()) {
                builder.addSetting(entry.getKey(), entry.getValue());
            }/*  www . j  a  v  a  2 s.co m*/
            break;
        }
        builder.pushLayer();
    }

    for (ImmutableMap.Entry<String, String> entry : extra.entrySet()) {
        builder.addSetting(entry.getKey(), entry.getValue());
    }
    builder.pushLayer();

    XcconfigStack stack = builder.build();

    ImmutableList<String> resolvedConfigs = stack.resolveConfigStack();
    ImmutableSortedSet<String> sortedConfigs = ImmutableSortedSet.copyOf(resolvedConfigs);
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("// This configuration is autogenerated.\n"
            + "// Re-run buck to update this file after modifying the hand-written configs.\n");
    for (String line : sortedConfigs) {
        stringBuilder.append(line);
        stringBuilder.append('\n');
    }
    return stringBuilder.toString();
}

From source file:com.facebook.buck.features.apple.project.WorkspaceAndProjectGenerator.java

private void writeWorkspaceSchemes(String workspaceName, Path outputDirectory,
        ImmutableMap<String, XcodeWorkspaceConfigDescriptionArg> schemeConfigs,
        ImmutableSetMultimap<String, Optional<TargetNode<?>>> schemeNameToSrcTargetNode,
        ImmutableSetMultimap<String, PBXTarget> buildForTestTargets,
        ImmutableSetMultimap<String, PBXTarget> ungroupedTestTargets,
        ImmutableMap<PBXTarget, Path> targetToProjectPathMap,
        ImmutableMap<BuildTarget, PBXTarget> buildTargetToPBXTarget) throws IOException {
    for (Map.Entry<String, XcodeWorkspaceConfigDescriptionArg> schemeConfigEntry : schemeConfigs.entrySet()) {
        String schemeName = schemeConfigEntry.getKey();
        XcodeWorkspaceConfigDescriptionArg schemeConfigArg = schemeConfigEntry.getValue();
        if (schemeConfigArg.getSrcTarget().isPresent()
                && !focusModules.isFocusedOn(schemeConfigArg.getSrcTarget().get())) {
            continue;
        }/*from w  w w.jav  a  2s  .co m*/

        ImmutableSet<PBXTarget> orderedBuildTargets = schemeNameToSrcTargetNode.get(schemeName).stream()
                .distinct().flatMap(Optionals::toStream).map(TargetNode::getBuildTarget)
                .map(buildTargetToPBXTarget::get).filter(Objects::nonNull)
                .collect(ImmutableSet.toImmutableSet());
        ImmutableSet<PBXTarget> orderedBuildTestTargets = buildForTestTargets.get(schemeName);
        ImmutableSet<PBXTarget> orderedRunTestTargets = ungroupedTestTargets.get(schemeName);

        Optional<String> runnablePath = schemeConfigArg.getExplicitRunnablePath();
        Optional<String> remoteRunnablePath;
        if (schemeConfigArg.getIsRemoteRunnable().orElse(false)) {
            // XXX TODO(beng): Figure out the actual name of the binary to launch
            remoteRunnablePath = Optional.of("/" + workspaceName);
        } else {
            remoteRunnablePath = Optional.empty();
        }
        SchemeGenerator schemeGenerator = buildSchemeGenerator(targetToProjectPathMap, workspaceName,
                outputDirectory, schemeName, schemeConfigArg.getSrcTarget().map(buildTargetToPBXTarget::get),
                Optional.of(schemeConfigArg), orderedBuildTargets, orderedBuildTestTargets,
                orderedRunTestTargets, runnablePath, remoteRunnablePath);
        schemeGenerator.writeScheme();
        schemeGenerators.put(schemeName, schemeGenerator);
    }
}

From source file:org.pircbotx.InputParser.java

/**
 * Process any lines relevant to connect. Only called before bot is logged
 * into the server/*from  w  w w. j a va  2s.co  m*/
 *
 * @param rawLine Raw, unprocessed line from the server
 * @param code
 * @param target
 * @param parsedLine Processed line
 * @throws IrcException If the server rejects the bot (nick already in use
 * or a 4** or 5** code
 * @throws IOException If an error occurs during upgrading to SSL
 */
public void processConnect(String rawLine, String code, String target, List<String> parsedLine)
        throws IrcException, IOException {
    if (CONNECT_CODES.contains(code)) {
        // We're connected to the server.
        bot.onLoggedIn(parsedLine.get(0));
        log.debug("Logged onto server.");

        configuration.getListenerManager().dispatchEvent(new ConnectEvent(bot));

        //Handle automatic on connect stuff
        if (configuration.getNickservPassword() != null)
            bot.sendIRC().identify(configuration.getNickservPassword());
        ImmutableMap<String, String> autoConnectChannels = bot.reconnectChannels();
        if (autoConnectChannels == null)
            if (configuration.isNickservDelayJoin())
                autoConnectChannels = ImmutableMap.of();
            else
                autoConnectChannels = configuration.getAutoJoinChannels();
        for (Map.Entry<String, String> channelEntry : autoConnectChannels.entrySet())
            bot.sendIRC().joinChannel(channelEntry.getKey(), channelEntry.getValue());
    } else if (code.equals("439"))
        //EXAMPLE: PircBotX: Target change too fast. Please wait 104 seconds
        // No action required.
        //TODO: Should we delay joining channels here or something?
        log.warn("Ignoring too fast error");
    else if (configuration.isCapEnabled() && code.equals("421") && parsedLine.get(1).equals("CAP"))
        //EXAMPLE: 421 you CAP :Unknown command
        log.warn("Ignoring unknown command error, server does not support CAP negotiation");
    else if (configuration.isCapEnabled() && code.equals("451") && target.equals("CAP")) {
        //EXAMPLE: 451 CAP :You have not registered
        //Ignore, this is from servers that don't support CAP
        log.warn("Ignoring not registered error, server does not support CAP negotiation");
    } else if (configuration.isCapEnabled() && code.equals("410") && parsedLine.get(1).contains("CAP")) {
        //EXAMPLE: 410 :Invalid CAP command
        //Ignore, Twitch.tv uses this code for some reason
        log.warn("Ignoring invalid command error, server does not support CAP negotiation");
    } else if ((code.startsWith("5") || code.startsWith("4")) && !code.equals("433"))
        //Ignore 433 NickAlreadyInUse, handled later
        throw new IrcException(IrcException.Reason.CannotLogin, "Received error: " + rawLine);
    else if (code.equals("670")) {
        //Server is saying that we can upgrade to TLS
        log.debug("Upgrading to TLS connection");
        SSLSocketFactory sslSocketFactory = ((SSLSocketFactory) SSLSocketFactory.getDefault());
        for (CapHandler curCapHandler : configuration.getCapHandlers())
            if (curCapHandler instanceof TLSCapHandler)
                sslSocketFactory = ((TLSCapHandler) curCapHandler).getSslSocketFactory();
        SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(bot.getSocket(),
                bot.getLocalAddress().getHostAddress(), bot.getSocket().getPort(), true);
        sslSocket.startHandshake();
        bot.changeSocket(sslSocket);

        //Notify CAP Handlers
        for (CapHandler curCapHandler : configuration.getCapHandlers())
            if (curCapHandler.handleUnknown(bot, rawLine))
                addCapHandlerFinished(curCapHandler);
    } else if (code.equals("CAP") && configuration.isCapEnabled()) {
        //Handle CAP Code; remove extra from params
        String capCommand = parsedLine.get(1);
        ImmutableList<String> capParams = ImmutableList.copyOf(StringUtils.split(parsedLine.get(2)));
        if (capCommand.equals("LS")) {
            log.debug("Starting Cap Handlers {}", getCapHandlersRemaining());
            for (CapHandler curCapHandler : getCapHandlersRemaining()) {
                if (curCapHandler.handleLS(bot, capParams))
                    addCapHandlerFinished(curCapHandler);
            }
        } else if (capCommand.equals("ACK")) {
            //Server is enabling a capability, store that
            bot.getEnabledCapabilities().addAll(capParams);

            for (CapHandler curCapHandler : getCapHandlersRemaining())
                if (curCapHandler.handleACK(bot, capParams))
                    addCapHandlerFinished(curCapHandler);
        } else if (capCommand.equals("NAK")) {
            for (CapHandler curCapHandler : getCapHandlersRemaining())
                if (curCapHandler.handleNAK(bot, capParams))
                    addCapHandlerFinished(curCapHandler);
        } else {
            //Maybe the CapHandlers know how to use it
            for (CapHandler curCapHandler : getCapHandlersRemaining())
                if (curCapHandler.handleUnknown(bot, rawLine))
                    addCapHandlerFinished(curCapHandler);
        }
    } else
        //Pass to CapHandlers, could be important
        for (CapHandler curCapHandler : getCapHandlersRemaining())
            if (curCapHandler.handleUnknown(bot, rawLine))
                addCapHandlerFinished(curCapHandler);
}

From source file:com.google.javascript.jscomp.FunctionTypeBuilder.java

/**
 * Infer the template type from the doc info.
 *//*w  w  w  .j  a v  a  2  s . co  m*/
FunctionTypeBuilder inferTemplateTypeName(@Nullable JSDocInfo info, JSType ownerType) {
    // NOTE: these template type names may override a list
    // of inherited ones from an overridden function.
    if (info != null) {
        ImmutableList.Builder<TemplateType> builder = ImmutableList.builder();
        ImmutableList<String> infoTemplateTypeNames = info.getTemplateTypeNames();
        ImmutableMap<String, Node> infoTypeTransformations = info.getTypeTransformations();
        if (!infoTemplateTypeNames.isEmpty()) {
            for (String key : infoTemplateTypeNames) {
                if (typeRegistry.isIObjectValueKey(fnName, key)) {
                    builder.add(typeRegistry.getIObjectValueKey());
                } else {
                    builder.add(typeRegistry.createTemplateType(key));
                }
            }
        }
        if (!infoTypeTransformations.isEmpty()) {
            for (Entry<String, Node> entry : infoTypeTransformations.entrySet()) {
                builder.add(
                        typeRegistry.createTemplateTypeWithTransformation(entry.getKey(), entry.getValue()));
            }
        }
        if (!infoTemplateTypeNames.isEmpty() || !infoTypeTransformations.isEmpty()) {
            templateTypeNames = builder.build();
        }
    }

    ImmutableList<TemplateType> keys = templateTypeNames;
    if (ownerType != null) {
        ImmutableList<TemplateType> ownerTypeKeys = ownerType.getTemplateTypeMap().getTemplateKeys();
        if (!ownerTypeKeys.isEmpty()) {
            ImmutableList.Builder<TemplateType> builder = ImmutableList.builder();
            builder.addAll(templateTypeNames);
            builder.addAll(ownerTypeKeys);
            keys = builder.build();
        }
    }

    if (!keys.isEmpty()) {
        typeRegistry.setTemplateTypeNames(keys);
    }
    return this;
}

From source file:com.facebook.buck.config.BuckConfig.java

public ImmutableMap<String, ImmutableMap<String, String>> getRawConfigForParser() {
    ImmutableMap<String, ImmutableMap<String, String>> rawSections = config.getSectionToEntries();

    // If the raw config doesn't have sections which have ignored fields, then just return it as-is.
    ImmutableSet<String> sectionsWithIgnoredFields = IGNORE_FIELDS_FOR_DAEMON_RESTART.keySet();
    if (Sets.intersection(rawSections.keySet(), sectionsWithIgnoredFields).isEmpty()) {
        return rawSections;
    }//w w w  . j a v  a2  s .  co m

    // Otherwise, iterate through the config to do finer-grain filtering.
    ImmutableMap.Builder<String, ImmutableMap<String, String>> filtered = ImmutableMap.builder();
    for (Map.Entry<String, ImmutableMap<String, String>> sectionEnt : rawSections.entrySet()) {
        String sectionName = sectionEnt.getKey();

        // If this section doesn't have a corresponding ignored section, then just add it as-is.
        if (!sectionsWithIgnoredFields.contains(sectionName)) {
            filtered.put(sectionEnt);
            continue;
        }

        // If none of this section's entries are ignored, then add it as-is.
        ImmutableMap<String, String> fields = sectionEnt.getValue();
        ImmutableSet<String> ignoredFieldNames = IGNORE_FIELDS_FOR_DAEMON_RESTART.getOrDefault(sectionName,
                ImmutableSet.of());
        if (Sets.intersection(fields.keySet(), ignoredFieldNames).isEmpty()) {
            filtered.put(sectionEnt);
            continue;
        }

        // Otherwise, filter out the ignored fields.
        ImmutableMap<String, String> remainingKeys = ImmutableMap
                .copyOf(Maps.filterKeys(fields, Predicates.not(ignoredFieldNames::contains)));

        if (!remainingKeys.isEmpty()) {
            filtered.put(sectionName, remainingKeys);
        }
    }

    return filtered.build();
}

From source file:com.android.tools.idea.wizard.ASGallery.java

public ASGallery(@NotNull ListModel model, @NotNull Function<? super E, Image> imageProvider,
        @NotNull Function<? super E, String> labelProvider, @NotNull Dimension thumbnailSize) {
    Font listFont = UIUtil.getListFont();
    if (listFont != null) {
        setFont(listFont);/* w  w w  . ja  va2 s. c  o  m*/
    }

    setThumbnailSize(thumbnailSize);
    setImageProvider(imageProvider);
    setLabelProvider(labelProvider);
    setModel(model);

    setOpaque(true);
    setFocusable(true);
    addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            requestFocusInWindow();
            int cell = getCellAt(e.getPoint());
            if (cell >= 0) {
                setSelectedIndex(cell);
            }
        }
    });
    addFocusListener(new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {
            reveal();
            updateFocusRectangle();
        }

        @Override
        public void focusLost(FocusEvent e) {
            updateFocusRectangle();
        }
    });
    addKeyListener(new KeyAdapter() {
        @Override
        public void keyTyped(KeyEvent e) {
            char keyChar = e.getKeyChar();
            if (keyChar != KeyEvent.CHAR_UNDEFINED) {
                incrementalSearch(keyChar);
            }
        }
    });
    setBackground(UIUtil.getListBackground());
    InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED);
    ActionMap actionMap = getActionMap();

    ImmutableMap<Integer, Action> keysToActions = ImmutableMap.<Integer, Action>builder()
            .put(KeyEvent.VK_DOWN, new MoveSelectionAction(1, 0))
            .put(KeyEvent.VK_UP, new MoveSelectionAction(-1, 0))
            .put(KeyEvent.VK_LEFT, new MoveSelectionAction(0, -1))
            .put(KeyEvent.VK_RIGHT, new MoveSelectionAction(0, 1)).put(KeyEvent.VK_HOME, new JumpSelection() {
                @Override
                public int getIndex() {
                    return 0;
                }
            }).put(KeyEvent.VK_END, new JumpSelection() {
                @Override
                public int getIndex() {
                    return myModel.getSize() - 1;
                }
            }).build();
    for (Map.Entry<Integer, Action> entry : keysToActions.entrySet()) {
        String key = "selection_move_" + entry.getKey();
        inputMap.put(KeyStroke.getKeyStroke(entry.getKey(), 0), key);
        actionMap.put(key, entry.getValue());
    }
}

From source file:org.elasticsearch.snapshots.SnapshotsService.java

/**
 * Returns list of indices with missing shards
 *
 * @param shards list of shard statuses/*from w ww.j av  a 2 s . c  om*/
 * @return list of failed indices
 */
private Set<String> indicesWithMissingShards(
        ImmutableMap<ShardId, SnapshotMetaData.ShardSnapshotStatus> shards) {
    Set<String> indices = null;
    for (ImmutableMap.Entry<ShardId, SnapshotMetaData.ShardSnapshotStatus> entry : shards.entrySet()) {
        if (entry.getValue().state() == State.MISSING) {
            if (indices == null) {
                indices = newHashSet();
            }
            indices.add(entry.getKey().getIndex());
        }
    }
    return indices;
}

From source file:com.facebook.buck.config.AbstractCellConfig.java

/**
 * Translates the 'cell name'->override map into a 'Path'->override map.
 * @param pathMapping a map containing paths to all of the cells we want to query.
 * @return 'Path'->override map//from  ww w  .j  a v  a2  s  .co  m
 */
public ImmutableMap<Path, RawConfig> getOverridesByPath(ImmutableMap<RelativeCellName, Path> pathMapping)
        throws MalformedOverridesException {

    ImmutableSet<RelativeCellName> relativeNamesOfCellsWithOverrides = FluentIterable.from(getValues().keySet())
            .filter(Predicates.not(ALL_CELLS_OVERRIDE::equals)).toSet();
    ImmutableSet.Builder<Path> pathsWithOverrides = ImmutableSet.builder();
    for (RelativeCellName cellWithOverride : relativeNamesOfCellsWithOverrides) {
        if (!pathMapping.containsKey(cellWithOverride)) {
            throw new MalformedOverridesException(
                    String.format("Trying to override settings for unknown cell %s", cellWithOverride));
        }
        pathsWithOverrides.add(pathMapping.get(cellWithOverride));
    }

    ImmutableMultimap<Path, RelativeCellName> pathToRelativeName = Multimaps.index(pathMapping.keySet(),
            Functions.forMap(pathMapping));

    for (Path pathWithOverrides : pathsWithOverrides.build()) {
        ImmutableCollection<RelativeCellName> namesForPath = pathToRelativeName.get(pathWithOverrides);
        if (namesForPath.size() > 1) {
            throw new MalformedOverridesException(
                    String.format("Configuration override is ambiguous: cell rooted at %s is reachable "
                            + "as [%s]. Please override the config by placing a .buckconfig.local file in the "
                            + "cell's root folder.", pathWithOverrides, Joiner.on(',').join(namesForPath)));
        }
    }

    Map<Path, RawConfig> overridesByPath = new HashMap<>();
    for (Map.Entry<RelativeCellName, Path> entry : pathMapping.entrySet()) {
        RelativeCellName cellRelativeName = entry.getKey();
        Path cellPath = entry.getValue();
        RawConfig configFromOtherRelativeName = overridesByPath.get(cellPath);
        RawConfig config = getForCell(cellRelativeName);
        if (configFromOtherRelativeName != null) {
            Preconditions.checkState(configFromOtherRelativeName.equals(config),
                    "Attempting to create cell %s at %s with conflicting overrides [%s] vs [%s].",
                    cellRelativeName, cellPath, configFromOtherRelativeName, config);
        } else {
            overridesByPath.put(cellPath, config);
        }
    }

    return ImmutableMap.copyOf(overridesByPath);
}

From source file:com.facebook.buck.android.relinker.NativeRelinker.java

public NativeRelinker(BuildRuleParams buildRuleParams, SourcePathResolver resolver,
        SourcePathRuleFinder ruleFinder, CxxBuckConfig cxxBuckConfig,
        ImmutableMap<TargetCpuType, NdkCxxPlatform> nativePlatforms,
        ImmutableMap<Pair<TargetCpuType, String>, SourcePath> linkableLibs,
        ImmutableMap<Pair<TargetCpuType, String>, SourcePath> linkableLibsAssets) {
    this.ruleFinder = ruleFinder;
    Preconditions.checkArgument(!linkableLibs.isEmpty() || !linkableLibsAssets.isEmpty(),
            "There should be at least one native library to relink.");

    this.buildRuleParams = buildRuleParams;
    this.resolver = resolver;
    this.cxxBuckConfig = cxxBuckConfig;
    this.nativePlatforms = nativePlatforms;

    /*/*w w w .j a v a  2  s . c  o m*/
    When relinking a library, any symbols needed by a (transitive) dependent must continue to be
    exported. As relinking one of those dependents may change the set of symbols that it needs,
    we only need to keep the symbols that are still used after a library is relinked. So, this
    relinking process basically works in the reverse order of the original link process. As each
    library is relinked, we now know the set of symbols that are needed in that library's
    dependencies.
            
    For linkables that can't be resolved to a BuildRule, we can't tell what libraries that one
    depends on. So, we essentially assume that everything depends on it.
    */

    ImmutableMap.Builder<BuildRule, Pair<TargetCpuType, SourcePath>> ruleMapBuilder = ImmutableMap.builder();
    ImmutableSet.Builder<Pair<TargetCpuType, SourcePath>> copiedLibraries = ImmutableSet.builder();

    for (Map.Entry<Pair<TargetCpuType, String>, SourcePath> entry : Iterables.concat(linkableLibs.entrySet(),
            linkableLibsAssets.entrySet())) {
        SourcePath source = entry.getValue();
        Optional<BuildRule> rule = ruleFinder.getRule(source);
        if (rule.isPresent()) {
            ruleMapBuilder.put(rule.get(), new Pair<>(entry.getKey().getFirst(), source));
        } else {
            copiedLibraries.add(new Pair<>(entry.getKey().getFirst(), source));
        }
    }

    ImmutableMap<BuildRule, Pair<TargetCpuType, SourcePath>> ruleMap = ruleMapBuilder.build();
    ImmutableSet<BuildRule> linkableRules = ruleMap.keySet();

    // Now, for every linkable build rule, we need to figure out all the other linkable build rules
    // that could depend on it (or rather, could use symbols from it).

    // This is the sub-graph that includes the linkableRules and all the dependents (including
    // non-linkable rules).
    final DirectedAcyclicGraph<BuildRule> graph = getBuildGraph(linkableRules);
    ImmutableList<BuildRule> sortedRules = TopologicalSort.sort(graph);
    // This maps a build rule to every rule in linkableRules that depends on it. This (added to the
    // copied libraries) is the set of linkables that could use a symbol from this build rule.
    ImmutableMap<BuildRule, ImmutableSet<BuildRule>> allDependentsMap = getAllDependentsMap(linkableRules,
            graph, sortedRules);

    ImmutableMap.Builder<SourcePath, SourcePath> pathMap = ImmutableMap.builder();

    // Create the relinker rules for the libraries that couldn't be resolved back to a base rule.
    ImmutableList.Builder<RelinkerRule> relinkRules = ImmutableList.builder();
    for (Pair<TargetCpuType, SourcePath> p : copiedLibraries.build()) {
        // TODO(cjhopman): We shouldn't really need a full RelinkerRule at this point. We know that we
        // are just going to copy it, we could just leave these libraries in place and only calculate
        // the list of needed symbols.
        TargetCpuType cpuType = p.getFirst();
        SourcePath source = p.getSecond();
        RelinkerRule relink = makeRelinkerRule(cpuType, source, ImmutableList.of());
        relinkRules.add(relink);
        pathMap.put(source, relink.getLibFileSourcePath());
    }
    ImmutableList<RelinkerRule> copiedLibrariesRules = relinkRules.build();

    // Process the remaining linkable rules in the reverse sorted order. This makes it easy to refer
    // to the RelinkerRules of dependents.
    Iterable<Pair<TargetCpuType, SourcePath>> sortedPaths = FluentIterable.from(sortedRules)
            .filter(linkableRules::contains).transform(Functions.forMap(ruleMap)).toList().reverse();
    Map<BuildRule, RelinkerRule> relinkerMap = new HashMap<>();

    for (Pair<TargetCpuType, SourcePath> p : sortedPaths) {
        TargetCpuType cpuType = p.getFirst();
        SourcePath source = p.getSecond();
        BuildRule baseRule = ruleFinder.getRuleOrThrow((BuildTargetSourcePath) source);
        // Relinking this library must keep any of the symbols needed by the libraries from the rules
        // in relinkerDeps.
        ImmutableList<RelinkerRule> relinkerDeps = ImmutableList.<RelinkerRule>builder()
                .addAll(copiedLibrariesRules)
                .addAll(Lists.transform(ImmutableList.copyOf(allDependentsMap.get(baseRule)),
                        Functions.forMap(relinkerMap)))
                .build();

        RelinkerRule relink = makeRelinkerRule(cpuType, source, relinkerDeps);
        relinkRules.add(relink);
        pathMap.put(source, relink.getLibFileSourcePath());
        relinkerMap.put(baseRule, relink);
    }

    Function<SourcePath, SourcePath> pathMapper = Functions.forMap(pathMap.build());
    rules = relinkRules.build();
    relinkedLibs = ImmutableMap.copyOf(Maps.transformValues(linkableLibs, pathMapper));
    relinkedLibsAssets = ImmutableMap.copyOf(Maps.transformValues(linkableLibsAssets, pathMapper));
}