/// <summary>
        /// Check if the type of the generic is the same for two generics. If not, log an issue.
        /// </summary>
        /// <param name="cmdlet">The cmdlet metadata currently being checked.</param>
        /// <param name="oldTypeMetadata">The type metadata from the old (serialized) assembly.</param>
        /// <param name="newTypeMetadata">The type metadata from the new assembly.</param>
        /// <param name="target">Target of the generic type breaking change..</param>
        /// <param name="issueLogger">ReportLogger that will keep track of issues found.</param>
        private bool HasSameGenericType(
            CmdletMetadata cmdlet,
            TypeMetadata oldTypeMetadata,
            TypeMetadata newTypeMetadata,
            string target,
            ReportLogger <BreakingChangeIssue> issueLogger)
        {
            // If the type of the generics are the same, return true
            string oldTypeName = oldTypeMetadata.GetClassNameWithoutApiVersion(oldTypeMetadata.Name);
            string newTypeName = newTypeMetadata.GetClassNameWithoutApiVersion(newTypeMetadata.Name);

            if (oldTypeName.Equals(newTypeName, StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            // Otherwise, log an issue and return false
            issueLogger?.LogBreakingChangeIssue(
                cmdlet: cmdlet,
                severity: 0,
                problemId: ProblemIds.BreakingChangeProblemId.ChangedGenericType,
                description: string.Format(Resources.ChangedGenericTypeDescription,
                                           target, oldTypeMetadata.Name, newTypeMetadata.Name),
                remediation: string.Format(Resources.ChangedGenericTypeRemediation,
                                           target, oldTypeMetadata.Name));

            return(false);
        }
        /// <summary>
        /// Checks if the type of the parameter is an array or a generic, and makes sure there are no breaking changes.
        /// If the type is not an array or a generic, it proceeds with the normal type checking with CompareTypeMetadata.
        /// </summary>
        /// <param name="cmdlet">The cmdlet whose parameter metadata is being checked for breaking changes.</param>
        /// <param name="parameter">The parameter whose type metadata is being checked for breaking changes.</param>
        /// <param name="oldTypeMetadata">The type metadata from the old (serialized) assembly.</param>
        /// <param name="newTypeMetadata">The type metadata from the new assembly.</param>
        /// <param name="issueLogger">ReportLogger that will keep track of issues found.</param>
        public void CheckParameterType(
            CmdletMetadata cmdlet,
            ParameterMetadata parameter,
            TypeMetadata oldTypeMetadata,
            TypeMetadata newTypeMetadata,
            ReportLogger <BreakingChangeIssue> issueLogger)
        {
            int    problemId   = ProblemIds.BreakingChangeProblemId.ChangedParameterElementType;
            string description = string.Format(Resources.ChangedParameterElementTypeDescription,
                                               parameter.Name, oldTypeMetadata.ElementType, newTypeMetadata.ElementType);
            string remediation = string.Format(Resources.ChangedParameterElementTypeRemediation,
                                               parameter.Name, oldTypeMetadata.ElementType);

            // If the type is an array, check for any breaking changes
            if (IsElementType(cmdlet, oldTypeMetadata, newTypeMetadata, problemId, description, remediation, issueLogger))
            {
                return;
            }

            string target = string.Format("parameter {0}", parameter.Name);

            // If the type is a generic, check for any breaking changes
            if (IsGenericType(cmdlet, oldTypeMetadata, newTypeMetadata, target, issueLogger))
            {
                return;
            }

            // If the types are different, log an issue
            string oldTypeName = oldTypeMetadata.GetClassNameWithoutApiVersion(oldTypeMetadata.Name);
            string newTypeName = newTypeMetadata.GetClassNameWithoutApiVersion(newTypeMetadata.Name);

            if (!oldTypeName.Equals(newTypeName, StringComparison.OrdinalIgnoreCase))
            {
                issueLogger?.LogBreakingChangeIssue(
                    cmdlet: cmdlet,
                    severity: 0,
                    problemId: ProblemIds.BreakingChangeProblemId.ChangedParameterType,
                    description: string.Format(Resources.ChangedParameterTypeDescription,
                                               cmdlet.Name, oldTypeMetadata.Name, parameter.Name),
                    remediation: string.Format(Resources.ChangedParameterTypeRemediation,
                                               parameter.Name, oldTypeMetadata.Name));
            }
            else
            {
                CompareTypeMetadata(cmdlet, oldTypeMetadata, newTypeMetadata, issueLogger);
            }
        }
        /// <summary>
        /// Check if the given types are arrays, and if so, see if their element types are the same. If not, log an issue.
        /// </summary>
        /// <param name="cmdlet">The cmdlet metadata currently being checked.</param>
        /// <param name="oldTypeMetadata">The type metadata from the old (serialized) assembly.</param>
        /// <param name="newTypeMetadata">The type metadata from the new assembly.</param>
        /// <param name="problemId">The problemId used for logging if there is an issue.</param>
        /// <param name="description">The description used for logging if there is an issue.</param>
        /// <param name="remediation">The remediation used for logging if there is an issue.</param>
        /// <param name="issueLogger">ReportLogger that will keep track of issues found.</param>
        private bool IsElementType(
            CmdletMetadata cmdlet,
            TypeMetadata oldTypeMetadata,
            TypeMetadata newTypeMetadata,
            int problemId,
            string description,
            string remediation,
            ReportLogger <BreakingChangeIssue> issueLogger)
        {
            // Check if the type is an array
            if (oldTypeMetadata.ElementType != null && newTypeMetadata.ElementType != null)
            {
                string oldTypeName = oldTypeMetadata.GetClassNameWithoutApiVersion(oldTypeMetadata.ElementType);
                string newTypeName = newTypeMetadata.GetClassNameWithoutApiVersion(newTypeMetadata.ElementType);
                // Check if the element of the array is the same in the old and new metadata
                if (oldTypeName.Equals(newTypeName, StringComparison.OrdinalIgnoreCase))
                {
                    // If we have not previously seen this element type,
                    // run this method on the type
                    if (!_typeSet.Contains(oldTypeMetadata.ElementType))
                    {
                        _typeSet.Add(oldTypeMetadata.ElementType);

                        var oldElementType = _oldTypeDictionary[oldTypeMetadata.ElementType];
                        var newElementType = _newTypeDictionary[newTypeMetadata.ElementType];

                        CompareTypeMetadata(cmdlet, oldElementType, newElementType, issueLogger);
                    }
                }
                // If the element type has changed, log an issue
                else
                {
                    issueLogger?.LogBreakingChangeIssue(
                        cmdlet: cmdlet,
                        severity: 0,
                        problemId: problemId,
                        description: description,
                        remediation: remediation);
                }

                return(true);
            }

            return(false);
        }