public static bool TryGetTimeSpan(string data, out TimeSpan span, out ValueNodeBase.ValueUnits units)
        {
            span = TimeSpan.MinValue;
            units = ValueNodeBase.ValueUnits.General;
            if (string.IsNullOrWhiteSpace(data)) return false;

            var split = data.Split(' ');
            if (split.Length != 2) return false;
            int val;
            if (!int.TryParse(split[0], out val)) return false;

            switch (split[1][0]) //just check first character
            {
                case 'D':
                case 'd':
                    span = new TimeSpan(val, 0, 0, 0);
                    units = ValueNodeBase.ValueUnits.Days;
                    return true;
                case 'H':
                case 'h':
                    span = new TimeSpan(val, 0, 0);
                    units = ValueNodeBase.ValueUnits.Hours;
                    return true;
                case 'M':
                case 'm':
                    span = new TimeSpan(0, val, 0);
                    units = ValueNodeBase.ValueUnits.Days;
                    return true;
                default:
                    return false;
            }
        }
        private bool FinishEvaluation(string val1, ValueNodeBase.ValueNodeType nodetype1, 
																	string val2, ValueNodeBase.ValueNodeType nodetype2)
        {
            do  //single-pass loop to allow breaking on error
            {
                //ints
                if (nodetype1 == ValueNodeBase.ValueNodeType.Int
                   && nodetype2 == ValueNodeBase.ValueNodeType.Int)
                {
                    int a, b;
                    if (!int.TryParse(val1, out a)) break;
                    if (!int.TryParse(val2, out b)) break;
                    return Compare(a, b);
                }

                //floats or in/float mix
                if ((nodetype1 == ValueNodeBase.ValueNodeType.Float
                    || nodetype1 == ValueNodeBase.ValueNodeType.Int)
                   && (nodetype2 == ValueNodeBase.ValueNodeType.Float
                    || nodetype2 == ValueNodeBase.ValueNodeType.Int))
                {
                    float a, b;
                    if (!float.TryParse(val1, out a)) break;
                    if (!float.TryParse(val2, out b)) break;
                    return Compare(a, b);
                }

                //dates
                if (nodetype1 == ValueNodeBase.ValueNodeType.Date
                   && nodetype2 == ValueNodeBase.ValueNodeType.Date)
                {
                    DateTime a, b;
                    if (!DateTime.TryParse(val1, out a)) break;
                    if (!DateTime.TryParse(val2, out b)) break;
                    return Compare(a, b);
                }

                //timespans
                if (nodetype1 == ValueNodeBase.ValueNodeType.DateSpan
                    && nodetype2 == ValueNodeBase.ValueNodeType.DateSpan)
                {
                    TimeSpan a, b;
                    ValueNodeBase.ValueUnits units1, units2;
                    if (!Input.TryGetTimeSpan(val1, out a, out units1)) break;
                    if (!Input.TryGetTimeSpan(val2, out b, out units2)) break;
                    return Compare(a, b);
                }

                //mix of int/float/tiemspan
                if ((nodetype1 == ValueNodeBase.ValueNodeType.DateSpan
                     || nodetype1 == ValueNodeBase.ValueNodeType.Float
                     || nodetype1 == ValueNodeBase.ValueNodeType.Int)
                    && (nodetype2 == ValueNodeBase.ValueNodeType.DateSpan
                        || nodetype2 == ValueNodeBase.ValueNodeType.Float
                        || nodetype2 == ValueNodeBase.ValueNodeType.Int))
                {
                    string span, val;
                    float a, b;
                    if (nodetype1 == ValueNodeBase.ValueNodeType.DateSpan)
                    {
                        span = val1;
                        val = val2;
                    }
                    else
                    {
                        span = val2;
                        val = val1;
                    }
                    var end = span.IndexOf(" ");
                    if (end < 1) break;
                    if (!float.TryParse(span.Substring(0, end), out a)) break;
                    if (!float.TryParse(val, out b)) break;
                    return Compare(a, b);
                }

                //special case for handling null dates (i.e. field node returned null)
                if (((nodetype1 == ValueNodeBase.ValueNodeType.DateSpan
                      || nodetype1 == ValueNodeBase.ValueNodeType.Date)
                     && val2 == null)
                    || ((nodetype2 == ValueNodeBase.ValueNodeType.DateSpan
                         || nodetype2 == ValueNodeBase.ValueNodeType.Date)
                        && val1 == null))
                    return false;

            } while (false);

            //if all else fails, compare as strings
            return Compare(val1, val2);
        }
 public static string EncodeTimeSpan(TimeSpan span, ValueNodeBase.ValueUnits units)
 {
     var test = span.ToString();
     switch (units)
     {
         case ValueNodeBase.ValueUnits.Days:
             return string.Format("{0} Days", span.Days);
         case ValueNodeBase.ValueUnits.Hours:
             return string.Format("{0} Days", span.Hours);
         case ValueNodeBase.ValueUnits.Minutes:
         case ValueNodeBase.ValueUnits.General:
             return string.Format("{0} Minutes", span.Days);
         default:
             throw new ArgumentOutOfRangeException("units");
     }
 }