/*******************************************************************************
 * Copyright (C) 2008-2010 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.report.explainer;

import java.awt.Desktop;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.net.ssl.SSLException;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;

import net.sf.taverna.t2.activities.dataflow.DataflowActivity;
import net.sf.taverna.t2.activities.dataflow.actions.EditNestedDataflowAction;
import net.sf.taverna.t2.activities.disabled.actions.DisabledActivityConfigurationAction;
import net.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity;
import net.sf.taverna.t2.activities.wsdl.xmlsplitter.AddXMLSplitterEdit;
import net.sf.taverna.t2.lang.ui.ReadOnlyTextArea;
import net.sf.taverna.t2.visit.DataflowCollation;
import net.sf.taverna.t2.visit.VisitKind;
import net.sf.taverna.t2.visit.VisitReport;
import net.sf.taverna.t2.visit.fragility.FragilityCheck;
import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
import net.sf.taverna.t2.workbench.design.actions.AddDataflowOutputAction;
import net.sf.taverna.t2.workbench.edits.EditManager;
import net.sf.taverna.t2.workbench.file.FileManager;
import net.sf.taverna.t2.workbench.report.FailedEntityKind;
import net.sf.taverna.t2.workbench.report.IncompleteDataflowKind;
import net.sf.taverna.t2.workbench.report.InvalidDataflowKind;
import net.sf.taverna.t2.workbench.report.ReportManager;
import net.sf.taverna.t2.workbench.report.UnresolvedOutputKind;
import net.sf.taverna.t2.workbench.report.UnsatisfiedEntityKind;
import net.sf.taverna.t2.workbench.report.view.ReportViewConfigureAction;
import net.sf.taverna.t2.workbench.retry.RetryConfigureAction;
import net.sf.taverna.t2.workbench.selection.SelectionManager;
import net.sf.taverna.t2.workbench.ui.impl.configuration.ui.T2ConfigurationFrame;
import net.sf.taverna.t2.workflowmodel.CompoundEdit;
import net.sf.taverna.t2.workflowmodel.Dataflow;
import net.sf.taverna.t2.workflowmodel.DataflowOutputPort;
import net.sf.taverna.t2.workflowmodel.Datalink;
import net.sf.taverna.t2.workflowmodel.Edit;
import net.sf.taverna.t2.workflowmodel.EditException;
import net.sf.taverna.t2.workflowmodel.Merge;
import net.sf.taverna.t2.workflowmodel.Processor;
import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
import net.sf.taverna.t2.workflowmodel.ProcessorOutputPort;
import net.sf.taverna.t2.workflowmodel.TokenProcessingEntity;
import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
import net.sf.taverna.t2.workflowmodel.processor.activity.DisabledActivity;
import net.sf.taverna.t2.workflowmodel.processor.dispatch.DispatchLayer;
import net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry;
import net.sf.taverna.t2.workflowmodel.utils.Tools;

import org.apache.log4j.Logger;

import uk.org.taverna.configuration.ConfigurationUIFactory;

/**
 * @author alanrw
 *
 */
public class BasicExplainer implements VisitExplainer {

	private static Logger logger = Logger.getLogger(BasicExplainer.class);

	private static String PLEASE_CONTACT = "Please contact the service provider or workflow creator.";

	private EditManager editManager;

	private FileManager fileManager;

	private ReportManager reportManager;

	private SelectionManager selectionManager;

	private List<ConfigurationUIFactory> configurationUIFactories;

	private ActivityIconManager activityIconManager;

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * net.sf.taverna.t2.workbench.report.explainer.VisitExplainer#canExplain
	 * (net.sf.taverna.t2.visit.VisitKind, int)
	 */
	public boolean canExplain(VisitKind vk, int resultId) {
		if (vk instanceof DataflowCollation) {
			return true;
		}
		if (vk instanceof FailedEntityKind) {
			return true;
		}
		if (vk instanceof IncompleteDataflowKind) {
			return true;
		}
		if (vk instanceof InvalidDataflowKind) {
			return true;
		}
		if (vk instanceof UnresolvedOutputKind) {
			return true;
		}
		if (vk instanceof UnsatisfiedEntityKind) {
			return true;
		}
		if (vk instanceof FragilityCheck) {
			return true;
		}
		if ((vk instanceof HealthCheck)
				&& ((resultId == HealthCheck.INVALID_SCRIPT)
						|| (resultId == HealthCheck.CONNECTION_PROBLEM)
						|| (resultId == HealthCheck.INVALID_URL)
						|| (resultId == HealthCheck.IO_PROBLEM)
						|| (resultId == HealthCheck.TIME_OUT)
						|| (resultId == HealthCheck.MISSING_DEPENDENCY)
						|| (resultId == HealthCheck.DEFAULT_VALUE)
						|| (resultId == HealthCheck.BAD_WSDL)
						|| (resultId == HealthCheck.NOT_HTTP)
						|| (resultId == HealthCheck.UNSUPPORTED_STYLE)
						|| (resultId == HealthCheck.UNKNOWN_OPERATION)
						|| (resultId == HealthCheck.NO_ENDPOINTS)
						|| (resultId == HealthCheck.INVALID_CONFIGURATION)
						|| (resultId == HealthCheck.NULL_DATATYPE)
						|| (resultId == HealthCheck.DISABLED)
						|| (resultId == HealthCheck.DATATYPE_SOURCE)
						|| (resultId == HealthCheck.UNRECOGNIZED)
						|| (resultId == HealthCheck.LOOP_CONNECTION)
						|| (resultId == HealthCheck.UNMANAGED_LOCATION) || (resultId == HealthCheck.INCOMPATIBLE_MIMETYPES))) {
			return true;
		}
		return false;
	}

