/**
  * Create the denormalization method
  *
  * @param $modelFqdn
  * @param Context  $context
  * @param $properties
  *
  * @return Stmt\ClassMethod
  */
 protected function createDenormalizeMethod($modelFqdn, Context $context, $properties)
 {
     $context->refreshScope();
     $objectVariable = new Expr\Variable('object');
     $statements = [new Stmt\If_(new Expr\Empty_(new Expr\Variable('data')), ['stmts' => [new Stmt\Return_(new Expr\ConstFetch(new Name("null")))]]), new Stmt\If_(new Expr\Isset_([new Expr\PropertyFetch(new Expr\Variable('data'), "{'\$ref'}")]), ['stmts' => [new Stmt\Return_(new Expr\New_(new Name('Reference'), [new Expr\PropertyFetch(new Expr\Variable('data'), "{'\$ref'}"), new Expr\Ternary(new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema')), null, new Expr\ConstFetch(new Name("null")))]))]]), new Expr\Assign($objectVariable, new Expr\New_(new Name("\\" . $modelFqdn))), new Stmt\If_(new Expr\BooleanNot(new Expr\Isset_([new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema'))])), ['stmts' => [new Expr\Assign(new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema')), $objectVariable)]])];
     foreach ($properties as $property) {
         $propertyVar = new Expr\PropertyFetch(new Expr\Variable('data'), sprintf("{'%s'}", $property->getName()));
         list($denormalizationStatements, $outputVar) = $property->getType()->createDenormalizationStatement($context, $propertyVar);
         $statements[] = new Stmt\If_(new Expr\FuncCall(new Name('property_exists'), [new Arg(new Expr\Variable('data')), new Arg(new Scalar\String_($property->getName()))]), ['stmts' => array_merge($denormalizationStatements, [new Expr\MethodCall($objectVariable, $this->getNaming()->getPrefixedMethodName('set', $property->getName()), [$outputVar])])]);
     }
     $statements[] = new Stmt\Return_($objectVariable);
     return new Stmt\ClassMethod('denormalize', ['type' => Stmt\Class_::MODIFIER_PUBLIC, 'params' => [new Param('data'), new Param('class'), new Param('format', new Expr\ConstFetch(new Name("null"))), new Param('context', new Expr\Array_(), 'array')], 'stmts' => $statements]);
 }
 /**
  * Create the normalization method.
  *
  * @param $modelFqdn
  * @param Context $context
  * @param $properties
  *
  * @return Stmt\ClassMethod
  */
 protected function createNormalizeMethod($modelFqdn, Context $context, $properties)
 {
     $context->refreshScope();
     $dataVariable = new Expr\Variable('data');
     $statements = [new Expr\Assign($dataVariable, new Expr\New_(new Name('\\stdClass')))];
     /** @var Property $property */
     foreach ($properties as $property) {
         $propertyVar = new Expr\MethodCall(new Expr\Variable('object'), $this->getNaming()->getPrefixedMethodName('get', $property->getName()));
         list($normalizationStatements, $outputVar) = $property->getType()->createNormalizationStatement($context, $propertyVar);
         $normalizationStatements[] = new Expr\Assign(new Expr\PropertyFetch($dataVariable, sprintf("{'%s'}", $property->getName())), $outputVar);
         if ($property->isNullable()) {
             $statements = array_merge($statements, $normalizationStatements);
             continue;
         }
         $statements[] = new Stmt\If_(new Expr\BinaryOp\NotIdentical(new Expr\ConstFetch(new Name('null')), $propertyVar), ['stmts' => $normalizationStatements]);
     }
     $statements[] = new Stmt\Return_($dataVariable);
     return new Stmt\ClassMethod('normalize', ['type' => Stmt\Class_::MODIFIER_PUBLIC, 'params' => [new Param('object'), new Param('format', new Expr\ConstFetch(new Name('null'))), new Param('context', new Expr\Array_(), 'array')], 'stmts' => $statements]);
 }