protected MGraph getOntologyAsMGraph(
      OWLOntologyID ontologyId, boolean merge, IRI universalPrefix) {
    if (merge)
      throw new UnsupportedOperationException(
          "Merge not implemented yet for Clerezza triple collections.");
    /*
     * TODO manage import rewrites better once the container ID is fully configurable (i.e. instead of
     * going upOne() add "session" or "ontology" if needed). But only do this if we keep considering
     * imported ontologies as *not* managed.
     */
    // if (!merge) { // TODO
    MGraph o =
        new IndexedMGraph(ontologyProvider.getStoredOntology(ontologyId, MGraph.class, merge));

    // Now rewrite import statements

    // Scan import statements for each owl:Ontology instance (hopefully one).
    String tid = getID();
    // Bit of a hack : since ontology spaces are named like {scopeid}/{core|custom}, in that
    // particular
    // case we go back to {scopeid}, whereas for sessions we maintain their original id.
    if (backwardPathLength > 0) tid = tid.split("/")[0];

    Iterator<Triple> it;
    List<Triple> newImports = new LinkedList<Triple>();
    synchronized (o) {
      it = o.filter(null, OWL.imports, null);
      // We use this list to avoid concurrent modification exceptions.
      List<Triple> replaceUs = new LinkedList<Triple>();
      while (it.hasNext()) replaceUs.add(it.next());

      for (Triple t : replaceUs) {
        String s = ((UriRef) (t.getObject())).getUnicodeString();
        // FIXME note the different import targets in the OWLOntology and TripleColllection objects!
        // s = s.substring(s.indexOf("::") + 2, s.length());
        boolean managed = managedOntologies.contains(IRI.create(s));
        UriRef target =
            new UriRef(
                (managed
                        ? universalPrefix + "/" + tid + "/"
                        : URIUtils.upOne(universalPrefix) + "/")
                    + s);
        o.remove(t);
        newImports.add(new TripleImpl(t.getSubject(), OWL.imports, target));
      }
    }

    for (Triple t : newImports) o.add(t);

    // } // TODO else if (merge)

    return o;
  }
  protected OWLOntology getOntologyAsOWLOntology(
      OWLOntologyID ontologyId, boolean merge, IRI universalPrefix) {
    // if (merge) throw new UnsupportedOperationException("Merge not implemented yet for
    // OWLOntology.");

    // Remove the check below. It might be an unmanaged dependency (TODO remove from collector and
    // reintroduce check?).
    // if (!hasOntology(ontologyIri)) return null;
    OWLOntology o;
    o = ontologyProvider.getStoredOntology(ontologyId, OWLOntology.class, merge);

    if (merge) {
      final Set<OWLOntology> set = new HashSet<OWLOntology>();
      log.debug("Merging {} with its imports, if any.", o);
      set.add(o);
      // Actually, if the provider already performed the merge, this won't happen
      for (OWLOntology impo : o.getImportsClosure()) {
        log.debug("Imported ontology {} will be merged with {}.", impo, o);
        set.add(impo);
      }
      OWLOntologySetProvider provider =
          new OWLOntologySetProvider() {
            @Override
            public Set<OWLOntology> getOntologies() {
              return set;
            }
          };
      OWLOntologyMerger merger = new OWLOntologyMerger(provider);
      try {
        o =
            merger.createMergedOntology(
                OWLManager.createOWLOntologyManager(), ontologyId.getOntologyIRI());
      } catch (OWLOntologyCreationException e) {
        log.error("Failed to merge imports for ontology " + ontologyId, e);
        // do not reassign the root ontology
      }
    } else {
      // Rewrite import statements
      List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>();
      OWLDataFactory df = OWLManager.getOWLDataFactory();

      /*
       * TODO manage import rewrites better once the container ID is fully configurable (i.e. instead of
       * going upOne() add "session" or "ontology" if needed). But only do this if we keep considering
       * imported ontologies as *not* managed.
       */
      for (OWLImportsDeclaration oldImp : o.getImportsDeclarations()) {
        changes.add(new RemoveImport(o, oldImp));
        String s = oldImp.getIRI().toString();
        // FIXME Ugly way to check, but we'll get through with it
        if (s.contains("::")) s = s.substring(s.indexOf("::") + 2, s.length());
        boolean managed = managedOntologies.contains(oldImp.getIRI());
        // For space, always go up at least one

        String tid = getID();
        if (backwardPathLength > 0) tid = tid.split("/")[0];

        IRI target =
            IRI.create(
                (managed
                        ? universalPrefix + "/" + tid + "/"
                        : URIUtils.upOne(universalPrefix) + "/")
                    + s);
        changes.add(new AddImport(o, df.getOWLImportsDeclaration(target)));
      }
      o.getOWLOntologyManager().applyChanges(changes);
    }

    return o;
  }
  /**
   * This method has no conversion calls, to it can be invoked by subclasses that wish to modify it
   * afterwards.
   *
   * <p>FIXME not merging yet FIXME not including imported ontologies unless they are merged
   * *before* storage.
   *
   * @param merge
   * @return
   */
  protected OWLOntology exportToOWLOntology(boolean merge, IRI prefix) {

    long before = System.currentTimeMillis();

    // Create a new ontology
    OWLOntology root;
    OWLOntologyManager ontologyManager = OWLManager.createOWLOntologyManager();
    IRI iri = IRI.create(prefix + _id);
    try {
      root = ontologyManager.createOntology(iri);
    } catch (OWLOntologyAlreadyExistsException e) {
      // It should be impossible, but just in case.
      ontologyManager.removeOntology(ontologyManager.getOntology(iri));
      try {
        root = ontologyManager.createOntology(iri);
      } catch (OWLOntologyAlreadyExistsException e1) {
        root = ontologyManager.getOntology(iri);
      } catch (OWLOntologyCreationException e1) {
        log.error("Failed to assemble root ontology for scope " + iri, e);
        root = null;
      }
    } catch (OWLOntologyCreationException e) {
      log.error("Failed to assemble root ontology for scope " + _id, e);
      root = null;
    }

    // Add the import declarations for directly managed ontologies.
    if (root != null) {

      if (merge) {

        final Set<OWLOntology> set = new HashSet<OWLOntology>();
        log.debug("Merging {} with its imports.", root);
        set.add(root);

        for (OWLOntologyID ontologyId : managedOntologies) {
          log.debug("Merging {} with {}.", ontologyId, root);
          set.add(getOntology(ontologyId, OWLOntology.class, true));
        }

        OWLOntologySetProvider provider =
            new OWLOntologySetProvider() {
              @Override
              public Set<OWLOntology> getOntologies() {
                return set;
              }
            };
        OWLOntologyMerger merger = new OWLOntologyMerger(provider);
        try {
          root = merger.createMergedOntology(OWLManager.createOWLOntologyManager(), iri);

        } catch (OWLOntologyCreationException e) {
          log.error("Failed to merge imports for ontology " + iri, e);
          root = null;
        }

      } else {
        // Add the import declarations for directly managed ontologies.
        List<OWLOntologyChange> changes = new LinkedList<OWLOntologyChange>();
        OWLDataFactory df = ontologyManager.getOWLDataFactory();

        String base = prefix + getID();
        for (int i = 0; i < backwardPathLength; i++)
          base = URIUtils.upOne(URI.create(base)).toString();
        base += "/";

        // The key set of managedOntologies contains the ontology IRIs, not their storage keys.
        for (OWLOntologyID ontologyId : managedOntologies) {
          // XXX some day the versionIRI will be the only physical reference for the ontology
          IRI physIRI = IRI.create(base + OntologyUtils.encode(ontologyId));
          changes.add(new AddImport(root, df.getOWLImportsDeclaration(physIRI)));
        }
        ontologyManager.applyChanges(changes);
      }
    }
    log.debug("OWL export of {} completed in {} ms.", getID(), System.currentTimeMillis() - before);

    return root;
  }
  /**
   * This method has no conversion calls, to it can be invoked by subclasses that wish to modify it
   * afterwards.
   *
   * @param merge
   * @return
   */
  protected MGraph exportToMGraph(boolean merge, IRI prefix) {
    // if (merge) throw new UnsupportedOperationException(
    // "Merge not implemented yet for Clerezza triple collections.");

    long before = System.currentTimeMillis();

    // No need to store, give it a name, or anything.
    MGraph root = new SimpleMGraph();
    UriRef iri = new UriRef(prefix + _id);
    // Add the import declarations for directly managed ontologies.
    if (root != null) {
      // Set the ontology ID
      root.add(new TripleImpl(iri, RDF.type, OWL.Ontology));

      if (merge) {
        log.warn(
            "Merging of Clerezza triple collections is only implemented one level down. Import statements will be preserved for further levels.");
        Iterator<Triple> it;
        Set<Resource> importTargets = new HashSet<Resource>();
        for (OWLOntologyID ontologyId : managedOntologies) {
          Graph g = getOntology(ontologyId, Graph.class, false);
          root.addAll(g);

          it = g.filter(null, OWL.imports, null);
          while (it.hasNext()) {
            IRI tgt;
            Resource r = it.next().getObject();
            try {
              if (r instanceof UriRef) tgt = IRI.create(((UriRef) r).getUnicodeString());
              else if (r instanceof Literal) tgt = IRI.create(((Literal) r).getLexicalForm());
              else tgt = IRI.create(r.toString());
              tgt = URIUtils.sanitize(tgt);
              importTargets.add(new UriRef(tgt.toString()));
            } catch (Exception ex) {
              log.error("FAILED to obtain import target from resource {}", r);
              continue;
            }
          }

          it = g.filter(null, RDF.type, OWL.Ontology);
          while (it.hasNext()) {
            NonLiteral ontology = it.next().getSubject();
            log.debug("Removing all triples related to {} from {}", ontology, iri);
            Iterator<Triple> it2 = g.filter(ontology, null, null);
            while (it2.hasNext()) root.remove(it2.next());
          }

          /*
           * Reinstate import statements, though. If imported ontologies were not merged earlier, we
           * are not doing it now anyway.
           */
          for (Resource target : importTargets) root.add(new TripleImpl(iri, OWL.imports, target));
        }

      } else {

        String base = prefix + getID();
        for (int i = 0; i < backwardPathLength; i++)
          base = URIUtils.upOne(URI.create(base)).toString();
        base += "/";

        // The key set of managedOntologies contains the ontology IRIs, not their storage keys.
        for (OWLOntologyID ontologyId : managedOntologies) {
          IRI physIRI =
              // ontologyId.getVersionIRI() == null ? URIUtils.sanitize(IRI
              // .create(base + ontologyId.getOntologyIRI())) : URIUtils.sanitize(IRI
              // .create(base + ontologyId.getVersionIRI()));
              IRI.create(base + OntologyUtils.encode(ontologyId));
          root.add(new TripleImpl(iri, OWL.imports, new UriRef(physIRI.toString())));
        }
      }

      log.debug(
          "Clerezza export of {} completed in {} ms.",
          getID(),
          System.currentTimeMillis() - before);
    }

    return root;
  }