protected function generateProperty($propertyName, array $data, $directory, array $dataTypes)
    {
        $property = $this->getPropertyClassName($propertyName);

        $class = new PhpClass();
        $class
            ->setQualifiedName('SecIT\\SchemaOrg\\Mapping\\Property\\'.$property)
            ->setParentClassName('AbstractProperty')
            ->setDescription($property.' class.'."\n\n".'@method '.$property.' setValue($value)')
            ->setMethod(PhpMethod::create('getSchemaUrl')
                ->setDescription('Get schema URL.')
                ->setType('string')
                ->setBody('return \''.$data['url'].'\';')
            )
        ;

        if ($this->backwardCompatibility && !$this->php7ClassNames) {
            $this->php7ClassNames = true;
            $deprecatedMessage = 'This class is deprecated and will be removed in release 3.4. Use SecIT\\SchemaOrg\\Mapping\\Property\\'.$this->getPropertyClassName($propertyName).' instead.';
            $this->php7ClassNames = false;
            $class->setDescription($class->getDescription()."\n\n".'@deprecated '.$deprecatedMessage);
        }

        $instanceCheckConditions = [];
        foreach ($data['ranges'] as $range) {
            if (isset($dataTypes[$range])) {
                $class->addUseStatement('SecIT\\SchemaOrg\\Mapping\\DataType');
                $instanceCheckConditions[] = '$value instanceof DataType\\'.$this->getDataTypeClassName($range);
            } else {
                $class->addUseStatement('SecIT\\SchemaOrg\\Mapping\\Type');
                $instanceCheckConditions[] = '$value instanceof Type\\'.$this->getTypeClassName($range);
            }
        }

        // if no conditions than always return true
        if (!$instanceCheckConditions) {
            $instanceCheckConditions[] = 'true';
        }

        $class
            ->setMethod(PhpMethod::create('isValueValid')
                ->setDescription('Check is value valid.')
                ->addParameter(PhpParameter::create('value')
                    ->setType('string')
                )
                ->setType('bool')
                ->setBody('return '.implode(' || ', $instanceCheckConditions).';')
            )
        ;

        $generator = new CodeGenerator();
        $code = $generator->generate($class);

        file_put_contents($directory.$property.'.php', "<?php\n\n".$code);
    }