@VisibleForTesting
  public Set<String> getSecurityGroupsForTagAndOptions(
      String region, @Nullable String group, TemplateOptions options) {
    Builder<String> groups = ImmutableSet.builder();

    if (group != null) {
      String markerGroup = namingConvention.create().sharedNameForGroup(group);

      groups.add(markerGroup);

      RegionNameAndIngressRules regionNameAndIngressRulesForMarkerGroup;

      if (userSpecifiedTheirOwnGroups(options)) {
        regionNameAndIngressRulesForMarkerGroup =
            new RegionNameAndIngressRules(region, markerGroup, new int[] {}, false);
        groups.addAll(EC2TemplateOptions.class.cast(options).getGroups());
      } else {
        regionNameAndIngressRulesForMarkerGroup =
            new RegionNameAndIngressRules(region, markerGroup, options.getInboundPorts(), true);
      }
      // this will create if not yet exists.
      securityGroupMap.getUnchecked(regionNameAndIngressRulesForMarkerGroup);
    }
    return groups.build();
  }
  @Override
  public Set<? extends Location> get() {
    Set<? extends Location> regionsOrJustProvider = regionToProviderOrJustProvider.get();
    Set<String> zoneIds = zoneIdsSupplier.get();
    if (zoneIds.size() == 0) return regionsOrJustProvider;
    Map<String, Location> zoneIdToParent =
        setParentOfZoneToRegionOrProvider(zoneIds, regionsOrJustProvider);
    Map<String, Supplier<Set<String>>> isoCodesById = isoCodesByIdSupplier.get();

    Builder<Location> locations = ImmutableSet.builder();
    if (!Iterables.all(regionsOrJustProvider, LocationPredicates.isProvider()))
      locations.addAll(regionsOrJustProvider);
    for (Map.Entry<String, Location> entry : zoneIdToParent.entrySet()) {
      String zoneId = entry.getKey();
      Location parent = entry.getValue();
      LocationBuilder builder =
          new LocationBuilder()
              .scope(LocationScope.ZONE)
              .id(zoneId)
              .description(zoneId)
              .parent(parent);
      if (isoCodesById.containsKey(zoneId)) builder.iso3166Codes(isoCodesById.get(zoneId).get());
      // be cautious.. only inherit iso codes if the parent is a region
      // regions may be added dynamically, and we prefer to inherit an
      // empty set of codes from a region, then a provider, whose code
      // are likely hard-coded.
      else if (parent.getScope() == LocationScope.REGION)
        builder.iso3166Codes(parent.getIso3166Codes());
      locations.add(builder.build());
    }
    return locations.build();
  }
  /**
   * Filters SchemaContext for yang modules
   *
   * @param delegate original SchemaContext
   * @param rootModules modules (yang schemas) to be available and all their dependencies (modules
   *     importing rootModule and whole chain of their imports)
   * @param additionalModuleIds (additional) modules (yang schemas) to be available and whole chain
   *     of their imports
   */
  public FilteringSchemaContextProxy(
      final SchemaContext delegate,
      final Collection<ModuleId> rootModules,
      final Set<ModuleId> additionalModuleIds) {

    Preconditions.checkArgument(rootModules != null, "Base modules cannot be null.");
    Preconditions.checkArgument(additionalModuleIds != null, "Additional modules cannot be null.");

    final Builder<Module> filteredModulesBuilder = new Builder<>();

    final SetMultimap<URI, Module> nsMap =
        Multimaps.newSetMultimap(new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
    final SetMultimap<String, Module> nameMap =
        Multimaps.newSetMultimap(new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);

    ImmutableMap.Builder<ModuleIdentifier, String> identifiersToSourcesBuilder =
        ImmutableMap.builder();

    // preparing map to get all modules with one name but difference in revision
    final TreeMultimap<String, Module> nameToModulesAll = getStringModuleTreeMultimap();

    nameToModulesAll.putAll(getStringModuleMap(delegate));

    // in case there is a particular dependancy to view filteredModules/yang models
    // dependancy is checked for module name and imports
    processForRootModules(delegate, rootModules, filteredModulesBuilder);

    // adding additional modules
    processForAdditionalModules(delegate, additionalModuleIds, filteredModulesBuilder);

    filteredModulesBuilder.addAll(
        getImportedModules(
            Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID),
            filteredModulesBuilder.build(),
            nameToModulesAll));

    /**
     * Instead of doing this on each invocation of getModules(), pre-compute it once and keep it
     * around -- better than the set we got in.
     */
    this.filteredModules = filteredModulesBuilder.build();

    for (final Module module : filteredModules) {
      nameMap.put(module.getName(), module);
      nsMap.put(module.getNamespace(), module);
      identifiersToSourcesBuilder.put(module, module.getSource());
    }

    namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
    nameToModules = ImmutableSetMultimap.copyOf(nameMap);
    identifiersToSources = identifiersToSourcesBuilder.build();
  }
 private void processForRootModules(
     SchemaContext delegate,
     final Collection<ModuleId> rootModules,
     Builder<Module> filteredModulesBuilder) {
   filteredModulesBuilder.addAll(
       Collections2.filter(
           delegate.getModules(),
           new Predicate<Module>() {
             @Override
             public boolean apply(@Nullable Module module) {
               return checkModuleDependency(module, rootModules);
             }
           }));
 }
 private void processForAdditionalModules(
     SchemaContext delegate,
     final Set<ModuleId> additionalModuleIds,
     Builder<Module> filteredModulesBuilder) {
   filteredModulesBuilder.addAll(
       Collections2.filter(
           delegate.getModules(),
           new Predicate<Module>() {
             @Override
             public boolean apply(@Nullable Module module) {
               return selectAdditionalModules(module, additionalModuleIds);
             }
           }));
 }
 @Override
 public Set<? extends Hardware> get() {
   Builder<Hardware> sizes = ImmutableSet.builder();
   sizes.add(cc1_4xlarge().supportsImageIds(ccAmis).build());
   sizes.add(cg1_4xlarge().supportsImageIds(ccAmis).build());
   sizes.add(cc2_8xlarge().supportsImageIds(ccAmis).build());
   sizes.add(hi1_4xlarge().supportsImageIds(ccAmis).build());
   sizes.add(hs1_8xlarge().supportsImageIds(ccAmis).build());
   sizes.addAll(
       ImmutableSet.<Hardware>of(
           t1_micro().build(),
           c1_medium().build(),
           c1_xlarge().build(),
           m1_large().build(),
           m1_small().build(),
           m1_medium().build(),
           m1_xlarge().build(),
           m2_xlarge().build(),
           m2_2xlarge().build(),
           m2_4xlarge().build(),
           m3_xlarge().build(),
           m3_2xlarge().build()));
   return sizes.build();
 }
 @Override
 public Set<E> read(JsonReader in) throws IOException {
   if (in.peek() == JsonToken.BEGIN_OBJECT) {
     Builder<E> builder = ImmutableSet.<E>builder();
     boolean foundValues = false;
     in.beginObject();
     while (in.hasNext()) {
       String name = in.nextName();
       if (Objects.equal("values", name)) {
         foundValues = true;
         builder.addAll(delegate.read(in));
       } else {
         in.skipValue();
       }
     }
     checkState(
         foundValues,
         "Expected BEGIN_ARRAY or the object to contain an array called 'values'");
     in.endObject();
     return builder.build();
   } else {
     return delegate.read(in);
   }
 }