/// <summary>
        /// Parses a VersionRange from its string representation.
        /// </summary>
        public static bool TryParse(string value, bool allowFloating, out VersionRange versionRange)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            versionRange = null;

            value = value.Trim();

            char[] charArray = value.ToCharArray();

            // * is the only range below 3 chars
            if (allowFloating && charArray.Length == 1 && charArray[0] == '*')
            {
                versionRange = AllStableFloating;
                return(true);
            }

            // Fail early if the string is too short to be valid
            if (charArray.Length < 3)
            {
                return(false);
            }

            string       minVersionString = null;
            string       maxVersionString = null;
            bool         isMinInclusive   = false;
            bool         isMaxInclusive   = false;
            NuGetVersion minVersion       = null;
            NuGetVersion maxVersion       = null;
            FloatRange   floatRange       = null;

            if (charArray[0] == '(' || charArray[0] == '[')
            {
                // The first character must be [ to (
                switch (charArray[0])
                {
                case '[':
                    isMinInclusive = true;
                    break;

                case '(':
                    isMinInclusive = false;
                    break;

                default:
                    return(false);
                }

                // The last character must be ] ot )
                switch (charArray[charArray.Length - 1])
                {
                case ']':
                    isMaxInclusive = true;
                    break;

                case ')':
                    isMaxInclusive = false;
                    break;

                default:
                    return(false);
                }

                // Get rid of the two brackets
                value = value.Substring(1, value.Length - 2);

                // Split by comma, and make sure we don't get more than two pieces
                string[] parts = value.Split(',');
                if (parts.Length > 2)
                {
                    return(false);
                }
                else if (parts.All(String.IsNullOrEmpty))
                {
                    // If all parts are empty, then neither of upper or lower bounds were specified. Version spec is of the format (,]
                    return(false);
                }

                // If there is only one piece, we use it for both min and max
                minVersionString = parts[0];
                maxVersionString = (parts.Length == 2) ? parts[1] : parts[0];
            }
            else
            {
                // default to min inclusive when there are no braces
                isMinInclusive = true;

                // use the entire value as the version
                minVersionString = value;
            }

            if (!String.IsNullOrWhiteSpace(minVersionString))
            {
                // parse the min version string
                if (allowFloating && minVersionString.Contains("*"))
                {
                    // single floating version
                    if (FloatRange.TryParse(minVersionString, out floatRange) && floatRange.HasMinVersion)
                    {
                        minVersion = floatRange.MinVersion;
                    }
                    else
                    {
                        // invalid float
                        return(false);
                    }
                }
                else
                {
                    // single non-floating version
                    if (!NuGetVersion.TryParse(minVersionString, out minVersion))
                    {
                        // invalid version
                        return(false);
                    }
                }
            }

            // parse the max version string, the max cannot float
            if (!String.IsNullOrWhiteSpace(maxVersionString))
            {
                if (!NuGetVersion.TryParse(maxVersionString, out maxVersion))
                {
                    // invalid version
                    return(false);
                }
            }

            // Successful parse!
            versionRange = new VersionRange(
                minVersion: minVersion,
                includeMinVersion: isMinInclusive,
                maxVersion: maxVersion,
                includeMaxVersion: isMaxInclusive,
                includePrerelease: null,
                floatRange: floatRange);

            return(true);
        }
        /// <summary>
        /// Parse a floating version into a FloatRange
        /// </summary>
        public static bool TryParse(string versionString, out FloatRange range)
        {
            range = null;

            if (versionString != null)
            {
                int starPos = versionString.IndexOf('*');

                string actualVersion = versionString;
                string releasePrefix = string.Empty;

                if (versionString.Length == 1 && starPos == 0)
                {
                    range = new FloatRange(NuGetVersionFloatBehavior.Major, new NuGetVersion(new Version(0, 0)));
                }
                else if (starPos == versionString.Length - 1)
                {
                    var behavior = NuGetVersionFloatBehavior.None;

                    actualVersion = versionString.Substring(0, versionString.Length - 1);

                    if (versionString.IndexOf('-') == -1)
                    {
                        // replace the * with a 0
                        actualVersion += "0";

                        int versionParts = actualVersion.Split('.').Length;

                        if (versionParts == 2)
                        {
                            behavior = NuGetVersionFloatBehavior.Minor;
                        }
                        else if (versionParts == 3)
                        {
                            behavior = NuGetVersionFloatBehavior.Patch;
                        }
                        else if (versionParts == 4)
                        {
                            behavior = NuGetVersionFloatBehavior.Revision;
                        }
                    }
                    else
                    {
                        behavior = NuGetVersionFloatBehavior.Prerelease;

                        // check for a prefix
                        if (versionString.IndexOf('-') == versionString.LastIndexOf('-'))
                        {
                            releasePrefix = actualVersion.Substring(versionString.LastIndexOf('-') + 1);

                            if (actualVersion.EndsWith("-"))
                            {
                                // remove the empty release label, the version will be release but
                                // the behavior will have to account for this
                                actualVersion += "-";
                            }
                            else if (actualVersion.EndsWith("."))
                            {
                                // ending with a . is not allowed
                                // TODO: solve this better
                                actualVersion += "0";
                            }
                        }
                    }

                    NuGetVersion version = null;
                    if (NuGetVersion.TryParse(actualVersion, out version))
                    {
                        // there is no float range for this version
                        range = new FloatRange(behavior, version, releasePrefix);
                    }
                }
                else
                {
                    // normal version parse
                    NuGetVersion version = null;
                    if (NuGetVersion.TryParse(versionString, out version))
                    {
                        // there is no float range for this version
                        range = new FloatRange(NuGetVersionFloatBehavior.None, version);
                    }
                }
            }

            return(range != null);
        }