public static AccessorProvider getAllAccessorsProvider(
      Elements elements,
      Types types,
      TypeElement originatingType,
      boolean useLegacyAccessorOrdering) {

    class CollectedOrdering extends Ordering<Element> {
      class Intratype {
        final String inType;
        final Ordering<String> ordering;
        final int rank;

        Intratype(String inType, int rank, List<String> accessors) {
          this.inType = inType;
          this.rank = rank;
          this.ordering = Ordering.explicit(accessors);
        }

        @Override
        public String toString() {
          return "(<=> " + inType + ", " + rank + ", " + ordering + ")";
        }
      }

      final boolean useLegacyMode = useLegacyAccessorOrdering || USE_LEGACY_ACCESSOR_ORDERING;
      final Map<String, Intratype> accessorOrderings = new LinkedHashMap<>();
      final ArrayListMultimap<String, TypeElement> accessorMapping = ArrayListMultimap.create();
      final Predicate<String> includeAccessorInOrdering = useLegacyMode
        ? Predicates.not(Predicates.in(accessorOrderings.keySet()))
        : Predicates.alwaysTrue();
      final Set<TypeElement> linearizedTypes;

      CollectedOrdering() {
        linearizedTypes = useLegacyMode
            ? new BottomUpOrdering().traverseElements(originatingType)
            : new TopDownOrdering().traverseElements(originatingType);
        collectAccessors();
      }

      void collectAccessors() {
        int i = 0;
        for (TypeElement type : linearizedTypes) {
          List<String> accessorsInType =
              FluentIterable.from(SourceOrdering.getEnclosedElements(type))
                  .filter(IsParameterlessNonstaticNonobject.PREDICATE)
                  .transform(ToSimpleName.FUNCTION)
                  .toList();

          String typeTag = type.getSimpleName().toString();
          Intratype intratype = new Intratype(typeTag, i++, accessorsInType);

          for (String name : accessorsInType) {
            accessorMapping.put(name, type);
            if (includeAccessorInOrdering.apply(name)) {
              accessorOrderings.put(name, intratype);
            }
          }
        }
      }

      @Override
      public int compare(Element left, Element right) {
        String leftKey = ToSimpleName.FUNCTION.apply(left);
        String rightKey = ToSimpleName.FUNCTION.apply(right);
        Intratype leftIntratype = accessorOrderings.get(leftKey);
        Intratype rightIntratype = accessorOrderings.get(rightKey);
        // can be issue under Eclipse (still?)
        if (leftIntratype == null || rightIntratype == null) return 0;
        return leftIntratype == rightIntratype
            ? leftIntratype.ordering.compare(leftKey, rightKey)
            : Integer.compare(leftIntratype.rank, rightIntratype.rank);
      }
    }

    final CollectedOrdering ordering = new CollectedOrdering();

    final ImmutableList<ExecutableElement> sortedList =
        ordering.immutableSortedCopy(
            disambiguateMethods(ElementFilter.methodsIn(
                elements.getAllMembers(originatingType))));

    return new AccessorProvider() {
      final ImmutableListMultimap<String, TypeElement> accessorMapping =
          ImmutableListMultimap.copyOf(ordering.accessorMapping);

      @Override
      public ImmutableListMultimap<String, TypeElement> accessorMapping() {
        return accessorMapping;
      }

      @Override
      public ImmutableList<ExecutableElement> get() {
        return sortedList;
      }
    };
  }
While we have {@link SourceOrdering}, there's still a problem: We have inheritance hierarchy,
and we want to have all defined or inherited accessors returned as members of target type,
like {@link Elements#getAllMembers(TypeElement)},
but we need to have them properly and stably sorted.
This implementation doesn't try to correctly resolve order for accessors inherited from
different supertypes(interfaces), just something that stable and reasonable wrt source ordering
without handling complex cases.
@param elements the elements utility
@param types the types utility
@param originatingType the type to traverse
@param useLegacyAccessorOrdering switch to legacy, pre 2.7.5 accessor ordering
@return provider of all accessors in source order and mapping
generator/src/org/immutables/generator/SourceOrdering.java