anchor.diff:  
       method JSONParse(aTok: Tokenizer): Object;
       method Walk(aCaller: ExecutionContext; aRoot: EcmaScriptObject; aReviver: EcmaScriptBaseFunctionObject; aName: string; aCurrent: EcmaScriptObject): Object;
  +  private
  +    method JSONStr(aExecutionContext: ExecutionContext; aStack: List<Object>; aGap, aIndent: string; aReplacerFunction: EcmaScriptBaseFunctionObject; 
  +      aProplist: List<String>; aWork: EcmaScriptObject; aValue: String): string;
  +    class method JSONQuote(val: String): string;
     end;  
   
   
  
positive.code: 
  method GlobalObject.JSONStringify(aCaller: ExecutionContext;aSelf: Object; params args: Array of Object): Object;
  begin
  end;
  
  
  
negative.code:   exit aReviver.CallEx(aCaller, aRoot,aName, lItem);
  end;
  
  method GlobalObject.JSONStr(aExecutionContext: ExecutionContext; aStack: List<Object>; aGap, aIndent: string; aReplacerFunction: EcmaScriptBaseFunctionObject; 
        aProplist: List<String>; aWork: EcmaScriptObject; aValue: String): string;
  begin
    var value := aWork.Get(aExecutionContext, 2, aValue);
    var lObj := EcmaScriptObject(Value);
    if lObj<> nil then begin
      var lCall := EcmaScriptBaseFunctionObject(lObj.Get(aExecutionContext, 2, 'toJSON'));
      value := lCall.CallEx(aExecutionContext, lObj, aValue);
    end;
    if aReplacerFunction <> nil then begin
      value := aReplacerFunction.CallEx(aExecutionContext, aWork,aValue, Value);
    end;
    lObj := EcmaScriptObject(VAlue);
    if lObj <> nil then begin
      if lobj.Class = 'Number' then Value := lObj.Value else
      if lObj.Class = 'String' then Value := lObj.Value;
      if lObj.Class = 'Boolean' then Value := lObj.Value;
    end;
    if value = nil then exit 'null';
    if value is boolean then begin 
      if boolean(value) then 
        exit 'true';
      exit 'false';
    end;
    if value is string then exit JSONQuote(String(value));
    if value is double then begin
      if Double.IsInfinity(Double(value)) then
        exit 'null'
      else
        exit Double(value).ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
    end;
    if value is Int32 then exit Int32(Value).ToString;
    if value is Int64 then exit Int64(Value).ToString;
    lObj := EcmaScriptObject(VAlue);
    if (lObj <> nil) and (lObj is not EcmaScriptBaseFunctionObject) then begin
      if aStack.Contains(lObj) then RaiseNativeError(NativeErrorType.TypeError, 'Recursive JSON structure');
      aStack.Add(lObj);
      var lWork := new StringBuilder;
      if lObj.Class = 'Array' then begin
        if EcmaScriptArrayObject(lObj).Items.Count = 0 then begin
          lWork.Append('[]');
  
        end;
  
        aIndent := aIndent + aGap;
  
        for i: Integer := 0 to EcmaScriptArrayObject(lObj).Items.Count -1 do begin
          var el := JSONStr(aExecutionContext, aStack, aGap, aIndent,aReplacerFunction, aProplist, lObj, i.ToString());
          if el =  nil then el := 'null';
          if i = 0 then begin
            if aGap = '' then
              lWork.Append('[')
            else begin
              lWork.Append('['#10);
              lWork.Append(aIndent);
            end;
          end;
          lWork.Append(el);
          if i = EcmaScriptArrayObject(lObj).Items.Count -1 then begin
            if aGap = '' then begin
              lWork.Append(']')
            end else begin
              lWork.Append(#10);
              lWork.Append(aIndent.Substring(0, aIndent.Length - aGap.Length));
              lWork.Append(']');
            end;
          end else begin
            if aGap = '' then lWork.Append(',') else begin
              lWork.Append(','#10);
              lWork.Append(aIndent);
            end;
          end;
        end; 
      end else begin
        if EcmaScriptArrayObject(lObj).Items.Count = 0 then exit '{}';
        var lStepBack := aIndent;
        aIndent := aIndent + aGap;
        var k := aProplist:ToArray;
        if k = nil then
          k := lObj.Values.Where(a->PropertyAttributes.Enumerable in a.Value.Attributes).Select(a->a.Key).ToArray;
        var lItems := new List<string>;
        for each el in k do begin
          var lVal := JSONStr(aExecutionContext, aStack, aGap, aIndent, aReplacerFunction, aProplist, lObj, el);
          if lVal <> nil then begin
            if aGap = '' then
              lItems.Add(JSONQuote(el)+':'+lVal)
            else
              lItems.Add(JSONQuote(el)+': '+lVal);
          end;
        end;
        if lItems.Count = 0 then
          lWork.Append('{}')
        else begin
          if aGap = '' then begin
            lWork.Append('{');
            for i: Integer := 0 to lItems.Count -1 do begin
              if i <> 0 then lWork.Append(',');
              lWork.Append(lItems[i]);
            end;
            lWork.Append('}');
          end else begin
            lWork.Append('{'#10);
            lWork.Append(aIndent);
            for i: Integer := 0 to lItems.Count -1 do begin
              if (i <> 0) and (i <> lItems.Count- 1) then begin 
                lWork.Append(','#10);
                lWork.Append(aIndent);
              end;
              lWork.Append(lItems[i]);
            end;
            lWork.Append(#10);
            lWork.Append(aIndent.Substring(0, aIndent.Length - aGap.Length));
            lWork.Append('}');
          end;
        end;
      end;
      aStack.Remove(lObj);
      exit lWork.ToString;
    end;
    exit nil;
  end;
  
  class method GlobalObject.JSONQuote(val: String): string;
  begin
    var sb := new StringBuilder;
    sb.Append('"');
    for i: Integer := 0 to val.Length -1 do begin
      case val[i] of
        '"': sb.Append('\"');
        '\': sb.Append('\\');
        #10: sb.Append('\n');
        #13: sb.Append('\r');
        #12: sb.Append('\f');
        #9: sb.Append('\t');
        #8: sb.Append('\b');
        #0 .. #7, #11, #14 ..#31: begin
          sb.Append('\u');
          sb.Append(Integer(val[i]).ToString('x4'));
        end
      else
        sb.Append(val[i]);
      end; // case
    end;
  
    sb.Append('"');
    exit sb.ToString;
  end;
  
  end.
  