	public JComponent getExplanation(VisitReport vr) {
		VisitKind vk = vr.getKind();
		int resultId = vr.getResultId();
		if (vk instanceof DataflowCollation) {
			return explanationDataflowCollation(vr);
		}
		if (vk instanceof FailedEntityKind) {
			return explanationFailedEntity(vr);
		}
		if ((vk instanceof IncompleteDataflowKind)
				&& (resultId == IncompleteDataflowKind.INCOMPLETE_DATAFLOW)) {
			return explanationDataflowIncomplete(vr);
		}
		if (vk instanceof InvalidDataflowKind) {
			return explanationInvalidDataflow(vr);
		}
		if (vk instanceof UnresolvedOutputKind) {
			return explanationUnresolvedOutput(vr);
		}
		if (vk instanceof UnsatisfiedEntityKind) {
			return explanationUnsatisfiedEntity(vr);
		}

		if ((vk instanceof FragilityCheck)
				&& (resultId == FragilityCheck.SOURCE_FRAGILE)) {
			return explanationSourceFragile(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_SCRIPT)) {
			return explanationBeanshellInvalidScript(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.CONNECTION_PROBLEM)) {
			return explanationConnectionProblem(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_URL)) {
			return explanationInvalidUrl(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.TIME_OUT)) {
			return explanationTimeOut(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.IO_PROBLEM)) {
			return explanationIoProblem(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.MISSING_DEPENDENCY)) {
			return explanationMissingDependency(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.DEFAULT_VALUE)) {
			return explanationDefaultValue(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.BAD_WSDL)) {
			return explanationBadWSDL(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.NOT_HTTP)) {
			return explanationNotHTTP(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNSUPPORTED_STYLE)) {
			return explanationUnsupportedStyle(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNKNOWN_OPERATION)) {
			return explanationUnknownOperation(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.NO_ENDPOINTS)) {
			return explanationNoEndpoints(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_CONFIGURATION)) {
			return explanationInvalidConfiguration(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.NULL_DATATYPE)) {
			return explanationNullDatatype(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.DISABLED)) {
			return explanationDisabled(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.DATATYPE_SOURCE)) {
			return explanationDatatypeSource(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNRECOGNIZED)) {
			return explanationUnrecognized(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.LOOP_CONNECTION)) {
			return explanationLoopConnection(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNMANAGED_LOCATION)) {
			return explanationUnmanagedLocation(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INCOMPATIBLE_MIMETYPES)) {
			return explanationIncompatibleMimetypes(vr);
		}
		return null;
	}

	public JComponent getSolution(VisitReport vr) {
		VisitKind vk = vr.getKind();
		int resultId = vr.getResultId();
		if (vk instanceof DataflowCollation) {
			return solutionDataflowCollation(vr);
		}
		if (vk instanceof FailedEntityKind) {
			return solutionFailedEntity(vr);
		}
		if ((vk instanceof IncompleteDataflowKind)
				&& (resultId == IncompleteDataflowKind.INCOMPLETE_DATAFLOW)) {
			return solutionDataflowIncomplete(vr);
		}
		if (vk instanceof InvalidDataflowKind) {
			return solutionInvalidDataflow(vr);
		}
		if (vk instanceof UnresolvedOutputKind) {
			return solutionUnresolvedOutput(vr);
		}
		if (vk instanceof UnsatisfiedEntityKind) {
			return solutionUnsatisfiedEntity(vr);
		}

		if ((vk instanceof FragilityCheck)
				&& (resultId == FragilityCheck.SOURCE_FRAGILE)) {
			return solutionSourceFragile(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_SCRIPT)) {
			return solutionBeanshellInvalidScript(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.CONNECTION_PROBLEM)) {
			return solutionConnectionProblem(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_URL)) {
			return solutionInvalidUrl(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.TIME_OUT)) {
			return solutionTimeOut(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.IO_PROBLEM)) {
			return solutionIoProblem(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.MISSING_DEPENDENCY)) {
			return solutionMissingDependency(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.DEFAULT_VALUE)) {
			return solutionDefaultValue(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.BAD_WSDL)) {
			return solutionBadWSDL(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.NOT_HTTP)) {
			return solutionNotHTTP(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNSUPPORTED_STYLE)) {
			return solutionUnsupportedStyle(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNKNOWN_OPERATION)) {
			return solutionUnknownOperation(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.NO_ENDPOINTS)) {
			return solutionNoEndpoints(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INVALID_CONFIGURATION)) {
			return solutionInvalidConfiguration(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.NULL_DATATYPE)) {
			return solutionNullDatatype(vr);
		}
		if ((vk instanceof HealthCheck) && (resultId == HealthCheck.DISABLED)) {
			return solutionDisabled(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.DATATYPE_SOURCE)) {
			return solutionDatatypeSource(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNRECOGNIZED)) {
			return solutionUnrecognized(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.LOOP_CONNECTION)) {
			return solutionLoopConnection(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.UNMANAGED_LOCATION)) {
			return solutionUnmanagedLocation(vr);
		}
		if ((vk instanceof HealthCheck)
				&& (resultId == HealthCheck.INCOMPATIBLE_MIMETYPES)) {
			return solutionIncompatibleMimetypes(vr);
		}
		return null;
	}

