anchor.diff:    FNodeType := pvType;
   end;
   
  +function TDValueNode.FindByName(pvName:String): TDValueNode;
  +var
  +  i:Integer;
  +begin
  +  i := IndexOf(pvName);
  +  if i = -1 then Result := nil else Result := Items[i];
  +end;
  +
  +function TDValueNode.FindByPath(pvPath:string): TDValueNode;
  +var
  +  lvParent:TDValueNode;
  +  j:Integer;
  +begin
  +  Result := InnerFindByPath(pvPath, lvParent, j);
  +end;
  +
  +function TDValueNode.ForceByName(pvName:string): TDValueNode;
  +begin
  +  Result := FindByName(pvName);
  +  if Result = nil then
  +  begin
  +    CheckSetNodeType(vntObject);
  +    Result := TDValueNode.Create(vntValue);
  +    Result.FName.AsString := pvName;
  +    Result.FParent := Self;
  +    FChildren.Add(Result);
  +  end;
  +end;
  +
  +function TDValueNode.ForceByPath(pvPath:String): TDValueNode;
  +var
  +  lvName:string;
  +  s:string;
  +  sPtr:PChar;
  +  lvParent:TDValueNode;
  +  j:Integer;
  +
  +begin
  +  Result := nil;
  +  s := pvPath;
  +
  +  lvParent := Self;
  +  sPtr := PChar(s);
  +  while sPtr^ <> #0 do
  +  begin
  +    lvName := GetFirst(sPtr, Path_SplitChars);
  +    if lvName = '' then
  +    begin
  +      Break;
  +    end else
  +    begin
  +      if sPtr^ = #0 then
  +      begin           // end
  +        Result := lvParent.ForceByName(lvName);
  +      end else
  +      begin
  +        // find or create childrean
  +        lvParent := lvParent.ForceByName(lvName);
  +      end;
  +    end;
  +    if sPtr^ = #0 then Break;
  +    Inc(sPtr);
  +  end;
  +end;
  +
  +function TDValueNode.GetItems(Index: Integer): TDValueNode;
  +begin
  +  Result := TDValueNode(FChildren[Index]);
  +end;
  +
   function TDValueNode.IndexOf(pvName: string): Integer;
  +var
  +  i:Integer;
   begin
     Result := -1;
  +  for i := 0 to FChildren.Count do
  +  begin
  +    if CompareText(Items[i].FName.AsString, pvName) = 0 then
  +    begin
  +      Result := i;
  +      Break;
  +    end;
  +  end;
  +end;
  +
  +function TDValueNode.InnerFindByPath(pvPath: string; var vParent:TDValueNode;
  +    var vIndex: Integer): TDValueNode;
  +var
  +  lvName:string;
  +  s:string;
  +  sPtr:PChar;
  +  lvTempObj, lvParent:TDValueNode;
  +  j:Integer;
  +begin
  +  s := pvPath;
  +
  +  Result := nil;
  +
  +  lvParent := Self;
  +  sPtr := PChar(s);
  +  while sPtr^ <> #0 do
  +  begin
  +    lvName := GetFirst(sPtr, ['.', '/','\']);
  +    if lvName = '' then
  +    begin
  +      Break;
  +    end else
  +    begin
  +      if sPtr^ = #0 then
  +      begin           // end
  +        j := lvParent.IndexOf(lvName);
  +        if j <> -1 then
  +        begin
  +          Result := lvParent.Items[j];
  +          vIndex := j;
  +          vParent := lvParent;
  +        end else
  +        begin
  +          Break;
  +        end;
  +      end else
  +      begin
  +        // find childrean
  +        lvTempObj := lvParent.FindByName(lvName);
  +        if lvTempObj = nil then
  +        begin
  +          Break;
  +        end else
  +        begin
  +          lvParent := lvTempObj;
  +        end;
  +      end;
  +    end;
  +    if sPtr^ = #0 then Break;
  +    Inc(sPtr);
  +  end;
   end;
   
   destructor TDValueItem.Destroy;
  
positive.code: function BinToHex(const ABytes: TBytes; ALowerCase: Boolean): DStringW;
  begin
    Result := BinToHex(@ABytes[0], Length(ABytes), ALowerCase);
  end;
  
  function GetDValueSize(ADValue: PDValueRecord): Integer;
  
negative.code: const
    TDValueNodeTypeStr: array[TDValueNodeType] of string = ('vntNull', 'vntArray', 'vntObject', 'vntValue');
  
    Path_SplitChars : TSysCharSet = ['.', '/' , '\'];
  
  
  type
    TDValueItem = class;
  