private LicensesProvider initializeLicensesProvider() {
    if (!ruleContext.getConfiguration().checkLicenses()) {
      return LicensesProviderImpl.EMPTY;
    }

    NestedSetBuilder<TargetLicense> builder = NestedSetBuilder.linkOrder();
    BuildConfiguration configuration = ruleContext.getConfiguration();
    Rule rule = ruleContext.getRule();
    License toolOutputLicense = rule.getToolOutputLicense(ruleContext.attributes());
    if (configuration.isHostConfiguration() && toolOutputLicense != null) {
      if (toolOutputLicense != License.NO_LICENSE) {
        builder.add(new TargetLicense(rule.getLabel(), toolOutputLicense));
      }
    } else {
      if (rule.getLicense() != License.NO_LICENSE) {
        builder.add(new TargetLicense(rule.getLabel(), rule.getLicense()));
      }

      for (TransitiveInfoCollection dep : ruleContext.getConfiguredTargetMap().values()) {
        LicensesProvider provider = dep.getProvider(LicensesProvider.class);
        if (provider != null) {
          builder.addTransitive(provider.getTransitiveLicenses());
        }
      }
    }

    return new LicensesProviderImpl(builder.build());
  }
  /**
   * Scans {@code action_listeners} associated with this build to see if any {@code extra_actions}
   * should be added to this configured target. If any action_listeners are present, a partial visit
   * of the artifact/action graph is performed (for as long as actions found are owned by this
   * {@link ConfiguredTarget}). Any actions that match the {@code action_listener} get an {@code
   * extra_action} associated. The output artifacts of the extra_action are reported to the {@link
   * AnalysisEnvironment} for bookkeeping.
   */
  private ExtraActionArtifactsProvider initializeExtraActions() {
    BuildConfiguration configuration = ruleContext.getConfiguration();
    if (configuration.isHostConfiguration()) {
      return ExtraActionArtifactsProvider.EMPTY;
    }

    ImmutableList<Artifact> extraActionArtifacts = ImmutableList.of();
    NestedSetBuilder<ExtraArtifactSet> builder = NestedSetBuilder.stableOrder();

    List<Label> actionListenerLabels = configuration.getActionListeners();
    if (!actionListenerLabels.isEmpty()
        && ruleContext.getRule().getAttributeDefinition(":action_listener") != null) {
      ExtraActionsVisitor visitor =
          new ExtraActionsVisitor(ruleContext, computeMnemonicsToExtraActionMap());

      // The action list is modified within the body of the loop by the addExtraAction() call,
      // thus the copy
      for (Action action :
          ImmutableList.copyOf(ruleContext.getAnalysisEnvironment().getRegisteredActions())) {
        if (!actionsWithoutExtraAction.contains(action)) {
          visitor.addExtraAction(action);
        }
      }

      extraActionArtifacts = visitor.getAndResetExtraArtifacts();
      if (!extraActionArtifacts.isEmpty()) {
        builder.add(ExtraArtifactSet.of(ruleContext.getLabel(), extraActionArtifacts));
      }
    }

    // Add extra action artifacts from dependencies
    for (TransitiveInfoCollection dep : ruleContext.getConfiguredTargetMap().values()) {
      ExtraActionArtifactsProvider provider = dep.getProvider(ExtraActionArtifactsProvider.class);
      if (provider != null) {
        builder.addTransitive(provider.getTransitiveExtraActionArtifacts());
      }
    }

    if (mandatoryStampFiles != null && !mandatoryStampFiles.isEmpty()) {
      builder.add(ExtraArtifactSet.of(ruleContext.getLabel(), mandatoryStampFiles));
    }

    if (extraActionArtifacts.isEmpty() && builder.isEmpty()) {
      return ExtraActionArtifactsProvider.EMPTY;
    }
    return new ExtraActionArtifactsProvider(extraActionArtifacts, builder.build());
  }
 /**
  * Populates the configuration specific mnemonicToExtraActionMap based on all action_listers
  * selected by the user (via the blaze option {@code --experimental_action_listener=<target>}).
  */
 private Multimap<String, ExtraActionSpec> computeMnemonicsToExtraActionMap() {
   // We copy the multimap here every time. This could be expensive.
   Multimap<String, ExtraActionSpec> mnemonicToExtraActionMap = HashMultimap.create();
   for (TransitiveInfoCollection actionListener :
       ruleContext.getPrerequisites(":action_listener", Mode.HOST)) {
     ExtraActionMapProvider provider = actionListener.getProvider(ExtraActionMapProvider.class);
     if (provider == null) {
       ruleContext.ruleError(
           String.format(
               "Unable to match experimental_action_listeners to this rule. "
                   + "Specified target %s is not an action_listener rule",
               actionListener.getLabel().toString()));
     } else {
       mnemonicToExtraActionMap.putAll(provider.getExtraActionMap());
     }
   }
   return mnemonicToExtraActionMap;
 }