	private static JComponent explanationFailedEntity(VisitReport vr) {
		if (vr.getSubject() instanceof Processor) {
			Processor p = (Processor) (vr.getSubject());
			DataflowActivity da = null;
			for (Activity a : p.getActivityList()) {
				if (a instanceof DataflowActivity) {
					da = (DataflowActivity) a;
					break;
				}
			}
			String message = "There is possibly a problem with the service's list handling";
			if (da != null) {
				message += ", or a problem with the nested workflow";
			}
			return createPanel(new Object[] { message + "." });
		} else if (vr.getSubject() instanceof Merge) {
			return createPanel(new Object[] { "The merge is combining data of different depths." });
		}
		return null;
	}

	private static JComponent explanationInvalidDataflow(VisitReport vr) {
		return createPanel(new Object[] { "The workflow contains errors - see other reports." });
	}

	private static JComponent explanationUnresolvedOutput(VisitReport vr) {
		DataflowOutputPort dop = (DataflowOutputPort) vr.getSubject();
		Datalink incomingLink = dop.getInternalInputPort().getIncomingLink();
		String message;
		if (incomingLink == null) {
			message = "The workflow output port is not connected.";
		} else {
			message = "The workflow output port is connected to a service or port that has errors.";
		}
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationUnsatisfiedEntity(VisitReport vr) {
		return createPanel(new Object[] { "The service could not be properly checked." });
	}

	private static JComponent explanationDataflowCollation(VisitReport vr) {
		if (vr.getStatus().equals(VisitReport.Status.SEVERE)) {
			return createPanel(new Object[] { "There are errors in the nested workflow." });
		} else {
			return createPanel(new Object[] { "There are warnings in the nested workflow." });
		}
	}

	private static JComponent explanationDataflowIncomplete(VisitReport vr) {
		return createPanel(new Object[] { "A workflow must contain at least one service or at least one output port." });
	}

	private static JComponent explanationSourceFragile(VisitReport vr) {
		ProcessorInputPort pip = (ProcessorInputPort) vr
				.getProperty("sinkPort");
		Processor sourceProcessor = (Processor) vr
				.getProperty("sourceProcessor");
		String message = "A single error input into ";
		if (pip == null) {
			message += "an input port ";
		} else {
			message += "\"" + pip.getName() + "\" ";
		}
		if (sourceProcessor != null) {
			message += "from \"" + sourceProcessor.getLocalName() + "\"";
		}
		message += " will cause this service to fail.  ";
		message += "If "
				+ (sourceProcessor == null ? "the source" : sourceProcessor
						.getLocalName())
				+ " is unlikely to fail (for example if it is a StringConstant) then this warning can be ignored.";
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationConnectionProblem(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			endpoint = "the endpoint";
		}
		String responseCode = (String) (vr.getProperty("responseCode"));
		if (responseCode == null) {
			responseCode = "an unexpected response code";
		} else {
			responseCode = "response code: " + responseCode;
		}
		return createPanel(new Object[] { "Taverna connected to \"" + endpoint
				+ "\" but received " + responseCode
				+ ".  The service may still work." });
	}

	private static JComponent explanationIoProblem(VisitReport vr) {
		String message = "Reading from ";
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			message += "the endpoint";
		} else {
			message += "\"" + endpoint + "\"";
		}
		message += " caused ";
		Exception e = (Exception) (vr.getProperty("exception"));
		if (e == null) {
			message += "an error";
		} else {
			message += e.getClass().getCanonicalName() + ": \""
					+ e.getMessage() + "\"";
		}
		return createPanel(new Object[] { message + "." });
	}

