[REEF-1286] Forward .NET Exceptions from the Evaluator to the Driver

This addressed the issue by
  * Adding Serializing of Evaluator Exceptions.
  * Modifying the FailedEvaluator test for both serializable and non-serializable Exceptions.

JIRA:
  [REEF-1286](https://issues.apache.org/jira/browse/REEF-1286)

This close #988
diff --git a/lang/cs/Org.Apache.REEF.Bridge/Clr2JavaImpl.h b/lang/cs/Org.Apache.REEF.Bridge/Clr2JavaImpl.h
index d00ae59..e3fef8a 100644
--- a/lang/cs/Org.Apache.REEF.Bridge/Clr2JavaImpl.h
+++ b/lang/cs/Org.Apache.REEF.Bridge/Clr2JavaImpl.h
@@ -158,12 +158,11 @@
                             virtual void OnError(String^ message);
                             virtual IEvaluatorRequestorClr2Java^ GetEvaluatorRequestor();
                             virtual String^ GetId();
-                            virtual EvaluatorException^ GetException();
                             virtual array<IFailedContextClr2Java^>^ GetFailedContextsClr2Java();
                             virtual IFailedTaskClr2Java^ GetFailedTaskClr2Java();
-                        private:
-                            String^ GetCause();
-                            String^ GetStackTrace();
+                            virtual array<byte>^ GetErrorBytes();
+                            virtual String^ GetJavaCause();
+                            virtual String^ GetJavaStackTrace();
                         };
 
                         public ref class HttpServerClr2Java : public IHttpServerBridgeClr2Java {
diff --git a/lang/cs/Org.Apache.REEF.Bridge/FailedEvaluatorClr2Java.cpp b/lang/cs/Org.Apache.REEF.Bridge/FailedEvaluatorClr2Java.cpp
index 9f0c8f5..f033c24 100644
--- a/lang/cs/Org.Apache.REEF.Bridge/FailedEvaluatorClr2Java.cpp
+++ b/lang/cs/Org.Apache.REEF.Bridge/FailedEvaluatorClr2Java.cpp
@@ -76,12 +76,6 @@
 						  return ManagedStringFromJavaString(env, _jstringId);
 					  }
 
-                      EvaluatorException^ FailedEvaluatorClr2Java::GetException() {
-                          String^ cause = this->GetCause();
-                          String^ stackTrace = this->GetStackTrace();
-                          return gcnew EvaluatorException(this->GetId(), cause, stackTrace);
-                      }
-
                       array<IFailedContextClr2Java^>^ FailedEvaluatorClr2Java::GetFailedContextsClr2Java() {
                           JNIEnv *env = RetrieveEnv(_jvm);
                           jclass jclassFailedEvaluator = env->GetObjectClass(_jobjectFailedEvaluator);
@@ -122,7 +116,20 @@
 						  HandleClr2JavaError(env, message, _jobjectFailedEvaluator);
 					  }
 
