}
  
  @SuppressWarnings("unchecked")
  @Override
  public Wrapper find(String name, final Object[] scopes) {
    Wrapper wrapper = null;
    final int length = scopes.length;
    List<Guard> guards = new ArrayList<Guard>(scopes.length);
    // Simple guard to break if the number of scopes at this call site have changed
    guards.add(createDepthGuard(length));
    NEXT:
    for (int i = length - 1; i >= 0; i--) {
      Object scope = scopes[i];
      if (scope == null) continue;
      // Make sure that the current scope is the same class
      guards.add(createClassGuard(i, scope));
      List<Wrapper> wrappers = null;
      int dotIndex;
      String subname = name;
      // Try and find a wrapper using the simple name
      wrapper = findWrapper(i, null, guards, scope, subname);
      if (wrapper != null) {
        break;
      }
      // If there is dot notation, start evaluating it
      while ((dotIndex = subname.indexOf('.')) != -1) {
        final String lookup = subname.substring(0, dotIndex);
        subname = subname.substring(dotIndex + 1);
        // This is used for lookups but otherwise always succeeds
        guards.add(createDotGuard(i, scope, lookup));
        List<Guard> wrapperGuard = new ArrayList<Guard>(1);
        wrapperGuard.add(createClassGuard(0, scope));
        wrapper = findWrapper(0, null, wrapperGuard, scope, lookup);
        if (wrappers == null) wrappers = new ArrayList<Wrapper>();
        if (wrapper != null) {
          // We need to dig into a scope when dot notation shows up
          wrappers.add(wrapper);
          try {
            // Pull out the next level
            scope = coerce(wrapper.call(new Object[]{scope}));
          } catch (GuardException e) {
            throw new AssertionError(e);
          }
        } else {
          // Failed to find a wrapper for the next dot