public void MagicProcessor() {
    if (modelChanges == null) {
      modelChanges = new ArrayList<ModelChange>();
      return;
    } else if (modelChanges.size() == 0) return;
    // else go!

    // gets all model deltas and processes!
    // System.out.println("[MAGIC] Update match set based on model change started...");

    long start = System.currentTimeMillis();

    Set<PQuery> affecteds = new HashSet<PQuery>();
    for (ModelChange change : modelChanges) {
      if (change instanceof EFeatureChange)
        affecteds.addAll(
            LookaheadMatcherTreat.RelativeSet.get(((EFeatureChange) change).getChangedFeature()));
      if (change instanceof EClassChange)
        affecteds.addAll(
            LookaheadMatcherTreat.RelativeSet.get(((EClassChange) change).getChange()));
      if (change instanceof EDataTypeChange)
        affecteds.addAll(
            LookaheadMatcherTreat.RelativeSet.get(((EDataTypeChange) change).getChange()));
    }

    ArrayList<ModelDelta> deltas = new ArrayList<ModelDelta>();

    for (PQuery affectedQuery : affecteds) {

      ArrayList<AheadStructure> cachedStructures =
          LookaheadMatcherTreat.GodSetStructures.get(affectedQuery);
      // deliver deltas for pattern!
      for (ModelChange change : modelChanges) {
        for (AheadStructure aSn : cachedStructures) {
          for (AxisConstraint rC : aSn.SearchedConstraints) {
            if (rC instanceof RelationConstraint && change instanceof EFeatureChange) {
              EFeatureChange changenow = (EFeatureChange) change;
              if (((RelationConstraint) rC).getEdge().equals(changenow.getChangedFeature()))
                rC.putToMailbox(change);
            } else if (rC instanceof TypeConstraint && change instanceof EDataTypeChange) {
              EDataTypeChange changenow = (EDataTypeChange) change;
              if (((TypeConstraint) rC).getType().equals(changenow.getChange()))
                rC.putToMailbox(change);
            }
            if (rC instanceof TypeConstraint && change instanceof EClassChange) {
              EClassChange changenow = (EClassChange) change;
              if (((TypeConstraint) rC).getType().equals(changenow.getChange()))
                rC.putToMailbox(change);
            }
          }
        }
      }

      for (ModelChange change : modelChanges) {
        // process this change: first remove all deltas from constraints with this change
        for (AheadStructure aSn : cachedStructures) {
          for (AxisConstraint rC : aSn.SearchedConstraints) {
            if (rC.hasMailboxContent()) {
              if (rC.getMailboxContent().contains(change)) rC.removeFromMailbox(change);
            }
          }
        }
        // apply modelchange:
        HashMap<PVariable, Object> knownLocalAndParameters = new HashMap<PVariable, Object>();
        for (AheadStructure aSn : cachedStructures) {
          // find all relationConstraints
          for (AxisConstraint rC : aSn.SearchedConstraints) {
            if (rC instanceof RelationConstraint && change instanceof EFeatureChange) {
              EFeatureChange changenow = (EFeatureChange) change;
              if (((RelationConstraint) rC).getEdge().equals(changenow.getChangedFeature())) {
                // affected relaconstraint's lookvariables should be bound!!
                knownLocalAndParameters.put(
                    ((RelationConstraint) rC).getSource(), changenow.getHost());
                knownLocalAndParameters.put(
                    ((RelationConstraint) rC).getTarget(), changenow.getInstance());
              }
            } else if (rC instanceof TypeConstraint && change instanceof EDataTypeChange) {
              EDataTypeChange changenow = (EDataTypeChange) change;
              if (((TypeConstraint) rC).getType().equals(changenow.getChange())) {
                // affected typeconstraint's lookvariable should be bound!!
                knownLocalAndParameters.put(
                    ((TypeConstraint) rC).getTypedVariable(), changenow.getInstance());
              }
            }
            if (rC instanceof TypeConstraint && change instanceof EClassChange) {
              EClassChange changenow = (EClassChange) change;
              if (((TypeConstraint) rC).getType().equals(changenow.getChange())) {
                // affected typeconstraint's lookvariable should be bound!!
                knownLocalAndParameters.put(
                    ((TypeConstraint) rC).getTypedVariable(), changenow.getInstance());
              }
            }
          }
        }

        // manual satisfy and clone cachedStructures (createNew* clones input):
        ArrayList<AheadStructure> newStructs = null;
        isModified = false;
        if (change instanceof EFeatureChange) {
          EFeatureChange changenow = (EFeatureChange) change;
          newStructs =
              createNewFromOldRelaC(
                  changenow.getHost(),
                  changenow.getInstance(),
                  changenow.getChangedFeature(),
                  cachedStructures);
        } else if (change instanceof EDataTypeChange) {
          EDataTypeChange changenow = (EDataTypeChange) change;
          newStructs =
              createNewFromOldTypeC(
                  false, changenow.getChange(), changenow.getInstance(), cachedStructures);
        }
        if (change instanceof EClassChange) {
          EClassChange changenow = (EClassChange) change;
          newStructs =
              createNewFromOldTypeC(
                  false, changenow.getChange(), changenow.getInstance(), cachedStructures);
        }
        if (isModified) {
          // the new matches that'll appear in matching based on manually satisfied structure
          Multiset<LookaheadMatching> newbies_toExamine =
              (new LookaheadMatcherInterface(this.navHelper))
                  .searchChangesAll(
                      treat.getIncQueryEngine(),
                      affectedQuery,
                      newStructs,
                      knownLocalAndParameters,
                      new TreatConstraintEnumerator(this.navHelper));

          // a new map to store a matching and whether it is added or removed
          HashMultimap<LookaheadMatching, Boolean> newMatchingsAndChange = HashMultimap.create();

          // iterate over multiset and create delta
          for (com.google.common.collect.Multiset.Entry<LookaheadMatching> inners :
              newbies_toExamine.entrySet()) {
            for (int pi = 0; pi < inners.getCount(); pi++)
              newMatchingsAndChange.put(inners.getElement(), change.isAddition());
          }
          // delta needed to propagate the changes
          if (newMatchingsAndChange.size() > 0) {
            ModelDelta d = new ModelDelta(affectedQuery, newMatchingsAndChange);
            deltas.add(d);
          }
        }
      }
    }

    // apply deltas
    for (ModelDelta delta : deltas) {
      // System.out.println("Propagate a delta: " + delta.getPattern().getFullyQualifiedName());
      AdvancedDeltaProcessor.getInstance().ReceiveDelta(delta);
    }
    AdvancedDeltaProcessor.getInstance().ProcessReceivedDeltaSet();

    // System.out.println("[MAGIC] Update match set based on model change ended! Time:" +
    // Long.toString(System.currentTimeMillis() - start));

    // finally:
    modelChanges = new ArrayList<ModelChange>();
  }