public FunctionMetadata GetMetadata(Type functionType)
        {
            FunctionMetadata functionMetadata = new FunctionMetadata(functionType);

            functionMetadata.Id = MD5.GetHashString(functionType.FullName);

            var displayNameAttr = functionType.GetCustomAttribute<DisplayNameAttribute>();
            functionMetadata.DisplayName = displayNameAttr != null ? displayNameAttr.DisplayName : null;

            var categoryAttr = functionType.GetCustomAttribute<CategoryAttribute>();
            functionMetadata.Category = categoryAttr != null ? categoryAttr.Category : null;

            var sectionAttr = functionType.GetCustomAttribute<SectionAttribute>();
            functionMetadata.Section = sectionAttr != null ? sectionAttr.Name : null;

            var descriptionAttr = functionType.GetCustomAttribute<DescriptionAttribute>();
            functionMetadata.Description = descriptionAttr != null ? descriptionAttr.Description : null;

            foreach (var signature in functionType.GetCustomAttributes<FunctionSignatureAttribute>())
            {
                functionMetadata.Signatures.Add(GetFunctionSignatureMetadata(signature));
            }

            foreach (var exampleUsage in functionType.GetCustomAttributes<ExampleUsageAttribute>())
            {
                functionMetadata.ExampleUsages.Add(new ExampleUsage(exampleUsage.Expression, exampleUsage.Result)
                {
                    CanMultipleResults = exampleUsage.CanMultipleResults
                });
            }

            return functionMetadata;
        }
        public void AllFunctionsTest_ShouldContainsCorrectedExampleUsages(FunctionMetadata item)
        {
            //action
            foreach (var exampleUsage in item.ExampleUsages)
            {
                //action
                int zeroThreshold = 14;
                int complexThreshold = 10;
                Expression<Object> tree = ExpressionTreeBuilder.BuildTree(exampleUsage.Expression);
                object actual = tree.Evaluate();

                //assert
                (actual is Complex || actual is CMatrix).Should().BeTrue("Result must have be only following types: Complex, Matrix.");

                if (actual is Complex) actual = NumericUtil.ComplexZeroThreshold((Complex)actual, complexThreshold, zeroThreshold);
                if (actual is CMatrix) actual = NumericUtilExtensions.ComplexZeroThreshold((CMatrix)actual, complexThreshold, zeroThreshold);

                if (!exampleUsage.CanMultipleResults)
                {
                    IFormattable formatedResult = (IFormattable)actual;
                    formatedResult.ToString(null, CultureInfo.InvariantCulture).Replace(" ", String.Empty)
                        .Should().Be(exampleUsage.Result.Replace(" ", String.Empty),
                        "Example usage contains inccorect result. Target type: {0}", item.FunctionType);
                }
            }
        }