	private static JComponent explanationInvalidUrl(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			endpoint = "the endpoint";
		}
		return createPanel(new Object[] { "Taverna was unable to connect to \""
				+ endpoint + "\" because it is not a valid URL." });
	}

	private static JComponent explanationTimeOut(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			endpoint = "the endpoint";
		}
		String timeOutString = (String) (vr.getProperty("timeOut"));
		if (timeOutString == null) {
			timeOutString = " the timeout limit";
		} else {
			try {
				Integer timeOut = Integer.parseInt(timeOutString);
				if (timeOut > 1000) {
					timeOutString = Float.toString(timeOut / 1000) + "s";
				} else {
					timeOutString += "ms";
				}
			} catch (NumberFormatException ex) {
				timeOutString = " the timeout limit";
			}
		}
		return createPanel(new Object[] { "Taverna was unable to connect to \""
				+ endpoint + "\" within " + timeOutString + "." });
	}

	private static JComponent explanationMissingDependency(VisitReport vr) {
		Set<String> dependencies = (Set<String>) (vr
				.getProperty("dependencies"));
		String message = "Taverna could not find ";
		if (dependencies == null) {
			message += "some dependencies";
		} else {
			for (Iterator i = dependencies.iterator(); i.hasNext();) {
				String s = (String) i.next();
				message += s;
				if (i.hasNext()) {
					message += " and ";
				}
			}
		}
		File directory = (File) vr.getProperty("directory");
		if (directory != null) {
			try {
				message += " in directory " + directory.getCanonicalPath();
			} catch (IOException e) {
				logger.error("Could not get path", e);
			}
		}
		return createPanel(new Object[] { message + "." });
	}

	private static JComponent explanationDefaultValue(VisitReport vr) {
		String value = (String) (vr.getProperty("value"));
		if (value == null) {
			value = "the default value";
		}
		return createPanel(new Object[] { "The service still has its value set to \""
				+ value + "\"" });
	}

	private static JComponent explanationBadWSDL(VisitReport vr) {
		Exception e = (Exception) (vr.getProperty("exception"));
		String message = "Parsing the WSDL caused ";
		if (e == null) {
			message += " an exception";
		} else {
			message += "\"" + e.getMessage() + "\"";
		}
		return createPanel(new Object[] { message + "." });
	}

	private static JComponent explanationNotHTTP(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			endpoint = "The endpoint";
		} else {
			endpoint = "\"" + endpoint + "\"";
		}
		return createPanel(new Object[] { endpoint
				+ " might not be accessible if you run the workflow on a different machine." });
	}

	private static JComponent explanationUnsupportedStyle(VisitReport vr) {
		String message = "Taverna does not support ";
		String style = (String) (vr.getProperty("style"));
		String use = (String) (vr.getProperty("use"));
		String kind = null;
		if ((style != null) && (use != null)) {
			kind = style + "/" + use;
		}
		if (kind == null) {
			message += " the kind of message the service uses.";
		} else {
			message += " the \"" + kind + "\" messages that the service uses.";
		}
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationUnknownOperation(VisitReport vr) {
		String message = "Taverna could not find the operation ";
		String operationName = (String) vr.getProperty("operationName");
		if (operationName == null) {
			operationName = "called by the service";
		} else {
			operationName = "\"" + operationName + "\"";
		}
		return createPanel(new Object[] { message + operationName + "." });
	}

	private static JComponent explanationNoEndpoints(VisitReport vr) {
		String message = "Taverna found the operation ";
		String operationName = (String) vr.getProperty("operationName");
		if (operationName == null) {
			operationName = "called by the service";
		} else {
			operationName = "\"" + operationName + "\"";
		}
		message += operationName;
		message += " but is unable to call it due to lack of location information.";
		return createPanel(new Object[] { message + operationName });
	}

	private static JComponent explanationInvalidConfiguration(VisitReport vr) {
		Exception e = (Exception) (vr.getProperty("exception"));
		String message = "Trying to understand the XML splitter caused ";
		if (e == null) {
			message += " an exception";
		} else {
			message += "\"" + e.getMessage() + "\"";
		}
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationNullDatatype(VisitReport vr) {
		String message = "The XML splitter appears to have a NULL datatype.";
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationDisabled(VisitReport vr) {
		String message = "Taverna could not contact the service when the workflow was opened.";
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationDatatypeSource(VisitReport vr) {
		String message = "The data going into ";
		String sinkPortName = (String) vr.getProperty("sinkPortName");
		if (sinkPortName == null) {
			sinkPortName = "a port";
		} else {
			sinkPortName = "port \"" + sinkPortName + "\"";
		}
		message += sinkPortName;
		String sourceName = (String) vr.getProperty("sourceName");
		String isProcessorSource = (String) vr.getProperty("isProcessorSource");
		if (sourceName != null) {
			message += " from ";
			if (isProcessorSource != null) {
				if (isProcessorSource.equals("true")) {
					message += "service ";
				} else {
					message += "port ";
				}
			}
			message += "\"" + sourceName + "\"";
		}
		message += " may not be XML.  The service requires XML as input.";
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationBeanshellInvalidScript(VisitReport vr) {
		Exception e = (Exception) vr.getProperty("exception");
		String exceptionMessage = null;
		if (e != null) {
			exceptionMessage = e.getMessage();
		}
		return createPanel(new Object[] {
				"There are errors in the script of the service.\nWhen the workflow runs, any calls of the service will fail with error: ",
				exceptionMessage + "." });
	}

	private static JComponent explanationUnrecognized(VisitReport vr) {
		String message = "Taverna could not recognize the service when the workflow was opened.";
		return createPanel(new Object[] { message });
	}

	private static JComponent explanationLoopConnection(VisitReport vr) {
		return createPanel(new Object[] { "Port \""
				+ vr.getProperty("portname") + "\" must be connected" });
	}

	private static JComponent explanationUnmanagedLocation(VisitReport vr) {
		return createPanel(new Object[] { "The external tool service is configured to run on a location that is not currently known to the Location Manager. It is a good idea to change it to a known location" });
	}

	private static JComponent explanationIncompatibleMimetypes(VisitReport vr) {
		ProcessorInputPort pip = (ProcessorInputPort) vr
				.getProperty("sinkPort");
		ProcessorOutputPort pop = (ProcessorOutputPort) vr
				.getProperty("sourcePort");
		Processor sourceProcessor = (Processor) vr
				.getProperty("sourceProcessor");
		String message = "The data";
		if (pop != null) {
			message += " from port \"" + pop.getName() + "\"";
			if (sourceProcessor != null) {
				message += " of service \"" + sourceProcessor.getLocalName()
						+ "\"";
			}
		}
		if (pip != null) {
			message += " into port \"" + pip.getName() + "\"";
		}
		message += " does not have a compatible mime type";
		return createPanel(new Object[] { message });
	}

	private JComponent solutionFailedEntity(VisitReport vr) {
		if (vr.getSubject() instanceof Processor) {
			Processor p = (Processor) (vr.getSubject());
			DataflowActivity da = null;
			for (Activity a : p.getActivityList()) {
				if (a instanceof DataflowActivity) {
					da = (DataflowActivity) a;
					break;
				}
			}
			String message = "Check the list handling of the service, including the predicted behavior of the service's inputs and outputs";
			JButton button = null;
			if (da != null) {
				message += ", or edit the nested workflow";
				button = new JButton();
				button.setAction(new EditNestedDataflowAction(da, fileManager));
				button.setText("Edit \"" + p.getLocalName() + "\"");
			}
			return createPanel(new Object[] { message + ".", button });
		} else if (vr.getSubject() instanceof Merge) {
			return createPanel(new Object[] { "Check the predicted behaviour of the data being merged." });
		}
		return null;
	}

	private static JComponent solutionInvalidDataflow(VisitReport vr) {
		String message = "Fix the errors within the workflow.";
		return createPanel(new Object[] { message });
	}

	private JComponent solutionUnresolvedOutput(VisitReport vr) {
		JButton deleteButton = null;

		DataflowOutputPort port = (DataflowOutputPort) vr.getSubject();
		DataflowOutputPort dop = (DataflowOutputPort) vr.getSubject();
		Datalink incomingLink = dop.getInternalInputPort().getIncomingLink();
		String message;
		if (incomingLink == null) {
			message = "Connect the workflow output port to a service or a workflow input port.  Alternatively,";
			final Dataflow d = fileManager.getCurrentDataflow();
			final DataflowOutputPort p = port;
			deleteButton = new JButton(new AbstractAction("Remove port") {
				public void actionPerformed(ActionEvent e) {
					Edit removeEdit = editManager.getEdits()
							.getRemoveDataflowOutputPortEdit(d, p);
					try {
						editManager.doDataflowEdit(d, removeEdit);
					} catch (EditException ex) {
						logger.error("Could not perform edit", ex);
					}
				}
			});
		} else {
			message = "Fix the errors of the service that the output port is connected to.";
		}
		return createPanel(new Object[] { message, deleteButton });
	}

	private JComponent solutionUnsatisfiedEntity(VisitReport vr) {
		String message = "";
		Dataflow currentDataflow = fileManager.getCurrentDataflow();
		Tools.ProcessorSplit ps = Tools.splitProcessors(
				currentDataflow.getProcessors(),
				(TokenProcessingEntity) (vr.getSubject()));
		Set<Processor> upStream = ps.getUpStream();
		boolean plural = false;
		for (Processor p : upStream) {
			Set<VisitReport> reports = reportManager.getReports(currentDataflow, p);
			for (VisitReport report : reports) {
				if (report.getKind() instanceof FailedEntityKind) {
					if (!message.equals("")) {
						message += " and";
						plural = true;
					}
					message += " " + p.getLocalName();
				}
			}
		}
		if (message.equals("")) {
			return null;
		}
		if (!plural) {
			message = "The underlying error is caused by" + message;
		} else {
			message = "The underlying errors are caused by" + message;
		}
		return createPanel(new Object[] { message + "." });
	}

	private JComponent solutionDataflowCollation(VisitReport vr) {
		String message = "Edit the nested workflow to fix its problems.";
		JButton button = null;
		Processor p = (Processor) (vr.getSubject());
		DataflowActivity da = null;
		for (Activity a : p.getActivityList()) {
			if (a instanceof DataflowActivity) {
				da = (DataflowActivity) a;
				break;
			}
		}
		if (da != null) {
			button = new JButton();
			button.setAction(new EditNestedDataflowAction(da, fileManager));
			button.setText("Edit \"" + p.getLocalName() + "\"");
		}
		String reminder = "Remember to save the nested workflow.";
		return createPanel(new Object[] { message, button, reminder });
	}

	private JComponent solutionDataflowIncomplete(VisitReport vr) {
		String message = "Add a service from the service panel to the workflow, or";
		JButton button = new JButton();
		button.setAction(new AddDataflowOutputAction(
				(Dataflow) vr.getSubject(), null, editManager, selectionManager));
		button.setText("Add an output port");
		return createPanel(new Object[] { message, button });
	}

	private JComponent solutionSourceFragile(VisitReport vr) {
		Processor sourceProcessor = (Processor) vr
				.getProperty("sourceProcessor");
		String labelText = "Make ";
		if (sourceProcessor == null) {
			labelText += "the source service ";
		} else {
			labelText += "\"" + sourceProcessor.getLocalName() + "\" ";
		}
		labelText += "more robust to failure by adding service retries.";
		JButton button = null;
		if (sourceProcessor != null) {
			Retry retryLayer = null;
			for (DispatchLayer dl : sourceProcessor.getDispatchStack()
					.getLayers()) {
				if (dl instanceof Retry) {
					retryLayer = (Retry) dl;
					break;
				}
			}
			if (retryLayer != null) {
				button = new JButton();
				button.setAction(new RetryConfigureAction(null, null,
						retryLayer, editManager, fileManager));
				button.setText("Set retry");
			}
		}
		return createPanel(new Object[] { labelText, button });
	}

	private static JComponent solutionBeanshellInvalidScript(VisitReport vr) {
		JButton button = new JButton();
		Processor p = (Processor) (vr.getSubject());
		button.setAction(new ReportViewConfigureAction(p));
		button.setText("Configure " + p.getLocalName());
		return createPanel(new Object[] {
				"Edit the service script, checking that the script is valid before saving it.",
				button });
	}

	private JComponent solutionConnectionProblem(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		String connectMessage = "";
		JButton connectButton = null;
		if (endpoint == null) {
			endpoint = "the endpoint";
			connectMessage = "Try to connect to the endpoint.";
		} else {
			connectMessage = "Try to connect to " + endpoint + " in a browser.";
			final String end = endpoint;
			connectButton = new JButton(new AbstractAction("Open in browser") {
				public void actionPerformed(ActionEvent e) {
					try {
						Desktop.getDesktop().browse(new URI(end));
					} catch (Exception ex) {
						logger.error("Failed to open endpoint", ex);
					}
				}
			});
		}
		String workedMessage = "If the connection did not work, please contact the service provider or workflow creator.  Alternatively, check if you are using an HTTP Proxy, and edit Taverna's proxy settings.";
		JButton preferencesButton = null;
		if (endpoint != null) {
			preferencesButton = new JButton(new AbstractAction(
					"Change HTTP proxy") {
				public void actionPerformed(ActionEvent e) {
					T2ConfigurationFrame.showConfiguration("HTTP proxy", configurationUIFactories);
				}
			});
		}
		String editMessage = null;
		JButton editButton = null;
		DisabledActivity da = null;
		for (Activity a : ((Processor) vr.getSubject()).getActivityList()) {
			if (a instanceof DisabledActivity) {
				da = (DisabledActivity) a;
				break;
			}
		}
		if (da != null) {
			editMessage = "If the service has moved, change the service's properties to its new location.";
			editButton = new JButton(new DisabledActivityConfigurationAction(
					da, null, editManager, fileManager, reportManager, activityIconManager));
		}
		return createPanel(new Object[] { connectMessage, connectButton,
				workedMessage, preferencesButton, editMessage, editButton });

	}

	private JComponent solutionInvalidUrl(VisitReport vr) {
		String message = "Contact the service provider or workflow creator.";
		String editMessage = "If the service has moved, change the service's properties to its new location.";
		JButton editButton = null;
		DisabledActivity da = null;
		for (Activity a : ((Processor) vr.getSubject()).getActivityList()) {
			if (a instanceof DisabledActivity) {
				da = (DisabledActivity) a;
				break;
			}
		}
		if (da != null) {
			editButton = new JButton(new DisabledActivityConfigurationAction(
					da, null, editManager, fileManager, reportManager, activityIconManager));
		}
		return createPanel(new Object[] { message, editMessage, editButton });
	}

	private JComponent solutionTimeOut(VisitReport vr) {
		String message = "Try to open ";
		String endpoint = (String) (vr.getProperty("endpoint"));
		JButton connectButton = null;
		if (endpoint == null) {
			message += "the endpoint ";
		} else {
			message += "\"" + endpoint + "\" ";
			final String end = endpoint;
			connectButton = new JButton(new AbstractAction("Open in browser") {
				public void actionPerformed(ActionEvent e) {
					try {
						Desktop.getDesktop().browse(new URI(end));
					} catch (Exception ex) {
						logger.error("Failed to open endpoint", ex);
					}
				}
			});
		}
		message += "in a file, or web, browser.";
		String workedMessage = "If the browser opened the address, then alter the validation timeout in the preferences";
		JButton preferencesButton = new JButton(new AbstractAction(
				"Change timeout") {
			public void actionPerformed(ActionEvent e) {
				T2ConfigurationFrame.showConfiguration("Validation report", configurationUIFactories);
			}
		});
		String didNotWorkMessage = "Alternatively, if the browser did not open the address, try later as the service may be temporarily offline.  If the service remains offline, please contact the service provider or workflow creator.";
		String editMessage = null;
		JButton editButton = null;
		DisabledActivity da = null;
		for (Activity a : ((Processor) vr.getSubject()).getActivityList()) {
			if (a instanceof DisabledActivity) {
				da = (DisabledActivity) a;
				break;
			}
		}
		if (da != null) {
			editMessage = "If the service has moved, change the service's properties to its new location.";
			editButton = new JButton(new DisabledActivityConfigurationAction(
					da, null, editManager, fileManager, reportManager, activityIconManager));
		}
		return createPanel(new Object[] { message, connectButton,
				workedMessage, preferencesButton, didNotWorkMessage,
				editMessage, editButton });
	}

	private JComponent solutionIoProblem(VisitReport vr) {
		String message = "";
		Exception e = (Exception) (vr.getProperty("exception"));
		if (e != null && e instanceof SSLException) {
			message += "There was a problem with establishing a HTTPS connection to the service. ";
			if (e.getMessage().toLowerCase()
					.contains("no trusted certificate found")) {
				message += "Looks like the authenticity of the service could not be confirmed. Check that you have imported the service's certificate under 'Trusted Certificates' in Credential Manager. "
						+ "If this is a WSDL service, try restarting Taverna to refresh certificates used in HTTPS connections.\n\n";
			} else if (e.getMessage().toLowerCase()
					.contains("received fatal alert: bad_certificate")) {
				message += "Looks like you could not be authenticated to the service. Check that you have imported your certificate under 'Your certificates' in Credential Manager. "
						+ "If this is a WSDL service, try restarting Taverna to refresh certificates used in HTTPS connections.\n\n";
			} else {
				message += "Check that you have imported the service's certificate under 'Trusted Certificates' in Credential Manager. "
						+ "If user authentication is required, also check that you have imported your certificate under 'Your certificates' in Credential Manager. "
						+ "If this is a WSDL service, try restarting Taverna to refresh certificates used in HTTPS connections.\n\n";
			}
		}
		message += "Try to open ";
		String endpoint = (String) (vr.getProperty("endpoint"));
		JButton connectButton = null;
		if (endpoint == null) {
			message += "the endpoint ";
		} else {
			message += "\"" + endpoint + "\" ";
			final String end = endpoint;
			connectButton = new JButton(new AbstractAction("Open in browser") {
				public void actionPerformed(ActionEvent e) {
					try {
						Desktop.getDesktop().browse(new URI(end));
					} catch (Exception ex) {
						logger.error("Failed to open endpoint", ex);
					}
				}
			});
		}
		message += "in a file, or web, browser.";
		String elseMessage = message.startsWith("Try to open") ? "If that does not work, please contact the service provider or workflow creator."
				: null;
		String editMessage = message.startsWith("Try to open") ? "If the service has moved, change the service's properties to its new location."
				: null;
		JButton editButton = null;
		DisabledActivity da = null;
		for (Activity a : ((Processor) vr.getSubject()).getActivityList()) {
			if (a instanceof DisabledActivity) {
				da = (DisabledActivity) a;
				break;
			}
		}
		if (da != null) {
			editButton = new JButton(new DisabledActivityConfigurationAction(
					da, null, editManager, fileManager, reportManager, activityIconManager));
		}
		return createPanel(new Object[] { message, connectButton, elseMessage,
				editMessage, editButton });
	}

	private static JComponent solutionMissingDependency(VisitReport vr) {
		String message = "Put ";
		Set<String> dependencies = (Set<String>) (vr
				.getProperty("dependencies"));
		if (dependencies == null) {
			message += "the dependencies";
		} else {
			for (Iterator i = dependencies.iterator(); i.hasNext();) {
				String s = (String) i.next();
				message += s;
				if (i.hasNext()) {
					message += " and ";
				}
			}
		}
		File directory = (File) vr.getProperty("directory");
		if (directory != null) {
			try {
				message += " in directory " + directory.getCanonicalPath();
			} catch (IOException e) {
				logger.error("Could not get path", e);
			}
		} else {
			message += " in the application directory.";
		}
		String elseMessage = "If you do not have the files, please contact the workflow creator.";
		return createPanel(new Object[] { message, elseMessage });
	}

	private static JComponent solutionDefaultValue(VisitReport vr) {
		String message = "Change the value of the service by clicking the \"Set value\" button";
		JButton button = new JButton();
		Processor p = (Processor) (vr.getSubject());
		button.setAction(new ReportViewConfigureAction(p));
		button.setText("Set value");
		return createPanel(new Object[] { message, button });
	}

	private static JComponent solutionBadWSDL(VisitReport vr) {
		return createPanel(new Object[] { PLEASE_CONTACT });
	}

	private static JComponent solutionNotHTTP(VisitReport vr) {
		String endpoint = (String) (vr.getProperty("endpoint"));
		if (endpoint == null) {
			endpoint = "the endpoint";
		} else {
			endpoint = "\"" + endpoint + "\"";
		}
		String message = "Move the file at " + endpoint + " to a web server.";
		return createPanel(new Object[] { message });
	}

	private static JComponent solutionUnsupportedStyle(VisitReport vr) {
		String message = "Contact the service provider to see if there is an alternative style of service available.";
		return createPanel(new Object[] { message });
	}

	private JComponent solutionUnknownOperation(VisitReport vr) {
		String message = "Contact the service provider to see if the operation has been renamed.";
		String editMessage = "If you know its new name, then please edit the service's properties.";
		JButton editButton = null;
		DisabledActivity da = null;
		for (Activity a : ((Processor) vr.getSubject()).getActivityList()) {
			if (a instanceof DisabledActivity) {
				da = (DisabledActivity) a;
				break;
			}
		}
		if (da != null) {
			editButton = new JButton(new DisabledActivityConfigurationAction(
					da, null, editManager, fileManager, reportManager, activityIconManager));
		}
		return createPanel(new Object[] { message, editMessage, editButton });
	}

	private static JComponent solutionNoEndpoints(VisitReport vr) {
		return createPanel(new Object[] { PLEASE_CONTACT });
	}

	private static JComponent solutionInvalidConfiguration(VisitReport vr) {
		return createPanel(new Object[] { PLEASE_CONTACT });
	}

	private static JComponent solutionNullDatatype(VisitReport vr) {
		return createPanel(new Object[] { PLEASE_CONTACT });
	}

	private static JComponent solutionDisabled(VisitReport vr) {
		String message = "Validate the workflow and fix any errors on the service.";
		return createPanel(new Object[] { message });
	}

	private JComponent solutionDatatypeSource(VisitReport vr) {
		String sinkPortName = (String) vr.getProperty("sinkPortName");
		if (sinkPortName == null) {
			return null;
		}
		String removeMessage = "1. Remove the link to " + "port \""
				+ sinkPortName + "\"";
		ProcessorInputPort pip = (ProcessorInputPort) vr
				.getProperty("sinkPort");
		final InputPortTypeDescriptorActivity a = (InputPortTypeDescriptorActivity) vr
				.getProperty("activity");
		String addSplitterMessage = "2. Add an XML splitter for " + "port \""
				+ sinkPortName + "\"";
		JButton button = null;
		if (pip != null) {
			Datalink incomingLink = pip.getIncomingLink();
			if (incomingLink != null) {
				button = new JButton();
				final Dataflow d = fileManager.getCurrentDataflow();
				final String portName = sinkPortName;
				final Datalink link = incomingLink;
				button.setAction(new AbstractAction(
						"Remove link and add XML splitter") {
					public void actionPerformed(ActionEvent e) {
						Edit removeLinkEdit = Tools
								.getDisconnectDatalinkAndRemovePortsEdit(link, editManager.getEdits());
						Edit addXMLEdit = new AddXMLSplitterEdit(d,
								(Activity<?>) a, portName, true, editManager.getEdits());
						List<Edit<?>> editList = Arrays.asList(new Edit<?>[] {
								removeLinkEdit, addXMLEdit });
						CompoundEdit ce = new CompoundEdit(editList);
						try {
							editManager.doDataflowEdit(d, ce);
						} catch (EditException ex) {
							logger.error("Could not perform edit", ex);
						}
					}
				});
			}
		}
		String addConnectionMessage = "3. Make a connection to the relevant port of the new XML splitter.";
		return createPanel(new Object[] { removeMessage, addSplitterMessage,
				button, addConnectionMessage });
	}

	private static JComponent solutionUnrecognized(VisitReport vr) {
		String message = "Please contact the workflow creator to find out what additional plugins, if any, need to be installed in Taverna.";
		return createPanel(new Object[] { message });
	}

	private static JComponent solutionLoopConnection(VisitReport vr) {
		return createPanel(new Object[] { "Connect port \""
				+ vr.getProperty("portname") + "\"" });
	}

	private static JComponent solutionUnmanagedLocation(VisitReport vr) {
		JButton button = new JButton();
		Processor p = (Processor) (vr.getSubject());
		button.setAction(new ReportViewConfigureAction(p));
		button.setText("Configure " + p.getLocalName());
		return createPanel(new Object[] {
				"Change the run locaton of the service", button });
	}

	private JComponent solutionIncompatibleMimetypes(VisitReport vr) {
		JButton sinkButton = new JButton();
		Processor sinkProcessor = (Processor) (vr.getProperty("sinkProcessor"));
		Processor sourceProcessor = (Processor) vr
				.getProperty("sourceProcessor");
		sinkButton.setAction(new ReportViewConfigureAction(sinkProcessor));
		sinkButton.setText("Configure " + sinkProcessor.getLocalName());
		JButton sourceButton = new JButton();
		sourceButton.setAction(new ReportViewConfigureAction(sourceProcessor));
		sourceButton.setText("Configure " + sourceProcessor.getLocalName());

		JButton deleteLinkButton = new JButton();
		final Datalink link = (Datalink) vr.getProperty("link");
		final Dataflow d = fileManager.getCurrentDataflow();
		deleteLinkButton.setAction(new AbstractAction("Remove link") {
			public void actionPerformed(ActionEvent e) {
				Edit removeLinkEdit = Tools
						.getDisconnectDatalinkAndRemovePortsEdit(link, editManager.getEdits());
				try {
					editManager.doDataflowEdit(d, removeLinkEdit);
				} catch (EditException ex) {
					logger.error("Could not perform edit", ex);
				}
			}
		});

		return createPanel(new Object[] {
				"Change the source or destination mimetype or remove the link",
				sourceButton, sinkButton, deleteLinkButton });
	}

	private static JPanel createPanel(Object[] components) {
		JPanel result = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.gridwidth = 1;
		gbc.weightx = 0.9;
		for (Object o : components) {
			if (o == null) {
				continue;
			}
			JComponent component = null;
			if (o instanceof String) {
				component = new ReadOnlyTextArea((String) o);
			} else if (o instanceof JComponent) {
				component = (JComponent) o;
			} else {
				logger.error("Unrecognized component " + o.getClass());
				continue;
			}
			gbc.gridy++;
			if (component instanceof JButton) {
				gbc.weightx = 0;
				gbc.gridwidth = 1;
				gbc.fill = GridBagConstraints.NONE;
			} else {
				gbc.weightx = 0.9;
				gbc.gridwidth = 2;
				gbc.fill = GridBagConstraints.HORIZONTAL;
			}
			result.add(component, gbc);
		}
		// gbc.weightx = 0.9;
		// gbc.weighty = 0.9;
		// gbc.gridx = 0;
		// gbc.gridy++;
		// gbc.gridwidth = 2;
		// gbc.fill = GridBagConstraints.BOTH;
		// result.add(new JPanel(), gbc);
		result.setBackground(SystemColor.text);
		return result;
	}

	public void setEditManager(EditManager editManager) {
		this.editManager = editManager;
	}

	public void setFileManager(FileManager fileManager) {
		this.fileManager = fileManager;
	}

	public void setReportManager(ReportManager reportManager) {
		this.reportManager = reportManager;
	}

	public void setSelectionManager(SelectionManager selectionManager) {
		this.selectionManager = selectionManager;
	}

	public void setConfigurationUIFactories(List<ConfigurationUIFactory> configurationUIFactories) {
		this.configurationUIFactories = configurationUIFactories;
	}

	public void setActivityIconManager(ActivityIconManager activityIconManager) {
		this.activityIconManager = activityIconManager;
	}

}
