/// <summary>
        /// Returns a string representation of both <see cref="IDictionary"/>s highlighting differences in array elements
        /// </summary>
        /// <param name="dict"></param>
        /// <param name="dict2"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static string AsciiArt(IDictionary dict, IDictionary dict2, string prefix = "")
        {
            var sb = new StringBuilder();

            List <object> keys1 = dict.Keys.Cast <object>().OrderBy(i => i).ToList();
            List <object> keys2 = dict2.Keys.Cast <object>().OrderBy(i => i).ToList();

            for (var i = 0; i < Math.Max(keys1.Count, keys2.Count); i++)
            {
                sb.Append(prefix + "[" + i + "] - ");

                //if run out of values in dictionary 1
                if (i > keys1.Count)
                {
                    sb.AppendLine(string.Format(" {0} - \t <NULL> \t {1}", keys2[i], dict2[keys2[i]]));
                }
                //if run out of values in dictionary 2
                else if (i > keys2.Count)
                {
                    sb.AppendLine(string.Format(" {0} - \t {1} \t <NULL>", keys1[i], dict[keys1[i]]));
                }
                else
                {
                    object val1 = dict[keys1[i]];
                    object val2 = dict2[keys2[i]];

                    if (val1 is Array && val2 is Array)
                    {
                        sb.Append(string.Format(" {0} : \r\n {1}",
                                                keys1[i],
                                                ArrayHelperMethods.AsciiArt((Array)val1,
                                                                            (Array)val2, prefix + "\t")));
                    }
                    else
                    //if both are dictionaries
                    if (IsDictionary(val1) && IsDictionary(val2))
                    {
                        sb.Append(string.Format(" {0} : \r\n {1}",
                                                keys1[i],
                                                AsciiArt((IDictionary)val1,
                                                         (IDictionary)val2, prefix + "\t")));
                    }
                    else
                    {
                        //if we haven't outrun of either array
                        sb.AppendLine(string.Format(" {0} - \t {1} \t {2} {3}",
                                                    keys1[i],
                                                    dict[keys1[i]],
                                                    dict2[keys2[i]],
                                                    FlexibleEquality.FlexibleEquals(dict[keys1[i]], dict2[keys2[i]]) ? "" : "<DIFF>"));
                    }
                }
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Returns a string representation of both arrays highlighting differences in array elements
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static string AsciiArt(Array a, Array b, string prefix = "")
        {
            var sb = new StringBuilder();

            for (var i = 0; i < Math.Max(a.Length, b.Length); i++)
            {
                sb.Append(prefix + " [" + i + "] - ");

                //if run out of values in dictionary 1
                if (i > a.Length)
                {
                    sb.AppendLine(string.Format(" \t <NULL> \t {0}", b.GetValue(i)));
                }
                //if run out of values in dictionary 2
                else if (i > b.Length)
                {
                    sb.AppendLine(string.Format(" \t {0} \t <NULL>", a.GetValue(i)));
                }
                else
                {
                    object val1 = a.GetValue(i);
                    object val2 = b.GetValue(i);

                    if (DictionaryHelperMethods.IsDictionary(val1) && DictionaryHelperMethods.IsDictionary(val2))
                    {
                        sb.Append(string.Format("\r\n {0}",
                                                DictionaryHelperMethods.AsciiArt((IDictionary)val1,
                                                                                 (IDictionary)val2, prefix + "\t")));
                    }
                    else
                    if (val1 is Array && val2 is Array)
                    {
                        sb.Append(string.Format("\r\n {0}",
                                                AsciiArt((Array)val1,
                                                         (Array)val2, prefix + "\t")));
                    }
                    else
                    {
                        //if we haven't outrun of either array
                        sb.AppendLine(string.Format(" \t {0} \t {1} {2}",
                                                    val1,
                                                    val2,
                                                    FlexibleEquality.FlexibleEquals(val1, val2) ? "" : "<DIFF>"));
                    }
                }
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Returns true if the two arrays contain the same elements (using <see cref="FlexibleEquality"/>)
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool ArrayEquals(Array a, Array b)
        {
            if (a.Length != b.Length)
            {
                return(false);
            }

            for (var i = 0; i < a.Length; i++)
            {
                if (!FlexibleEquality.FlexibleEquals(a.GetValue(i), b.GetValue(i)))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Determines whether the two dictionaries contain the same keys and values (using <see cref="FlexibleEquality"/>).  Handles any generic dictionary and uses
        /// Equals for comparison.  Note that this will handle Values that are sub dictionaries (recursively calling <see cref="DictionaryEquals"/>) but will not handle
        /// when keys are dictionaries.
        /// </summary>
        /// <param name="dict1"></param>
        /// <param name="dict2"></param>
        /// <returns>true if the keys/values are Equal and neither contains novel keys</returns>
        public static bool DictionaryEquals(IDictionary dict1, IDictionary dict2)
        {
            //if either is null
            if (dict1 == null || dict2 == null)
            {
                return(dict1 == dict2); //they are only equal if they are both null
            }
            var keys1 = new HashSet <object>();

            foreach (object k in dict1.Keys)
            {
                keys1.Add(k);
            }

            var keys2 = new HashSet <object>();

            foreach (object k in dict2.Keys)
            {
                keys2.Add(k);
            }

            //they do not contain the same keys
            if (!keys1.SetEquals(keys2))
            {
                return(false);
            }

            //do all the key value pairs in dictionary 1 match dictionary 2
            foreach (object key in keys1)
            {
                if (!FlexibleEquality.FlexibleEquals(dict1[key], dict2[key]))
                {
                    return(false);
                }
            }

            //they keys are the same set and the values are Equal too
            return(true);
        }