[BugĀ 410843] Unsupported servers cannot be removed from list of generic
client runtimes
[BugĀ 410844] Restrict supported servers for client and service runtimes 
diff --git a/bundles/org.eclipse.jst.ws.consumption.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.jst.ws.consumption.ui/META-INF/MANIFEST.MF
index 43e6238..0d179f5 100644
--- a/bundles/org.eclipse.jst.ws.consumption.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jst.ws.consumption.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %PLUGIN_NAME
 Bundle-SymbolicName: org.eclipse.jst.ws.consumption.ui; singleton:=true
-Bundle-Version: 1.1.350.qualifier
+Bundle-Version: 1.1.351.qualifier
 Bundle-Activator: org.eclipse.jst.ws.internal.consumption.ui.plugin.WebServiceConsumptionUIPlugin
 Bundle-Vendor: %PLUGIN_PROVIDER
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/widgets/runtime/ProjectSelectionWidget.java b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/widgets/runtime/ProjectSelectionWidget.java
index 8614d80..9b749c9 100644
--- a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/widgets/runtime/ProjectSelectionWidget.java
+++ b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/widgets/runtime/ProjectSelectionWidget.java
@@ -289,13 +289,14 @@
     listenersOff();
     String selectedModuleProject = moduleProject_.getText();    
     String runtimeId = trsIds_.getRuntimeId();
+    String serverId = trsIds_.getServerId();
     String typeId = trsIds_.getTypeId();
     
     //Get all the projects that are compatible with the type and runtime
     String[] projectNames = null;
     if (isClient_)
     {
-      projectNames = WebServiceRuntimeExtensionUtils2.getProjectsForClientTypeAndRuntime(typeId, runtimeId);
+      projectNames = WebServiceRuntimeExtensionUtils2.getProjectsForClientTypeAndRuntime(typeId, runtimeId, serverId);
     }
     else
     {
diff --git a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ClientRuntimeDescriptor.java b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ClientRuntimeDescriptor.java
index 1163198..fe1554b 100644
--- a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ClientRuntimeDescriptor.java
+++ b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ClientRuntimeDescriptor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.runtime.CoreException;
@@ -47,12 +48,17 @@
   private String runtimePreferredServerType;
   private  Set<String> suitableProjectTemplates;
   private  Set<String> unsuitableProjectTemplates;
+  private boolean allowClientServerRestriction;
+  private List<String> supportedServers;
+  private List<String> unsupportedServers;
   
   public ClientRuntimeDescriptor(IConfigurationElement elem, Hashtable allWebServiceClientImpls, Hashtable allRuntimes)
   {
     this.elem = elem;
     this.allWebServiceClientImpls = allWebServiceClientImpls;
     this.allRuntimes = allRuntimes;
+    
+    allowClientServerRestriction = Boolean.parseBoolean(elem.getAttribute("allowClientServerRestriction"));
   }
   
   public WebServiceClientImpl getClientImplementationType()
@@ -220,4 +226,46 @@
     }
     return runtimePreferredServerType;
   }
+  
+  public boolean allowClientServersRestriction() {
+	  return allowClientServerRestriction;
+  }
+   
+  /**
+   * Note that only the supported or unsupported attribute should be used, not both.
+   */
+  public boolean isSupportedServer(String id) {
+	if(!allowClientServerRestriction)
+		return false;
+	if(supportedServers == null) {
+		String serverElements = elem.getAttribute("supportedServers");
+		supportedServers = parseServers(serverElements);
+	}
+	return supportedServers.contains(id);
+  }
+  
+  /**
+   * Note that only the supported or unsupported attribute should be used, not both.
+   */
+  public boolean isUnsupportedServer(String id) {
+	if(!allowClientServerRestriction)
+		return false;
+	if(unsupportedServers == null) {
+		String serverElements = elem.getAttribute("unsupportedServers");
+		unsupportedServers = parseServers(serverElements);
+	}
+	return unsupportedServers.contains(id);
+  }
+  
+  private List<String> parseServers(String serverElements) {
+	List<String> serverList = new ArrayList<String>();
+	if(serverElements != null) {
+		String[] servers = serverElements.split("\\s+");
+		for (int i = 0; i < servers.length; i++)  {
+			if (servers[i].length() > 0)
+				serverList.add(servers[i]);
+		}
+	}
+	return serverList;
+  }
 }
diff --git a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ServiceRuntimeDescriptor.java b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ServiceRuntimeDescriptor.java
index 2397cbe..b653469 100644
--- a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ServiceRuntimeDescriptor.java
+++ b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/ServiceRuntimeDescriptor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.runtime.CoreException;
@@ -39,6 +40,7 @@
   private IConfigurationElement elem;
   private Hashtable allWebServiceImpls;
   private Hashtable allRuntimes;
