/**
  * Creates a value node for $value, and attaches it to the current subject of $writer.
  * If a value node for $value was already created, null is returned. Otherwise, the
  * value node's lname is returned, which should be used to generate detailed about the
  * value into the writer returned by getValueNodeWriter().
  *
  * When this method returns a non-null lname, the current subject of the RdfWriter returned by
  * getValueNodeWriter() will the be value node with that lname.
  *
  * @param RdfWriter $writer
  * @param string $propertyValueNamespace Property value relation namespace
  * @param string $propertyValueLName Property value relation name
  * @param string $dataType Property data type (unused, passed here for symmetry
  *        with the signature of ValueSnakRdfBuilder::addValue).
  * @param DataValue $value
  *
  * @return string|null The LName of the value node (in the RdfVocabulary::NS_VALUE namespace),
  *  or null if the value node should not be processed (generally, because it already has
  *  been processed).
  */
 public function attachValueNode(RdfWriter $writer, $propertyValueNamespace, $propertyValueLName, $dataType, DataValue $value)
 {
     $valueLName = $value->getHash();
     $writer->say(RdfVocabulary::$claimToValue[$propertyValueNamespace], $propertyValueLName)->is(RdfVocabulary::NS_VALUE, $valueLName);
     if ($this->dedupeBag->alreadySeen($valueLName, 'V') !== false) {
         return null;
     }
     $this->valueNodeWriter->about(RdfVocabulary::NS_VALUE, $valueLName)->a(RdfVocabulary::NS_ONTOLOGY, $this->vocabulary->getValueTypeName($value));
     return $valueLName;
 }
 /**
  * Adds the given Statement from the given Entity to the RDF graph.
  *
  * @param EntityId $entityId
  * @param Statement $statement
  * @param bool $isBest Is this best ranked statement?
  */
 private function addStatement(EntityId $entityId, Statement $statement, $isBest)
 {
     $statementLName = $this->vocabulary->getStatementLName($statement);
     $this->addMainSnak($entityId, $statementLName, $statement, $isBest);
     // XXX: separate builder for qualifiers?
     if ($this->produceQualifiers) {
         // this assumes statement was added by addMainSnak
         foreach ($statement->getQualifiers() as $q) {
             $this->snakBuilder->addSnak($this->statementWriter, $q, RdfVocabulary::NSP_QUALIFIER);
         }
     }
     // XXX: separate builder for references?
     if ($this->produceReferences) {
         /** @var Reference $reference */
         foreach ($statement->getReferences() as $reference) {
             //FIXME: split body into separate method
             $hash = $reference->getSnaks()->getHash();
             $refLName = $hash;
             $this->statementWriter->about(RdfVocabulary::NS_STATEMENT, $statementLName)->say(RdfVocabulary::NS_PROV, 'wasDerivedFrom')->is(RdfVocabulary::NS_REFERENCE, $refLName);
             if ($this->dedupeBag->alreadySeen($hash, 'R') !== false) {
                 continue;
             }
             $this->referenceWriter->about(RdfVocabulary::NS_REFERENCE, $refLName)->a(RdfVocabulary::NS_ONTOLOGY, 'Reference');
             foreach ($reference->getSnaks() as $refSnak) {
                 $this->snakBuilder->addSnak($this->referenceWriter, $refSnak, RdfVocabulary::NSP_REFERENCE);
             }
         }
     }
 }