<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def GenApiConfig(service_class_names, config_string_generator=None, hostname=None, application_path=None, **additional_kwargs):
 """Write an API configuration for endpoints annotated ProtoRPC services. Args: service_class_names: A list of fully qualified ProtoRPC service classes. config_string_generator: A generator object that produces API config strings using its pretty_print_config_to_json method. hostname: A string hostname which will be used as the default version hostname. If no hostname is specificied in the @endpoints.api decorator, this value is the fallback. application_path: A string with the path to the AppEngine application. Raises: TypeError: If any service classes don't inherit from remote.Service. messages.DefinitionNotFoundError: If a service can't be found. Returns: A map from service names to a string containing the API configuration of the service in JSON format. """

  # First, gather together all the different APIs implemented by these
  # classes.  There may be fewer APIs than service classes.  Each API is
  # uniquely identified by (name, version).  Order needs to be preserved here,
  # so APIs that were listed first are returned first.
  api_service_map = collections.OrderedDict()
  resolved_services = []

  for service_class_name in service_class_names:
    module_name, base_service_class_name = service_class_name.rsplit('.', 1)
    module = __import__(module_name, fromlist=base_service_class_name)
    service = getattr(module, base_service_class_name)
    if hasattr(service, 'get_api_classes'):
      resolved_services.extend(service.get_api_classes())
    elif (not isinstance(service, type) or
          not issubclass(service, remote.Service)):
      raise TypeError('%s is not a ProtoRPC service' % service_class_name)
    else:
      resolved_services.append(service)

  for resolved_service in resolved_services:
    services = api_service_map.setdefault(
        (resolved_service.api_info.name, resolved_service.api_info.api_version), [])
    services.append(resolved_service)

  # If hostname isn't specified in the API or on the command line, we'll
  # try to build it from information in app.yaml.
  app_yaml_hostname = _GetAppYamlHostname(application_path)

  service_map = collections.OrderedDict()
  config_string_generator = (
      config_string_generator or api_config.ApiConfigGenerator())
  for api_info, services in api_service_map.iteritems():
    assert services, 'An API must have at least one ProtoRPC service'
    # Only override hostname if None.  Hostname will be the same for all
    # services within an API, since it's stored in common info.
    hostname = services[0].api_info.hostname or hostname or app_yaml_hostname

    # Map each API by name-version.
    service_map['%s-%s' % api_info] = (
        config_string_generator.pretty_print_config_to_json(
            services, hostname=hostname, **additional_kwargs))

  return service_map