anchor.diff:    | Equals, String s -> expected = s
     | NotEquals, String s -> expected <> s
     | (Equals | NotEquals), Number _ -> failwith "Equals and not equals work only on strings or booleans"
  -  | GreaterThan, Number n -> n > decimal expected
  -  | LessThan, Number n -> n < decimal expected
  -  | InRange, Number n -> let expected = expected.Split(',') in n > decimal expected.[0] && n < decimal expected.[1]
  +  | GreaterThan, Number n -> n > float expected
  +  | LessThan, Number n -> n < float expected
  +  | InRange, Number n -> let expected = expected.Split(',') in n > float expected.[0] && n < float expected.[1]
     | (GreaterThan | LessThan | InRange), (Bool _ | String _) -> failwith "Relational operator work only on numbers"
   
   let transformData (objs:seq<(string * Value)[]>) = function
  
positive.code:   | WindowAggregation.MiddleKey -> [ "middle " + kname, kvalues.[(kvalues.Length-1)/2] ]
  
  let getExpandAggregationFunction kname agg = 
    let ret fld f = fun row -> fld, pickField fld row |> asDecimal |> f |> Number
    match agg with
    | WindowAggregation.Mean(fld) -> 
        let mutable sum = 0M
        let mutable count = 0M
        ret fld (fun v -> sum <- sum + v; count <- count + v; sum / count)
    | WindowAggregation.Min(fld) -> 
        let mutable min = Decimal.MaxValue
        ret fld (fun v -> (if v < min then min <- v); min)
    | WindowAggregation.Max(fld) ->
        let mutable max = Decimal.MinValue
        ret fld (fun v -> (if v > max then max <- v); max)
    | WindowAggregation.Sum(fld) -> 
        let mutable sum = 0M
        ret fld (fun v -> sum <- sum + v; sum)
    | WindowAggregation.FirstKey -> 
        let mutable first = None
  
negative.code:   Array.pick (fun (n, v) -> if n = name then Some v else None) obj
  
  let asString = function String s -> s | Number n -> string n | Date d -> d.ToString("g") | Bool b -> string b
  let asFloat = function String s -> float s | Number n -> n | Date d -> float d.Ticks | Bool true -> 1. | Bool false -> 0.
  
  let applyGroupAggregation kvals group = function
   | GroupAggregation.GroupKey -> kvals
   | GroupAggregation.CountAll -> [ "count", Number(group |> Seq.length |> float) ]
   | GroupAggregation.CountDistinct(fld) -> [ fld, Number(group |> Seq.distinctBy (pickField fld) |> Seq.length |> float) ]
   | GroupAggregation.ConcatValues(fld) -> [ fld, group |> Seq.map(fun obj -> pickField fld obj |> asString) |> Seq.distinct |> String.concat ", " |> String ]
   | GroupAggregation.Sum(fld) -> [ fld, group |> Seq.sumBy (fun obj -> pickField fld obj |> asFloat) |> Number ]
   | GroupAggregation.Mean(fld) -> [ fld, group |> Seq.averageBy (fun obj -> pickField fld obj |> asFloat) |> Number ]
  
  let applyWinAggregation kname group agg = 
    let nums fld = group |> Seq.map (fun obj -> pickField fld obj |> asFloat)
    let kvalues = Seq.map (pickField kname) group |> Array.ofSeq
    match agg with
    | WindowAggregation.Mean(fld) -> [ fld, nums fld |> Seq.average |> Number ]
  