/**
   * Return the names of all persistent (mapped) classes that extend or implement the given class or
   * interface, accounting for implicit/explicit polymorphism settings and excluding mapped
   * subclasses/joined-subclasses of other classes in the result.
   */
  public String[] getImplementors(String className) throws MappingException {

    final Class clazz;
    try {
      clazz = ReflectHelper.classForName(className);
    } catch (ClassNotFoundException cnfe) {
      return new String[] {className}; // for a dynamic-class
    }

    ArrayList results = new ArrayList();
    Iterator iter = entityPersisters.values().iterator();
    while (iter.hasNext()) {
      // test this entity to see if we must query it
      EntityPersister testPersister = (EntityPersister) iter.next();
      if (testPersister instanceof Queryable) {
        Queryable testQueryable = (Queryable) testPersister;
        String testClassName = testQueryable.getEntityName();
        boolean isMappedClass = className.equals(testClassName);
        if (testQueryable.isExplicitPolymorphism()) {
          if (isMappedClass) {
            return new String[] {className}; // NOTE EARLY EXIT
          }
        } else {
          if (isMappedClass) {
            results.add(testClassName);
          } else {
            final Class mappedClass = testQueryable.getMappedClass(EntityMode.POJO);
            if (mappedClass != null && clazz.isAssignableFrom(mappedClass)) {
              final boolean assignableSuperclass;
              if (testQueryable.isInherited()) {
                Class mappedSuperclass =
                    getEntityPersister(testQueryable.getMappedSuperclass())
                        .getMappedClass(EntityMode.POJO);
                assignableSuperclass = clazz.isAssignableFrom(mappedSuperclass);
              } else {
                assignableSuperclass = false;
              }
              if (!assignableSuperclass) {
                results.add(testClassName);
              }
            }
          }
        }
      }
    }
    return (String[]) results.toArray(new String[results.size()]);
  }