void assertServiceIdentification(WFSCapabilitiesType caps) {
    ServiceIdentificationType sa = caps.getServiceIdentification();
    assertNotNull(sa);

    assertEquals(1, sa.getKeywords().size());

    KeywordsType keywords = (KeywordsType) sa.getKeywords().get(0);
    List<String> simpleKeywords = new ArrayList<String>();
    for (Object o : keywords.getKeyword()) {
      LanguageStringType lst = (LanguageStringType) o;
      simpleKeywords.add(lst.getValue());
    }
    assertTrue(simpleKeywords.contains("WFS"));
    assertTrue(simpleKeywords.contains("WMS"));
    assertTrue(simpleKeywords.contains("GEOSERVER"));

    assertEquals("WFS", sa.getServiceType().getValue());
    assertEquals("2.0.0", sa.getServiceTypeVersion().get(0));
  }
  public WPSCapabilitiesType run(GetCapabilitiesType request) throws WPSException {
    // do the version negotiation dance
    List<String> provided = Collections.singletonList("1.0.0");
    List<String> accepted = null;
    if (request.getAcceptVersions() != null) accepted = request.getAcceptVersions().getVersion();
    String version = RequestUtils.getVersionOws11(provided, accepted);

    if (!"1.0.0".equals(version)) {
      throw new WPSException("Could not understand version:" + version);
    }

    // TODO: add update sequence negotiation

    // encode the response
    Wps10Factory wpsf = Wps10Factory.eINSTANCE;
    Ows11Factory owsf = Ows11Factory.eINSTANCE;

    WPSCapabilitiesType caps = wpsf.createWPSCapabilitiesType();
    caps.setVersion("1.0.0");

    // TODO: make configurable
    caps.setLang("en");

    // ServiceIdentification
    ServiceIdentificationType si = owsf.createServiceIdentificationType();
    caps.setServiceIdentification(si);

    si.getTitle().add(Ows11Util.languageString(wps.getTitle()));
    si.getAbstract().add(Ows11Util.languageString(wps.getAbstract()));

    KeywordsType kw = Ows11Util.keywords(wps.keywordValues());
    ;
    if (kw != null) {
      si.getKeywords().add(kw);
    }

    si.setServiceType(Ows11Util.code("WPS"));
    si.getServiceTypeVersion().add("1.0.0");
    si.setFees(wps.getFees());

    if (wps.getAccessConstraints() != null) {
      si.getAccessConstraints().add(wps.getAccessConstraints());
    }

    // ServiceProvider
    ServiceProviderType sp = owsf.createServiceProviderType();
    caps.setServiceProvider(sp);

    // TODO: set provder name from context
    GeoServerInfo geoServer = wps.getGeoServer().getGlobal();
    if (geoServer.getContact().getContactOrganization() != null) {
      sp.setProviderName(geoServer.getContact().getContactOrganization());
    } else {
      sp.setProviderName("GeoServer");
    }

    sp.setProviderSite(owsf.createOnlineResourceType());
    sp.getProviderSite().setHref(geoServer.getOnlineResource());
    sp.setServiceContact(responsibleParty(geoServer, owsf));

    // OperationsMetadata
    OperationsMetadataType om = owsf.createOperationsMetadataType();
    caps.setOperationsMetadata(om);

    OperationType gco = owsf.createOperationType();
    gco.setName("GetCapabilities");
    gco.getDCP().add(Ows11Util.dcp("wps", request));
    om.getOperation().add(gco);

    OperationType dpo = owsf.createOperationType();
    dpo.setName("DescribeProcess");
    dpo.getDCP().add(Ows11Util.dcp("wps", request));
    om.getOperation().add(dpo);

    OperationType eo = owsf.createOperationType();
    eo.setName("Execute");
    eo.getDCP().add(Ows11Util.dcp("wps", request));
    om.getOperation().add(eo);

    ProcessOfferingsType po = wpsf.createProcessOfferingsType();
    caps.setProcessOfferings(po);

    // gather the process list
    for (ProcessFactory pf : Processors.getProcessFactories()) {
      for (Name name : pf.getNames()) {
        if (!getProcessBlacklist().contains(name)) {
          ProcessBriefType p = wpsf.createProcessBriefType();
          p.setProcessVersion(pf.getVersion(name));
          po.getProcess().add(p);

          p.setIdentifier(Ows11Util.code(name));
          p.setTitle(Ows11Util.languageString(pf.getTitle(name)));
          p.setAbstract(Ows11Util.languageString(pf.getDescription(name)));
        }
      }
    }
    // sort it
    ECollections.sort(
        po.getProcess(),
        new Comparator() {

          public int compare(Object o1, Object o2) {
            ProcessBriefType pb1 = (ProcessBriefType) o1;
            ProcessBriefType pb2 = (ProcessBriefType) o2;

            final String id1 = pb1.getIdentifier().getValue();
            final String id2 = pb2.getIdentifier().getValue();
            return id1.compareTo(id2);
          }
        });

    LanguagesType1 languages = wpsf.createLanguagesType1();
    caps.setLanguages(languages);

    DefaultType2 defaultLanguage = wpsf.createDefaultType2();
    languages.setDefault(defaultLanguage);
    defaultLanguage.setLanguage("en-US");

    LanguagesType supportedLanguages = wpsf.createLanguagesType();
    languages.setSupported(supportedLanguages);
    supportedLanguages.getLanguage().add("en-US");

    return caps;
    // Version detection and alternative invocation if being implemented.
  }