protected function _graphToRDF($graph, $namer, $options) {
    $rval = array();

    $ids = array_keys((array)$graph);
    sort($ids);
    foreach($ids as $id) {
      $node = $graph->{$id};
      if($id === '"') {
        $id = '';
      }
      $properties = array_keys((array)$node);
      sort($properties);
      foreach($properties as $property) {
        $items = $node->{$property};
        if($property === '@type') {
          $property = self::RDF_TYPE;
        } else if(self::_isKeyword($property)) {
          continue;
        }

        foreach($items as $item) {
          // skip relative IRI subjects and predicates
          if(!(self::_isAbsoluteIri($id) && self::_isAbsoluteIri($property))) {
            continue;
          }

          // RDF subject
          $subject = new stdClass();
          $subject->type = (strpos($id, '_:') === 0) ? 'blank node' : 'IRI';
          $subject->value = $id;

          // RDF predicate
          $predicate = new stdClass();
          $predicate->type = (strpos($property, '_:') === 0 ?
            'blank node' : 'IRI');
          $predicate->value = $property;

          // skip bnode predicates unless producing generalized RDF
          if($predicate->type === 'blank node' &&
            !$options['produceGeneralizedRdf']) {
            continue;
          }

          if(self::_isList($item)) {
            // convert @list to triples
            $this->_listToRDF(
              $item->{'@list'}, $namer, $subject, $predicate, $rval);
          } else {
            // convert value or node object to triple
            $object = $this->_objectToRDF($item);
            // skip null objects (they are relative IRIs)
            if($object) {
              $rval[] = (object)array(
                'subject' => $subject,
                'predicate' => $predicate,
                'object' => $object);
            }
          }
        }
      }
    }

    return $rval;
  }