private Set<Fragment> getConfigurationFragments(BuildConfigurationValue.Key key, Environment env)
      throws InvalidConfigurationException {
    // Get SkyKeys for the fragments we need to load.
    Set<SkyKey> fragmentKeys = new LinkedHashSet<>();
    for (Class<? extends BuildConfiguration.Fragment> fragmentClass : key.getFragments()) {
      fragmentKeys.add(ConfigurationFragmentValue.key(key.getBuildOptions(), fragmentClass));
    }

    // Load them as Skyframe deps.
    Map<SkyKey, ValueOrException<InvalidConfigurationException>> fragmentDeps =
        env.getValuesOrThrow(fragmentKeys, InvalidConfigurationException.class);
    if (env.valuesMissing()) {
      return null;
    }

    // Collect and return the results.
    ImmutableSet.Builder<Fragment> fragments = ImmutableSet.builder();
    for (ValueOrException<InvalidConfigurationException> value : fragmentDeps.values()) {
      fragments.add(((ConfigurationFragmentValue) value.get()).getFragment());
    }
    return fragments.build();
  }
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws InterruptedException, SkyFunctionException {
    BuildConfigurationValue.Key key = (BuildConfigurationValue.Key) skyKey.argument();
    Set<Fragment> fragments;
    try {
      fragments = getConfigurationFragments(key, env);
    } catch (InvalidConfigurationException e) {
      throw new BuildConfigurationFunctionException(e);
    }
    if (fragments == null) {
      return null;
    }

    ClassToInstanceMap<Fragment> fragmentsMap = MutableClassToInstanceMap.create();
    for (Fragment fragment : fragments) {
      fragmentsMap.put(fragment.getClass(), fragment);
    }

    return new BuildConfigurationValue(
        new BuildConfiguration(
            directories, fragmentsMap, key.getBuildOptions(), !key.actionsEnabled()));
  }