示例#1
0
        private static void GenerateSerializeMethod()
        {
            var serializeMethod          = _context.BaseBarfSerializer.ResolveMethod("Serialize", _context.Type, typeof(BarfSerializationArgs));
            var serializeMethodReference = _context.Import(serializeMethod);
            var method = CreateMethodOverride(serializeMethodReference, _context.Import(typeof(void)), false, false, false);

            method.Parameters.Add(new ParameterDefinition(_context.Import(_context.Type))
            {
                Name = "instance"
            });
            method.Parameters.Add(new ParameterDefinition(_context.Import(typeof(BarfSerializationArgs)))
            {
                Name = "args"
            });
            _context.BarfSerializer.Methods.Add(method);
            var methodHeader = new MethodHeader
            {
                Attributes     = CallingConventions.HasThis,
                DeclaringType  = _context.BaseBarfSerializer,
                ParameterTypes = new[] { _context.Type, typeof(BarfSerializationArgs) },
                ReturnType     = typeof(void)
            };

            using (var writer = new CecilCilWriter(methodHeader, method.Body))
            {
                // type is not available yet so we're using void since that type is not referenced anyway.
                _context.SerializerBuilder.GenerateSerializeMethod(writer);
            }
        }
示例#2
0
        private static void GenerateFillMethod()
        {
            var fillMethod = typeof(IBarfTester <>)
                             .ResolveGenericType(_context.Type)
                             .ResolveMethod("Fill");
            var fillMethodReference = _context.Module.Import(fillMethod);
            var method = CreateMethodOverride(fillMethodReference, _context.Import(typeof(void)), false, false, true);

            method.Parameters.Add(new ParameterDefinition(_context.Import(_context.Type.ResolveByRef()))
            {
                Name = "instance"
            });
            method.Parameters.Add(new ParameterDefinition(_context.Import(typeof(FillArgs)))
            {
                Name = "args"
            });
            _context.BarfTester.Methods.Add(method);
            var methodHeader = new MethodHeader
            {
                Attributes     = CallingConventions.HasThis,
                DeclaringType  = typeof(void),                // a place holder
                ParameterTypes = new[] { _context.Type.ResolveByRef(), typeof(FillArgs) },
                ReturnType     = typeof(void)
            };

            using (var writer = new CecilCilWriter(methodHeader, method.Body))
            {
                _context.TesterBuilder.GenerateFill(writer);
            }
        }
示例#3
0
        /// <summary>
        ///     <para>Initializes a new instance of the <see cref="MsilWriter"/> class.</para>
        /// </summary>
        /// <param name="method">The dynamic method to write to.</param>
        public MsilWriter(DynamicMethod method)
        {
            var parameters = method.GetParameters();

            _methodHeader = new MethodHeader
            {
                Attributes     = method.CallingConvention,
                DeclaringType  = method.DeclaringType,
                ParameterTypes = method.GetParameters()
                                 .Select <ParameterInfo, Type>(p => p.ParameterType)
                                 .ToArray <Type>(),
                ReturnType = method.ReturnType ?? typeof(void)
            };
            _parameters = new SimpleParameter[parameters.Length];
            int positionOffset = method.IsStatic ? 0 : 1;

            for (int i = 0; i < parameters.Length; ++i)
            {
                _parameters[i] = new SimpleParameter(
                    this,
                    parameters[i].Position + positionOffset,
                    parameters[i].ParameterType,
                    null);
            }
            _ilGenerator = method.GetILGenerator();
        }
        public async ValueTask HandleMethodHeader(MethodHeader header)
        {
            Debug.Assert(header.ClassId == 60);
            switch (header.MethodId)
            {
            case 60:    //deliver method
            {
                var deliver = await ReadBasicDeliver().ConfigureAwait(false);

                if (!_consumers.TryGetValue(deliver.ConsumerTag, out var consumer))
                {
                    throw new Exception($"{nameof(BasicHandler)}: cant signal to consume");
                }
                await consumer.Delivery(deliver).ConfigureAwait(false);

                break;
            }

            case 21:    // consume-ok
            {
                var result = await ReadBasicConsumeOk().ConfigureAwait(false);

                _consumerCreateSrc.SetResult(result);
                break;
            }

            default: throw new Exception($"{nameof(BasicHandler)}.HandleMethodAsync: cannot read frame (class-id,method-id):({header.ClassId},{header.MethodId})");
            }
        }