-                      String^ FailedEvaluatorClr2Java::GetCause() {
+                      array<byte>^ FailedEvaluatorClr2Java::GetErrorBytes() {
+                          JNIEnv *env = RetrieveEnv(_jvm);
+                          jclass jclassFailedEvaluator = env->GetObjectClass(_jobjectFailedEvaluator);
+                          jmethodID jmidGetError = env->GetMethodID(jclassFailedEvaluator, "getErrorBytes", "()[B");
+                          jobject methodCallReturn = env->CallObjectMethod(_jobjectFailedEvaluator, jmidGetError);
+                          if (methodCallReturn == NULL) {
+                              return nullptr;
+                          }
+
+                          jbyteArray error = reinterpret_cast<jbyteArray>(methodCallReturn);
+                          return ManagedByteArrayFromJavaByteArray(env, error);
+                      }
+
+                      String^ FailedEvaluatorClr2Java::GetJavaCause() {
                           JNIEnv *env = RetrieveEnv(_jvm);
                           jclass jclassFailedEvaluator = env->GetObjectClass(_jobjectFailedEvaluator);
                           jmethodID jmidGetCause = env->GetMethodID(jclassFailedEvaluator, "getCause", "()Ljava/lang/String;");
@@ -135,7 +142,7 @@
                           return ManagedStringFromJavaString(env, cause);
                       }
 
-                      String^ FailedEvaluatorClr2Java::GetStackTrace() {
+                      String^ FailedEvaluatorClr2Java::GetJavaStackTrace() {
                           JNIEnv *env = RetrieveEnv(_jvm);
                           jclass jclassFailedEvaluator = env->GetObjectClass(_jobjectFailedEvaluator);
                           jmethodID jmidGetStackTrace = env->GetMethodID(jclassFailedEvaluator, "getStackTrace", "()Ljava/lang/String;");
diff --git a/lang/cs/Org.Apache.REEF.Common/Exceptions/NonSerializableEvaluatorException.cs b/lang/cs/Org.Apache.REEF.Common/Exceptions/NonSerializableEvaluatorException.cs
new file mode 100644
index 0000000..8ce0913
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Common/Exceptions/NonSerializableEvaluatorException.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Org.Apache.REEF.Common.Exceptions
+{
+    /// <summary>
+    /// Encapsulates <see cref="Exception#ToString"/> for an Exception from a 
+    /// REEF Evaluator that was not Serializable to the Job Driver.
+    /// </summary>
+    [Serializable]
+    public sealed class NonSerializableEvaluatorException : Exception
+    {
+        public NonSerializableEvaluatorException(string message, SerializationException serializationException)
+            : base(message, serializationException)
+        {
+        }
+
+        public NonSerializableEvaluatorException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
index 313d06a..b48e0e2 100644
--- a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
+++ b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
@@ -107,6 +107,7 @@
     <Compile Include="Events\IContextStart.cs" />
     <Compile Include="Events\IContextStop.cs" />
     <Compile Include="Exceptions\JobException.cs" />
+    <Compile Include="Exceptions\NonSerializableEvaluatorException.cs" />
     <Compile Include="Exceptions\NonSerializableTaskException.cs" />
     <Compile Include="Files\PathUtilities.cs" />
     <Compile Include="IContextAndTaskSubmittable.cs" />
diff --git a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
index 4c86218..1c92192 100644
--- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
+++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
@@ -17,10 +17,13 @@
 
 using System;
 using System.Globalization;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using Org.Apache.REEF.Common.Exceptions;
 using Org.Apache.REEF.Common.Protobuf.ReefProtocol;
 using Org.Apache.REEF.Common.Runtime.Evaluator.Context;
 using Org.Apache.REEF.Tang.Annotations;
-using Org.Apache.REEF.Utilities;
 using Org.Apache.REEF.Utilities.Diagnostics;
 using Org.Apache.REEF.Utilities.Logging;
 using Org.Apache.REEF.Wake.Time;
@@ -242,17 +245,31 @@
                 Logger.Log(Level.Error, "Evaluator {0} failed with exception {1}.", _evaluatorId, e);
                 _state = State.FAILED;
 
-                var errorMessage = string.Format(
-                        CultureInfo.InvariantCulture,
-                        "failed with error [{0}] with message [{1}] and stack trace [{2}]",
-                        e,
-                        e.Message,
-                        e.StackTrace);
+                byte[] errorBytes = null;
+
+                try
+                {
+                    using (var memStream = new MemoryStream())
+                    {
+                        var formatter = new BinaryFormatter();
+                        formatter.Serialize(memStream, e);
+                        errorBytes = memStream.ToArray();
+                    }
+                }
+                catch (SerializationException se)
+                {
+                    using (var memStream = new MemoryStream())
+                    {
+                        var formatter = new BinaryFormatter();
+                        formatter.Serialize(memStream, new NonSerializableEvaluatorException(e.ToString(), se));
+                        errorBytes = memStream.ToArray();
+                    }
+                }
 
                 var evaluatorStatusProto = new EvaluatorStatusProto()
                 {
                     evaluator_id = _evaluatorId,
-                    error = ByteUtilities.StringToByteArrays(errorMessage),
+                    error = errorBytes,
                     state = _state
                 };
 
diff --git a/lang/cs/Org.Apache.REEF.Driver/Bridge/Clr2java/IFailedEvaluatorClr2Java.cs b/lang/cs/Org.Apache.REEF.Driver/Bridge/Clr2java/IFailedEvaluatorClr2Java.cs
index 19b51b8..3dcd2ae 100644
--- a/lang/cs/Org.Apache.REEF.Driver/Bridge/Clr2java/IFailedEvaluatorClr2Java.cs
+++ b/lang/cs/Org.Apache.REEF.Driver/Bridge/Clr2java/IFailedEvaluatorClr2Java.cs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-using Org.Apache.REEF.Driver.Evaluator;
 using Org.Apache.REEF.Utilities.Attributes;
 
 namespace Org.Apache.REEF.Driver.Bridge.Clr2java
@@ -23,14 +22,39 @@
     [Private, Interop("FailedEvaluatorClr2Java.cpp", "Clr2JavaImpl.h")]
     public interface IFailedEvaluatorClr2Java
     {
+        /// <summary>
+        /// Gets the Evaluator requestor.
+        /// </summary>
         IEvaluatorRequestorClr2Java GetEvaluatorRequestor();
 
+        /// <summary>
+        /// Gets the ID of the failed Evaluator.
+        /// </summary>
         string GetId();
 
+        /// <summary>
+        /// Gets the failed Contexts on the Evaluator.
+        /// </summary>
         IFailedContextClr2Java[] GetFailedContextsClr2Java();
 
+        /// <summary>
+        /// Gets the failed Task on the Evaluator.
+        /// </summary>
         IFailedTaskClr2Java GetFailedTaskClr2Java();
 
-        EvaluatorException GetException();
+        /// <summary>
+        /// Gets the Serialized Exception.
+        /// </summary>
+        byte[] GetErrorBytes();
+
+        /// <summary>
+        /// Gets the Java Exception message.
+        /// </summary>
+        string GetJavaCause();
+
+        /// <summary>
+        /// Gets the Java stack trace.
+        /// </summary>
+        string GetJavaStackTrace();
     }
 }
diff --git a/lang/cs/Org.Apache.REEF.Driver/Bridge/Events/FailedEvaluator.cs b/lang/cs/Org.Apache.REEF.Driver/Bridge/Events/FailedEvaluator.cs
index bf126c0..337b793 100644
--- a/lang/cs/Org.Apache.REEF.Driver/Bridge/Events/FailedEvaluator.cs
+++ b/lang/cs/Org.Apache.REEF.Driver/Bridge/Events/FailedEvaluator.cs
@@ -15,9 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
+using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 using Org.Apache.REEF.Driver.Bridge.Clr2java;
 using Org.Apache.REEF.Driver.Context;
 using Org.Apache.REEF.Driver.Evaluator;
@@ -31,6 +34,7 @@
     {
         private readonly string _id;
         private readonly IList<IFailedContext> _failedContexts;
+        private readonly EvaluatorException _evaluatorException;
 
         public FailedEvaluator(IFailedEvaluatorClr2Java clr2Java)
         {
@@ -39,6 +43,24 @@
             _failedContexts = new List<IFailedContext>(
                 FailedEvaluatorClr2Java.GetFailedContextsClr2Java().Select(clr2JavaFailedContext => 
                     new FailedContext(clr2JavaFailedContext)));
+
+            var errorBytes = FailedEvaluatorClr2Java.GetErrorBytes();
+            if (errorBytes != null)
+            {
+                // When the Exception originates from the C# side.
+                var formatter = new BinaryFormatter();
+                using (var memStream = new MemoryStream(errorBytes))
+                {
+                    var inner = (Exception)formatter.Deserialize(memStream);
+                    _evaluatorException = new EvaluatorException(_id, inner.Message, inner);
+                }
+            }
+            else
+            {
+                // When the Exception originates from Java.
+                _evaluatorException = new EvaluatorException(
+                    _id, FailedEvaluatorClr2Java.GetJavaCause(), FailedEvaluatorClr2Java.GetJavaStackTrace());
+            }
         }
 
         [DataMember]
@@ -51,7 +73,7 @@
 
         public EvaluatorException EvaluatorException
         {
-            get { return FailedEvaluatorClr2Java.GetException(); }
+            get { return _evaluatorException; }
         }
 
         public IList<IFailedContext> FailedContexts
diff --git a/lang/cs/Org.Apache.REEF.Driver/Evaluator/EvaluatorException.cs b/lang/cs/Org.Apache.REEF.Driver/Evaluator/EvaluatorException.cs
index c21a113..5d67f38 100644
--- a/lang/cs/Org.Apache.REEF.Driver/Evaluator/EvaluatorException.cs
+++ b/lang/cs/Org.Apache.REEF.Driver/Evaluator/EvaluatorException.cs
@@ -26,12 +26,20 @@
         private readonly string _evaluatorId;
         private readonly Optional<string> _javaStackTrace;
 
-        [Private]
-        public EvaluatorException(string evaluatorId, string message, string javaStackTrace)
+        internal EvaluatorException(string evaluatorId, string message, string javaStackTrace)
             : base(message)
         {
             _evaluatorId = evaluatorId;
-            _javaStackTrace = Optional<string>.OfNullable(javaStackTrace);
+            _javaStackTrace = string.IsNullOrWhiteSpace(javaStackTrace)
+                ? Optional<string>.Empty()
+                : Optional<string>.Of(javaStackTrace);
+        }
+
+        internal EvaluatorException(string evaluatorId, string message, Exception inner)
+            : base(message, inner)
+        {
+            _evaluatorId = evaluatorId;
+            _javaStackTrace = Optional<string>.Empty();
         }
 
         public string EvaluatorId
diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestNonSerializableException.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestNonSerializableException.cs
new file mode 100644
index 0000000..3fcea6c
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestNonSerializableException.cs
@@ -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.
+
+using System;
+
+namespace Org.Apache.REEF.Tests.Functional.Bridge.Exceptions
+{
+    internal sealed class TestNonSerializableException : Exception
+    {
+        public TestNonSerializableException(string message)
+            : base(message)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
new file mode 100644
index 0000000..ee9840e
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
@@ -0,0 +1,36 @@
+// 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.
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Org.Apache.REEF.Tests.Functional.Bridge.Exceptions
+{
+    [Serializable]
+    internal sealed class TestSerializableException : Exception
+    {
+        public TestSerializableException(string message)
+            : base(message)
+        {
+        }
+
+        public TestSerializableException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Parameters/ShouldThrowSerializableException.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Parameters/ShouldThrowSerializableException.cs
new file mode 100644
index 0000000..544026d
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Parameters/ShouldThrowSerializableException.cs
@@ -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.
+
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Tests.Functional.Bridge.Parameters
+{
+    [NamedParameter(documentation: "Used to indicate whether FailTask should throw a Serializable or non-Serializable Exception.")]
+    internal sealed class ShouldThrowSerializableException : Name<bool>
+    {
+        private ShouldThrowSerializableException()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestFailedTaskEventHandler.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestFailedTaskEventHandler.cs
index dfcb9f6..251dc61 100644
--- a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestFailedTaskEventHandler.cs
+++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestFailedTaskEventHandler.cs
@@ -28,6 +28,8 @@
 using Org.Apache.REEF.Tang.Implementations.Tang;
 using Org.Apache.REEF.Tang.Interface;
 using Org.Apache.REEF.Tang.Util;
+using Org.Apache.REEF.Tests.Functional.Bridge.Exceptions;
+using Org.Apache.REEF.Tests.Functional.Bridge.Parameters;
 using Org.Apache.REEF.Utilities.Logging;
 using Xunit;
 
@@ -204,35 +206,5 @@
                 throw new TestNonSerializableException(ExpectedExceptionMessage);
             }
         }
-
-        [NamedParameter(documentation: "Used to indicate whether FailTask should throw a Serializable or non-Serializable Exception.")]
-        private sealed class ShouldThrowSerializableException : Name<bool>
-        {
-            private ShouldThrowSerializableException()
-            {
-            }
-        }
-
-        [Serializable]
-        private sealed class TestSerializableException : Exception
-        {
-            public TestSerializableException(string message)
-                : base(message)
-            {
-            }
-
-            public TestSerializableException(SerializationInfo info, StreamingContext context)
-                : base(info, context)
-            {
-            }
-        }
-
-        private sealed class TestNonSerializableException : Exception
-        {
-            public TestNonSerializableException(string message)
-                : base(message)
-            {
-            }
-        }
     }
 }
diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs
index ec8fc07..fda2c0c 100644
--- a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs
+++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs
@@ -17,13 +17,18 @@
 
 using System;
 using System.Threading;
+using Org.Apache.REEF.Common.Exceptions;
 using Org.Apache.REEF.Common.Tasks;
 using Org.Apache.REEF.Driver;
 using Org.Apache.REEF.Driver.Evaluator;
 using Org.Apache.REEF.Driver.Task;
 using Org.Apache.REEF.Tang.Annotations;
+using Org.Apache.REEF.Tang.Implementations.Configuration;
+using Org.Apache.REEF.Tang.Implementations.Tang;
 using Org.Apache.REEF.Tang.Interface;
 using Org.Apache.REEF.Tang.Util;
+using Org.Apache.REEF.Tests.Functional.Bridge.Exceptions;
+using Org.Apache.REEF.Tests.Functional.Bridge.Parameters;
 using Org.Apache.REEF.Utilities.Logging;
 using Xunit;
 
@@ -34,21 +39,21 @@
     {
         private const string ExpectedEvaluatorFailureMessage = "Unhandled Exception.";
         private const string ExpectedTaskId = "TaskID";
-        private const string SuccessMessage = "Evaluator successfully received unhandled Exception.";
+        private const string SerializableSuccessMessage = "Evaluator successfully received serializable unhandled Exception.";
+        private const string NonSerializableSuccessMessage = "Evaluator successfully received nonserializable unhandled Exception.";
 
         /// <summary>
         /// This test validates that an unhandled Task Exception crashes the Evaluator and the Evaluator
         /// does an attempt to send a final message to the Driver.
-        /// TODO[JIRA REEF-1286]: Currently, this only validates the first portion, but does not yet validate the final message.
-        /// TODO[JIRA REEF-1286]: The verification of the final message can be done when the Exceptions are serializable.
         /// </summary>
         [Fact]
         public void TestUnhandledTaskExceptionCrashesEvaluator()
         {
             var testFolder = DefaultRuntimeFolder + Guid.NewGuid().ToString("N").Substring(0, 4);
             TestRun(GetDriverConfiguration(), typeof(TestUnhandledTaskException), 1, "testUnhandledTaskException", "local", testFolder);
-            ValidateSuccessForLocalRuntime(0, numberOfEvaluatorsToFail: 1, testFolder: testFolder);
-            ValidateMessageSuccessfullyLoggedForDriver(SuccessMessage, testFolder, 1);
+            ValidateSuccessForLocalRuntime(0, numberOfEvaluatorsToFail: 2, testFolder: testFolder);
+            ValidateMessageSuccessfullyLoggedForDriver(SerializableSuccessMessage, testFolder, 1);
+            ValidateMessageSuccessfullyLoggedForDriver(NonSerializableSuccessMessage, testFolder, 1);
         }
 
         private static IConfiguration GetDriverConfiguration()
@@ -68,16 +73,27 @@
         /// </summary>
         private sealed class UnhandledExceptionTestTask : ITask
         {
+            private readonly bool _shouldThrowSerializableException;
+
             [Inject]
-            private UnhandledExceptionTestTask()
+            private UnhandledExceptionTestTask(
+                [Parameter(typeof(ShouldThrowSerializableException))] bool shouldThrowSerializableException)
             {
+                _shouldThrowSerializableException = shouldThrowSerializableException;
             }
 
             public byte[] Call(byte[] memento)
             {
                 var thread = new Thread(() =>
                 {
-                    throw new Exception(ExpectedEvaluatorFailureMessage);
+                    if (_shouldThrowSerializableException)
+                    {
+                        throw new TestSerializableException(ExpectedEvaluatorFailureMessage);
+                    }
+                    else
+                    {
+                        throw new TestNonSerializableException(ExpectedEvaluatorFailureMessage);
+                    }
                 });
 
                 thread.Start();
@@ -105,6 +121,7 @@
             private static readonly Logger Logger = Logger.GetLogger(typeof(UnhandledExceptionTestDriver));
 
             private readonly IEvaluatorRequestor _evaluatorRequestor;
+            private bool _shouldReceiveSerializableException = true;
 
             [Inject]
             private UnhandledExceptionTestDriver(IEvaluatorRequestor evaluatorRequestor)
@@ -128,7 +145,12 @@
                     .Set(TaskConfiguration.Task, GenericType<UnhandledExceptionTestTask>.Class)
                     .Build();
 
-                value.SubmitTask(taskConf);
+                var shouldThrowSerializableConfig = TangFactory.GetTang().NewConfigurationBuilder()
+                    .BindNamedParameter<ShouldThrowSerializableException, bool>(
+                        GenericType<ShouldThrowSerializableException>.Class, _shouldReceiveSerializableException.ToString())
+                    .Build();
+
+                value.SubmitTask(Configurations.Merge(taskConf, shouldThrowSerializableConfig));
             }
 
             public void OnNext(ICompletedTask value)
@@ -150,7 +172,7 @@
 
                 if (!value.EvaluatorException.Message.Contains(ExpectedEvaluatorFailureMessage))
                 {
-                    // TODO[JIRA REEF-1286]: Verify the Exception message and the type of Exception.
+                    throw new Exception("Evaluator expected to contain the message " + ExpectedEvaluatorFailureMessage);
                 }
 
                 if (!value.FailedTask.IsPresent())
@@ -163,7 +185,43 @@
                     throw new Exception("Failed Task does not have the right Task ID.");
                 }
 
-                Logger.Log(Level.Info, SuccessMessage);
+                if (_shouldReceiveSerializableException)
+                {
+                    var serializableEx = value.EvaluatorException.InnerException as TestSerializableException;
+                    if (serializableEx == null)
+                    {
+                        throw new Exception("Evaluator InnerException expected to be of type " + typeof(TestSerializableException).Name);
+                    }
+
+                    if (!serializableEx.Message.Equals(ExpectedEvaluatorFailureMessage))
+                    {
+                        throw new Exception("Evaluator InnerException.Message expected to be " + ExpectedEvaluatorFailureMessage);
+                    }
+
+                    _shouldReceiveSerializableException = false;
+                    Logger.Log(Level.Info, SerializableSuccessMessage);
+
+                    _evaluatorRequestor.Submit(
+                        _evaluatorRequestor.NewBuilder()
+                            .SetCores(1)
+                            .SetNumber(1)
+                            .Build());
+                }
+                else
+                {
+                    var nonSerializableEx = value.EvaluatorException.InnerException as NonSerializableEvaluatorException;
+                    if (nonSerializableEx == null)
+                    {
+                        throw new Exception("Evaluator Exception expected to be of type " + typeof(NonSerializableEvaluatorException));
+                    }
+
+                    if (!nonSerializableEx.Message.Contains(ExpectedEvaluatorFailureMessage))
+                    {
+                        throw new Exception("Evaluator InnerException.Message expected to contain the message " + ExpectedEvaluatorFailureMessage);
+                    }
+
+                    Logger.Log(Level.Info, NonSerializableSuccessMessage);
+                }
             }
 
             public void OnError(Exception error)
diff --git a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
index bf58810..293f8d4 100644
--- a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
+++ b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
@@ -74,11 +74,14 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Functional\Bridge\HelloSimpleEventHandlers.cs" />
+    <Compile Include="Functional\Bridge\Parameters\ShouldThrowSerializableException.cs" />
     <Compile Include="Functional\Bridge\TestBridgeClient.cs" />
     <Compile Include="Functional\Bridge\TestCloseTask.cs" />
     <Compile Include="Functional\Bridge\TestContextStack.cs" />
     <Compile Include="Functional\Bridge\TestFailedEvaluatorEventHandler.cs" />
     <Compile Include="Functional\Bridge\TestFailedTaskEventHandler.cs" />
+    <Compile Include="Functional\Bridge\Exceptions\TestNonSerializableException.cs" />
+    <Compile Include="Functional\Bridge\Exceptions\TestSerializableException.cs" />
     <Compile Include="Functional\Bridge\TestSimpleContext.cs" />
     <Compile Include="Functional\Bridge\TestSimpleEventHandlers.cs" />
     <Compile Include="Functional\Bridge\TestSuspendTask.cs" />
@@ -181,6 +184,7 @@
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
   <Import Project="$(PackagesDir)\StyleCop.MSBuild.$(StyleCopVersion)\build\StyleCop.MSBuild.Targets" Condition="Exists('$(PackagesDir)\StyleCop.MSBuild.$(StyleCopVersion)\build\StyleCop.MSBuild.Targets')" />
diff --git a/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/FailedEvaluatorBridge.java b/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/FailedEvaluatorBridge.java
index 89be5f3..8acabce 100644
--- a/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/FailedEvaluatorBridge.java
+++ b/lang/java/reef-bridge-java/src/main/java/org/apache/reef/javabridge/FailedEvaluatorBridge.java
@@ -23,6 +23,7 @@
 import org.apache.reef.annotations.audience.Private;
 import org.apache.reef.driver.evaluator.EvaluatorRequestor;
 import org.apache.reef.driver.evaluator.FailedEvaluator;
+import org.apache.reef.exception.NonSerializableException;
 import org.apache.reef.io.naming.Identifiable;
 import org.apache.reef.util.logging.LoggingScopeFactory;
 
@@ -55,14 +56,36 @@
     this.activeContextBridgeFactory = activeContextBridgeFactory;
   }
 
+  /**
+   * @return the Evaluator number.
+   */
   public int getNewlyRequestedEvaluatorNumber() {
     return evaluatorRequestorBridge.getEvaluatorNumber();
   }
 
+  /**
+   * @return the Evaluator requestor.
+   */
   public EvaluatorRequestorBridge getEvaluatorRequestorBridge() {
     return evaluatorRequestorBridge;
   }
 
+  /**
+   * @return the non-serializable error in bytes, may translate into a serialized C# Exception.
+   */
+  public byte[] getErrorBytes() {
+    if (jfailedEvaluator.getEvaluatorException() != null &&
+        jfailedEvaluator.getEvaluatorException().getCause() instanceof NonSerializableException) {
+      return ((NonSerializableException)jfailedEvaluator.getEvaluatorException().getCause()).getError();
+    }
+
+    // If not an instance of NonSerializableException, that means that the Exception is from Java.
+    return null;
+  }
+
+  /**
+   * @return the localized message of the Evaluator Exception.
+   */
   public String getCause() {
     if (jfailedEvaluator.getEvaluatorException() != null) {
       return jfailedEvaluator.getEvaluatorException().getLocalizedMessage();
@@ -71,6 +94,9 @@
     return null;
   }
 
+  /**
+   * @return the stack trace of the Evaluator Exception.
+   */
   public String getStackTrace() {
     if (jfailedEvaluator.getEvaluatorException() != null) {
       return ExceptionUtils.getStackTrace(jfailedEvaluator.getEvaluatorException());
@@ -79,6 +105,9 @@
     return null;
   }
 
+  /**
+   * @return the list of failed Contexts associated with the Evaluator.
+   */
   public FailedContextBridge[] getFailedContexts() {
     if (jfailedEvaluator.getFailedContextList() == null) {
       return new FailedContextBridge[0];
@@ -95,6 +124,9 @@
     return failedContextBridges;
   }
 
+  /**
+   * @return the failed task running on the Evaluator, if any.
+   */
   public FailedTaskBridge getFailedTask() {
     if (!jfailedEvaluator.getFailedTask().isPresent()) {
       return null;
diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/exception/NonSerializableException.java b/lang/java/reef-common/src/main/java/org/apache/reef/exception/NonSerializableException.java
new file mode 100644
index 0000000..3286c98
--- /dev/null
+++ b/lang/java/reef-common/src/main/java/org/apache/reef/exception/NonSerializableException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.reef.exception;
+
+import org.apache.reef.annotations.audience.DriverSide;
+
+/**
+ * An {@link Exception} that indicates that an Exception from the Evaluator
+ * was not able to be serialized.
+ */
+@DriverSide
+public final class NonSerializableException extends Exception {
+  private final byte[] error;
+
+  public NonSerializableException(final String message, final byte[] error) {
+    super(message);
+    this.error = error;
+  }
+
+  /**
+   * @return the Exception representation in a byte array.
+   */
+  public byte[] getError() {
+    return error;
+  }
+}
diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/EvaluatorManager.java b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/EvaluatorManager.java
index e364ff1..f483868 100644
--- a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/EvaluatorManager.java
+++ b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/EvaluatorManager.java
@@ -24,6 +24,7 @@
 import org.apache.reef.driver.parameters.EvaluatorConfigurationProviders;
 import org.apache.reef.driver.restart.DriverRestartManager;
 import org.apache.reef.driver.restart.EvaluatorRestartState;
+import org.apache.reef.exception.NonSerializableException;
 import org.apache.reef.runtime.common.driver.evaluator.pojos.ContextStatusPOJO;
 import org.apache.reef.runtime.common.driver.evaluator.pojos.EvaluatorStatusPOJO;
 import org.apache.reef.runtime.common.driver.evaluator.pojos.State;
@@ -468,7 +469,7 @@
         evaluatorException = new EvaluatorException(getId(), exception.get());
       } else {
         evaluatorException = new EvaluatorException(getId(),
-            new Exception("Exception sent, but can't be deserialized"));
+            new NonSerializableException("Exception sent, but can't be deserialized", evaluatorStatus.getError()));
       }
     } else {
       evaluatorException = new EvaluatorException(getId(), new Exception("No exception sent"));