docs: public Set<Explanation<OWLAxiom>> getExplanations(OWLAxiom entailment, int limit) throws ExplanationException {
  
          numberOfOPlusJustificationsFound = 0;
          
          TelemetryTimer computeOplusTimer = new TelemetryTimer();
          TelemetryTimer computeOplusJustificationsTimer = new TelemetryTimer();
          TelemetryTimer islaconicTimer = new TelemetryTimer();
          TelemetryTimer reconstituteTimer = new TelemetryTimer();
          TelemetryTimer ispreferredCheckTimer = new TelemetryTimer();
  
          TelemetryInfo info = new DefaultTelemetryInfo(getClass().getSimpleName(), computeOplusTimer, computeOplusJustificationsTimer, islaconicTimer, reconstituteTimer, ispreferredCheckTimer);
          TelemetryTransmitter transmitter = TelemetryTransmitter.getTransmitter();
          transmitter.beginTransmission(info);
  
          transmitter.recordMeasurement(info, "oplus splitting", oplusSplitting.toString());
  
          transmitter.recordMeasurement(info, "input type", modularityTreatment.toString());
  
          final Set<Explanation<OWLAxiom>> preferredLaconicExplanations;
          try {
              OWLDataFactory dataFactory = new OWLDataFactoryImpl();
  
              OPlusGenerator transformation = new OPlusGenerator(dataFactory, oplusSplitting);
              OWLOntologyManager man = OWLManager.createOWLOntologyManager();
  
              transmitter.recordMeasurement(info, "input axioms size", inputAxioms.size());
  
              Set<OWLAxiom> oplusInput;
              if (modularityTreatment.equals(ModularityTreatment.MODULE)) {
                  SyntacticLocalityModuleExtractor extractor = new SyntacticLocalityModuleExtractor(man, (OWLOntology) null, inputAxioms, ModuleType.STAR);
                  oplusInput = extractor.extract(entailment.getSignature());
              }
              else {
                  oplusInput = new HashSet<OWLAxiom>(inputAxioms);
              }
  
              transmitter.recordMeasurement(info, "module size", oplusInput.size());
  
              computeOplusTimer.start();
              Set<OWLAxiom> oplusAxiomsRaw = transformation.transform(oplusInput);
              computeOplusTimer.stop();
              transmitter.recordTiming(info, "time to compute oplus", computeOplusTimer);
  
  
              transmitter.recordMeasurement(info, "oplus axioms size", oplusAxiomsRaw.size());
  
              Set<OWLAxiom> oplusAxioms = new HashSet<OWLAxiom>(oplusAxiomsRaw);
  
              ExplanationGenerator<OWLAxiom> gen = delegateFactory.createExplanationGenerator(oplusAxioms, new MediatingProgresssMonitor());
  
              computeOplusJustificationsTimer.start();
              Set<Explanation<OWLAxiom>> oplusExpls = gen.getExplanations(entailment);
              computeOplusJustificationsTimer.stop();
              transmitter.recordTiming(info, "time to compute oplus justifications", computeOplusJustificationsTimer);
  
  
  
  
              IsLaconicChecker checker = new IsLaconicChecker(dataFactory, entailmentCheckerFactory, LaconicCheckerMode.EARLY_TERMINATING);
              Set<Explanation<OWLAxiom>> laconicExplanations = new HashSet<Explanation<OWLAxiom>>();
  
              islaconicTimer.start();
              for (Explanation<OWLAxiom> expl : oplusExpls) {
                  if(progressMonitor.isCancelled()) {
                      throw new ExplanationGeneratorInterruptedException();
                  }
                  if (checker.isLaconic(expl)) {
                      laconicExplanations.add(expl);
                  }
              }
              islaconicTimer.stop();
              transmitter.recordTiming(info, "time to check laconic oplus justifications", islaconicTimer);
  
              transmitter.recordMeasurement(info, "number of laconic oplus justifications", laconicExplanations.size());
  
  
              reconstituteTimer.start();
              Set<Explanation<OWLAxiom>> reconstitutedLaconicExpls = getReconstitutedExplanations(dataFactory, transformation, laconicExplanations);
              reconstituteTimer.stop();
              transmitter.recordTiming(info, "time to reconstitute justifications", reconstituteTimer);
  
              transmitter.recordMeasurement(info, "number of reconstituted justifications", reconstitutedLaconicExpls.size());
  
  
              preferredLaconicExplanations = new HashSet<Explanation<OWLAxiom>>();
  
              Map<Explanation<OWLAxiom>, Set<OWLAxiom>> oplusCache = new HashMap<Explanation<OWLAxiom>, Set<OWLAxiom>>();
  
  
              ispreferredCheckTimer.start();
              Set<Explanation<OWLAxiom>> toFilter = new HashSet<Explanation<OWLAxiom>>();
              List<Explanation<OWLAxiom>> explsList = new ArrayList<Explanation<OWLAxiom>>(reconstitutedLaconicExpls);
              for (int i = 0; i < explsList.size(); i++) {
                  for (int j = i + 1; j < explsList.size(); j++) {
                      Explanation<OWLAxiom> explI = explsList.get(i);
                      Explanation<OWLAxiom> explJ = explsList.get(j);
                      Set<OWLAxiom> oplusI = oplusCache.get(explI);
                      if (oplusI == null) {
                          OPlusGenerator generator = new OPlusGenerator(dataFactory, OPlusSplitting.NONE);
                          oplusI = generator.transform(explI.getAxioms());
                          oplusCache.put(explI, oplusI);
                      }
                      Set<OWLAxiom> oplusJ = oplusCache.get(explJ);
                      if (oplusJ == null) {
                          OPlusGenerator generator = new OPlusGenerator(dataFactory, OPlusSplitting.NONE);
                          oplusJ = generator.transform(explJ.getAxioms());
                          oplusCache.put(explJ, oplusJ);
                      }
                      if (oplusI.containsAll(oplusJ) || oplusJ.containsAll(oplusI)) {
                          toFilter.add(explI);
                          toFilter.add(explJ);
                      }
                  }
              }
  
              preferredLaconicExplanations.addAll(reconstitutedLaconicExpls);
              preferredLaconicExplanations.removeAll(toFilter);
  
              transmitter.recordMeasurement(info, "number of non-check preferred laconic justifications", preferredLaconicExplanations.size());
              transmitter.recordMeasurement(info, "number of check laconic justifications", toFilter.size());
  
  //        System.out.println("I have found " + toFilter.size() + " explanations that require filtering");
  //        System.out.println("This means that I already know that there are " + preferredLaconicExplanations.size() + " preferred laconic explanations");
  
  
  
              for (final Explanation<OWLAxiom> laconicExpl : toFilter) {
                  Set<OWLAxiom> sources = getSourceAxioms(laconicExpl, transformation);
                  ExplanationGenerator<OWLAxiom> explanationGenerator = delegateFactory.createExplanationGenerator(sources);
                  Set<Explanation<OWLAxiom>> regularExpls = explanationGenerator.getExplanations(laconicExpl.getEntailment());
      //            System.out.println("From the axiom sources I have found " + regularExpls.size() + " regular justifications");
                  try {
                      for (Explanation<OWLAxiom> regularExpl : regularExpls) {
  
                          int size = preferredLaconicExplanations.size();
                          LaconicExplanationGeneratorBasedOnDeltaPlus lacGen = new LaconicExplanationGeneratorBasedOnDeltaPlus(regularExpl.getAxioms(), entailmentCheckerFactory, delegateFactory, new ExplanationProgressMonitor<OWLAxiom>() {
  
                              private boolean cancelled = false;
  
                              public void foundExplanation(ExplanationGenerator<OWLAxiom> owlAxiomExplanationGenerator, Explanation<OWLAxiom> owlAxiomExplanation, Set<Explanation<OWLAxiom>> allFoundExplanations) {
                                  if (owlAxiomExplanation.equals(laconicExpl)) {
                                      preferredLaconicExplanations.add(laconicExpl);
                                      cancelled = true;
                                  }
                              }
  
                              public boolean isCancelled() {
                                  return cancelled;
                              }
                          });
                          Set<Explanation<OWLAxiom>> deltaPlusGeneratedExpls = lacGen.getExplanations(laconicExpl.getEntailment());
  
  
                          if (preferredLaconicExplanations.size() != size) {
                              break;
                          }
                      }
                  }
                  catch (ExplanationGeneratorInterruptedException e) {
                      System.out.println("Early termination");
                  }
              }
              ispreferredCheckTimer.stop();
  
              final Set<Explanation<OWLAxiom>> progressFound = new HashSet<Explanation<OWLAxiom>>();
              for (Explanation<OWLAxiom> expl : preferredLaconicExplanations) {
                  progressFound.add(expl);
                  progressMonitor.foundExplanation(this, expl, progressFound);
              }
  
  
              transmitter.recordTiming(info, "time to check preferred laconic justifications", ispreferredCheckTimer);
  
              transmitter.recordMeasurement(info, "number of preferred laconic justifications", preferredLaconicExplanations.size());
          }
          finally {
              transmitter.recordMeasurement(info, "number of oplus justifications", numberOfOPlusJustificationsFound);
              transmitter.endTransmission(info);
          }
          return preferredLaconicExplanations;
  
      }