示例#5
0
        public async ValueTask HandleMethodAsync(MethodHeader method)
        {
            Debug.Assert(method.ClassId == 20);
            switch (method.MethodId)
            {
            case 11:
            {
                _isOpen = await ReadChannelOpenOk().ConfigureAwait(false);

                _openSrc.SetResult(_isOpen);

                break;
            }

            /*case 20 when method.MethodId == 40: //close
             *  {
             *      _isOpen = false;
             *      _openCloseSrc.SetResult(_isOpen);
             *      break;
             *
             *  }
             */
            case 41:
            {
                var result = await ReadChannelCloseOk().ConfigureAwait(false);

                _isOpen = false;
                _closeSrc.SetResult(_isOpen);
                break;
            }

            default:
                throw new Exception($"{nameof(RabbitMQDefaultChannel)}.HandleMethodAsync :cannot read frame (class-id,method-id):({method.ClassId},{method.MethodId})");
            }
        }
示例#6
0
        private MethodBody CallTokenOverload(MethodHeader header)
        {
            var args = header.Parameters.Select(p => p.Name).ToList();

            args.Add("CancellationToken.None");

            var body = CallEscapedMethod(header.MethodName, string.Join(", ", args));

            return(new MethodBody(true, false, new[] { body }));
        }
示例#7
0
 public MethodBody GetMethodBody(MethodHeader header)
 {
     if (methodConfig.HasTokenInterfaceOverload)
     {
         return(CallTokenOverload(header));
     }
     else
     {
         return(CallNormalBody());
     }
 }
示例#8
0
        public override void TerminateMethodBody(MethodBody body)
        {
            long pos = m_binaryWriter.BaseStream.Position;

            if (body.HasVariables || body.HasExceptionHandlers ||
                m_codeWriter.BaseStream.Length >= 64 || body.MaxStack > 8)
            {
                MethodHeader header = MethodHeader.FatFormat;
                if (body.InitLocals)
                {
                    header |= MethodHeader.InitLocals;
                }
                if (body.HasExceptionHandlers)
                {
                    header |= MethodHeader.MoreSects;
                }

                m_binaryWriter.Write((byte)header);
                m_binaryWriter.Write((byte)0x30);                   // (header size / 4) << 4
                m_binaryWriter.Write((short)body.MaxStack);
                m_binaryWriter.Write((int)m_codeWriter.BaseStream.Length);
                // the token should be zero if there are no variables
                int token = body.HasVariables ? ((int)TokenType.Signature | body.LocalVarToken) : 0;
                m_binaryWriter.Write(token);

                if (body.HasExceptionHandlers)
                {
                    WriteExceptionHandlerCollection(body.ExceptionHandlers);
                }
            }
            else
            {
                m_binaryWriter.Write((byte)((byte)MethodHeader.TinyFormat |
                                            m_codeWriter.BaseStream.Length << 2));
            }

            m_binaryWriter.Write(m_codeWriter);
            m_binaryWriter.QuadAlign();

            m_reflectWriter.MetadataWriter.AddData(
                (int)(m_binaryWriter.BaseStream.Position - pos));
        }
示例#9
0
        public async ValueTask HandleMethodAsync(MethodHeader method)
        {
            Debug.Assert(method.ClassId == 40);
            switch (method.MethodId)
            {
            case 11:     //declare-ok
            {
                _declareOkSrc.SetResult(await ReadExchangeDeclareOk().ConfigureAwait(false));
                break;
            }

            case 21:
            {
                _deleteOkSrc.SetResult(await ReadExchangeDeleteOk().ConfigureAwait(false));
                break;
            }

            default:
                throw new Exception($"{nameof(ExchangeHandler)}.HandleMethodAsync :cannot read frame (class-id,method-id):({method.ClassId},{method.MethodId})");
            }
        }