+  private boolean allowServiceServerRestriction;
   private String id;
   private WebServiceImpl serviceImplementationType;
   private RuntimeDescriptor runtime;
@@ -52,6 +54,7 @@
   private String runtimePreferredServerType;
   private  Set<String> suitableProjectTemplates;
   private  Set<String> unsuitableProjectTemplates;
+  private List<String> supportedServers;
   
   public ServiceRuntimeDescriptor(IConfigurationElement elem, Hashtable allWebServiceImpls, Hashtable allRuntimes)
   {
@@ -59,6 +62,7 @@
     this.allWebServiceImpls = allWebServiceImpls;
     this.allRuntimes = allRuntimes;
 
+    allowServiceServerRestriction = Boolean.parseBoolean(elem.getAttribute("allowServiceServerRestriction"));
     bottomUp = (Boolean.valueOf(elem.getAttribute("bottomUp"))).booleanValue();
     topDown = (Boolean.valueOf(elem.getAttribute("topDown"))).booleanValue();    
   }
@@ -252,4 +256,30 @@
     }
     return runtimePreferredServerType;
   }
+  
+  public boolean allowServiceServersRestriction() {
+	  return allowServiceServerRestriction;
+  }
+    
+  public boolean isSupportedServer(String id) {
+	if(!allowServiceServerRestriction)
+		return false;
+	if(supportedServers == null) {
+		String serverElements = elem.getAttribute("supportedServers");
+		supportedServers = parseServers(serverElements);
+	}
+	return supportedServers.contains(id);
+  }
+  
+  private List<String> parseServers(String serverElements) {
+	List<String> serverList = new ArrayList<String>();
+	if(serverElements != null) {
+		String[] servers = serverElements.split("\\s+");
+		for (int i = 0; i < servers.length; i++)  {
+			if (servers[i].length() > 0)
+				serverList.add(servers[i]);
+		}
+	}
+	return serverList;
+  }
 }
diff --git a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/WebServiceRuntimeExtensionUtils2.java b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/WebServiceRuntimeExtensionUtils2.java
index c37dbd1..ef21872 100644
--- a/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/WebServiceRuntimeExtensionUtils2.java
+++ b/bundles/org.eclipse.jst.ws.consumption.ui/src/org/eclipse/jst/ws/internal/consumption/ui/wsrt/WebServiceRuntimeExtensionUtils2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -753,6 +753,13 @@
     {
       if (serverIds[i].equals(serverFactoryId))
       {
+      	  ServiceRuntimeDescriptor desc = getServiceRuntimeDescriptorById(serviceRuntimeId);
+    	  if(desc.allowServiceServersRestriction()) {
+    		  if(desc.isSupportedServer(serverFactoryId))
+    			  return true;
+    		  else
+    			  continue;
+    	  }
         return true;
       }
     }
@@ -967,6 +974,12 @@
           {
             if (fIds[j].equals(serverFactoryId))
             {
+            	if(desc.allowServiceServersRestriction()) {
+            		if(desc.isSupportedServer(serverFactoryId))
+            			return true;
+            		else
+            			continue;
+            	}
               return true;
             }
           }          
@@ -1639,6 +1652,13 @@
     {
       if (serverIds[i].equals(serverFactoryId))
       {
+        ClientRuntimeDescriptor desc = getClientRuntimeDescriptorById(clientRuntimeId);
+    	if(desc.allowClientServersRestriction()) {
+    		if(desc.isSupportedServer(serverFactoryId))
+    			return true;
+    		else
+    			continue;
+    	}
         return true;
       }
     }
