/// <summary>
        /// Deserialize a user type instance from a POF stream by reading its
        /// state using the specified <see cref="IPofReader"/> object.
        /// </summary>
        /// <remarks>
        /// An implementation of <b>IPofSerializer</b> is required to follow
        /// the following steps in sequence for reading in an object of a
        /// user type:
        /// <list type="number">
        /// <item>
        /// <description>
        /// If the object is evolvable, the implementation must get the
        /// version by calling <see cref="IPofWriter.VersionId"/>.
        /// </description>
        /// </item>
        /// <item>
        /// <description>
        /// The implementation may read any combination of the
        /// properties of the user type by using "read" methods of the
        /// <b>IPofReader</b>, but it must do so in the order of the property
        /// indexes.
        /// </description>
        /// </item>
        /// <item>
        /// <description>
        /// After all desired properties of the user type have been read,
        /// the implementation must terminate the reading of the user type by
        /// calling <see cref="IPofReader.ReadRemainder"/>.
        /// </description>
        /// </item>
        /// </list>
        /// </remarks>
        /// <param name="reader">
        /// The <b>IPofReader</b> with which to read the object's state.
        /// </param>
        /// <returns>
        /// The deserialized user type instance.
        /// </returns>
        /// <exception cref="IOException">
        /// If an I/O error occurs.
        /// </exception>
        public object Deserialize(IPofReader reader)
        {
            PortableException e = new PortableException();

            reader.RegisterIdentity(e);
            e.ReadExternal(reader);
            reader.ReadRemainder();
            return(e);
        }
        public void PortableExceptionConstructorTest()
        {
            IConnection conn = initiator.EnsureConnection();
            Channel     cacheServiceChannel = (Channel)conn.OpenChannel(CacheServiceProtocol.Instance,
                                                                        "CacheServiceProxy", null, null);

            EnsureCacheRequest ensureCacheRequest =
                (EnsureCacheRequest)cacheServiceChannel.MessageFactory.CreateMessage(EnsureCacheRequest.TYPE_ID);

            ensureCacheRequest.CacheName = "nonexisting";
            Assert.AreEqual(EnsureCacheRequest.TYPE_ID, ensureCacheRequest.TypeId);

            IStatus ensureCacheStatus = cacheServiceChannel.Send(ensureCacheRequest);

            Assert.IsInstanceOf(typeof(EnsureCacheRequest), ensureCacheRequest);
            Assert.AreEqual(EnsureCacheRequest.TYPE_ID, ensureCacheRequest.TypeId);
            try
            {
                ensureCacheStatus.WaitForResponse(-1);
            }
            catch (PortableException pe)
            {
                Assert.IsNotNull(pe);
                Assert.IsTrue(pe.Name.StartsWith("Portable("));
                Assert.IsNull(pe.InnerException);
                Assert.IsTrue(pe.Message.ToLower().IndexOf("no scheme") >= 0);

                string[] fullStackTrace = pe.FullStackTrace;
                string   stackTrace     = pe.StackTrace;
                Assert.IsTrue(fullStackTrace.Length > 0);
                foreach (string s in fullStackTrace)
                {
                    Assert.IsTrue(stackTrace.IndexOf(s) > 0);
                }
                Assert.IsTrue(stackTrace.IndexOf("process boundary") > 0);
                Assert.IsTrue(
                    pe.ToString().Equals(pe.Name + ": " + pe.Message));

                using (Stream stream = new MemoryStream())
                {
                    DataWriter  writer = new DataWriter(stream);
                    IPofContext ctx    = (IPofContext)cacheServiceChannel.Serializer;
                    ctx.Serialize(writer, pe);
                    stream.Position = 0;
                    DataReader        reader = new DataReader(stream);
                    PortableException result = (PortableException)ctx.Deserialize(reader);

                    Assert.AreEqual(pe.Name, result.Name);
                    Assert.AreEqual(pe.Message, result.Message);
                }
            }
        }
        public void PortableExceptionSerializationTest()
        {
            IConnection conn = initiator.EnsureConnection();
            Channel     cacheServiceChannel = (Channel)conn.OpenChannel(CacheServiceProtocol.Instance,
                                                                        "CacheServiceProxy", null, null);

            EnsureCacheRequest ensureCacheRequest =
                (EnsureCacheRequest)cacheServiceChannel.MessageFactory.CreateMessage(EnsureCacheRequest.TYPE_ID);

            ensureCacheRequest.CacheName = "nonexisting";

            IStatus ensureCacheStatus = cacheServiceChannel.Send(ensureCacheRequest);

            try
            {
                ensureCacheStatus.WaitForResponse(-1);
            }
            catch (PortableException pe)
            {
                IFormatter formatter = new BinaryFormatter();
                byte[]     buffer    = new byte[1024 * 16];
                Stream     stream    = new MemoryStream(buffer);
                formatter.Serialize(stream, pe);
                stream.Close();

                stream = new MemoryStream(buffer);
                PortableException desPE = (PortableException)formatter.Deserialize(stream);
                Assert.IsNotNull(desPE);
                stream.Close();

                // these values should be initialized before serialization
                Assert.AreEqual(pe.Name, desPE.Name);
                Assert.AreEqual(pe.Message, desPE.Message);
                Assert.AreEqual(pe.InnerException, desPE.InnerException);
                Assert.IsNull(pe.InnerException);
                Assert.AreEqual(pe.FullStackTrace, desPE.FullStackTrace);
            }
        }
        /// <summary>
        /// Write the exception to the specified stream.
        /// </summary>
        /// <param name="writer">
        /// The <b>IPofWriter</b> to write to.
        /// </param>
        /// <param name="e">
        /// The <b>Exception</b> to write.
        /// </param>
        public static void WriteException(IPofWriter writer, Exception e)
        {
            string name;

            string[] arrTrace;

            if (e is PortableException)
            {
                PortableException pe = (PortableException)e;
                name     = pe.Name;
                arrTrace = pe.FullStackTrace;
            }
            else
            {
                name     = e.GetType().FullName;
                arrTrace = new string[] { e.StackTrace };
            }

            writer.WriteString(0, name);
            writer.WriteString(1, e.Message);
            writer.WriteCollection(2, new ArrayList(arrTrace), typeof(string));
            writer.WriteObject(3, e.InnerException);
        }