final Map<String, BasicOperator> mso,
final BasicOperator rootOperator) {
final Collection<BasicOperator> deleted = new LinkedList<BasicOperator>();
final Collection<BasicOperator> added = new LinkedList<BasicOperator>();
final ReplaceLit replaceLit = (ReplaceLit) mso.get("replaceLit");
final Optional optional = (Optional) mso.get("optional");
final ReplaceLit replaceLitUnder = new ReplaceLit();
added.add(replaceLitUnder);
final Object[] optionalVars = optional.getIntersectionVariables()
.toArray();
final LinkedList<Variable> replaceLitLeft = replaceLit
.getSubstitutionsLiteralLeft();
final LinkedList<Literal> replaceLitRight = replaceLit
.getSubstitutionsLiteralRight();
Variable var;
Literal lit;
for (int i = 0; i < replaceLitLeft.size(); i++) {
var = replaceLitLeft.get(i);
// Split ReplaceLit and pull only not intersection variables
// downwards
if (!arrayContains(optionalVars, var)) {
lit = replaceLitRight.get(i);
replaceLitUnder.addSubstitution(var, lit);
replaceLit.removeSubstitutionVars(i);
}
}
final LinkedList<BasicOperator> pres = (LinkedList<BasicOperator>) replaceLit
.getPrecedingOperators();
final LinkedList<OperatorIDTuple> succs = (LinkedList<OperatorIDTuple>) optional
.getSucceedingOperators();
final int index = replaceLit.getOperatorIDTuple(optional).getId();
// If everything could be pushed downwards, the old ReplaceLit can be
// deleted
if (replaceLit.getSubstitutionsLiteralLeft().size() == 0) {
BasicOperator pre;
for (int i = 0; i < pres.size(); i++) {
pre = pres.get(i);
pre.addSucceedingOperator(new OperatorIDTuple(optional, index));
pre.removeSucceedingOperator(replaceLit);
optional.addPrecedingOperator(pre);
}
optional.removePrecedingOperator(replaceLit);
deleted.add(replaceLit);
}
// Insert the new ReplaceLit under the Optional
optional.setSucceedingOperator(new OperatorIDTuple(replaceLitUnder, 0));
replaceLitUnder.setPrecedingOperator(optional);
replaceLitUnder.setSucceedingOperators(succs);
BasicOperator succ;