@@ -1741,7 +1761,8 @@
           String[] factoryIds = getServerFactoryIdsByClientRuntime(desc.getId());
           for (int j=0; j<factoryIds.length; j++)
           {
-            if (factoryIds[j].equals(serverFactoryId))
+          	// Check if the IDs match and the server is supported by the client.
+            if (factoryIds[j].equals(serverFactoryId) && !desc.isUnsupportedServer(serverFactoryId))
             {
               return true;
             }
@@ -1779,7 +1800,8 @@
     	if (serverId == null || doesClientRuntimeSupportServer(crIds[i], serverId)) { 
 	      ClientRuntimeDescriptor desc = getClientRuntimeDescriptorById(crIds[i]);
 	      String thisRuntimeId = desc.getRuntime().getId();
-	      if (thisRuntimeId.equals(runtimeId))
+	      // Check if the IDs match and the server is supported by the runtime.
+	      if (thisRuntimeId.equals(runtimeId) && !desc.isUnsupportedServer(serverId))
 	      {
 	        //Get the templates for this clientRuntime
 	        Set templates = FacetMatchCache.getInstance().getTemplatesForClientRuntime(desc.getId());
@@ -1985,12 +2007,26 @@
    */
   public static String[] getProjectsForClientTypeAndRuntime(String typeId, String runtimeId)
   {
+	  return getProjectsForClientTypeAndRuntime(typeId, runtimeId, null);
+  }
+  
+  /**
+   * Returns the names of all projects in the workspace which support the given Web service client 
+   * implementation type and Web service runtime.
+   * 
+   * @param typeId id of a Web service client implementation type
+   * @param runtimeId id of a Web service runtime
+   * @param serverId id of the target server for filtering unsupported server runtimes
+   * @return String[] array of project names. The array may have 0 elements.
+   */
+  public static String[] getProjectsForClientTypeAndRuntime(String typeId, String runtimeId, String serverId)
+  {
     IProject[] projects = FacetUtils.getAllProjects();
     ArrayList validProjects = new ArrayList();
     
     for (int i=0; i<projects.length;i++)
     {
-      if (doesClientTypeAndRuntimeSupportProject(typeId, runtimeId, projects[i].getName()))
+      if (doesClientTypeAndRuntimeSupportProject(typeId, runtimeId, projects[i].getName(), serverId))
       {
         validProjects.add(projects[i].getName());        
       }      
@@ -2016,7 +2052,28 @@
    * <li>if projectName is null or empty</li>
    * </ul>
    */
-  public static boolean doesClientTypeAndRuntimeSupportProject(String typeId, String runtimeId, String projectName)
+  public static boolean doesClientTypeAndRuntimeSupportProject(String typeId, String runtimeId, String projectName) {
+	  return doesClientTypeAndRuntimeSupportProject(typeId, runtimeId, projectName, null);
+  }
+  
+  /**
+   * Returns whether or not the given project supports the given Web service client implementation type 
+   * and Web service runtime.
+   * 
+   * @param typeId id of a Web service client implementation type
+   * @param runtimeId id of a Web service runtime
+   * @param projectName name of an IProject in the workspace
+   * @param serverId id of the target server for filtering unsupported server runtimes
+   * @return boolean <code>true</code> if the project supports the given Web service type and 
+   * Web service runtime. Returns <code>false</code>
+   * <ul> 
+   * <li>if the project does not support the given Web service client implementation type and 
+   * Web service runtime or</li>
+   * <li>if the project does not exist or</li>
+   * <li>if projectName is null or empty</li>
+   * </ul>
+   */
+  public static boolean doesClientTypeAndRuntimeSupportProject(String typeId, String runtimeId, String projectName, String serverId)
   {
     String[] descs = getClientRuntimesByType(typeId);
     for (int j = 0; j < descs.length; j++)
@@ -2024,7 +2081,7 @@
       ClientRuntimeDescriptor desc = getClientRuntimeDescriptorById(descs[j]);
       if (desc.getRuntime().getId().equals(runtimeId))
       {
-        if (doesClientRuntimeSupportProject(descs[j], projectName))
+        if (doesClientRuntimeSupportProject(descs[j], projectName, serverId))
         {
           return true;
         }
@@ -2049,8 +2106,31 @@
    * <li>if projectName is null or empty</li>
    * </ul>
    */
-  public static boolean doesClientRuntimeSupportProject(String clientRuntimeId, String projectName)
+  public static boolean doesClientRuntimeSupportProject(String clientRuntimeId, String projectName) {
+	  return doesClientRuntimeSupportProject(clientRuntimeId, projectName, null);
+  }
+  
+  /**
+   * Returns whether or not the given project supports the given clientRuntime.
+   * @param clientRuntimeId id of a clientRuntime
+   * @param projectName name of an IProject in the workspace
+   * @param serverId id of the target server for filtering unsupported server runtimes
+   * @return boolean <code>true</code> if the project supports the given
+   * clientRuntime. Returns <code>false</code>
+   * <ul> 
+   * <li>if the project does not support the given clientRuntime or</li>
+   * <li>if the project does not exist or</li>
+   * <li>if projectName is null or empty</li>
+   * </ul>
+   */
+  public static boolean doesClientRuntimeSupportProject(String clientRuntimeId, String projectName, String serverId)
   {
+  	// Check if there is an unsupported server to filter
+	if(serverId != null) {
+		ClientRuntimeDescriptor desc = getClientRuntimeDescriptorById(clientRuntimeId);
+		if(desc.isUnsupportedServer(serverId))
+			return false;
+	}
     FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(true, clientRuntimeId, projectName);
     if (fm != null)
     {