Inheritance: ISerializable
		internal IMessage FormatFault (SoapFault fault, IMethodCallMessage mcm)
		{
			ServerFault sf = fault.Detail as ServerFault;
			Exception e = null;
			
			if (sf != null) {
				if(_serverFaultExceptionField != null)
					e = (Exception) _serverFaultExceptionField.GetValue(sf);
			}
			if (e == null)
				e = new RemotingException (fault.FaultString);

			return new ReturnMessage((System.Exception)e, mcm);
		}
		internal IMessage FormatFault (SoapFault fault, IMethodCallMessage mcm)
		{
			ServerFault sf = fault.Detail as ServerFault;
			Exception e = null;
			
			if (sf != null) {
				if(_serverFaultExceptionField != null)
					e = (Exception) _serverFaultExceptionField.GetValue(sf);
#if TARGET_JVM				
				if (e == null && sf.ExceptionType != null)
				{
					try
					{
						Type te = Type.GetType(sf.ExceptionType);
						if (te != null)
						{
							ConstructorInfo ce = te.GetConstructor(
								BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance,
								null, new Type[] {typeof(string)}, null);

							if (ce != null)
							{
								e = (Exception) ce.Invoke(new object[] {sf.ExceptionMessage});
							}
							else
							{
								e = (Exception) Activator.CreateInstance(te);
							}
						}
					}
					catch
					{
						e = null;
					}
				}
#endif
			}
			if (e == null)
				e = new RemotingException (fault.FaultString);

			return new ReturnMessage((System.Exception)e, mcm);
		}
        [System.Security.SecurityCritical]  // auto-generated_required
        public virtual void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
        {
            if (info==null) 
            {
               throw new ArgumentNullException("info");
            }
            Contract.EndContractBlock();
                        
            if ( (obj!=null) && (obj !=_rootObj))
            {
                (new MessageSurrogate(_ss)).GetObjectData(obj, info, context);
            }
            else 
            {
                IMethodReturnMessage msg = obj as IMethodReturnMessage;
                if(null != msg)
                {

                    if (msg.Exception == null)
                    {
                        String responseElementName;
                        String responseElementNS;
                        String returnElementName;                    

                        // obtain response element name namespace
                        MethodBase mb = msg.MethodBase;
                        SoapMethodAttribute attr = (SoapMethodAttribute)InternalRemotingServices.GetCachedSoapAttribute(mb);
                        responseElementName = attr.ResponseXmlElementName;
                        responseElementNS = attr.ResponseXmlNamespace;
                        returnElementName = attr.ReturnXmlElementName;

                        ArgMapper mapper = new ArgMapper(msg, true /*fOut*/);
                        Object[] args = mapper.Args;
                        info.FullTypeName = responseElementName;
                        info.AssemblyName = responseElementNS;
                        Type retType = ((MethodInfo)mb).ReturnType;                                         
                        if (!((retType == null) || (retType == _voidType)))
                        {
                            info.AddValue(returnElementName, msg.ReturnValue, retType);
                        }
                        if (args != null)
                        {
                            Type[] types = mapper.ArgTypes;
                            for (int i=0; i<args.Length; i++)
                            {
                                String name;
                                name = mapper.GetArgName(i);
                                if ((name == null) || (name.Length == 0))
                                {
                                    name = "__param" + i;
                                }
                                info.AddValue(
                                        name, 
                                        args[i], 
                                        types[i].IsByRef?
                                            types[i].GetElementType():types[i]);
                            }
                        }
                    }
                    else
                    {
                        Object oClientIsClr = CallContext.GetData("__ClientIsClr");
                        bool bClientIsClr = (oClientIsClr == null) ? true:(bool)oClientIsClr;
                        info.FullTypeName = "FormatterWrapper";
                        info.AssemblyName = DefaultFakeRecordAssemblyName;

                        Exception ex = msg.Exception;
                        StringBuilder sb = new StringBuilder();
                        bool bMustUnderstandError = false;
                        while(ex != null)
                        {
                            if (ex.Message.StartsWith("MustUnderstand", StringComparison.Ordinal))
                                bMustUnderstandError = true;

                            sb.Append(" **** ");
                            sb.Append(ex.GetType().FullName); 
                            sb.Append(" - ");
                            sb.Append(ex.Message);
                            
                            ex = ex.InnerException;
                        }

                        ServerFault serverFault = null;
                        if (bClientIsClr)
                            serverFault = new ServerFault(msg.Exception); // Clr is the Client use full exception
                        else
                            serverFault = new ServerFault(msg.Exception.GetType().AssemblyQualifiedName, sb.ToString(), msg.Exception.StackTrace); 

                        String faultType = "Server";
                        if (bMustUnderstandError)
                            faultType = "MustUnderstand";

                        SoapFault soapFault = new SoapFault(faultType, sb.ToString(), null, serverFault);
                        info.AddValue("__WrappedObject", soapFault, _soapFaultType);                   
                    }
                }
                else
                {

                    IMethodCallMessage mcm = (IMethodCallMessage)obj;

                    // obtain method namespace        
                    MethodBase mb = mcm.MethodBase;                
                    String methodElementNS = SoapServices.GetXmlNamespaceForMethodCall(mb);       

                    Object[] args = mcm.InArgs;
                    String[] names = GetInArgNames(mcm, args.Length);
                    Type[] sig = (Type[])mcm.MethodSignature;
                    info.FullTypeName = mcm.MethodName;
                    info.AssemblyName = methodElementNS;
                    RemotingMethodCachedData cache = (RemotingMethodCachedData)InternalRemotingServices.GetReflectionCachedData(mb);
                    int[] requestArgMap = cache.MarshalRequestArgMap;


                    Contract.Assert(
                        args!=null || sig.Length == args.Length, 
                        "Signature mismatch");

                    for (int i = 0; i < args.Length; i++)
                    {
                        String paramName = null;
                        if ((names[i] == null) || (names[i].Length == 0))
                            paramName = "__param" + i;
                        else
                            paramName = names[i];

                        int sigPosition = requestArgMap[i];
                        Type argType = null;

                        if (sig[sigPosition].IsByRef)
                            argType = sig[sigPosition].GetElementType();
                        else
                            argType = sig[sigPosition];

                        info.AddValue(paramName, args[i], argType);
                    }
                }
            }
        } // GetObjectData
 public virtual void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
 {
     if (info == null)
     {
         throw new ArgumentNullException("info");
     }
     if ((obj != null) && (obj != this._rootObj))
     {
         new MessageSurrogate(this._ss).GetObjectData(obj, info, context);
     }
     else
     {
         IMethodReturnMessage mm = obj as IMethodReturnMessage;
         if (mm != null)
         {
             if (mm.Exception != null)
             {
                 object data = CallContext.GetData("__ClientIsClr");
                 bool flag = (data == null) || ((bool) data);
                 info.FullTypeName = "FormatterWrapper";
                 info.AssemblyName = this.DefaultFakeRecordAssemblyName;
                 Exception innerException = mm.Exception;
                 StringBuilder builder = new StringBuilder();
                 bool flag2 = false;
                 while (innerException != null)
                 {
                     if (innerException.Message.StartsWith("MustUnderstand", StringComparison.Ordinal))
                     {
                         flag2 = true;
                     }
                     builder.Append(" **** ");
                     builder.Append(innerException.GetType().FullName);
                     builder.Append(" - ");
                     builder.Append(innerException.Message);
                     innerException = innerException.InnerException;
                 }
                 ServerFault serverFault = null;
                 if (flag)
                 {
                     serverFault = new ServerFault(mm.Exception);
                 }
                 else
                 {
                     serverFault = new ServerFault(mm.Exception.GetType().AssemblyQualifiedName, builder.ToString(), mm.Exception.StackTrace);
                 }
                 string faultCode = "Server";
                 if (flag2)
                 {
                     faultCode = "MustUnderstand";
                 }
                 SoapFault fault2 = new SoapFault(faultCode, builder.ToString(), null, serverFault);
                 info.AddValue("__WrappedObject", fault2, _soapFaultType);
             }
             else
             {
                 MethodBase methodBase = mm.MethodBase;
                 SoapMethodAttribute cachedSoapAttribute = (SoapMethodAttribute) InternalRemotingServices.GetCachedSoapAttribute(methodBase);
                 string responseXmlElementName = cachedSoapAttribute.ResponseXmlElementName;
                 string responseXmlNamespace = cachedSoapAttribute.ResponseXmlNamespace;
                 string returnXmlElementName = cachedSoapAttribute.ReturnXmlElementName;
                 ArgMapper mapper = new ArgMapper(mm, true);
                 object[] args = mapper.Args;
                 info.FullTypeName = responseXmlElementName;
                 info.AssemblyName = responseXmlNamespace;
                 Type returnType = ((MethodInfo) methodBase).ReturnType;
                 if ((returnType != null) && !(returnType == _voidType))
                 {
                     info.AddValue(returnXmlElementName, mm.ReturnValue, returnType);
                 }
                 if (args != null)
                 {
                     Type[] argTypes = mapper.ArgTypes;
                     for (int i = 0; i < args.Length; i++)
                     {
                         string argName = mapper.GetArgName(i);
                         if ((argName == null) || (argName.Length == 0))
                         {
                             argName = "__param" + i;
                         }
                         info.AddValue(argName, args[i], argTypes[i].IsByRef ? argTypes[i].GetElementType() : argTypes[i]);
                     }
                 }
             }
         }
         else
         {
             IMethodCallMessage m = (IMethodCallMessage) obj;
             MethodBase mb = m.MethodBase;
             string xmlNamespaceForMethodCall = SoapServices.GetXmlNamespaceForMethodCall(mb);
             object[] inArgs = m.InArgs;
             string[] inArgNames = this.GetInArgNames(m, inArgs.Length);
             Type[] methodSignature = (Type[]) m.MethodSignature;
             info.FullTypeName = m.MethodName;
             info.AssemblyName = xmlNamespaceForMethodCall;
             int[] marshalRequestArgMap = InternalRemotingServices.GetReflectionCachedData(mb).MarshalRequestArgMap;
             for (int j = 0; j < inArgs.Length; j++)
             {
                 string name = null;
                 if ((inArgNames[j] == null) || (inArgNames[j].Length == 0))
                 {
                     name = "__param" + j;
                 }
                 else
                 {
                     name = inArgNames[j];
                 }
                 int index = marshalRequestArgMap[j];
                 Type type = null;
                 if (methodSignature[index].IsByRef)
                 {
                     type = methodSignature[index].GetElementType();
                 }
                 else
                 {
                     type = methodSignature[index];
                 }
                 info.AddValue(name, inArgs[j], type);
             }
         }
     }
 }