// DONE
 @Override
 public void visit(OWLObjectUnionOf desc) {
   int reduceTo = this.rebuiltObjects.size();
   for (OWLDescription operand : desc.getOperands()) {
     operand.accept(this);
   }
   HashSet<OWLDescription> ds = this.getRelevantDescriptionsAsSet(reduceTo);
   this.rebuiltObjects.add(this.factory.getOWLObjectUnionOf(ds));
 }
 public void visit(OWLObjectUnionOf owlOr) {
   try {
     // We can't do "nested" arg lists, so translate all operands
     // and put the pointers into a set first, then create the intersection
     Set<ClassPointer> operandPointers = new HashSet<ClassPointer>();
     for (OWLDescription desc : owlOr.getOperands()) {
       desc.accept(this);
       operandPointers.add(getLastClassPointer());
     }
     faCTPlusPlus.initArgList();
     for (ClassPointer operandPointer : operandPointers) {
       faCTPlusPlus.addArg(operandPointer);
     }
     faCTPlusPlus.closeArgList();
     lastClassPointer = faCTPlusPlus.getConceptOr();
   } catch (Exception e) {
     throw new FaCTPlusPlusRuntimeException(e);
   }
 }
  protected OWLDescription doReplacing(GenericOWLDescriptionRewritingContext context) {
    // cast down the replacment context

    OWLDescription initialTerm =
        ((PartialDescriptionRewritingApproximationTypeContext) context).getOwlDescription();
    ApproximationType approximationType =
        ((PartialDescriptionRewritingApproximationTypeContext) context).getApproximationType();
    Set<URI> notS = ((PartialDescriptionRewritingApproximationTypeContext) context).getNotS();

    // perform replacement if possible
    OWLDescription replacement =
        getRewritingStrategy()
            .rewrite(
                new PartialDescriptionRewritingApproximationTypeContext(
                    initialTerm, approximationType, notS));

    if (replacement == null) {
      // there is a replacement for this term
      throw new IllegalArgumentException("Rewritingstrategy never should deliver null back");
    }
    // recurse down the object tree

    // If the term is negated, change the approx-type
    if (replacement instanceof OWLObjectComplementOf) {
      OWLObjectComplementOf complement = (OWLObjectComplementOf) replacement;
      OWLDescription filler = complement.getOperand();

      if (filler instanceof OWLObjectIntersectionOf) {
        OWLObjectIntersectionOf intersection = (OWLObjectIntersectionOf) filler;

        Set<OWLDescription> subterms = new HashSet<OWLDescription>();

        // recurse into operands
        for (OWLDescription subTerm : intersection.getOperands()) {
          subterms.add(
              doReplacing(
                  new PartialDescriptionRewritingApproximationTypeContext(
                      subTerm, approximationType.invert(), notS)));
        }

        // return a freshly constructed Complementobject with intersection
        return getOwlDataFactory()
            .getOWLObjectComplementOf(getOwlDataFactory().getOWLObjectIntersectionOf(subterms));

      } else if (filler instanceof OWLObjectUnionOf) {
        OWLObjectUnionOf union = (OWLObjectUnionOf) filler;
        Set<OWLDescription> subterms = new HashSet<OWLDescription>();

        // recurse into operands
        for (OWLDescription subTerm : union.getOperands()) {
          subterms.add(
              doReplacing(
                  new PartialDescriptionRewritingApproximationTypeContext(
                      subTerm, approximationType.invert(), notS)));
        }

        // return a freshly constructed Complementobject with intersection
        return getOwlDataFactory()
            .getOWLObjectComplementOf(getOwlDataFactory().getOWLObjectUnionOf(subterms));

      } else if (filler instanceof OWLObjectMaxCardinalityRestriction) {
        OWLObjectMaxCardinalityRestriction maxR = (OWLObjectMaxCardinalityRestriction) replacement;
        // recurse into subterm
        // return a freshly constructed Complementobject with intersection
        return getOwlDataFactory()
            .getOWLObjectComplementOf(
                getOwlDataFactory()
                    .getOWLObjectMaxCardinalityRestriction(
                        maxR.getProperty(),
                        maxR.getCardinality(),
                        doReplacing(
                            new PartialDescriptionRewritingApproximationTypeContext(
                                maxR.getFiller(), approximationType.invert().invert(), notS))));

      } else if (filler instanceof OWLObjectMinCardinalityRestriction) {
        OWLObjectMinCardinalityRestriction minR = (OWLObjectMinCardinalityRestriction) replacement;
        return getOwlDataFactory()
            .getOWLObjectComplementOf(
                getOwlDataFactory()
                    .getOWLObjectMinCardinalityRestriction(
                        minR.getProperty(),
                        minR.getCardinality(),
                        doReplacing(
                            new PartialDescriptionRewritingApproximationTypeContext(
                                minR.getFiller(), approximationType.invert(), notS))));
      }

    } else { // term is not negatated
      if (replacement instanceof OWLObjectIntersectionOf) {
        OWLObjectIntersectionOf intersection = (OWLObjectIntersectionOf) replacement;

        Set<OWLDescription> subterms = new HashSet<OWLDescription>();

        // recurse into operands
        for (OWLDescription subTerm : intersection.getOperands()) {
          subterms.add(
              doReplacing(
                  new PartialDescriptionRewritingApproximationTypeContext(
                      subTerm, approximationType, notS)));
        }

        // return a freshly constructed intersection
        return getOwlDataFactory().getOWLObjectIntersectionOf(subterms);

      } else if (replacement instanceof OWLObjectUnionOf) {
        OWLObjectUnionOf union = (OWLObjectUnionOf) replacement;
        Set<OWLDescription> subterms = new HashSet<OWLDescription>();

        // recurse into operands
        for (OWLDescription subTerm : union.getOperands()) {
          subterms.add(
              doReplacing(
                  new PartialDescriptionRewritingApproximationTypeContext(
                      subTerm, approximationType, notS)));
        }

        // return a freshly constructed Complementobject with intersection
        return getOwlDataFactory().getOWLObjectUnionOf(subterms);

      } else if (replacement instanceof OWLObjectMaxCardinalityRestriction) {
        OWLObjectMaxCardinalityRestriction maxR = (OWLObjectMaxCardinalityRestriction) replacement;
        // recurse into subterm
        // return a freshly constructed Complementobject with intersection
        return getOwlDataFactory()
            .getOWLObjectMaxCardinalityRestriction(
                maxR.getProperty(),
                maxR.getCardinality(),
                doReplacing(
                    new PartialDescriptionRewritingApproximationTypeContext(
                        maxR.getFiller(), approximationType.invert(), notS)));

      } else if (replacement instanceof OWLObjectMinCardinalityRestriction) {
        OWLObjectMinCardinalityRestriction minR = (OWLObjectMinCardinalityRestriction) replacement;
        return getOwlDataFactory()
            .getOWLObjectMinCardinalityRestriction(
                minR.getProperty(),
                minR.getCardinality(),
                doReplacing(
                    new PartialDescriptionRewritingApproximationTypeContext(
                        minR.getFiller(), approximationType, notS)));
      }
    }

    // end recursion
    return replacement;
  }