code: public function generate($sourceDocument, $targetDocument)
      {
          if ($sourceDocument === null || $targetDocument === null) {
              return $targetDocument;
          }
  
          if ($sourceDocument == new \stdClass()) {
              return null;
          }
  
          if (is_array($sourceDocument)) {
              if ($sourceDocument !== $targetDocument) {
                  return $targetDocument;
              }
  
              return null;
          }
  
          $patchDocument = new \stdClass();
          $sourceDocumentVars = get_object_vars($sourceDocument);
          $targetDocumentVars = get_object_vars($targetDocument);
  
          foreach ($targetDocumentVars as $var => $value) {
              if (!in_array($var, array_keys($sourceDocumentVars))
                  || !in_array($value, array_values($sourceDocumentVars))
              ) {
                  $patchDocument->$var = $value;
              }
          }
  
          foreach ($sourceDocumentVars as $var => $value) {
              if ($targetDocumentVars === []) {
                  $patchDocument->$var = null;
                  break;
              }
  
              if (is_object($value)) {
                  if ($sourceDocument->$var !== null && is_object($sourceDocument->$var)) {
                      $subPatch = $this->generate($sourceDocument->$var, $targetDocument->$var);
                      if ($subPatch !== null) {
                          $patchDocument->$var = $subPatch;
                      }
                  }
              } elseif (!in_array($var, array_keys($targetDocumentVars))
                        || !in_array($value, array_values($targetDocumentVars))) {
                  $sourceDocument->$var = null;
                  if (!in_array($var, array_keys($targetDocumentVars))) {
                      $patchDocument->$var = null;
                  }
              }
          }
  
          if (count(get_object_vars($patchDocument)) > 0) {
              return $patchDocument;
          }
  
          return null;
      }
docs: Generate patch for given source document via target document.
  
  @param mixed $sourceDocument
  @param mixed $targetDocument
  
  @return mixed