A description of a single parameter This does not match a UIA structure, but is used as a simple data class to help form those structures.
        private static IEnumerable <UiaParameterDescription> BuildParamsFromProviderMethodInfo(MethodInfo mInfo)
        {
            // Accordingly to UIA docs, In params should go before any Out params

            var inParams = from parameterInfo in mInfo.GetParameters()
                           where !parameterInfo.IsOut
                           let uiaType = UiaTypesHelper.TypeToAutomationType(parameterInfo.ParameterType)
                                         select new UiaParameterDescription(parameterInfo.Name, uiaType);

            var outParams = from parameterInfo in mInfo.GetParameters()
                            where parameterInfo.IsOut
                            let uiaType = UiaTypesHelper.TypeToOutAutomationType(parameterInfo.ParameterType.GetElementType())
                                          select new UiaParameterDescription(parameterInfo.Name, uiaType);

            var retParam = Enumerable.Empty <UiaParameterDescription>();

            if (mInfo.ReturnType != typeof(void))
            {
                var uiaRetType    = UiaTypesHelper.TypeToOutAutomationType(mInfo.ReturnType);
                var retParamDescr = new UiaParameterDescription(UiaTypesHelper.RetParamUnspeakableName, uiaRetType);
                retParam = new[] { retParamDescr };
            }

            return(inParams.Concat(outParams).Concat(retParam));
        }
        public void AddParameter(UiaParameterDescription param)
        {
            if (PatternMethodParamDescriptions.Count > 0 && UiaTypesHelper.IsOutType(PatternMethodParamDescriptions.Last().UiaType) && UiaTypesHelper.IsInType(param.UiaType))
            {
                throw new ArgumentException("In param can't go after an out one. Please, ensure the correct order");
            }
            if (ProviderMethodInfo != null &&
                param.Name != UiaTypesHelper.RetParamUnspeakableName &&
                !_providerMethodInfoIndicies.ContainsKey(param.Name))
            {
                throw new ArgumentException("Provided provider's method info does not have argument with this name");
            }

            UIAutomationType type = param.UiaType;
            var marshalledName    = Marshal.StringToCoTaskMemUni(param.Name);

            if (UiaTypesHelper.IsInType(type))
            {
                _inParamNames.Add(marshalledName);
                _inParamTypes.Add(type);
            }
            else
            {
                _outParamNames.Add(marshalledName);
                _outParamTypes.Add(type);
            }
            PatternMethodParamDescriptions.Add(param);
        }
        private static IEnumerable<UiaParameterDescription> BuildParamsFromProviderMethodInfo(MethodInfo mInfo)
        {
            // Accordingly to UIA docs, In params should go before any Out params

            var inParams = from parameterInfo in mInfo.GetParameters()
                           where !parameterInfo.IsOut
                           let uiaType = UiaTypesHelper.TypeToAutomationType(parameterInfo.ParameterType)
                           select new UiaParameterDescription(parameterInfo.Name, uiaType);

            var outParams = from parameterInfo in mInfo.GetParameters()
                            where parameterInfo.IsOut
                            let uiaType = UiaTypesHelper.TypeToOutAutomationType(parameterInfo.ParameterType.GetElementType())
                            select new UiaParameterDescription(parameterInfo.Name, uiaType);

            var retParam = Enumerable.Empty<UiaParameterDescription>();
            if (mInfo.ReturnType != typeof(void))
            {
                var uiaRetType = UiaTypesHelper.TypeToOutAutomationType(mInfo.ReturnType);
                var retParamDescr = new UiaParameterDescription(UiaTypesHelper.RetParamUnspeakableName, uiaRetType);
                retParam = new[] {retParamDescr};
            }

            return inParams.Concat(outParams).Concat(retParam);
        }
        public void AddParameter(UiaParameterDescription param)
        {
            if (PatternMethodParamDescriptions.Count > 0 && UiaTypesHelper.IsOutType(PatternMethodParamDescriptions.Last().UiaType) && UiaTypesHelper.IsInType(param.UiaType))
                throw new ArgumentException("In param can't go after an out one. Please, ensure the correct order");
            if (ProviderMethodInfo != null
                && param.Name != UiaTypesHelper.RetParamUnspeakableName
                && !_providerMethodInfoIndicies.ContainsKey(param.Name))
            {
                throw new ArgumentException("Provided provider's method info does not have argument with this name");
            }

            UIAutomationType type = param.UiaType;
            var marshalledName = Marshal.StringToCoTaskMemUni(param.Name);
            if (UiaTypesHelper.IsInType(type))
            {
                _inParamNames.Add(marshalledName);
                _inParamTypes.Add(type);
            }
            else
            {
                _outParamNames.Add(marshalledName);
                _outParamTypes.Add(type);
            }
            PatternMethodParamDescriptions.Add(param);
        }