示例#10
0
        private static void GenerateCreateEmptyMethod()
        {
            var createEmptyMethod          = _context.BaseBarfSerializer.ResolveMethod("CreateEmpty", Type.EmptyTypes);
            var createEmtpyMethodReference = _context.Import(createEmptyMethod);
            var method = CreateMethodOverride(createEmtpyMethodReference, _context.Import(_context.Type), false, false, false);

            _context.BarfSerializer.Methods.Add(method);
            var methodHeader = new MethodHeader
            {
                Attributes     = CallingConventions.HasThis,
                DeclaringType  = _context.BaseBarfSerializer,
                ParameterTypes = Type.EmptyTypes,
                ReturnType     = _context.Type
            };

            using (var writer = new CecilCilWriter(methodHeader, method.Body))
            {
                // type is not available yet so we're using void since that type is not referenced anyway.
                _context.SerializerBuilder.GenerateCreateEmptyMethod(writer);
            }
        }
        public async ValueTask HandleMethodAsync(MethodHeader method)
        {
            Debug.Assert(method.ClassId == 50);
            switch (method.MethodId)
            {
            case 11:     //declare-ok
            {
                _declareOkSrc.SetResult(await ReadQueueDeclareOk().ConfigureAwait(false));
                break;
            }

            case 21:    //bind-ok
            {
                _commonSrc.SetResult(await ReadBindOkUnbindOk().ConfigureAwait(false));
                break;
            }

            case 51:    //unbind-ok
            {
                _commonSrc.SetResult(await ReadBindOkUnbindOk().ConfigureAwait(false));
                break;
            }

            case 31:    //purge-ok
            {
                _purgeOrDeleteSrc.SetResult(await ReadQueuePurgeOkDeleteOk().ConfigureAwait(false));
                break;
            }

            case 41:     //delete-ok
            {
                _purgeOrDeleteSrc.SetResult(await ReadQueuePurgeOkDeleteOk().ConfigureAwait(false));
                break;
            }

            default:
                throw new Exception($"{nameof(QueueHandler)}.HandleMethodAsync :cannot read frame (class-id,method-id):({method.ClassId},{method.MethodId})");
            }
        }
