Merge pull request #3389 from lambdageek/bug-43099
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Dispatcher / XmlSerializerOperationFormatter.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Dispatcher
5 {
6     using System.Collections;
7     using System.ServiceModel.Channels;
8     using System.ServiceModel;
9     using System.ServiceModel.Description;
10     using System.Collections.Generic;
11     using System.Collections.ObjectModel;
12     using System.Diagnostics;
13     using System.Runtime.Serialization;
14     using System.Reflection;
15     using System.Xml;
16     using System.Xml.Serialization;
17     using System.ServiceModel.Diagnostics;
18     using System.IO;
19     using System.Xml.Schema;
20
21     class XmlSerializerOperationFormatter : OperationFormatter
22     {
23         const string soap11Encoding = "http://schemas.xmlsoap.org/soap/encoding/";
24         const string soap12Encoding = "http://www.w3.org/2003/05/soap-encoding";
25
26         bool isEncoded;
27
28         MessageInfo requestMessageInfo;
29         MessageInfo replyMessageInfo;
30
31         public XmlSerializerOperationFormatter(OperationDescription description, XmlSerializerFormatAttribute xmlSerializerFormatAttribute,
32             MessageInfo requestMessageInfo, MessageInfo replyMessageInfo) :
33             base(description, xmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc, xmlSerializerFormatAttribute.IsEncoded)
34         {
35             if (xmlSerializerFormatAttribute.IsEncoded && xmlSerializerFormatAttribute.Style != OperationFormatStyle.Rpc)
36                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDocEncodedNotSupported, description.Name)));
37             this.isEncoded = xmlSerializerFormatAttribute.IsEncoded;
38
39             this.requestMessageInfo = requestMessageInfo;
40             this.replyMessageInfo = replyMessageInfo;
41         }
42
43         protected override void AddHeadersToMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
44         {
45             XmlSerializer serializer;
46             MessageHeaderDescriptionTable headerDescriptionTable;
47             MessageHeaderDescription unknownHeaderDescription;
48             bool mustUnderstand;
49             bool relay;
50             string actor;
51             try
52             {
53                 if (isRequest)
54                 {
55                     serializer = requestMessageInfo.HeaderSerializer;
56                     headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
57                     unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
58                 }
59                 else
60                 {
61                     serializer = replyMessageInfo.HeaderSerializer;
62                     headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
63                     unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
64                 }
65                 if (serializer != null)
66                 {
67                     object[] headerValues = new object[headerDescriptionTable.Count];
68                     MessageHeaderOfTHelper messageHeaderOfTHelper = null;
69                     int headerIndex = 0;
70
71                     foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
72                     {
73                         object parameterValue = parameters[headerDescription.Index];
74                         if (!headerDescription.IsUnknownHeaderCollection)
75                         {
76                             if (headerDescription.TypedHeader)
77                             {
78                                 if (messageHeaderOfTHelper == null)
79                                     messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
80                                 headerValues[headerIndex++] = messageHeaderOfTHelper.GetContentAndSaveHeaderAttributes(parameters[headerDescription.Index], headerDescription);
81                             }
82                             else
83                                 headerValues[headerIndex++] = parameterValue;
84                         }
85                     }
86
87                     MemoryStream memoryStream = new MemoryStream();
88                     XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
89                     bufferWriter.WriteStartElement("root");
90                     serializer.Serialize(bufferWriter, headerValues, null, isEncoded ? GetEncoding(message.Version.Envelope) : null);
91                     bufferWriter.WriteEndElement();
92                     bufferWriter.Flush();
93                     XmlDocument doc = new XmlDocument();
94                     memoryStream.Position = 0;
95                     doc.Load(new XmlTextReader(memoryStream) { DtdProcessing = DtdProcessing.Prohibit });
96                     //doc.Save(Console.Out);
97                     foreach (XmlElement element in doc.DocumentElement.ChildNodes)
98                     {
99                         MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(element.LocalName, element.NamespaceURI);
100                         if (matchingHeaderDescription == null)
101                             message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
102                                                                             false/*mustUnderstand*/, null/*actor*/, false/*relay*/, element));
103                         else
104                         {
105                             if (matchingHeaderDescription.TypedHeader)
106                                 messageHeaderOfTHelper.GetHeaderAttributes(matchingHeaderDescription, out mustUnderstand, out relay, out actor);
107                             else
108                             {
109                                 mustUnderstand = matchingHeaderDescription.MustUnderstand;
110                                 relay = matchingHeaderDescription.Relay;
111                                 actor = matchingHeaderDescription.Actor;
112                             }
113                             message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
114                                                                             mustUnderstand, actor, relay, element));
115                         }
116                     }
117                 }
118                 if (unknownHeaderDescription != null && parameters[unknownHeaderDescription.Index] != null)
119                 {
120                     foreach (object unknownHeader in (IEnumerable)parameters[unknownHeaderDescription.Index])
121                     {
122
123                         XmlElement element = (XmlElement)GetContentOfMessageHeaderOfT(unknownHeaderDescription, unknownHeader, out mustUnderstand, out relay, out actor);
124                         if (element != null)
125                             message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
126                                                                   mustUnderstand, actor, relay, element));
127                     }
128                 }
129             }
130             catch (InvalidOperationException e)
131             {
132                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
133                     SR.GetString(SR.SFxErrorSerializingHeader, messageDescription.MessageName, e.Message), e));
134             }
135         }
136
137         protected override void GetHeadersFromMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
138         {
139             try
140             {
141                 XmlSerializer serializer;
142                 MessageHeaderDescriptionTable headerDescriptionTable;
143                 MessageHeaderDescription unknownHeaderDescription;
144                 if (isRequest)
145                 {
146                     serializer = requestMessageInfo.HeaderSerializer;
147                     headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
148                     unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
149                 }
150                 else
151                 {
152                     serializer = replyMessageInfo.HeaderSerializer;
153                     headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
154                     unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
155                 }
156                 MessageHeaders headers = message.Headers;
157                 ArrayList unknownHeaders = null;
158                 XmlDocument xmlDoc = null;
159                 if (unknownHeaderDescription != null)
160                 {
161                     unknownHeaders = new ArrayList();
162                     xmlDoc = new XmlDocument();
163                 }
164                 if (serializer == null)
165                 {
166                     if (unknownHeaderDescription != null)
167                     {
168                         for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
169                             AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, null/*bufferWriter*/, headers[headerIndex], headers.GetReaderAtHeader(headerIndex));
170                         parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
171                     }
172                     return;
173                 }
174
175
176                 MemoryStream memoryStream = new MemoryStream();
177                 XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
178                 message.WriteStartEnvelope(bufferWriter);
179                 message.WriteStartHeaders(bufferWriter);
180                 MessageHeaderOfTHelper messageHeaderOfTHelper = null;
181                 for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
182                 {
183                     MessageHeaderInfo header = headers[headerIndex];
184                     XmlDictionaryReader headerReader = headers.GetReaderAtHeader(headerIndex);
185                     MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(header.Name, header.Namespace);
186                     if (matchingHeaderDescription != null)
187                     {
188                         if (header.MustUnderstand)
189                             headers.UnderstoodHeaders.Add(header);
190                         if (matchingHeaderDescription.TypedHeader)
191                         {
192                             if (messageHeaderOfTHelper == null)
193                                 messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
194                             messageHeaderOfTHelper.SetHeaderAttributes(matchingHeaderDescription, header.MustUnderstand, header.Relay, header.Actor);
195                         }
196
197                     }
198                     if (matchingHeaderDescription == null && unknownHeaderDescription != null)
199                         AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, bufferWriter, header, headerReader);
200                     else
201                         bufferWriter.WriteNode(headerReader, false);
202                     headerReader.Close();
203                 }
204                 bufferWriter.WriteEndElement();
205                 bufferWriter.WriteEndElement();
206                 bufferWriter.Flush();
207
208                 /*
209                 XmlDocument doc = new XmlDocument();
210                 memoryStream.Position = 0;
211                 doc.Load(memoryStream);
212                 doc.Save(Console.Out);
213                 */
214
215                 memoryStream.Position = 0;
216                 XmlDictionaryReader bufferReader = XmlDictionaryReader.CreateTextReader(memoryStream.GetBuffer(), 0, (int)memoryStream.Length, XmlDictionaryReaderQuotas.Max);
217
218                 bufferReader.ReadStartElement();
219                 bufferReader.MoveToContent();
220                 if (!bufferReader.IsEmptyElement)
221                 {
222                     bufferReader.ReadStartElement();
223                     object[] headerValues = (object[])serializer.Deserialize(bufferReader, isEncoded ? GetEncoding(message.Version.Envelope) : null);
224                     int headerIndex = 0;
225                     foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
226                     {
227                         if (!headerDescription.IsUnknownHeaderCollection)
228                         {
229                             object parameterValue = headerValues[headerIndex++];
230                             if (headerDescription.TypedHeader && parameterValue != null)
231                                 parameterValue = messageHeaderOfTHelper.CreateMessageHeader(headerDescription, parameterValue);
232                             parameters[headerDescription.Index] = parameterValue;
233                         }
234                     }
235                     bufferReader.Close();
236                 }
237                 if (unknownHeaderDescription != null)
238                     parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
239             }
240             catch (InvalidOperationException e)
241             {
242                 // all exceptions from XmlSerializer get wrapped in InvalidOperationException,
243                 // so we must be conservative and never turn this into a fault
244                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
245                     SR.GetString(SR.SFxErrorDeserializingHeader, messageDescription.MessageName), e));
246             }
247         }
248
249         private static void AddUnknownHeader(MessageHeaderDescription unknownHeaderDescription, ArrayList unknownHeaders, XmlDocument xmlDoc, XmlDictionaryWriter bufferWriter, MessageHeaderInfo header, XmlDictionaryReader headerReader)
250         {
251             object unknownHeader = xmlDoc.ReadNode(headerReader);
252             if (bufferWriter != null)
253                 ((XmlElement)unknownHeader).WriteTo(bufferWriter);
254             if (unknownHeader != null && unknownHeaderDescription.TypedHeader)
255                 unknownHeader = TypedHeaderManager.Create(unknownHeaderDescription.Type, unknownHeader, header.MustUnderstand, header.Relay, header.Actor);
256
257             unknownHeaders.Add(unknownHeader);
258         }
259
260         protected override void WriteBodyAttributes(XmlDictionaryWriter writer, MessageVersion version)
261         {
262             if (isEncoded && version.Envelope == EnvelopeVersion.Soap11)
263             {
264                 string encoding = GetEncoding(version.Envelope);
265                 writer.WriteAttributeString("encodingStyle", version.Envelope.Namespace, encoding);
266             }
267             writer.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace);
268             writer.WriteAttributeString("xmlns", "xsd", null, XmlSchema.Namespace);
269         }
270
271         protected override void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, string action, MessageDescription messageDescription, object returnValue, object[] parameters, bool isRequest)
272         {
273             if (writer == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
274             if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
275             try
276             {
277                 MessageInfo messageInfo;
278                 if (isRequest)
279                     messageInfo = requestMessageInfo;
280                 else
281                     messageInfo = replyMessageInfo;
282                 if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
283                 {
284                     SerializeBody(writer, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, returnValue, parameters);
285                     return;
286                 }
287
288                 object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
289                 object bodyObject = parameters[messageDescription.Body.Parts[0].Index];
290                 if (bodyObject == null)
291                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxBodyCannotBeNull, messageDescription.MessageName)));
292                 int i = 0;
293                 foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
294                 {
295                     MemberInfo member = bodyPart.MemberInfo;
296                     FieldInfo field = member as FieldInfo;
297                     if (field != null)
298                         bodyPartValues[i++] = field.GetValue(bodyObject);
299                     else
300                     {
301                         PropertyInfo property = member as PropertyInfo;
302                         if (property != null)
303                             bodyPartValues[i++] = property.GetValue(bodyObject, null);
304                     }
305                 }
306                 SerializeBody(writer, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, null/*returnValue*/, bodyPartValues);
307             }
308             catch (InvalidOperationException e)
309             {
310                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
311                     SR.GetString(SR.SFxErrorSerializingBody, messageDescription.MessageName, e.Message), e));
312             }
313         }
314
315         void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object returnValue, object[] parameters)
316         {
317             if (serializer == null)
318             {
319                 return;
320             }
321
322             bool hasReturnValue = IsValidReturnValue(returnPart);
323             object[] bodyParameters = new object[bodyParts.Count + (hasReturnValue ? 1 : 0)];
324             int paramIndex = 0;
325
326             if (hasReturnValue)
327                 bodyParameters[paramIndex++] = returnValue;
328
329             for (int i = 0; i < bodyParts.Count; i++)
330                 bodyParameters[paramIndex++] = parameters[bodyParts[i].Index];
331
332             string encoding = isEncoded ? GetEncoding(version.Envelope) : null;
333             serializer.Serialize(writer, bodyParameters, null, encoding);
334         }
335
336
337         protected override object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, string action, MessageDescription messageDescription, object[] parameters, bool isRequest)
338         {
339             MessageInfo messageInfo;
340             if (isRequest)
341                 messageInfo = requestMessageInfo;
342             else
343                 messageInfo = replyMessageInfo;
344             if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
345                 return DeserializeBody(reader, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, parameters, isRequest);
346
347             object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
348             DeserializeBody(reader, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, bodyPartValues, isRequest);
349             object bodyObject = Activator.CreateInstance(messageDescription.Body.Parts[0].Type);
350             int i = 0;
351             foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
352             {
353                 MemberInfo member = bodyPart.MemberInfo;
354                 FieldInfo field = member as FieldInfo;
355                 if (field != null)
356                     field.SetValue(bodyObject, bodyPartValues[i++]);
357                 else
358                 {
359                     PropertyInfo property = member as PropertyInfo;
360                     if (property != null)
361                         property.SetValue(bodyObject, bodyPartValues[i++], null);
362                 }
363             }
364             parameters[messageDescription.Body.Parts[0].Index] = bodyObject;
365             return null;
366         }
367
368         object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object[] parameters, bool isRequest)
369         {
370             try
371             {
372                 if (reader == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
373                 if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
374                 object returnValue = null;
375                 if (serializer == null)
376                 {
377                     return null;
378                 }
379                 if (reader.NodeType == XmlNodeType.EndElement)
380                     return null;
381
382                 object[] bodyParameters = (object[])serializer.Deserialize(reader, isEncoded ? GetEncoding(version.Envelope) : null);
383
384                 int paramIndex = 0;
385                 if (IsValidReturnValue(returnPart))
386                     returnValue = bodyParameters[paramIndex++];
387
388                 for (int i = 0; i < bodyParts.Count; i++)
389                     parameters[bodyParts[i].Index] = bodyParameters[paramIndex++];
390                 return returnValue;
391             }
392             catch (InvalidOperationException e)
393             {
394                 // all exceptions from XmlSerializer get wrapped in InvalidOperationException,
395                 // so we must be conservative and never turn this into a fault
396                 string resourceKey = isRequest ? SR.SFxErrorDeserializingRequestBody : SR.SFxErrorDeserializingReplyBody;
397
398                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
399                     SR.GetString(resourceKey, OperationName), e));
400             }
401         }
402
403         internal static string GetEncoding(EnvelopeVersion version)
404         {
405             if (version == EnvelopeVersion.Soap11)
406             {
407                 return soap11Encoding;
408             }
409             else if (version == EnvelopeVersion.Soap12)
410             {
411                 return soap12Encoding;
412             }
413             else
414             {
415                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("version",
416                     SR.GetString(SR.EnvelopeVersionNotSupported, version));
417             }
418         }
419
420         internal abstract class MessageInfo
421         {
422             internal abstract XmlSerializer BodySerializer { get; }
423             internal abstract XmlSerializer HeaderSerializer { get; }
424             internal abstract MessageHeaderDescriptionTable HeaderDescriptionTable { get; }
425             internal abstract MessageHeaderDescription UnknownHeaderDescription { get; }
426             internal abstract MessagePartDescriptionCollection RpcEncodedTypedMessageBodyParts { get; }
427         }
428
429         class MessageHeaderOfTHelper
430         {
431             object[] attributes;
432             internal MessageHeaderOfTHelper(int parameterCount)
433             {
434                 attributes = new object[parameterCount];
435             }
436             internal object GetContentAndSaveHeaderAttributes(object parameterValue, MessageHeaderDescription headerDescription)
437             {
438                 if (parameterValue == null)
439                     return null;
440                 bool mustUnderstand;
441                 bool relay;
442                 string actor;
443                 if (headerDescription.Multiple)
444                 {
445                     object[] messageHeaderOfTArray = (object[])parameterValue;
446                     MessageHeader<object>[] messageHeaderOfTAttributes = new MessageHeader<object>[messageHeaderOfTArray.Length];
447                     Array tArray = Array.CreateInstance(headerDescription.Type, messageHeaderOfTArray.Length);
448                     for (int i = 0; i < tArray.Length; i++)
449                     {
450                         tArray.SetValue(GetContentOfMessageHeaderOfT(headerDescription, messageHeaderOfTArray[i], out mustUnderstand, out relay, out actor), i);
451                         messageHeaderOfTAttributes[i] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
452                     }
453                     attributes[headerDescription.Index] = messageHeaderOfTAttributes;
454                     return tArray;
455                 }
456                 else
457                 {
458                     object content = GetContentOfMessageHeaderOfT(headerDescription, parameterValue, out mustUnderstand, out relay, out actor);
459                     attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
460                     return content;
461                 }
462
463             }
464
465             internal void GetHeaderAttributes(MessageHeaderDescription headerDescription, out bool mustUnderstand, out bool relay, out string actor)
466             {
467                 MessageHeader<object> matchingMessageHeaderOfTAttribute = null;
468                 if (headerDescription.Multiple)
469                 {
470                     MessageHeader<object>[] messageHeaderOfTAttributes = (MessageHeader<object>[])attributes[headerDescription.Index];
471                     for (int i = 0; i < messageHeaderOfTAttributes.Length; i++)
472                     {
473                         if (messageHeaderOfTAttributes[i] != null)
474                         {
475                             matchingMessageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
476                             messageHeaderOfTAttributes[i] = null;
477                             break;
478                         }
479                     }
480                     //assert(matchingMessageHeaderOfTAttribute != null);
481
482                 }
483                 else
484                     matchingMessageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
485                 mustUnderstand = matchingMessageHeaderOfTAttribute.MustUnderstand;
486                 relay = matchingMessageHeaderOfTAttribute.Relay;
487                 actor = matchingMessageHeaderOfTAttribute.Actor;
488             }
489
490             internal void SetHeaderAttributes(MessageHeaderDescription headerDescription, bool mustUnderstand, bool relay, string actor)
491             {
492                 if (headerDescription.Multiple)
493                 {
494                     if (attributes[headerDescription.Index] == null)
495                         attributes[headerDescription.Index] = new List<MessageHeader<object>>();
496                     ((List<MessageHeader<object>>)attributes[headerDescription.Index]).Add(new MessageHeader<object>(null, mustUnderstand, actor, relay));
497                 }
498                 else
499                     attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
500
501             }
502             internal object CreateMessageHeader(MessageHeaderDescription headerDescription, object headerValue)
503             {
504                 if (headerDescription.Multiple)
505                 {
506                     IList<MessageHeader<object>> messageHeaderOfTAttributes = (IList<MessageHeader<object>>)attributes[headerDescription.Index];
507                     object[] messageHeaderOfTArray = (object[])Array.CreateInstance(TypedHeaderManager.GetMessageHeaderType(headerDescription.Type), messageHeaderOfTAttributes.Count);
508                     Array headerValues = (Array)headerValue;
509                     for (int i = 0; i < messageHeaderOfTArray.Length; i++)
510                     {
511                         MessageHeader<object> messageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
512                         messageHeaderOfTArray[i] = TypedHeaderManager.Create(headerDescription.Type, headerValues.GetValue(i),
513                                                                       messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
514                     }
515                     return messageHeaderOfTArray;
516                 }
517                 else
518                 {
519                     MessageHeader<object> messageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
520                     return TypedHeaderManager.Create(headerDescription.Type, headerValue,
521                                                                   messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
522
523                 }
524             }
525         }
526     }
527 }