public static Map<EKey, Equations> processClass(final ClassReader classReader, final String presentableUrl) {

    // It is OK to share pending states, actions and results for analyses.
    // Analyses are designed in such a way that they first write to states/actions/results and then read only those portion
    // of states/actions/results which were written by the current pass of the analysis.
    // Since states/actions/results are quite expensive to create (32K array) for each analysis, we create them once per class analysis.
    final ExpandableArray<State> sharedPendingStates = new ExpandableArray<>();
    final ExpandableArray<PendingAction> sharedPendingActions = new ExpandableArray<>();
    final ExpandableArray<PResults.PResult> sharedResults = new ExpandableArray<>();
    final Map<EKey, Equations> equations = new HashMap<>();

    FieldData data = FieldData.read(classReader);
    data.registerVolatileFields(equations);
    Set<Member> staticFinalFields = data.staticFinalFields();

    if ((classReader.getAccess() & Opcodes.ACC_ENUM) != 0) {
      // ordinal() method is final in java.lang.Enum, but for some reason referred on call sites using specific enum class
      // it's used on every enum switch statement, so forcing its purity is important
      EKey ordinalKey = new EKey(new Member(classReader.getClassName(), "ordinal", "()I"), Out, true);
      equations.put(ordinalKey, new Equations(
        Collections.singletonList(new DirectionResultPair(Pure.asInt(), new Effects(DataValue.LocalDataValue, Collections.emptySet()))),
        true));
    }

    classReader.accept(
      new MethodAnalysisVisitor(equations, presentableUrl, sharedPendingStates, sharedPendingActions, sharedResults, staticFinalFields), ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

    return equations;
  }
public static Map<EKey, Equations> processClass(final ClassReader classReader, final String presentableUrl)