示例#12
0
        private async ValueTask HandleMethod(MethodHeader method)
        {
            Debug.Assert(method.ClassId == 10);
            switch (method.ClassId)
            {
            case 10 when method.MethodId == 10:
            {
                ServerInfo = await ReadStartAsync().ConfigureAwait(false);
                await SendStartOk(ClientInfo, _connectionInfo).ConfigureAwait(false);

                break;
            }

            case 10 when method.MethodId == 30:
            {
                MainInfo = await ProcessTuneMethodAsync().ConfigureAwait(false);
                await SendTuneOk(MainInfo).ConfigureAwait(false);
                await SendOpen(_connectionInfo.VHost).ConfigureAwait(false);

                break;
            }

            case 10 when method.MethodId == 41:
            {
                _isOpen = await ReadOpenOkAsync().ConfigureAwait(false);

                _openOkSrc.SetResult(_isOpen);
                break;
            }

            case 10 when method.MethodId == 50:     //close-ok
            {
                break;
            }

            default:
                throw new Exception($"{nameof(RabbitMQChannelZero)}:cannot read frame (class-id,method-id):({method.ClassId},{method.MethodId})");
            }
        }
        internal async ValueTask ProcessConnection(RabbitMQProtocolReader protocol, FrameHeader header, MethodHeader method, CancellationToken token = default)
        {
            if (header.Channel != 0)
            {
                ReaderThrowHelper.ThrowIfFrameTypeMissmatch();
            }
            switch (method.MethodId)
            {
            case 10:
            {
                var serverConf = await protocol.ReadStartAsync(token).ConfigureAwait(false);

                await _connectionHandler.OnStartAsync(serverConf).ConfigureAwait(false);

                break;
            }

            case 30:
            {
                var tuneConf = await protocol.ReadTuneMethodAsync(token).ConfigureAwait(false);

                await _connectionHandler.OnTuneAsync(tuneConf).ConfigureAwait(false);

                break;
            }

            case 41:
            {
                var result = await protocol.ReadConnectionOpenOkAsync(token).ConfigureAwait(false);

                await _connectionHandler.OnOpenOkAsync();

                break;
            }

            case 50:     //close
            {
                var closeInfo = await protocol.ReadCloseAsync(token).ConfigureAwait(false);

                await _connectionHandler.OnCloseAsync(closeInfo).ConfigureAwait(false);

                break;
            }

            case 51:     //close-ok
            {
                var result = await protocol.ReadCloseOkAsync(token).ConfigureAwait(false);

                await _connectionHandler.OnCloseOkAsync().ConfigureAwait(false);

                break;
            }

            default:
                throw new RabbitMQMethodException(nameof(ProcessConnection), method.ClassId, method.MethodId);
            }
        }
        internal async ValueTask ProcessChannel(RabbitMQProtocolReader protocol, FrameHeader header, MethodHeader method, CancellationToken token = default)
        {
            switch (method.MethodId)
            {
            case 11:     //open-ok
            {
                var openOk = await protocol.ReadChannelOpenOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnChannelOpenOkAsync(header.Channel).ConfigureAwait(false);

                break;
            }

            case 40:     //close
            {
                var closeInfo = await protocol.ReadCloseAsync(token).ConfigureAwait(false);;
                await _channelHandler.OnChannelCloseAsync(header.Channel, closeInfo).ConfigureAwait(false);

                break;
            }

            case 41:     //close-ok
            {
                var closeOk = await protocol.ReadCloseOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnChannelCloseOkAsync(header.Channel).ConfigureAwait(false);

                break;
            }

            default:
                throw new RabbitMQMethodException(nameof(ProcessChannel), method.ClassId, method.MethodId);
            }
        }
示例#15
0
        /// <summary>
        /// Decodes the instruction stream of the reader and populates the compiler.
        /// </summary>
        /// <param name="compiler">The compiler to populate.</param>
        /// <param name="header">The method header.</param>
        private void Decode(IMethodCompiler compiler, MethodHeader header)
        {
            // Start of the code stream
            long codeStart = codeReader.BaseStream.Position;

            // End of the code stream
            long codeEnd = codeReader.BaseStream.Position + header.CodeSize;

            // Prefix instruction
            bool prefix = false;

            // Setup context
            Context ctx = new Context(instructionSet);

            while (codeEnd != codeReader.BaseStream.Position)
            {
                // Determine the instruction offset
                int instOffset = (int)(codeReader.BaseStream.Position - codeStart);

                // Read the next opcode from the stream
                OpCode op = (OpCode)codeReader.ReadByte();
                if (OpCode.Extop == op)
                    op = (OpCode)(0x100 | codeReader.ReadByte());

                ICILInstruction instruction = CILInstruction.Get(op);

                if (instruction == null)
                    throw new Exception("CIL " + op + " is not yet supported");

                // Create and initialize the corresponding instruction
                ctx.AppendInstruction(instruction);
                ctx.Label = instOffset;
                instruction.Decode(ctx, this);
                ctx.HasPrefix = prefix;

                Debug.Assert(ctx.Instruction != null);

                // Do we need to patch branch targets?
                if (instruction is IBranchInstruction && instruction.FlowControl != FlowControl.Return)
                {
                    int pc = (int)(codeReader.BaseStream.Position - codeStart);

                    for (int i = 0; i < ctx.BranchTargets.Length; i++)
                        ctx.BranchTargets[i] += pc;
                }

                prefix = (instruction is PrefixInstruction);
            }
        }
示例#16
0
 private static string MethodHeaderToString(MethodHeader header)
 {
   return "MethodHeader ("+ header.method.FullName + "); params = " + 
     DataStructUtil.IEnum2String(header.parameters, TypedVarPrinter);
 }
