code: @Nonnull
    final String writeManifest( @Nonnull final TreeLogger logger,
                                @Nonnull final Set<String> staticResources,
                                @Nonnull final Map<String, String> fallbackResources,
                                @Nonnull final Set<String> cacheResources )
      throws UnableToCompleteException
    {
      final ManifestDescriptor descriptor = new ManifestDescriptor();
      final List<String> cachedResources =
        Stream
          .concat( staticResources.stream(), cacheResources.stream() )
          .sorted()
          .distinct()
          .collect( Collectors.toList() );
      descriptor.getCachedResources().addAll( cachedResources );
      descriptor.getFallbackResources().putAll( fallbackResources );
      descriptor.getNetworkResources().add( "*" );
      try
      {
        return descriptor.toString();
      }
      catch ( final Exception e )
      {
        logger.log( Type.ERROR, "Error generating manifest: " + e, e );
        throw new UnableToCompleteException();
      }
    }
docs: Write a manifest file for the given set of artifacts and return it as a
  string
  
  @param staticResources   - the static resources of the app, such as
  index.html file
  @param fallbackResources the fall back files to add to the manifest.
  @param cacheResources    the gwt output artifacts like cache.html files
  @return the manifest as a string