public Map<EKey, Effects> solve() {
    while (!moving.isEmpty()) {
      EKey key = moving.pop();
      Effects effects = solved.get(key);

      EKey[] propagateKeys;
      Effects[] propagateEffects;

      if (key.stable) {
        propagateKeys = new EKey[]{key, key.mkUnstable()};
        propagateEffects = new Effects[]{effects, effects};
      }
      else {
        propagateKeys = new EKey[]{key.mkStable(), key};
        propagateEffects = new Effects[]{effects, new Effects(DataValue.UnknownDataValue1, Effects.TOP_EFFECTS)};
      }
      for (int i = 0; i < propagateKeys.length; i++) {
        ProgressManager.checkCanceled();
        EKey pKey = propagateKeys[i];
        Effects pEffects = propagateEffects[i];
        Set<EKey> dKeys = dependencies.remove(pKey);
        if (dKeys != null) {
          for (EKey dKey : dKeys) {
            Effects dEffects = pending.remove(dKey);
            if (dEffects == null) {
              // already solved, for example, solution is top
              continue;
            }
            Set<EffectQuantum> newEffects = new HashSet<>();
            Set<EffectQuantum> delta = null;
            DataValue returnValue = substitute(dEffects.returnValue, pKey, pEffects);

            for (EffectQuantum dEffect : dEffects.effects) {
              if (dEffect instanceof EffectQuantum.CallQuantum) {
                EffectQuantum.CallQuantum call = substitute((EffectQuantum.CallQuantum)dEffect, pKey, pEffects);
                if (call.key.equals(pKey)) {
                  delta = substitute(pEffects, call.data, call.isStatic);
                  if (delta.equals(Effects.TOP_EFFECTS)) {
                    newEffects = delta;
                    break;
                  }
                  newEffects.addAll(delta);
                }
                else {
                  newEffects.add(call);
                }
                continue;
              }
              if (dEffect instanceof EffectQuantum.ReturnChangeQuantum retChange && retChange.key.equals(pKey)) {
                if (pEffects.returnValue != DataValue.LocalDataValue) {
                  newEffects = delta = Effects.TOP_EFFECTS;
                  break;
                }
                continue;
              }
              if (dEffect instanceof EffectQuantum.FieldReadQuantum && ((EffectQuantum.FieldReadQuantum)dEffect).key.equals(pKey)) {
                newEffects.addAll(pEffects.effects);
                continue;
              }
              newEffects.add(dEffect);
            }

            if (Effects.TOP_EFFECTS.equals(delta) && returnValue.equals(DataValue.UnknownDataValue1)) {
              solved.put(dKey, new Effects(returnValue, Effects.TOP_EFFECTS));
              moving.push(dKey);
            }
            else {
              Effects result = new Effects(returnValue, newEffects);
              if (result.dependencies().findFirst().isPresent()) {
                pending.put(dKey, result);
              }
              else {
                solved.put(dKey, result);
                moving.push(dKey);
              }
            }
          }
        }
      }
    }
    return solved;
  }
public Map<EKey, Effects> solve()