示例#17
0
 private static string MethodHeaderToString(MethodHeader header)
 {
     return("MethodHeader (" + header.method.FullName + "); params = " +
            DataStructUtil.IEnum2String(header.parameters, TypedVarPrinter));
 }
        //internal ValueTask ProcessMethod(RabbitMQProtocolReader protocol, ref Frame frame)
        internal ValueTask ProcessMethod(RabbitMQProtocolReader protocol, ref FrameHeader header, ref MethodHeader method, CancellationToken token = default)
        {
            switch (method.ClassId)
            {
            case 10:
            {
                return(ProcessConnection(protocol, header, method, token));
            }

            case 20:
            {
                return(ProcessChannel(protocol, header, method, token));
            }

            case 40:
            {
                return(ProcessExchange(protocol, header, method, token));
            }

            case 50:
            {
                return(ProcessQueue(protocol, header, method, token));
            }

            case 60:
            {
                return(ProcessBasic(protocol, header, method, token));
            }

            default:
            {
                throw new RabbitMQMethodException(nameof(ProcessMethod), method.ClassId, method.MethodId);
            }
            }
        }
        internal async ValueTask ProcessBasic(RabbitMQProtocolReader protocol, FrameHeader header, MethodHeader method, CancellationToken token = default)
        {
            switch (method.MethodId)
            {
            case 60:     //deliver method
            {
                var deliver = await protocol.ReadBasicDeliverAsync(token).ConfigureAwait(false);

                await _channelHandler.OnBeginDeliveryAsync(header.Channel, deliver, protocol).ConfigureAwait(false);

                break;
            }

            case 21:     // consume-ok
            {
                var tag = await protocol.ReadBasicConsumeOkAsync(token).ConfigureAwait(false);;
                await _channelHandler.OnConsumeOkAsync(header.Channel, tag).ConfigureAwait(false);

                break;
            }

            case 11:     // qos-ok
            {
                var qosOk = await protocol.ReadBasicQoSOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnQosOkAsync(header.Channel).ConfigureAwait(false);

                break;
            }

            case 31:     //consumer cancel-ok
            {
                var tag = await protocol.ReadBasicConsumeCancelOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnConsumeCancelOkAsync(header.Channel, tag).ConfigureAwait(false);

                break;
            }

            case 30:
            {
                var cancelInfo = await protocol.ReadBasicConsumeCancelAsync(token).ConfigureAwait(false);

                await _channelHandler.OnConsumeCancelAsync(header.Channel, cancelInfo);

                break;
            }

            default:
                throw new RabbitMQMethodException(nameof(ProcessBasic), method.ClassId, method.MethodId);
            }
        }
