// Path: src/main/java/org/semanticweb/owl/explanation/api/ExplanationException.java
// public class ExplanationException extends OWLRuntimeException {
// 
// 
//     public ExplanationException(Throwable cause) {
//         super(cause);
//     }
// 
// 
//     public ExplanationException(String message) {
//         super(message);
//     }
// 
// 
//     public ExplanationException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: src/main/java/org/semanticweb/owl/explanation/api/RootDerivedReasoner.java
// public interface RootDerivedReasoner {
// 
//     /**
//      * Gets the root unsatisfiable classes.
//      * @return A set of classes that represent the root unsatisfiable classes
//      */
//     Set<OWLClass> getRootUnsatisfiableClasses() throws ExplanationException;
// 
//     Set<OWLClass> getDependentChildClasses(OWLClass cls);
// 
// 
//     Set<OWLClass> getDependentDescendantClasses(OWLClass cls);
// }


import org.semanticweb.owl.explanation.api.ExplanationException;
import org.semanticweb.owl.explanation.api.RootDerivedReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.search.EntitySearcher;
import java.util.*;

    private boolean dirty;


    public StructuralRootDerivedReasoner(OWLOntologyManager man, OWLReasoner reasoner, OWLReasonerFactory reasonerFactory) {
        this.man = man;
        this.reasonerFactory = reasonerFactory;
        this.reasoner = reasoner;
        this.child2Parent = new HashMap<OWLClass, Set<OWLClass>>();
        this.parent2Child = new HashMap<OWLClass, Set<OWLClass>>();
        roots = new HashSet<OWLClass>();

        try {
            getMergedOntology();
        }
        catch (ExplanationException e) {
            e.printStackTrace();
        }
        dirty = true;
    }


    public OWLOntology getMergedOntology() throws ExplanationException {
        try {
            if (mergedOntology == null) {
                mergedOntology = man.createOntology(IRI.create("owlapi:ontology:merge"), reasoner.getRootOntology().getImportsClosure(), true);
            }
            return mergedOntology;
        }
        catch (OWLOntologyCreationException e) {
// Path: src/main/java/org/semanticweb/owl/explanation/api/ExplanationException.java
// public class ExplanationException extends OWLRuntimeException {
// 
// 
//     public ExplanationException(Throwable cause) {
//         super(cause);
//     }
// 
// 
//     public ExplanationException(String message) {
//         super(message);
//     }
// 
// 
//     public ExplanationException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: src/main/java/org/semanticweb/owl/explanation/api/RootDerivedReasoner.java
// public interface RootDerivedReasoner {
// 
//     /**
//      * Gets the root unsatisfiable classes.
//      * @return A set of classes that represent the root unsatisfiable classes
//      */
//     Set<OWLClass> getRootUnsatisfiableClasses() throws ExplanationException;
// 
//     Set<OWLClass> getDependentChildClasses(OWLClass cls);
// 
// 
//     Set<OWLClass> getDependentDescendantClasses(OWLClass cls);
// }


// Path: src/main/java/org/semanticweb/owl/explanation/impl/rootderived/StructuralRootDerivedReasoner.java
import org.semanticweb.owl.explanation.api.ExplanationException;
import org.semanticweb.owl.explanation.api.RootDerivedReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.search.EntitySearcher;
import java.util.*;


    private boolean dirty;


    public StructuralRootDerivedReasoner(OWLOntologyManager man, OWLReasoner reasoner, OWLReasonerFactory reasonerFactory) {
        this.man = man;
        this.reasonerFactory = reasonerFactory;
        this.reasoner = reasoner;
        this.child2Parent = new HashMap<OWLClass, Set<OWLClass>>();
        this.parent2Child = new HashMap<OWLClass, Set<OWLClass>>();
        roots = new HashSet<OWLClass>();

        try {
            getMergedOntology();
        }
        catch (ExplanationException e) {
            e.printStackTrace();
        }
        dirty = true;
    }


    public OWLOntology getMergedOntology() throws ExplanationException {
        try {
            if (mergedOntology == null) {
                mergedOntology = man.createOntology(IRI.create("owlapi:ontology:merge"), reasoner.getRootOntology().getImportsClosure(), true);
            }
            return mergedOntology;
        }
        catch (OWLOntologyCreationException e) {
            throw new ExplanationException(e);