@Override
 public boolean hasOntology(OWLOntologyID ontologyId) {
   Set<OWLOntologyID> aliases = ontologyProvider.listAliases(ontologyId);
   if (managedOntologies.contains(ontologyId)) return true;
   for (OWLOntologyID alias : aliases) if (managedOntologies.contains(alias)) return true;
   return false;
 }
  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;
  }
  @Override
  public void removeOntology(OWLOntologyID publicKey)
      throws OntologyCollectorModificationException {
    if (publicKey == null)
      throw new IllegalArgumentException(
          "Cannot remove an ontology by providing a null public key.");
    if (publicKey.getOntologyIRI() == null)
      throw new IllegalArgumentException(
          "Cannot remove an ontology whose public key has a null ontology IRI.");
    if (locked) throw new UnmodifiableOntologyCollectorException(this);

    Set<OWLOntologyID> aliases = ontologyProvider.listAliases(publicKey);
    aliases.add(publicKey);
    boolean removed = false;
    for (OWLOntologyID alias : aliases) removed |= managedOntologies.remove(alias);
    // Don't fire if the ontology wasn't there in the first place.
    if (removed) fireOntologyRemoved(publicKey);
    else throw new MissingOntologyException(this, publicKey);
  }
  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;
  }
  @Override
  public synchronized OWLOntologyID addOntology(OntologyInputSource<?> ontologySource)
      throws UnmodifiableOntologyCollectorException {

    // Check for error conditions.
    if (locked) throw new UnmodifiableOntologyCollectorException(this);
    if (ontologySource == null)
      throw new IllegalArgumentException("Ontology source cannot be null.");

    log.debug("Adding ontology to collector {}", getID());
    OWLOntologyID key = null;

    if (ontologySource.hasRootOntology()) {
      long before = System.currentTimeMillis();
      Object o = ontologySource.getRootOntology();
      // // FIXME restore ownership management, but maybe not by directly setting the versionIRI
      // if (ontologyProvider.hasOntology(id.getOntologyIRI())) if (o instanceof MGraph)
      // claimOwnership((MGraph) o);
      // else if (o instanceof OWLOntology) claimOwnership((OWLOntology) o);

      // Check the origin anyhow, as it may be useful for setting aliases with physical locations
      // etc.
      if (ontologySource.hasOrigin())
        key = ontologyProvider.loadInStore(o, false, ontologySource.getOrigin());
      else key = ontologyProvider.loadInStore(o, false);
      if (key != null) {
        managedOntologies.add(key);
        // Note that imported ontologies are not considered as managed! TODO should we change this?
        log.info("Add ontology completed in {} ms.", (System.currentTimeMillis() - before));
        // Fire the event
        fireOntologyAdded(key);
      }
    } else if (ontologySource.hasOrigin()) {
      // Just the origin : see if it is satisfiable
      log.debug("Checking origin satisfiability...");
      Origin<?> origin = ontologySource.getOrigin();
      Object ref = origin.getReference();
      log.debug("Origin wraps a {}", ref.getClass().getCanonicalName());
      if (ref instanceof IRI)
        try {
          log.debug("Deferring addition to physical IRI {} (if available).", ref);
          key = addOntology(new RootOntologySource((IRI) ref));
        } catch (OWLOntologyCreationException e) {
          throw new RuntimeException(e);
        }
      else if (ref instanceof UriRef) {
        log.debug("Deferring addition to stored Clerezza graph {} (if available).", ref);
        key = addOntology(new GraphSource((UriRef) ref));
      } else if (ref instanceof OWLOntologyID) {
        OWLOntologyID idref = (OWLOntologyID) ref;
        log.debug("Deferring addition to stored ontology with public key {} (if available).", ref);
        if (!ontologyProvider.hasOntology(idref)) throw new MissingOntologyException(this, idref);
        key = idref;
        if (managedOntologies.add(idref)) fireOntologyAdded(idref);
      } else throw new IllegalArgumentException("Invalid origin " + origin);
    } else
      throw new IllegalArgumentException(
          "Ontology source must provide either an ontology object, or a way to reference one (i.e. an origin).");
    log.info("Public key : {}", key);
    return key;
  }