public static Range ToRange(this string rangeString)
        {
            if (String.IsNullOrWhiteSpace(rangeString)) {
                return Range.Invalid;
            }

            Range range = new Range() { Distance = 1.0f };
            string[] parts = rangeString.Split();

            AttackType type;
            string distanceStr = parts[parts.Length - 1];
            string typeStr = parts.Length > 1 ? String.Concat(parts[0], parts[1]) : parts[0];
            if (!Enum.TryParse(typeStr, true, out type)) {
                if (!Enum.TryParse(parts[0], true, out type)) {
                    return Range.Invalid;
                }
                else if (parts.Length >= 2) {
                    distanceStr = parts[1];
                }
            }
            else if (parts.Length >= 3) {
                distanceStr = parts[2];
            }

            float distance;
            if (Single.TryParse(distanceStr, out distance)) {
                range.Distance = distance;
            }

            // final fixup
            range.AttackType = type;
            if (range.AttackType == AttackType.Personal) {
                range.Distance = 0.0f;
            }

            return range;
        }
        private Range CreateRange()
        {
            Specific specific;
            Range range = new Range { Distance = 1.0f };
            if (this.Rules.Count == 0) {
                return range;
            }
            else if (!this.Rules[0].Specifics.TryGetValue("Range", out specific)) {
                return range;
            }

            string weaponRange = specific.Value;
            string[] parts = weaponRange.Trim().Split('/');

            float distance, max = 0;
            Single.TryParse(parts[0], out distance);
            if (parts.Length > 1) {
                Single.TryParse(parts[1], out max);
            }
            range.Distance = distance;
            range.MaxDistance = max;

            return range;
        }