gt:                                                      " : " + e.getMessage(), e);
context: /*
   * ProActive Parallel Suite(TM):
   * The Open Source library for parallel and distributed
   * Workflows & Scheduling, Orchestration, Cloud Automation
   * and Big Data Analysis on Enterprise Grids & Clouds.
   *
   * Copyright (c) 2007 - 2017 ActiveEon
   * Contact: contact@activeeon.com
   *
   * This library is free software: you can redistribute it and/or
   * modify it under the terms of the GNU Affero General Public License
   * as published by the Free Software Foundation: version 3 of
   * the License.
   *
   * 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 Affero General Public License for more details.
   *
   * You should have received a copy of the GNU Affero General Public License
   * along with this program. If not, see <http://www.gnu.org/licenses/>.
   *
   * If needed, contact us to obtain a release under GPL Version 2 or 3
   * or a different license than the AGPL.
   */
  package org.ow2.proactive.scheduler.task;
  
  import java.io.IOException;
  import java.io.NotSerializableException;
  import java.io.Serializable;
  import java.util.HashMap;
  import java.util.Map;
  
  import javax.xml.bind.annotation.XmlAccessType;
  import javax.xml.bind.annotation.XmlAccessorType;
  
  import org.apache.log4j.Logger;
  import org.objectweb.proactive.core.util.converter.ByteToObjectConverter;
  import org.objectweb.proactive.core.util.converter.ObjectToByteConverter;
  import org.objectweb.proactive.utils.StackTraceUtil;
  import org.ow2.proactive.scheduler.common.exception.InternalSchedulerException;
  import org.ow2.proactive.scheduler.common.task.TaskId;
  import org.ow2.proactive.scheduler.common.task.TaskLogs;
  import org.ow2.proactive.scheduler.common.task.TaskResult;
  import org.ow2.proactive.scheduler.common.task.flow.FlowAction;
  import org.ow2.proactive.utils.ObjectByteConverter;
  
  
  /**
   * Class representing the task result.
   * A task result can be an exception or a serializable object that you have to cast into your own type.
   * Before getting the object it is recommended that you call the hadException() method.
   * It will tell you if an exception occurred in the task that generate this result.
   *
   * @author The ProActive Team
   * @since ProActive Scheduling 0.9
   */
  @XmlAccessorType(XmlAccessType.FIELD)
  public class TaskResultImpl implements TaskResult {
      public static final Logger logger = Logger.getLogger(TaskResultImpl.class);
  
      /** The task identification of the result */
      private TaskId id = null;
  
      /** The value of the result if no exception occurred as a byte array */
      private byte[] serializedValue = null;
  
      /** true if this result contains raw data **/
      private boolean isRaw = false;
  
      /** The value of the result if no exception occurred */
      private transient Serializable value = null;
  
      private Map<String, Serializable> resultMap = new HashMap<>();
  
      private Map<String, String> metadata = new HashMap<>();
  
      /** The exception thrown by the task as a byte array */
      private byte[] serializedException = null;
  
      /** The exception thrown by the task */
      private transient Throwable exception = null;
  
      /** Task output */
      private TaskLogs output = null;
  
      /** Description definition of this result */
      private String previewerClassName = null;
  
      /** result of the FlowScript if there was one, or null */
      private FlowAction flowAction = null;
  
      //Managed by taskInfo, this field is here only to bring taskDuration to core AO
      private long taskDuration = -1;
  
      /**
       * A map which contains the propagated variables of the previous (dependent)
       * tasks.
       */
      private Map<String, byte[]> propagatedVariables = new HashMap();
  
      public TaskResultImpl(TaskId id, byte[] serializedValue, byte[] serializedException, TaskLogs output,
              Map<String, String> metadata, Map<String, byte[]> propagatedVariables, boolean isRaw) {
          this(id, serializedValue, serializedException, output, isRaw);
          if (propagatedVariables == null) {
              this.propagatedVariables = new HashMap();
          } else {
              this.propagatedVariables = propagatedVariables;
          }
          this.metadata = metadata;
      }
  
      public TaskResultImpl(TaskId id, byte[] serializedValue, byte[] serializedException, TaskLogs output,
              boolean isRaw) {
          this(id, output);
          this.serializedValue = serializedValue;
          this.serializedException = serializedException;
          this.output = output;
          this.isRaw = isRaw;
      }
  
      private TaskResultImpl(TaskId id, TaskLogs output) {
          this.id = id;
          this.output = output;
      }
  
      public TaskResultImpl(TaskId id, Throwable exception) {
          this(id, exception, null, 0);
      }
  
      /**
       * Return a new instance of task result represented by a task id, its result and its output.
       *
       * @param id the identification of the task that send this result.
       * @param value the result of the task.
       * @param output the output of the task.
       * @param execDuration the execution duration of the task itself
       */
      public TaskResultImpl(TaskId id, Serializable value, TaskLogs output, long execDuration) {
          this(id, output);
          this.taskDuration = execDuration;
          this.value = value;
          try {
              if (value instanceof byte[]) {
                  // object is already a byte array
                  this.serializedValue = (byte[]) value;
                  this.isRaw = true;
              } else {
                  //try to serialize user result
                  this.serializedValue = ObjectToByteConverter.ObjectStream.convert(value);
              }
          } catch (IOException ioe1) {
              //error while serializing
              logger.error("", ioe1);
              try {
                  //try to serialize the cause as an exception
                  this.serializedException = ObjectToByteConverter.ObjectStream.convert(ioe1);
              } catch (IOException ioe2) {
                  //cannot serialize the cause
                  logger.error("", ioe2);
                  try {
                      //serialize a NotSerializableException with the cause message
                      this.serializedException = ObjectToByteConverter.ObjectStream.convert(new NotSerializableException(ioe2.getMessage()));
                  } catch (IOException ioe3) {
                      //this should not append as the NotSerializableException is serializable and
                      //the given argument is a string (also serializable)
                      logger.error("", ioe3);
                  }
              }
          }
      }
  
      /**
       * Return a new instance of task result represented by a task id and its exception.
       *
       * @param id the identification of the task that send this result.
       * @param exception the exception that occurred in the task.
       * @param output the output of the task.
       * @param execDuration the execution duration of the task itself
       */
      public TaskResultImpl(TaskId id, Throwable exception, TaskLogs output, long execDuration) {
          this(id, output);
          this.taskDuration = execDuration;
          this.exception = exception;
          this.serializedException = computeSerializedException(exception);
      }
  
      private static byte[] computeSerializedException(Throwable exception) {
          byte[] answer = new byte[0];
          try {
              //try to serialize the user exception
              answer = ObjectToByteConverter.ObjectStream.convert(exception);
          } catch (IOException ioe2) {
              //cannot serialize the exception
              logger.error("", ioe2);
              try {
                  //serialize a NotSerializableException with the cause message
                  answer = ObjectToByteConverter.ObjectStream.convert(new NotSerializableException(ioe2.getMessage()));
              } catch (IOException ioe3) {
                  //this should not append as the NotSerializableException is serializable and
                  //the given argument is a string (also serializable)
                  logger.error("", ioe3);
              }
          }
          return answer;
      }
  
      /**
       * If a FlowScript was executed on this task, its result
       * is stored so that the action can be performed later when
       * processed by the core.
       *
       * return the Action to perform for this task
       */
      public FlowAction getAction() {
          return this.flowAction;
      }
  
      /**
       * If a FlowScript was executed on this task, its result
       * is stored so that the action can be performed later when
       * processed by the core.
       *
       * @param act an Control Flow action to embed in this TaskResult
       */
      public void setAction(FlowAction act) {
          this.flowAction = act;
      }
  
      /**
       * @param l logs of the task
       */
      public void setLogs(TaskLogs l) {
          this.output = l;
      }
  
      /**
       * @see org.ow2.proactive.scheduler.common.task.TaskResult#hadException()
       */
      public boolean hadException() {
          return serializedException != null;
      }
  
      public void setException(Throwable ex) {
          this.exception = ex;
          this.serializedException = computeSerializedException(ex);
      }
  
      /**
       * @see org.ow2.proactive.scheduler.common.task.TaskResult#getTaskId()
       */
      public TaskId getTaskId() {
          return id;
      }
  
      /**
       * @see org.ow2.proactive.scheduler.common.task.TaskResult#value()
       */
      public Serializable value() throws Throwable {
          if (hadException()) {
              Throwable thrown = null;
              try {
                  thrown = this.instanciateException(this.getTaskClassLoader());
              } catch (IOException e) {
                  throw new InternalSchedulerException("Cannot instanciate exception thrown by the task " + this.id +
  