示例#20
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        private MethodHeader ReadMethodHeader(EndianAwareBinaryReader reader)
        {
            MethodHeader header = new MethodHeader();

            // Read first byte
            header.Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (header.Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    header.CodeSize = ((uint)(header.Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    header.Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    header.Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.Flags);
                    if (MethodFlags.ValidHeader != (header.Flags & MethodFlags.HeaderSizeMask))
                        throw new InvalidDataException(@"Invalid method header.");
                    header.MaxStack = reader.ReadUInt16();
                    header.CodeSize = reader.ReadUInt32();
                    header.LocalsSignature = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new InvalidDataException(@"Invalid method header while trying to decode " + this.methodCompiler.Method.ToString() + ". (Flags = " + header.Flags.ToString("X") + ", Rva = " + this.methodCompiler.Method.Rva + ")");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (header.Flags & MethodFlags.MoreSections))
                return header;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + header.CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    methodCompiler.ExceptionClauseHeader.AddClause(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;

            return header;
        }
        internal async ValueTask ProcessExchange(RabbitMQProtocolReader protocol, FrameHeader header, MethodHeader method, CancellationToken token = default)
        {
            switch (method.MethodId)
            {
            case 11:     //declare-ok
            {
                var declareOk = await protocol.ReadExchangeDeclareOkAsync(token).ConfigureAwait(false);;
                await _channelHandler.OnExchangeDeclareOkAsync(header.Channel).ConfigureAwait(false);;
                break;
            }

            case 21:     //delete-ok
            {
                var declareOk = protocol.ReadExchangeDeleteOkAsync(token).ConfigureAwait(false);;
                await _channelHandler.OnExchangeDeleteOkAsync(header.Channel).ConfigureAwait(false);;
                break;
            }

            default:
                throw new RabbitMQMethodException(nameof(ProcessExchange), method.ClassId, method.MethodId);
            }
        }
        internal async ValueTask ProcessQueue(RabbitMQProtocolReader protocol, FrameHeader header, MethodHeader method, CancellationToken token = default)
        {
            switch (method.MethodId)
            {
            case 11:     //declare-ok
            {
                var declareOk = await protocol.ReadQueueDeclareOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnQueueDeclareOkAsync(header.Channel, declareOk).ConfigureAwait(false);

                break;
            }

            case 21:     //bind-ok
            {
                var bindOk = await protocol.ReadQueueBindOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnQueueBindOkAsync(header.Channel).ConfigureAwait(false);

                break;
            }

            case 51:     //unbind-ok
            {
                var unbindOk = await protocol.ReadQueueUnbindOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnQueueUnbindOkAsync(header.Channel).ConfigureAwait(false);

                break;
            }

            case 31:     //purge-ok
            {
                var purged = await protocol.ReadQueuePurgeOkAsync(token).ConfigureAwait(false);

                await _channelHandler.OnQueuePurgeOkAsync(header.Channel, purged).ConfigureAwait(false);

                break;
            }

            case 41:     //delete-ok
            {
                var deleted = await protocol.ReadQueueDeleteOkAsync(token).ConfigureAwait(false);;
                await _channelHandler.OnQueueDeleteOkAsync(header.Channel, deleted).ConfigureAwait(false);;
                break;
            }

            default:
                throw new RabbitMQMethodException(nameof(ProcessQueue), method.ClassId, method.MethodId);
            }
        }
示例#23
0
        /// <summary>
        /// Converts the xml documentation string into a description object.
        /// </summary>
        public static Description GetDescription(IEntity entity)
        {
            IHeader header = null;

            var method = entity as IMethod;

            if (method != null)
            {
                header = new MethodHeader(method);
            }
            var field = entity as IField;

            if (field != null)
            {
                header = new FieldHeader(field);
            }

            var property = entity as IProperty;

            if (property != null)
            {
                header = new PropertyHeader(property);
            }

            if (header == null)
            {
                header = new SimpleHeader(AmbienceService.GetCurrentAmbience().Convert(entity));
            }


            var    description      = new Description(header);
            string xmlDocumentation = entity.Documentation;

            if (string.IsNullOrEmpty(xmlDocumentation))
            {
                return(description);
            }

            try
            {
                // original pattern without escape symbols: \<see cref=\"[^\"]+\.([^\"]+)\"\ /\>
                const string seeCrefPattern = "\\<see cref=\\\"[^\\\"]+\\.([^\\\"]+)\\\"\\ /\\>";
                xmlDocumentation = Regex.Replace(xmlDocumentation, seeCrefPattern, "$1");

                XDocument xml = XDocument.Parse("<docroot>" + xmlDocumentation + "</docroot>");

                foreach (XElement element in xml.Root.Elements())
                {
                    Test[element.Name.LocalName] = element.ToString();
                }

                XElement summary = xml.Descendants("summary").FirstOrDefault();
                if (summary != null)
                {
                    description.Summary = summary.Value.Trim();
                }

                XElement[] xmlParameters = xml.Descendants("param").ToArray();
                foreach (XElement node in xmlParameters)
                {
                    string    name = node.Attribute("name").Value;
                    string    parameterDescription = node.Value;
                    Parameter parameterObject      =
                        description.Parameters.FirstOrDefault(parameter => parameter.Name == name);
                    if (parameterObject != null)
                    {
                        parameterObject.Description = parameterDescription;
                    }
                }
            }
            catch (Exception)
            {
                return(new SimpleDescription(xmlDocumentation));
            }
            return(description);
        }