http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/PartialServiceDescriptionsNotification.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/PartialServiceDescriptionsNotification.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/PartialServiceDescriptionsNotification.java
new file mode 100644
index 0000000..763b32a
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/PartialServiceDescriptionsNotification.java
@@ -0,0 +1,41 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import java.util.Collection;
+
+import org.apache.taverna.servicedescriptions.ServiceDescription;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class PartialServiceDescriptionsNotification extends
+               AbstractProviderNotification {
+       private final Collection<? extends ServiceDescription> 
serviceDescriptions;
+
+       public PartialServiceDescriptionsNotification(
+                       ServiceDescriptionProvider provider,
+                       Collection<? extends ServiceDescription> 
serviceDescriptions) {
+               super(provider, "Found " + serviceDescriptions.size() + " 
services");
+               this.serviceDescriptions = serviceDescriptions;
+       }
+
+       public Collection<? extends ServiceDescription> 
getServiceDescriptions() {
+               return serviceDescriptions;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderErrorNotification.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderErrorNotification.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderErrorNotification.java
new file mode 100644
index 0000000..ed786f5
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderErrorNotification.java
@@ -0,0 +1,38 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class ProviderErrorNotification extends AbstractProviderNotification {
+
+       private final Throwable cause;
+
+       public ProviderErrorNotification(ServiceDescriptionProvider provider,
+                       String message, Throwable cause) {
+               super(provider, message);
+               this.cause = cause;
+       }
+
+       public Throwable getCause() {
+               return cause;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderStatusNotification.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderStatusNotification.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderStatusNotification.java
new file mode 100644
index 0000000..384631e
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderStatusNotification.java
@@ -0,0 +1,31 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class ProviderStatusNotification extends AbstractProviderNotification {
+
+       public ProviderStatusNotification(ServiceDescriptionProvider provider,
+                       String message) {
+               super(provider, message);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderUpdatingNotification.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderUpdatingNotification.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderUpdatingNotification.java
new file mode 100644
index 0000000..3e35c5d
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderUpdatingNotification.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class ProviderUpdatingNotification extends AbstractProviderNotification 
{
+
+       public ProviderUpdatingNotification(ServiceDescriptionProvider 
provider) {
+               super(provider, "Updating");
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderWarningNotification.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderWarningNotification.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderWarningNotification.java
new file mode 100644
index 0000000..3348504
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ProviderWarningNotification.java
@@ -0,0 +1,31 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class ProviderWarningNotification extends AbstractProviderNotification {
+
+       public ProviderWarningNotification(ServiceDescriptionProvider provider,
+                       String message) {
+               super(provider, message);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/RemovedProviderEvent.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/RemovedProviderEvent.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/RemovedProviderEvent.java
new file mode 100644
index 0000000..b2b0494
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/RemovedProviderEvent.java
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class RemovedProviderEvent extends AbstractProviderEvent {
+
+       public RemovedProviderEvent(ServiceDescriptionProvider provider) {
+               super(provider);
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionProvidedEvent.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionProvidedEvent.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionProvidedEvent.java
new file mode 100644
index 0000000..520906c
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionProvidedEvent.java
@@ -0,0 +1,39 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+import java.util.Set;
+
+import org.apache.taverna.servicedescriptions.ServiceDescription;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+
+public class ServiceDescriptionProvidedEvent extends AbstractProviderEvent {
+       private final Set<ServiceDescription> serviceDescriptions;
+
+       public ServiceDescriptionProvidedEvent(ServiceDescriptionProvider 
provider,
+                       Set<ServiceDescription> serviceDescriptions) {
+               super(provider);
+               this.serviceDescriptions = serviceDescriptions;
+       }
+
+       public Set<ServiceDescription> getServiceDescriptions() {
+               return serviceDescriptions;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionRegistryEvent.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionRegistryEvent.java
 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionRegistryEvent.java
new file mode 100644
index 0000000..68c98b2
--- /dev/null
+++ 
b/taverna-activity-palette-api/src/main/java/org/apache/taverna/servicedescriptions/events/ServiceDescriptionRegistryEvent.java
@@ -0,0 +1,23 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.servicedescriptions.events;
+
+public abstract class ServiceDescriptionRegistryEvent {
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionConstants.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionConstants.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionConstants.java
deleted file mode 100644
index c5221be..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionConstants.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-public interface ServiceDescriptionConstants {
-       String SERVICE_PANEL_CONFIGURATION = "servicePanelConfiguration";
-       String PROVIDERS = "providers";
-       String IGNORED = "ignored";
-       String PROVIDER_ID = "providerID";
-       String CONFIGURATION = "configuration";
-       String TYPE = "type";
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
deleted file mode 100644
index 379888a..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.CONFIGURATION;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.IGNORED;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDERS;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDER_ID;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.TYPE;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.taverna.scufl2.api.configurations.Configuration;
-import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-class ServiceDescriptionDeserializer {
-       private List<ServiceDescriptionProvider> serviceDescriptionProviders;
-
-       ServiceDescriptionDeserializer(
-                       List<ServiceDescriptionProvider> 
serviceDescriptionProviders) {
-               this.serviceDescriptionProviders = serviceDescriptionProviders;
-       }
-
-       public void deserialize(ServiceDescriptionRegistry registry,
-                       File serviceDescriptionsFile) throws 
DeserializationException {
-               try (FileInputStream serviceDescriptionFileStream = new 
FileInputStream(
-                               serviceDescriptionsFile)) {
-                       deserialize(registry, serviceDescriptionFileStream);
-               } catch (FileNotFoundException ex) {
-                       throw new DeserializationException("Could not locate 
file "
-                                       + 
serviceDescriptionsFile.getAbsolutePath()
-                                       + " containing service descriptions.");
-               } catch (IOException ex) {
-                       throw new DeserializationException(
-                                       "Could not read stream containing 
service descriptions from "
-                                                       + 
serviceDescriptionsFile.getAbsolutePath(), ex);
-               }
-       }
-
-       public void deserialize(ServiceDescriptionRegistry registry,
-                       URL serviceDescriptionsURL) throws 
DeserializationException {
-               try (InputStream serviceDescriptionInputStream = 
serviceDescriptionsURL
-                               .openStream()) {
-                       deserialize(registry, serviceDescriptionInputStream);
-               } catch (FileNotFoundException ex) {
-                       throw new DeserializationException("Could not open URL "
-                                       + serviceDescriptionsURL
-                                       + " containing service descriptions.");
-               } catch (IOException ex) {
-                       throw new DeserializationException(
-                                       "Could not read stream containing 
service descriptions from "
-                                                       + 
serviceDescriptionsURL, ex);
-               }
-       }
-
-       private static final JsonFactory factory = new JsonFactory();
-
-       private void deserialize(ServiceDescriptionRegistry registry,
-                       InputStream serviceDescriptionsInputStream) throws 
IOException,
-                       DeserializationException {
-               ObjectNode node = (ObjectNode) new ObjectMapper(factory)
-                               .readTree(serviceDescriptionsInputStream);
-               List<ServiceDescriptionProvider> providers = 
deserializeProviders(node,
-                               true);
-               for (ServiceDescriptionProvider provider : providers)
-                       registry.addServiceDescriptionProvider(provider);
-       }
-
-       public Collection<? extends ServiceDescriptionProvider> 
deserializeDefaults(
-                       ServiceDescriptionRegistry registry,
-                       File defaultConfigurableServiceProvidersFile)
-                       throws DeserializationException {
-               ObjectNode node;
-               try (FileInputStream serviceDescriptionStream = new 
FileInputStream(
-                               defaultConfigurableServiceProvidersFile)) {
-                       node = (ObjectNode) new ObjectMapper(factory)
-                                       .readTree(serviceDescriptionStream);
-               } catch (IOException e) {
-                       throw new DeserializationException("Can't read "
-                                       + 
defaultConfigurableServiceProvidersFile);
-               }
-               return deserializeProviders(node, false);
-       }
-
-       private List<ServiceDescriptionProvider> deserializeProviders(
-                       ObjectNode rootNode, boolean obeyIgnored)
-                       throws DeserializationException {
-               List<ServiceDescriptionProvider> providers = new ArrayList<>();
-
-               ArrayNode providersNode = (ArrayNode) rootNode.get(PROVIDERS);
-               if (providersNode != null)
-                       for (JsonNode provider : providersNode)
-                               providers.add(deserializeProvider((ObjectNode) 
provider));
-
-               if (obeyIgnored) {
-                       ArrayNode ignoredNode = (ArrayNode) 
rootNode.get(IGNORED);
-                       if (ignoredNode != null)
-                               for (JsonNode provider : ignoredNode)
-                                       providers
-                                                       
.remove(deserializeProvider((ObjectNode) provider));
-               }
-
-               return providers;
-       }
-
-       private ServiceDescriptionProvider deserializeProvider(
-                       ObjectNode providerNode) throws 
DeserializationException {
-               String providerId = 
providerNode.get(PROVIDER_ID).asText().trim();
-               ServiceDescriptionProvider provider = null;
-               for (ServiceDescriptionProvider serviceProvider : 
serviceDescriptionProviders)
-                       if (serviceProvider.getId().equals(providerId)) {
-                               provider = serviceProvider;
-                               break;
-                       }
-               if (provider == null)
-                       throw new DeserializationException(
-                                       "Could not find provider with id " + 
providerId);
-
-               /*
-                * So we know the service provider now, but we need a separate 
instance
-                * of that provider for each providerElem. E.g. we can have 2 
or more
-                * WSDL provider elements and need to return a separate provider
-                * instance for each as they will have different configurations.
-                */
-               ServiceDescriptionProvider instance = provider.newInstance();
-
-               if (instance instanceof ConfigurableServiceProvider)
-                       try {
-                               Configuration config = new Configuration();
-                               
config.setType(URI.create(providerNode.get(TYPE).textValue()));
-                               config.setJson(providerNode.get(CONFIGURATION));
-                               if (config != null)
-                                       ((ConfigurableServiceProvider) 
instance).configure(config);
-                       } catch (Exception e) {
-                               throw new DeserializationException(
-                                               "Could not configure provider " 
+ providerId
-                                                               + " using bean 
" + providerNode, e);
-                       }
-               return instance;
-       }
-
-       @SuppressWarnings("serial")
-       static class DeserializationException extends Exception {
-               public DeserializationException(String string) {
-                       super(string);
-               }
-
-               public DeserializationException(String string, Exception ex) {
-                       super(string, ex);
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
deleted file mode 100644
index d481727..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
+++ /dev/null
@@ -1,652 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-import static java.lang.System.currentTimeMillis;
-import static java.lang.Thread.MIN_PRIORITY;
-import static java.lang.Thread.currentThread;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.taverna.lang.observer.MultiCaster;
-import org.apache.taverna.lang.observer.Observer;
-import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionsConfiguration;
-import 
net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider.FindServiceDescriptionsCallBack;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
-import net.sf.taverna.t2.servicedescriptions.events.AddedProviderEvent;
-import 
net.sf.taverna.t2.servicedescriptions.events.PartialServiceDescriptionsNotification;
-import net.sf.taverna.t2.servicedescriptions.events.ProviderErrorNotification;
-import net.sf.taverna.t2.servicedescriptions.events.ProviderStatusNotification;
-import 
net.sf.taverna.t2.servicedescriptions.events.ProviderUpdatingNotification;
-import 
net.sf.taverna.t2.servicedescriptions.events.ProviderWarningNotification;
-import net.sf.taverna.t2.servicedescriptions.events.RemovedProviderEvent;
-import 
net.sf.taverna.t2.servicedescriptions.events.ServiceDescriptionProvidedEvent;
-import 
net.sf.taverna.t2.servicedescriptions.events.ServiceDescriptionRegistryEvent;
-import 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionDeserializer.DeserializationException;
-
-import org.apache.commons.beanutils.BeanUtils;
-import org.apache.log4j.Logger;
-
-import uk.org.taverna.configuration.app.ApplicationConfiguration;
-
-public class ServiceDescriptionRegistryImpl implements 
ServiceDescriptionRegistry {
-       /**
-        * If a writable property of this name on a provider exists (ie. the 
provider has a method
-        * setServiceDescriptionRegistry(ServiceDescriptionRegistry registry) - 
then this property will
-        * be set to the current registry.
-        */
-       public static final String SERVICE_DESCRIPTION_REGISTRY = 
"serviceDescriptionRegistry";
-       public static Logger logger = 
Logger.getLogger(ServiceDescriptionRegistryImpl.class);
-       public static final ThreadGroup threadGroup = new ThreadGroup("Service 
description providers");
-       /**
-        * Total maximum timeout while waiting for description threads to finish
-        */
-       private static final long DESCRIPTION_THREAD_TIMEOUT_MS = 3000;
-       protected static final String CONF_DIR = "conf";
-       protected static final String SERVICE_PROVIDERS_FILENAME = 
"service_providers.xml";
-       private static final String 
DEFAULT_CONFIGURABLE_SERVICE_PROVIDERS_FILENAME = 
"default_service_providers.xml";
-
-       private ServiceDescriptionsConfiguration serviceDescriptionsConfig;
-       private ApplicationConfiguration applicationConfiguration;
-       /**
-        * <code>false</code> until first call to {@link 
#loadServiceProviders()} - which is done by
-        * first call to {@link #getServiceDescriptionProviders()}.
-        */
-       private boolean hasLoadedProviders = false;
-       /**
-        * <code>true</code> while {@link #loadServiceProviders(File)},
-        * {@link #loadServiceProviders(URL)} or {@link 
#loadServiceProviders()} is in progress, avoids
-        * triggering {@link #saveServiceDescriptions()} on
-        * {@link #addServiceDescriptionProvider(ServiceDescriptionProvider)} 
calls.
-        */
-       private boolean loading = false;
-       private MultiCaster<ServiceDescriptionRegistryEvent> observers = new 
MultiCaster<>(this);
-       private List<ServiceDescriptionProvider> serviceDescriptionProviders;
-       private Set<ServiceDescriptionProvider> allServiceProviders;
-       private Map<ServiceDescriptionProvider, Set<ServiceDescription>> 
providerDescriptions = new HashMap<>();
-       private Map<ServiceDescriptionProvider, Thread> 
serviceDescriptionThreads = new HashMap<>();
-       /**
-        * Service providers added by the user, should be saved
-        */
-       private Set<ServiceDescriptionProvider> userAddedProviders = new 
HashSet<>();
-       private Set<ServiceDescriptionProvider> userRemovedProviders = new 
HashSet<>();
-       private Set<ServiceDescriptionProvider> 
defaultServiceDescriptionProviders;
-       /**
-        * File containing a list of configured ConfigurableServiceProviders 
which is used to get the
-        * default set of service descriptions together with those provided by 
AbstractTemplateServiceS.
-        * This file is located in the conf directory of the Taverna startup 
directory.
-        */
-       private File defaultConfigurableServiceProvidersFile;
-       private boolean defaultSystemConfigurableProvidersLoaded = false;
-
-       static {
-               threadGroup.setMaxPriority(MIN_PRIORITY);
-       }
-
-       public ServiceDescriptionRegistryImpl(
-                       ApplicationConfiguration applicationConfiguration) {
-               this.applicationConfiguration = applicationConfiguration;
-               defaultConfigurableServiceProvidersFile = new File(
-                               getTavernaStartupConfigurationDirectory(),
-                               
DEFAULT_CONFIGURABLE_SERVICE_PROVIDERS_FILENAME);
-       }
-
-       /**
-        * Get the Taverna distribution (startup) configuration directory.
-        */
-       private File getTavernaStartupConfigurationDirectory() {
-               File distroHome = null;
-               File configDirectory = null;
-               distroHome = applicationConfiguration.getStartupDir();
-               configDirectory = new File(distroHome, "conf");
-               if (!configDirectory.exists())
-                       configDirectory.mkdir();
-               return configDirectory;
-       }
-
-       private static void joinThreads(Collection<? extends Thread> threads,
-                       long descriptionThreadTimeoutMs) {
-               long finishJoinBy = currentTimeMillis() + 
descriptionThreadTimeoutMs;
-               for (Thread thread : threads) {
-                       // No shorter timeout than 1 ms (thread.join(0) waits 
forever!)
-                       long timeout = Math.max(1, finishJoinBy - 
currentTimeMillis());
-                       try {
-                               thread.join(timeout);
-                       } catch (InterruptedException e) {
-                               currentThread().interrupt();
-                               return;
-                       }
-                       if (thread.isAlive())
-                               logger.debug("Thread did not finish " + thread);
-               }
-       }
-
-
-       @Override
-       public void addObserver(Observer<ServiceDescriptionRegistryEvent> 
observer) {
-               observers.addObserver(observer);
-       }
-
-       @Override
-       public void addServiceDescriptionProvider(ServiceDescriptionProvider 
provider) {
-               synchronized (this) {
-                       userRemovedProviders.remove(provider);
-                       if 
(!getDefaultServiceDescriptionProviders().contains(provider))
-                               userAddedProviders.add(provider);
-                       allServiceProviders.add(provider);
-               }
-
-               // Spring-like auto-config
-               try {
-                       // BeanUtils should ignore this if provider does not 
have that property
-                       BeanUtils.setProperty(provider, 
SERVICE_DESCRIPTION_REGISTRY, this);
-               } catch (IllegalAccessException | InvocationTargetException e) {
-                       logger.warn("Could not set serviceDescriptionRegistry 
on "
-                                       + provider, e);
-               }
-
-               if (!loading)
-                       saveServiceDescriptions();
-               observers.notify(new AddedProviderEvent(provider));
-               updateServiceDescriptions(false, false);
-       }
-
-       private File findServiceDescriptionsFile() {
-               File confDir = new File(
-                               
applicationConfiguration.getApplicationHomeDir(), CONF_DIR);
-               confDir.mkdirs();
-               if (!confDir.isDirectory())
-                       throw new RuntimeException("Invalid directory: " + 
confDir);
-               File serviceDescriptionsFile = new File(confDir,
-                               SERVICE_PROVIDERS_FILENAME);
-               return serviceDescriptionsFile;
-       }
-
-       @Override
-       public List<Observer<ServiceDescriptionRegistryEvent>> getObservers() {
-               return observers.getObservers();
-       }
-
-       // Fallback to this method that uses hardcoded default services if you 
cannot read them from
-       // the file.
-//     @SuppressWarnings("unchecked")
-//     public synchronized Set<ServiceDescriptionProvider> 
getDefaultServiceDescriptionProvidersFallback() {
-//             /*if (defaultServiceDescriptionProviders != null) {
-//      return defaultServiceDescriptionProviders;
-//      }
-//      defaultServiceDescriptionProviders = new 
HashSet<ServiceDescriptionProvider>();
-//              */
-//             for (ServiceDescriptionProvider provider : 
serviceDescriptionProviders) {
-//
-//                     /* We do not need these - already loaded them from 
getDefaultServiceDescriptionProviders()
-//      if (!(provider instanceof ConfigurableServiceProvider)) {
-//      defaultServiceDescriptionProviders.add(provider);
-//      continue;
-//      }*/
-//
-//                     // Just load the hard coded default configurable 
service providers
-//                     if (provider instanceof ConfigurableServiceProvider){
-//                             ConfigurableServiceProvider<Object> template = 
((ConfigurableServiceProvider<Object>)
-//                                             provider);
-//                             // Get configurations
-//                             List<Object> configurables = 
template.getDefaultConfigurations();
-//                             for (Object config : configurables) {
-//                                     // Make a copy that we can configure
-//                                     ConfigurableServiceProvider<Object> 
configurableProvider = template.clone();
-//                                     try {
-//                                             
configurableProvider.configure(config);
-//                                     } catch (ConfigurationException e) {
-//                                             logger.warn("Can't configure 
provider "
-//                                                             + 
configurableProvider + " with " + config);
-//                                             continue;
-//                                     }
-//                                     
defaultServiceDescriptionProviders.add(configurableProvider);
-//                             }
-//                     }
-//             }
-//             return defaultServiceDescriptionProviders;
-//     }
-
-       // Get the default services.
-       @Override
-       public synchronized Set<ServiceDescriptionProvider> 
getDefaultServiceDescriptionProviders() {
-               if (defaultServiceDescriptionProviders != null)
-                       return defaultServiceDescriptionProviders;
-               defaultServiceDescriptionProviders = new HashSet<>();
-
-               /*
-                * Add default configurable service description providers from 
the
-                * default_service_providers.xml file
-                */
-               if (defaultConfigurableServiceProvidersFile.exists()) {
-                       try {
-                               ServiceDescriptionDeserializer deserializer = 
new ServiceDescriptionDeserializer(
-                                               serviceDescriptionProviders);
-                               
defaultServiceDescriptionProviders.addAll(deserializer
-                                               .deserializeDefaults(this,
-                                                               
defaultConfigurableServiceProvidersFile));
-                               /*
-                                * We have successfully loaded the defaults for 
system
-                                * configurable providers. Note that there are 
still defaults
-                                * for third party configurable providers, 
which will be loaded
-                                * below using getDefaultConfigurations().
-                                */
-                               defaultSystemConfigurableProvidersLoaded = true;
-                       } catch (Exception e) {
-                               logger.error("Could not load default service 
providers from "
-                                               + 
defaultConfigurableServiceProvidersFile.getAbsolutePath(), e);
-
-                               /*
-                                * Fallback on the old hardcoded method of 
loading default
-                                * system configurable service providers using
-                                * getDefaultConfigurations().
-                                */
-                               defaultSystemConfigurableProvidersLoaded = 
false;
-                       }
-               } else {
-                       logger.warn("Could not find the file "
-                                       + 
defaultConfigurableServiceProvidersFile.getAbsolutePath()
-                                       + " containing default system service 
providers. "
-                                       + "Using the hardcoded list of default 
system providers.");
-
-                       /*
-                        * Fallback on the old hardcoded method of loading 
default system
-                        * configurable service providers using 
getDefaultConfigurations().
-                        */
-                       defaultSystemConfigurableProvidersLoaded = false;
-               }
-
-               /*
-                * Load other default service description providers - template, 
local
-                * workers and third party configurable service providers
-                */
-               for (ServiceDescriptionProvider provider : 
serviceDescriptionProviders) {
-                       /*
-                        * Template service providers (beanshell, string 
constant, etc. )
-                        * and providers of local workers.
-                        */
-                       if (!(provider instanceof ConfigurableServiceProvider)) 
{
-                               
defaultServiceDescriptionProviders.add(provider);
-                               continue;
-                       }
-
-                       /*
-                        * Default system or third party configurable service 
description
-                        * provider. System ones are read from the
-                        * default_service_providers.xml file so 
getDefaultConfigurations()
-                        * on them will not have much effect here unless
-                        * defaultSystemConfigurableProvidersLoaded is set to 
false.
-                        */
-                       //FIXME needs to be designed to work using 
Configuration instances
-                       //FIXME needs to get configurations via OSGi discovery
-                       /*
-                       ConfigurableServiceProvider template = 
(ConfigurableServiceProvider) provider;
-                       // Get configurations
-                       for (ObjectNode config : 
template.getDefaultConfigurations()) {
-                               // Make a copy that we can configure
-                               ConfigurableServiceProvider 
configurableProvider = template.clone();
-                               try {
-                                       configurableProvider.configure(config);
-                               } catch (ConfigurationException e) {
-                                       logger.warn("Can't configure provider "
-                                                       + configurableProvider 
+ " with " + config);
-                                       continue;
-                               }
-                               
defaultServiceDescriptionProviders.add(configurableProvider);
-                       }
-                       */
-               }
-
-               return defaultServiceDescriptionProviders;
-       }
-
-       @Override
-       public synchronized Set<ServiceDescriptionProvider> 
getServiceDescriptionProviders() {
-               if (allServiceProviders != null)
-                       return new HashSet<>(allServiceProviders);
-               allServiceProviders = new HashSet<>(userAddedProviders);
-               synchronized (this) {
-                       if (!hasLoadedProviders)
-                               try {
-                                       loadServiceProviders();
-                               } catch (Exception e) {
-                                       logger.error("Could not load service 
providers", e);
-                               } finally {
-                                       hasLoadedProviders = true;
-                               }
-               }
-               for (ServiceDescriptionProvider provider : 
getDefaultServiceDescriptionProviders()) {
-                       if (userRemovedProviders.contains(provider))
-                               continue;
-                       if (provider instanceof ConfigurableServiceProvider
-                                       && 
!serviceDescriptionsConfig.isIncludeDefaults())
-                               // We'll skip the default configurable service 
provders
-                               continue;
-                       allServiceProviders.add(provider);
-               }
-               return new HashSet<>(allServiceProviders);
-       }
-
-       @Override
-       public Set<ServiceDescriptionProvider> getServiceDescriptionProviders(
-                       ServiceDescription sd) {
-               Set<ServiceDescriptionProvider> result = new HashSet<>();
-               for (ServiceDescriptionProvider sdp : 
providerDescriptions.keySet())
-                       if (providerDescriptions.get(sdp).contains(sd))
-                               result.add(sdp);
-               return result;
-       }
-
-       @Override
-       public Set<ServiceDescription> getServiceDescriptions() {
-               updateServiceDescriptions(false, true);
-               Set<ServiceDescription> serviceDescriptions = new HashSet<>();
-               synchronized (providerDescriptions) {
-                       for (Set<ServiceDescription> providerDesc : 
providerDescriptions
-                                       .values())
-                               serviceDescriptions.addAll(providerDesc);
-               }
-               return serviceDescriptions;
-       }
-
-       @Override
-       public ServiceDescription getServiceDescription(URI serviceType) {
-               for (ServiceDescription serviceDescription : 
getServiceDescriptions())
-                       if 
(serviceDescription.getActivityType().equals(serviceType))
-                               return serviceDescription;
-               return null;
-       }
-
-       @Override
-       public List<ConfigurableServiceProvider> 
getUnconfiguredServiceProviders() {
-               List<ConfigurableServiceProvider> providers = new ArrayList<>();
-               for (ServiceDescriptionProvider provider : 
serviceDescriptionProviders)
-                       if (provider instanceof ConfigurableServiceProvider)
-                               providers.add((ConfigurableServiceProvider) 
provider);
-               return providers;
-       }
-
-       @Override
-       public Set<ServiceDescriptionProvider> getUserAddedServiceProviders() {
-               return new HashSet<>(userAddedProviders);
-       }
-
-       @Override
-       public Set<ServiceDescriptionProvider> getUserRemovedServiceProviders() 
{
-               return new HashSet<>(userRemovedProviders);
-       }
-
-       @Override
-       public void loadServiceProviders() {
-               File serviceProviderFile = findServiceDescriptionsFile();
-               if (serviceProviderFile.isFile())
-                       loadServiceProviders(serviceProviderFile);
-               hasLoadedProviders = true;
-       }
-
-       @Override
-       public void loadServiceProviders(File serviceProvidersFile) {
-               ServiceDescriptionDeserializer deserializer = new 
ServiceDescriptionDeserializer(
-                               serviceDescriptionProviders);
-               loading = true;
-               try {
-                       deserializer.deserialize(this, serviceProvidersFile);
-               } catch (DeserializationException e) {
-                       logger.error("failed to deserialize configuration", e);
-               }
-               loading = false;
-       }
-
-       @Override
-       public void loadServiceProviders(URL serviceProvidersURL) {
-               ServiceDescriptionDeserializer deserializer = new 
ServiceDescriptionDeserializer(
-                               serviceDescriptionProviders);
-               loading = true;
-               try {
-                       deserializer.deserialize(this, serviceProvidersURL);
-               } catch (DeserializationException e) {
-                       logger.error("failed to deserialize configuration", e);
-               }
-               loading = false;
-       }
-
-       @Override
-       public void refresh() {
-               updateServiceDescriptions(true, false);
-       }
-
-       @Override
-       public void removeObserver(Observer<ServiceDescriptionRegistryEvent> 
observer) {
-               observers.removeObserver(observer);
-       }
-
-       @Override
-       public synchronized void removeServiceDescriptionProvider(
-                       ServiceDescriptionProvider provider) {
-               if (!userAddedProviders.remove(provider))
-                       // Not previously added - must be a default one.. but 
should we remove it?
-                       if (loading || 
serviceDescriptionsConfig.isRemovePermanently()
-                                       && 
serviceDescriptionsConfig.isIncludeDefaults())
-                               userRemovedProviders.add(provider);
-               if (allServiceProviders.remove(provider)) {
-                       synchronized (providerDescriptions) {
-                               Thread thread = 
serviceDescriptionThreads.remove(provider);
-                               if (thread != null)
-                                       thread.interrupt();
-                               providerDescriptions.remove(provider);
-                       }
-                       observers.notify(new RemovedProviderEvent(provider));
-               }
-               if (!loading)
-                       saveServiceDescriptions();
-       }
-
-       @Override
-       public void saveServiceDescriptions() {
-               File serviceDescriptionsFile = findServiceDescriptionsFile();
-               saveServiceDescriptions(serviceDescriptionsFile);
-       }
-
-       @Override
-       public void saveServiceDescriptions(File serviceDescriptionsFile) {
-               ServiceDescriptionSerializer serializer = new 
ServiceDescriptionSerializer();
-               try {
-                       serializer.serializeRegistry(this, 
serviceDescriptionsFile);
-               } catch (IOException e) {
-                       throw new RuntimeException("Can't save service 
descriptions to "
-                                       + serviceDescriptionsFile);
-               }
-       }
-
-       /**
-        * Exports all configurable service providers (that give service
-        * descriptions) currently found in the Service Registry (apart from 
service
-        * templates and local services) regardless of who added them (user or
-        * default system providers).
-        * <p>
-        * Unlike {@link #saveServiceDescriptions}, this export does not have 
the
-        * "ignored providers" section as this is just a plain export of 
everything
-        * in the Service Registry.
-        * 
-        * @param serviceDescriptionsFile
-        */
-       @Override
-       public void exportCurrentServiceDescriptions(File 
serviceDescriptionsFile) {
-               ServiceDescriptionSerializer serializer = new 
ServiceDescriptionSerializer();
-               try {
-                       serializer.serializeFullRegistry(this, 
serviceDescriptionsFile);
-               } catch (IOException e) {
-                       throw new RuntimeException("Could not save service 
descriptions to "
-                                       + serviceDescriptionsFile);
-               }
-       }
-
-       public void setServiceDescriptionProvidersList(
-                       List<ServiceDescriptionProvider> 
serviceDescriptionProviders) {
-               this.serviceDescriptionProviders = serviceDescriptionProviders;
-       }
-
-       private void updateServiceDescriptions(boolean refreshAll, boolean 
waitFor) {
-               List<Thread> threads = new ArrayList<>();
-               for (ServiceDescriptionProvider provider : 
getServiceDescriptionProviders()) {
-                       synchronized (providerDescriptions) {
-                               if (providerDescriptions.containsKey(provider) 
&& !refreshAll)
-                                       // We'll used the cached values
-                                       continue;
-                               Thread oldThread = 
serviceDescriptionThreads.get(provider);
-                               if (oldThread != null && oldThread.isAlive()) {
-                                       if (refreshAll)
-                                               // New thread will override the 
old thread
-                                               oldThread.interrupt();
-                                       else {
-                                               // observers.notify(new 
ProviderStatusNotification(provider, "Waiting for provider"));
-                                               continue;
-                                       }
-                               }
-                               // Not run yet - we'll start a new tread
-                               Thread thread = new 
FindServiceDescriptionsThread(provider);
-                               threads.add(thread);
-                               serviceDescriptionThreads.put(provider, thread);
-                               thread.start();
-                       }
-               }
-               if (waitFor)
-                       joinThreads(threads, DESCRIPTION_THREAD_TIMEOUT_MS);
-       }
-
-       @Override
-       public boolean isDefaultSystemConfigurableProvidersLoaded() {
-               return defaultSystemConfigurableProvidersLoaded;
-       }
-
-       /**
-        * Sets the serviceDescriptionsConfig.
-        * 
-        * @param serviceDescriptionsConfig
-        *            the new value of serviceDescriptionsConfig
-        */
-       public void setServiceDescriptionsConfig(
-                       ServiceDescriptionsConfiguration 
serviceDescriptionsConfig) {
-               this.serviceDescriptionsConfig = serviceDescriptionsConfig;
-       }
-
-       class FindServiceDescriptionsThread extends Thread implements
-                       UncaughtExceptionHandler, 
FindServiceDescriptionsCallBack {
-               private final ServiceDescriptionProvider provider;
-               private boolean aborting = false;
-               private final Set<ServiceDescription> providerDescs = new 
HashSet<>();
-
-               FindServiceDescriptionsThread(ServiceDescriptionProvider 
provider) {
-                       super(threadGroup, "Find service descriptions from " + 
provider);
-                       this.provider = provider;
-                       setUncaughtExceptionHandler(this);
-                       setDaemon(true);
-               }
-
-               @Override
-               public void fail(String message, Throwable ex) {
-                       logger.warn("Provider " + getProvider() + ": " + 
message, ex);
-                       if (aborting)
-                               return;
-                       observers.notify(new 
ProviderErrorNotification(getProvider(),
-                                       message, ex));
-               }
-
-               @Override
-               public void finished() {
-                       if (aborting)
-                               return;
-                       synchronized (providerDescriptions) {
-                               providerDescriptions.put(getProvider(), 
providerDescs);
-                       }
-                       observers.notify(new 
ServiceDescriptionProvidedEvent(getProvider(),
-                                       providerDescs));
-               }
-
-               @Override
-               public void partialResults(
-                               Collection<? extends ServiceDescription> 
serviceDescriptions) {
-                       if (aborting)
-                               return;
-                       providerDescs.addAll(serviceDescriptions);
-                       synchronized (providerDescriptions) {
-                               providerDescriptions.put(getProvider(), 
providerDescs);
-                       }
-                       observers.notify(new 
PartialServiceDescriptionsNotification(
-                                       getProvider(), serviceDescriptions));
-               }
-
-               @Override
-               public void status(String message) {
-                       logger.debug("Provider " + getProvider() + ": " + 
message);
-                       if (aborting)
-                               return;
-                       observers.notify(new 
ProviderStatusNotification(getProvider(),
-                                       message));
-               }
-
-               @Override
-               public void warning(String message) {
-                       logger.warn("Provider " + getProvider() + ": " + 
message);
-                       if (aborting)
-                               return;
-                       observers.notify(new 
ProviderWarningNotification(getProvider(),
-                                       message));
-               }
-
-               public ServiceDescriptionProvider getProvider() {
-                       return provider;
-               }
-
-               @Override
-               public void interrupt() {
-                       aborting = true;
-                       super.interrupt();
-               }
-
-               @Override
-               public void run() {
-                       observers.notify(new 
ProviderUpdatingNotification(provider));
-                       getProvider().findServiceDescriptionsAsync(this);
-               }
-
-               @Override
-               public void uncaughtException(Thread t, Throwable ex) {
-                       logger.error("Uncaught exception in " + t, ex);
-                       fail("Uncaught exception", ex);
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
deleted file mode 100644
index 8a047a3..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.CONFIGURATION;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.IGNORED;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDERS;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDER_ID;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.SERVICE_PANEL_CONFIGURATION;
-import static 
net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.TYPE;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Set;
-
-import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
-
-import org.apache.log4j.Logger;
-import org.jdom.JDOMException;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-class ServiceDescriptionSerializer {
-       private static Logger logger = Logger
-                       .getLogger(ServiceDescriptionSerializer.class);
-
-       public void serializeRegistry(ServiceDescriptionRegistry registry, File 
file)
-                       throws IOException {
-               Set<ServiceDescriptionProvider> ignoreProviders = registry
-                               .getUserRemovedServiceProviders();
-               JsonNode registryElement = serializeRegistry(registry, 
ignoreProviders);
-               try (BufferedOutputStream bufferedOutStream = new 
BufferedOutputStream(
-                               new FileOutputStream(file))) {
-                       bufferedOutStream.write(registryElement.toString()
-                                       .getBytes("UTF-8"));
-               }
-       }
-
-       /**
-        * Export the whole service registry to an xml file, regardless of who 
added
-        * the service provider (user or system default). In this case there 
will be
-        * no "ignored providers" in the saved file.
-        */
-       public void serializeFullRegistry(ServiceDescriptionRegistry registry,
-                       File file) throws IOException {
-               JsonNode registryElement = serializeRegistry(registry, 
ALL_PROVIDERS);
-               try (BufferedOutputStream bufferedOutStream = new 
BufferedOutputStream(
-                               new FileOutputStream(file))) {
-                       bufferedOutStream.write(registryElement.toString()
-                                       .getBytes("UTF-8"));
-               }
-       }
-
-       private static final JsonNodeFactory factory = JsonNodeFactory.instance;
-       private static final Set<ServiceDescriptionProvider> ALL_PROVIDERS = 
null;
-
-       private JsonNode serializeRegistry(ServiceDescriptionRegistry registry,
-                       Set<ServiceDescriptionProvider> ignoreProviders) {
-               ObjectNode overallConfiguration = factory.objectNode();
-               overallConfiguration.put(SERVICE_PANEL_CONFIGURATION,
-                               ignoreProviders != ALL_PROVIDERS ? "full" : 
"defaults only");
-               ArrayNode providers = overallConfiguration.putArray(PROVIDERS);
-
-               for (ServiceDescriptionProvider provider : registry
-                               .getUserAddedServiceProviders())
-                       try {
-                               providers.add(serializeProvider(provider));
-                       } catch (JDOMException | IOException e) {
-                               logger.warn("Could not serialize " + provider, 
e);
-                       }
-
-               if (ignoreProviders != ALL_PROVIDERS) {
-                       ArrayNode ignored = 
overallConfiguration.putArray(IGNORED);
-                       for (ServiceDescriptionProvider provider : 
ignoreProviders)
-                               try {
-                                       
ignored.add(serializeProvider(provider));
-                               } catch (JDOMException | IOException e) {
-                                       logger.warn("Could not serialize " + 
provider, e);
-                               }
-               }
-
-               return overallConfiguration;
-       }
-
-       private JsonNode serializeProvider(ServiceDescriptionProvider provider)
-                       throws JDOMException, IOException {
-               ObjectNode node = factory.objectNode();
-               node.put(PROVIDER_ID, provider.getId());
-
-               if (provider instanceof ConfigurableServiceProvider) {
-                       ConfigurableServiceProvider configurable = 
(ConfigurableServiceProvider) provider;
-                       node.put(TYPE, 
configurable.getConfiguration().getType().toString());
-                       node.put(CONFIGURATION, 
configurable.getConfiguration().getJson());
-               }
-               return node;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
deleted file mode 100644
index ee180a7..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-import org.jdom.Namespace;
-
-public interface ServiceDescriptionXMLConstants {
-
-       public static final Namespace SERVICE_DESCRIPTION_NS = Namespace
-                       
.getNamespace("http://taverna.sf.net/2009/xml/servicedescription";);
-       public static final String PROVIDER = "provider";
-       public static final String PROVIDERS = "providers";
-       public static final String SERVICE_DESCRIPTIONS = "serviceDescriptions";
-       public static final String IGNORED_PROVIDERS = "ignoredProviders";
-       public static final String PROVIDER_IDENTIFIER = "providerId";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
deleted file mode 100644
index ef0295c..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.servicedescriptions.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionsConfiguration;
-
-import uk.org.taverna.configuration.AbstractConfigurable;
-import uk.org.taverna.configuration.ConfigurationManager;
-
-public class ServiceDescriptionsConfigurationImpl extends AbstractConfigurable
-               implements ServiceDescriptionsConfiguration {
-       private static final String INCLUDE_DEFAULTS = "includeDefaults";
-       private static final String SERVICE_PALETTE = "Service providers";
-       private static final String SERVICE_PALETTE_PREFIX = "ServiceProviders";
-       private static final String CATEGORY = "Services";
-       private static final String UUID = 
"f0d1ef24-9337-412f-b2c3-220a01e2efd0";
-       private static final String REMOVE_PERMANENTLY = "removePermanently";
-
-       public ServiceDescriptionsConfigurationImpl(
-                       ConfigurationManager configurationManager) {
-               super(configurationManager);
-       }
-
-       @Override
-       public String getCategory() {
-               return CATEGORY;
-       }
-
-       @Override
-       public Map<String, String> getDefaultPropertyMap() {
-               Map<String, String> defaults = new HashMap<String, String>();
-               defaults.put(INCLUDE_DEFAULTS, "true");
-               defaults.put(REMOVE_PERMANENTLY, "true");
-               return defaults;
-       }
-
-       @Override
-       public String getDisplayName() {
-               return SERVICE_PALETTE;
-       }
-
-       @Override
-       public String getFilePrefix() {
-               return SERVICE_PALETTE_PREFIX;
-       }
-
-       @Override
-       public String getUUID() {
-               return UUID;
-       }
-
-       @Override
-       public boolean isIncludeDefaults() {
-               return Boolean.parseBoolean(getProperty(INCLUDE_DEFAULTS));
-       }
-
-       @Override
-       public void setIncludeDefaults(boolean includeDefaults) {
-               setProperty(INCLUDE_DEFAULTS, 
Boolean.toString(includeDefaults));
-       }
-
-       @Override
-       public boolean isRemovePermanently() {
-               return Boolean.parseBoolean(getProperty(REMOVE_PERMANENTLY));
-       }
-
-       @Override
-       public void setRemovePermanently(boolean removePermanently) {
-               setProperty(REMOVE_PERMANENTLY, 
Boolean.toString(removePermanently));
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
deleted file mode 100644
index 46f82c4..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.activitypalette;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import uk.org.taverna.configuration.AbstractConfigurable;
-import uk.org.taverna.configuration.ConfigurationManager;
-
-public class ActivityPaletteConfiguration extends AbstractConfigurable {
-       private Map<String,String> defaultPropertyMap;
-
-       public ActivityPaletteConfiguration(ConfigurationManager 
configurationManager) {
-               super(configurationManager);
-       }
-
-       @Override
-       public String getCategory() {
-               return "Services";
-       }
-
-       @Override
-       public Map<String, String> getDefaultPropertyMap() {
-               if (defaultPropertyMap == null) {
-                       defaultPropertyMap = new HashMap<>();
-
-                       // //wsdl
-                       //defaultPropertyMap.put("taverna.defaultwsdl", 
"http://www.ebi.ac.uk/xembl/XEMBL.wsdl,"+
-                       //                    
"http://soap.genome.jp/KEGG.wsdl,"+
-                       //                    
"http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/eutils.wsdl,"+
-                       //                    
"http://soap.bind.ca/wsdl/bind.wsdl,"+
-                       //                    
"http://www.ebi.ac.uk/ws/services/urn:Dbfetch?wsdl";);
-
-                       // //soaplab
-                       //defaultPropertyMap.put("taverna.defaultsoaplab", 
"http://www.ebi.ac.uk/soaplab/services/";);
-
-                       // //biomart
-                       
//defaultPropertyMap.put("taverna.defaultmartregistry","http://www.biomart.org/biomart";);
-
-                       //add property names
-                       //defaultPropertyMap.put("name.taverna.defaultwsdl", 
"WSDL");
-                       
//defaultPropertyMap.put("name.taverna.defaultsoaplab","Soaplab");
-                       
//defaultPropertyMap.put("name.taverna.defaultmartregistry", "Biomart");
-               }
-               return defaultPropertyMap;
-       }
-
-       @Override
-       public String getDisplayName() {
-               return "Activity Palette";
-       }
-
-       @Override
-       public String getFilePrefix() {
-               return "ActivityPalette";
-       }
-
-       @Override
-       public String getUUID() {
-               return "ad9f3a60-5967-11dd-ae16-0800200c9a66";
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
deleted file mode 100644
index 6166e60..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.activitypalette;
-
-import static java.awt.BorderLayout.CENTER;
-import static java.awt.BorderLayout.EAST;
-import static java.awt.BorderLayout.NORTH;
-import static java.awt.BorderLayout.SOUTH;
-import static java.awt.FlowLayout.LEFT;
-import static java.awt.FlowLayout.RIGHT;
-import static javax.swing.BoxLayout.Y_AXIS;
-import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
-import static javax.swing.JOptionPane.WARNING_MESSAGE;
-import static javax.swing.JOptionPane.YES_NO_OPTION;
-import static javax.swing.JOptionPane.YES_OPTION;
-import static javax.swing.JOptionPane.showConfirmDialog;
-import static javax.swing.JOptionPane.showInputDialog;
-import static javax.swing.border.BevelBorder.LOWERED;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.swing.BoxLayout;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.DefaultListCellRenderer;
-import javax.swing.DefaultListModel;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.border.BevelBorder;
-
-import org.apache.log4j.Logger;
-
-@SuppressWarnings("serial")
-public class ActivityPaletteConfigurationPanel extends JPanel {
-       private static Logger logger = Logger
-                       .getLogger(ActivityPaletteConfigurationPanel.class);
-
-       private Map<String,List<String>> values = new HashMap<>();
-       private Map<String,String> names = new HashMap<>();
-       private DefaultComboBoxModel<String> model;
-       private DefaultListModel<String> listModel;
-       private JList<String> propertyListItems;
-       private String selectedKey;
-       private JButton deleteTypeButton;
-       private final ActivityPaletteConfiguration config;
-
-       public ActivityPaletteConfigurationPanel(ActivityPaletteConfiguration 
config) {
-               super(new BorderLayout());
-               this.config = config;
-
-               model = new DefaultComboBoxModel<>();
-               for (String key : config.getInternalPropertyMap().keySet()) {
-                       if (key.startsWith("taverna.")
-                                       && config.getPropertyStringList(key) != 
null) {
-                               model.addElement(key);
-                               values.put(key,
-                                               new 
ArrayList<>(config.getPropertyStringList(key)));
-                       }
-                       if (key.startsWith("name.taverna."))
-                               names.put(key, 
config.getProperty(key).toString());
-               }
-               deleteTypeButton = new JButton("Delete");
-
-               final JButton addTypeButton = new JButton("Add");
-               final JComboBox<String> comboBox = new JComboBox<>(model);
-               comboBox.setRenderer(new DefaultListCellRenderer() {
-                       @Override
-                       public Component getListCellRendererComponent(JList<?> 
list,
-                                       Object value, int index, boolean 
isSelected,
-                                       boolean cellHasFocus) {
-                               if (value != null && value instanceof String) {
-                                       String name = names.get("name." + 
value);
-                                       if (name != null)
-                                               value = name;
-                               }
-                               return super.getListCellRendererComponent(list, 
value, index,
-                                               isSelected, cellHasFocus);
-                       }
-               });
-
-               deleteTypeButton.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               String displayText = names.get("name." + 
selectedKey);
-                               if (displayText == null)
-                                       displayText = selectedKey;
-                               if (confirm("Confirm removal",
-                                               "Are you sure you wish to 
remove the type "
-                                                               + displayText + 
"?")) {
-                                       names.remove("name." + selectedKey);
-                                       values.remove(selectedKey);
-                                       model.removeElement(selectedKey);
-                                       comboBox.setSelectedIndex(0);
-                               }
-                       }
-               });
-
-               addTypeButton.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               String key = input("New key", "Provide the new 
key.");
-                               if (key == null)
-                                       return;
-                               String name = input("Name for the key",
-                                               "Provide the name for the key: 
" + key);
-                               if (name == null)
-                                       return;
-
-                               values.put(key, new ArrayList<String>());
-                               names.put("name." + key, name);
-                               model.addElement(key);
-                               comboBox.setSelectedItem(key);
-                       }
-               });
-
-               comboBox.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               if (comboBox.getSelectedItem() != null
-                                               && comboBox.getSelectedItem() 
instanceof String) {
-                                       selectedKey = (String) 
comboBox.getSelectedItem();
-                                       List<String> selectedList = 
values.get(selectedKey);
-                                       populateList(selectedList);
-                                       
deleteTypeButton.setEnabled(selectedList.size() == 0);
-                               }
-                       }
-               });
-
-               JPanel propertySelectionPanel = new JPanel(new 
FlowLayout(LEFT));
-               propertySelectionPanel.add(new JLabel("Activity type:"));
-               propertySelectionPanel.add(comboBox);
-               propertySelectionPanel.add(addTypeButton);
-               propertySelectionPanel.add(deleteTypeButton);
-               add(propertySelectionPanel, NORTH);
-
-               JPanel listPanel = new JPanel(new BorderLayout());
-               listModel = new DefaultListModel<>();
-               propertyListItems = new JList<>(listModel);
-               propertyListItems.setBorder(new BevelBorder(LOWERED));
-
-               listPanel.add(propertyListItems, CENTER);
-               listPanel.add(listButtons(), EAST);
-
-               add(listPanel, CENTER);
-
-               add(applyButtonPanel(), SOUTH);
-
-               if (model.getSize() > 0)
-                       comboBox.setSelectedItem(model.getElementAt(0));
-       }
-
-       private void populateList(List<String> selectedList) {
-               listModel.removeAllElements();
-               for (String item : selectedList)
-                       listModel.addElement(item);
-       }
-
-       private JPanel applyButtonPanel() {
-               JPanel applyPanel = new JPanel(new FlowLayout(RIGHT));
-               JButton applyButton = new JButton("Apply");
-
-               applyButton.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               config.getInternalPropertyMap().clear();
-                               for (String key : values.keySet()) {
-                                       List<String> properties = 
values.get(key);
-                                       config.setPropertyStringList(key, new 
ArrayList<>(
-                                                       properties));
-                               }
-                               for (String key : names.keySet())
-                                       config.setProperty(key, names.get(key));
-                               store();
-                       }
-               });
-
-               applyPanel.add(applyButton);
-               return applyPanel;
-       }
-
-       private void store() {
-               try {
-                       //FIXME
-                       //ConfigurationManager.getInstance().store(config);
-               } catch (Exception e1) {
-                       logger.error("There was an error storing the 
configuration:"
-                                       + config.getFilePrefix() + " (UUID=" + 
config.getUUID()
-                                       + ")", e1);
-               }
-       }
-
-       private JPanel listButtons() {
-               JPanel panel = new JPanel();
-               panel.setLayout(new BoxLayout(panel, Y_AXIS));
-               JButton addButton = new JButton("+");
-               addButton.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               String value = input("New property", "Provide 
new value for: "
-                                               + selectedKey);
-                               if (value != null) {
-                                       listModel.addElement(value);
-                                       values.get(selectedKey).add(value);
-                                       deleteTypeButton.setEnabled(false);
-                               }
-                       }
-               });
-
-               JButton deleteButton = new JButton("-");
-               deleteButton.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               Object value = 
propertyListItems.getSelectedValue();
-                               if (confirm("Confirm removal",
-                                               "Are you sure you wish to 
remove " + value + "?")) {
-                                       listModel.removeElement(value);
-                                       values.get(selectedKey).remove(value);
-                                       if (values.get(selectedKey).size() == 0)
-                                               
deleteTypeButton.setEnabled(true);
-                               }
-                       }
-               });
-
-               panel.add(addButton);
-               panel.add(deleteButton);
-
-               return panel;
-       }
-
-       private boolean confirm(String title, String message) {
-               return showConfirmDialog(this, message, title, YES_NO_OPTION,
-                               WARNING_MESSAGE) == YES_OPTION;
-       }
-
-       private String input(String title, String message) {
-               return showInputDialog(this, message, title, 
INFORMATION_MESSAGE);
-       }
-
-/*     private JButton getAddTypeButton() {
-               JButton result = new JButton("Add");
-               result.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent e) {
-                               String val = input("New property value","New 
property value");
-                               if (val!=null) {
-                                       if (values.get(val) == null) {
-                                               model.addElement(val);
-                                               values.put(val, new 
ArrayList<String>());
-                                       } else
-                                               
showMessageDialog(ActivityPaletteConfigurationPanel.this, "This property 
already exists");
-                               }
-                       }
-               });
-               return result;
-       }
-*/
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
 
b/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
deleted file mode 100644
index 39c4a5a..0000000
--- 
a/taverna-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.activitypalette;
-
-import javax.swing.JPanel;
-
-import uk.org.taverna.configuration.Configurable;
-import uk.org.taverna.configuration.ConfigurationUIFactory;
-
-public class ActivityPaletteConfigurationUIFactory implements
-               ConfigurationUIFactory {
-       private ActivityPaletteConfiguration activityPaletteConfiguration;
-
-       @Override
-       public boolean canHandle(String uuid) {
-               return uuid != null && uuid.equals(getConfigurable().getUUID());
-       }
-
-       @Override
-       public Configurable getConfigurable() {
-               return activityPaletteConfiguration;
-       }
-
-       @Override
-       public JPanel getConfigurationPanel() {
-               return new ActivityPaletteConfigurationPanel(
-                               activityPaletteConfiguration);
-       }
-
-       public void setActivityPaletteConfiguration(
-                       ActivityPaletteConfiguration 
activityPaletteConfiguration) {
-               this.activityPaletteConfiguration = 
activityPaletteConfiguration;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionConstants.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionConstants.java
 
b/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionConstants.java
new file mode 100644
index 0000000..8331c88
--- /dev/null
+++ 
b/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionConstants.java
@@ -0,0 +1,10 @@
+package org.apache.taverna.servicedescriptions.impl;
+
+public interface ServiceDescriptionConstants {
+       String SERVICE_PANEL_CONFIGURATION = "servicePanelConfiguration";
+       String PROVIDERS = "providers";
+       String IGNORED = "ignored";
+       String PROVIDER_ID = "providerID";
+       String CONFIGURATION = "configuration";
+       String TYPE = "type";
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionDeserializer.java
----------------------------------------------------------------------
diff --git 
a/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionDeserializer.java
 
b/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionDeserializer.java
new file mode 100644
index 0000000..546a278
--- /dev/null
+++ 
b/taverna-activity-palette-impl/src/main/java/org/apache/taverna/servicedescriptions/impl/ServiceDescriptionDeserializer.java
@@ -0,0 +1,167 @@
+package org.apache.taverna.servicedescriptions.impl;
+
+import static 
org.apache.taverna.servicedescriptions.impl.ServiceDescriptionConstants.CONFIGURATION;
+import static 
org.apache.taverna.servicedescriptions.impl.ServiceDescriptionConstants.IGNORED;
+import static 
org.apache.taverna.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDERS;
+import static 
org.apache.taverna.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDER_ID;
+import static 
org.apache.taverna.servicedescriptions.impl.ServiceDescriptionConstants.TYPE;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.servicedescriptions.ConfigurableServiceProvider;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+class ServiceDescriptionDeserializer {
+       private List<ServiceDescriptionProvider> serviceDescriptionProviders;
+
+       ServiceDescriptionDeserializer(
+                       List<ServiceDescriptionProvider> 
serviceDescriptionProviders) {
+               this.serviceDescriptionProviders = serviceDescriptionProviders;
+       }
+
+       public void deserialize(ServiceDescriptionRegistry registry,
+                       File serviceDescriptionsFile) throws 
DeserializationException {
+               try (FileInputStream serviceDescriptionFileStream = new 
FileInputStream(
+                               serviceDescriptionsFile)) {
+                       deserialize(registry, serviceDescriptionFileStream);
+               } catch (FileNotFoundException ex) {
+                       throw new DeserializationException("Could not locate 
file "
+                                       + 
serviceDescriptionsFile.getAbsolutePath()
+                                       + " containing service descriptions.");
+               } catch (IOException ex) {
+                       throw new DeserializationException(
+                                       "Could not read stream containing 
service descriptions from "
+                                                       + 
serviceDescriptionsFile.getAbsolutePath(), ex);
+               }
+       }
+
+       public void deserialize(ServiceDescriptionRegistry registry,
+                       URL serviceDescriptionsURL) throws 
DeserializationException {
+               try (InputStream serviceDescriptionInputStream = 
serviceDescriptionsURL
+                               .openStream()) {
+                       deserialize(registry, serviceDescriptionInputStream);
+               } catch (FileNotFoundException ex) {
+                       throw new DeserializationException("Could not open URL "
+                                       + serviceDescriptionsURL
+                                       + " containing service descriptions.");
+               } catch (IOException ex) {
+                       throw new DeserializationException(
+                                       "Could not read stream containing 
service descriptions from "
+                                                       + 
serviceDescriptionsURL, ex);
+               }
+       }
+
+       private static final JsonFactory factory = new JsonFactory();
+
+       private void deserialize(ServiceDescriptionRegistry registry,
+                       InputStream serviceDescriptionsInputStream) throws 
IOException,
+                       DeserializationException {
+               ObjectNode node = (ObjectNode) new ObjectMapper(factory)
+                               .readTree(serviceDescriptionsInputStream);
+               List<ServiceDescriptionProvider> providers = 
deserializeProviders(node,
+                               true);
+               for (ServiceDescriptionProvider provider : providers)
+                       registry.addServiceDescriptionProvider(provider);
+       }
+
+       public Collection<? extends ServiceDescriptionProvider> 
deserializeDefaults(
+                       ServiceDescriptionRegistry registry,
+                       File defaultConfigurableServiceProvidersFile)
+                       throws DeserializationException {
+               ObjectNode node;
+               try (FileInputStream serviceDescriptionStream = new 
FileInputStream(
+                               defaultConfigurableServiceProvidersFile)) {
+                       node = (ObjectNode) new ObjectMapper(factory)
+                                       .readTree(serviceDescriptionStream);
+               } catch (IOException e) {
+                       throw new DeserializationException("Can't read "
+                                       + 
defaultConfigurableServiceProvidersFile);
+               }
+               return deserializeProviders(node, false);
+       }
+
+       private List<ServiceDescriptionProvider> deserializeProviders(
+                       ObjectNode rootNode, boolean obeyIgnored)
+                       throws DeserializationException {
+               List<ServiceDescriptionProvider> providers = new ArrayList<>();
+
+               ArrayNode providersNode = (ArrayNode) rootNode.get(PROVIDERS);
+               if (providersNode != null)
+                       for (JsonNode provider : providersNode)
+                               providers.add(deserializeProvider((ObjectNode) 
provider));
+
+               if (obeyIgnored) {
+                       ArrayNode ignoredNode = (ArrayNode) 
rootNode.get(IGNORED);
+                       if (ignoredNode != null)
+                               for (JsonNode provider : ignoredNode)
+                                       providers
+                                                       
.remove(deserializeProvider((ObjectNode) provider));
+               }
+
+               return providers;
+       }
+
+       private ServiceDescriptionProvider deserializeProvider(
+                       ObjectNode providerNode) throws 
DeserializationException {
+               String providerId = 
providerNode.get(PROVIDER_ID).asText().trim();
+               ServiceDescriptionProvider provider = null;
+               for (ServiceDescriptionProvider serviceProvider : 
serviceDescriptionProviders)
+                       if (serviceProvider.getId().equals(providerId)) {
+                               provider = serviceProvider;
+                               break;
+                       }
+               if (provider == null)
+                       throw new DeserializationException(
+                                       "Could not find provider with id " + 
providerId);
+
+               /*
+                * So we know the service provider now, but we need a separate 
instance
+                * of that provider for each providerElem. E.g. we can have 2 
or more
+                * WSDL provider elements and need to return a separate provider
+                * instance for each as they will have different configurations.
+                */
+               ServiceDescriptionProvider instance = provider.newInstance();
+
+               if (instance instanceof ConfigurableServiceProvider)
+                       try {
+                               Configuration config = new Configuration();
+                               
config.setType(URI.create(providerNode.get(TYPE).textValue()));
+                               config.setJson(providerNode.get(CONFIGURATION));
+                               if (config != null)
+                                       ((ConfigurableServiceProvider) 
instance).configure(config);
+                       } catch (Exception e) {
+                               throw new DeserializationException(
+                                               "Could not configure provider " 
+ providerId
+                                                               + " using bean 
" + providerNode, e);
+                       }
+               return instance;
+       }
+
+       @SuppressWarnings("serial")
+       static class DeserializationException extends Exception {
+               public DeserializationException(String string) {
+                       super(string);
+               }
+
+               public DeserializationException(String string, Exception ex) {
+                       super(string, ex);
+               }
+       }
+}

Reply via email to