/**
  * Checks if the EJB class implements the TimedObject interface
  *
  * @param descriptor the Enterprise Java Bean deployment descriptor
  * @return <code>Result</code> the results for this assertion
  */
 public Result check(EjbDescriptor descriptor) {
   Result result = getInitializedResult();
   ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();
   boolean isEjb30 = descriptor.getEjbBundleDescriptor().getSpecVersion().equalsIgnoreCase("3.0");
   if (descriptor.isTimedObject()) {
     // Timers can be created for stateless session beans, message-driven beans,
     // and 2.1 entity beans.Timers cannot be created for stateful session beans or EJB 3.0
     // entities.
     if (((descriptor instanceof EjbEntityDescriptor) && isEjb30)
         || ((descriptor instanceof EjbSessionDescriptor)
             && ((((EjbSessionDescriptor) descriptor).getSessionType())
                 .equals(EjbSessionDescriptor.STATEFUL)))) {
       addErrorDetails(result, compName);
       result.failed(
           smh.getLocalString(
               getClass().getName() + ".failed1",
               "[ {0} ] must not implement the TimedObject interface."
                   + "Only 2.1 entity beans or stateless session beans may "
                   + "implement the TimedObject interface",
               new Object[] {descriptor.getEjbClassName()}));
     }
   }
   if (result.getStatus() != Result.FAILED) {
     addGoodDetails(result, compName);
     result.passed(
         smh.getLocalString(
             getClass().getName() + ".passed",
             "[ {0} ] properly implements the TimedObject interface",
             new Object[] {descriptor.getEjbClassName()}));
   }
   return result;
 }
  private void commonToBothInterfaces(String intf, EjbDescriptor descriptor) {
    try {
      Class intfClass = Class.forName(intf, false, getVerifierContext().getClassLoader());

      for (Method remoteMethod : intfClass.getMethods()) {

        // we don't test the EJB methods
        if (remoteMethod.getDeclaringClass().getName().equals("javax.ejb.EJBObject")) continue;
        Class beanClass =
            Class.forName(
                descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());
        for (Method method : beanClass.getMethods()) {

          if (method.getName().equals(remoteMethod.getName())
              && !RmiIIOPUtils.isValidRmiIIOPReturnType(method.getReturnType())) {
            // The methods arguments types must be legal types for
            // RMI-IIOP.  This means that their return values must
            // be of valid types for RMI-IIOP,
            addErrorDetails(result, compName);
            result.failed(
                smh.getLocalString(
                    getClass().getName() + ".failed",
                    "Error: business method [ {0} ] was found, but "
                        + "business method has invalid return type [ {1} ]. Business "
                        + "method return type must be a valid type for RMI-IIOP.",
                    new Object[] {method.getName(), method.getReturnType()}));
          }
        }
      }

    } catch (ClassNotFoundException e) {
      Verifier.debug(e);
      addErrorDetails(result, compName);
      result.failed(
          smh.getLocalString(
              getClass().getName() + ".failedException",
              "Error: Remote interface [ {0} ] or bean class [ {1} ] does "
                  + "not exist or is not loadable within bean [ {2} ].",
              new Object[] {
                descriptor.getRemoteClassName(), descriptor.getEjbClassName(), descriptor.getName()
              }));
    }
  }
  /**
   * Entity Bean's ejbCreate(...) methods return test. Each entity Bean class may define zero or
   * more ejbCreate(...) methods. The number and signatures of a entity Bean's create methods are
   * specific to each EJB class. The method signatures must follow these rules:
   *
   * <p>The method name must be ejbCreate.
   *
   * <p>The return type must be primary key type.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) {
        boolean oneFailed = false;
        boolean oneWarning = false;
        int foundAtLeastOne = 0;
        try {
          Context context = getVerifierContext();
          ClassLoader jcl = context.getClassLoader();
          Class c =
              Class.forName(
                  descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());

          String primaryKeyType = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName();
          boolean ejbCreateFound = false;
          boolean returnsPrimaryKeyType = false;
          // start do while loop here....
          do {
            Method[] methods = c.getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
              // reset flags from last time thru loop
              ejbCreateFound = false;
              returnsPrimaryKeyType = false;
              // The method name must be ejbCreate.
              if (methods[i].getName().startsWith("ejbCreate")) {
                foundAtLeastOne++;
                ejbCreateFound = true;

                // The return type must be primary key type.
                Class rt = methods[i].getReturnType();
                if (rt.getName().equals(primaryKeyType)) {
                  returnsPrimaryKeyType = true;
                }

                // now display the appropriate results for this particular ejbCreate
                // method
                if (ejbCreateFound && !returnsPrimaryKeyType) {
                  if (primaryKeyType.equals("java.lang.Object")) {
                    oneWarning = true;
                    result.addWarningDetails(
                        smh.getLocalString(
                            "tests.componentNameConstructor",
                            "For [ {0} ]",
                            new Object[] {compName.toString()}));
                    result.addWarningDetails(
                        smh.getLocalString(
                            getClass().getName() + ".debug1",
                            "For EJB Class [ {0} ] method [ {1} ]",
                            new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                    result.addWarningDetails(
                        smh.getLocalString(
                            getClass().getName() + ".warning",
                            "Warning: An [ {0} ] method was found, but [ {1} ] method has [ {2} ] return type.   Deployment descriptor primary key type [ {3} ]. Definition of the primary key type is deferred to deployment time ?",
                            new Object[] {
                              methods[i].getName(),
                              methods[i].getName(),
                              methods[i].getReturnType().getName(),
                              primaryKeyType
                            }));
                  } else {
                    oneFailed = true;
                    result.addErrorDetails(
                        smh.getLocalString(
                            "tests.componentNameConstructor",
                            "For [ {0} ]",
                            new Object[] {compName.toString()}));
                    result.addErrorDetails(
                        smh.getLocalString(
                            getClass().getName() + ".debug1",
                            "For EJB Class [ {0} ] method [ {1} ]",
                            new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                    result.addErrorDetails(
                        smh.getLocalString(
                            getClass().getName() + ".failed",
                            "Error: An [ {0} ] method was found, but [ {1} ] method has illegal return value.   [ {2} ] methods must return primary key type [ {3} ].",
                            new Object[] {
                              methods[i].getName(),
                              methods[i].getName(),
                              methods[i].getName(),
                              primaryKeyType
                            }));
                    break;
                  }
                }
              }
            }
            if (oneFailed == true) break;
          } while (((c = c.getSuperclass()) != null) && (foundAtLeastOne == 0));

          if (foundAtLeastOne == 0) {
            result.addNaDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.notApplicable(
                smh.getLocalString(
                    getClass().getName() + ".notApplicable0",
                    "[ {0} ] does not declare any ejbCreate(...) methods.",
                    new Object[] {descriptor.getEjbClassName()}));
          }
          if (oneFailed == false && foundAtLeastOne > 0) {
            result.addGoodDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.addGoodDetails(
                smh.getLocalString(
                    getClass().getName() + ".debug1",
                    "For EJB Class [ {0} ]",
                    new Object[] {descriptor.getEjbClassName()}));
            result.addGoodDetails(
                smh.getLocalString(
                    getClass().getName() + ".passed",
                    "[ {0} ] properly declares ejbCreate<method> method to return primary key type [ {1} ].",
                    new Object[] {descriptor.getEjbClassName(), primaryKeyType}));
          }
        } catch (ClassNotFoundException e) {
          Verifier.debug(e);
          result.addErrorDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.failed(
              smh.getLocalString(
                  getClass().getName() + ".failedException",
                  "Error: [ {0} ] class not found.",
                  new Object[] {descriptor.getEjbClassName()}));
          oneFailed = true;
        }

        if (oneFailed) {
          result.setStatus(result.FAILED);
        } else if (foundAtLeastOne == 0) {
          result.setStatus(result.NOT_APPLICABLE);
        } else {
          if (oneWarning) {
            result.setStatus(result.WARNING);
          } else {

            result.setStatus(result.PASSED);
          }
        }

        return result;

      } else { // if (CONTAINER_PERSISTENCE.equals(persistence)) {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable1",
                "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.",
                new Object[] {
                  EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistence
                }));
        return result;
      }

    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Entity Bean's ejbPostCreate(...) methods test. Each entity Bean class may define zero or more
   * ejbPostCreate(...) methods. The number and signatures of a entity Bean's create methods are
   * specific to each EJB class. The method signatures must follow these rules:
   *
   * <p>The method name must be ejbPostCreate.
   *
   * <p>The method must not be declared as static.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      boolean oneFailed = false;
      int foundAtLeastOne = 0;
      try {
        Context context = getVerifierContext();
        ClassLoader jcl = context.getClassLoader();
        Class c =
            Class.forName(
                descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());

        boolean ejbPostCreateFound = false;
        boolean isStatic = false;
        // start do while loop here....
        do {
          Method[] methods = c.getDeclaredMethods();
          for (int i = 0; i < methods.length; i++) {
            // reset flags from last time thru loop
            ejbPostCreateFound = false;
            isStatic = false;

            // The method name must be ejbPostCreate.
            if (methods[i].getName().startsWith("ejbPostCreate")) {
              foundAtLeastOne++;
              ejbPostCreateFound = true;

              // The method must not be declared as final or static.
              int modifiers = methods[i].getModifiers();
              if (Modifier.isStatic(modifiers)) {
                isStatic = true;
              }

              // now display the appropriate results for this particular
              // ejbPostCreate method
              if (ejbPostCreateFound && (!isStatic)) {
                result.addGoodDetails(
                    smh.getLocalString(
                        "tests.componentNameConstructor",
                        "For [ {0} ]",
                        new Object[] {compName.toString()}));
                result.addGoodDetails(
                    smh.getLocalString(
                        getClass().getName() + ".debug1",
                        "For EJB Class [ {0} ] method [ {1} ]",
                        new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                result.addGoodDetails(
                    smh.getLocalString(
                        getClass().getName() + ".passed",
                        "[ {0} ] properly declares non-static [ {1} ] method.",
                        new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
              } else if (ejbPostCreateFound && isStatic) {
                oneFailed = true;
                result.addErrorDetails(
                    smh.getLocalString(
                        "tests.componentNameConstructor",
                        "For [ {0} ]",
                        new Object[] {compName.toString()}));
                result.addErrorDetails(
                    smh.getLocalString(
                        getClass().getName() + ".debug1",
                        "For EJB Class [ {0} ] ejbPostCreate(...) Method [ {1} ]",
                        new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                result.addErrorDetails(
                    smh.getLocalString(
                        getClass().getName() + ".failed",
                        "Error: A static [ {0} ]  method was found, but [ {1} ] cannot be declared as static.",
                        new Object[] {methods[i].getName(), methods[i].getName()}));
              }
            }
          }
        } while (((c = c.getSuperclass()) != null) && (foundAtLeastOne == 0));

        if (foundAtLeastOne == 0) {
          result.addNaDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.notApplicable(
              smh.getLocalString(
                  getClass().getName() + ".notApplicable1",
                  "[ {0} ] does not declare any ejbPostCreate(...) methods.",
                  new Object[] {descriptor.getEjbClassName()}));
        }
      } catch (ClassNotFoundException e) {
        Verifier.debug(e);
        result.addErrorDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.failed(
            smh.getLocalString(
                getClass().getName() + ".failedException",
                "Error: [ {0} ] class not found.",
                new Object[] {descriptor.getEjbClassName()}));
        oneFailed = true;
      }

      if (oneFailed) {
        result.setStatus(result.FAILED);
      } else if (foundAtLeastOne == 0) {
        result.setStatus(result.NOT_APPLICABLE);
      } else {
        result.setStatus(result.PASSED);
      }

      return result;

    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Define ejbFindByPrimaryKey method arguments test.
   *
   * <p>Every entity enterprise Bean class must define the ejbFindByPrimaryKey method.
   *
   * <p>The methods arguments types must be legal types for RMI-IIOP.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistentType = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistentType)) {
        Class[] ejbFinderMethodParameterTypes;
        boolean ejbFindByPrimaryKeyMethodFound = false;
        boolean oneFailed = false;
        boolean isLegalRMIIIOP = false;
        try {
          // retrieve the EJB Class Methods
          Context context = getVerifierContext();
          ClassLoader jcl = context.getClassLoader();
          Class EJBClass =
              Class.forName(
                  descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());
          // start do while loop here....
          do {
            Method[] ejbFinderMethods = EJBClass.getDeclaredMethods();

            for (int j = 0; j < ejbFinderMethods.length; ++j) {
              if (ejbFinderMethods[j].getName().equals("ejbFindByPrimaryKey")) {
                // Every entity enterprise Bean class must define the
                // ejbFindByPrimaryKey method.
                ejbFindByPrimaryKeyMethodFound = true;

                // The methods arguments types must be legal types for RMI-IIOP.
                ejbFinderMethodParameterTypes = ejbFinderMethods[j].getParameterTypes();
                if (RmiIIOPUtils.isValidRmiIIOPParameters(ejbFinderMethodParameterTypes)) {
                  // these method parameters are valid, continue
                  isLegalRMIIIOP = true;
                }

                if (ejbFindByPrimaryKeyMethodFound && isLegalRMIIIOP) {
                  result.addGoodDetails(
                      smh.getLocalString(
                          "tests.componentNameConstructor",
                          "For [ {0} ]",
                          new Object[] {compName.toString()}));
                  result.addGoodDetails(
                      smh.getLocalString(
                          getClass().getName() + ".debug1",
                          "For EJB Class [ {0} ] Finder Method [ {1} ]",
                          new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()}));
                  result.addGoodDetails(
                      smh.getLocalString(
                          getClass().getName() + ".passed",
                          "An [ {0} ] method with valid RMI-IIOP argument types was found.",
                          new Object[] {ejbFinderMethods[j].getName()}));
                } else if (ejbFindByPrimaryKeyMethodFound && (!isLegalRMIIIOP)) {
                  oneFailed = true;
                  result.addErrorDetails(
                      smh.getLocalString(
                          "tests.componentNameConstructor",
                          "For [ {0} ]",
                          new Object[] {compName.toString()}));
                  result.addErrorDetails(
                      smh.getLocalString(
                          getClass().getName() + ".debug1",
                          "For EJB Class [ {0} ] Finder Method [ {1} ]",
                          new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()}));
                  result.addErrorDetails(
                      smh.getLocalString(
                          getClass().getName() + ".failed",
                          "Error: An [ {0} ] method was found, but [ {1} ] method has illegal parameter values. [ {2} ] methods arguments types must be legal types for RMI-IIOP.",
                          new Object[] {
                            ejbFinderMethods[j].getName(),
                            ejbFinderMethods[j].getName(),
                            ejbFinderMethods[j].getName()
                          }));
                }
                // found one, and there should only be one, break out
                break;
              }
            }
          } while (((EJBClass = EJBClass.getSuperclass()) != null)
              && (!ejbFindByPrimaryKeyMethodFound));

          if (!ejbFindByPrimaryKeyMethodFound) {
            oneFailed = true;
            result.addErrorDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.addErrorDetails(
                smh.getLocalString(
                    getClass().getName() + ".debug3",
                    "For EJB Class [ {0} ]",
                    new Object[] {descriptor.getEjbClassName()}));
            result.addErrorDetails(
                smh.getLocalString(
                    getClass().getName() + ".failed1",
                    "Error: No ejbFindByPrimaryKey method was found in bean class."));
          }

        } catch (ClassNotFoundException e) {
          Verifier.debug(e);
          result.addErrorDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.failed(
              smh.getLocalString(
                  getClass().getName() + ".failedException",
                  "Error: EJB Class [ {0} ] does not exist or is not loadable.",
                  new Object[] {descriptor.getEjbClassName()}));
          oneFailed = true;
        }

        if (oneFailed) {
          result.setStatus(result.FAILED);
        } else {
          result.setStatus(result.PASSED);
        }
      } else { // (CONTAINER_PERSISTENCE.equals(persistentType))
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable2",
                "Expected persistence type [ {0} ], but bean [ {1} ] has persistence type [ {2} ]",
                new Object[] {
                  EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistentType
                }));
      }

      return result;

    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Optionally implemented SessionSynchronization interface transaction demarcation test. If an
   * enterprise bean implements the javax.ejb.SessionSynchronization interface, the Application
   * Assembler can specify only the following values for the transaction attributes of the bean's
   * methods: Required RequiresNew Mandatory
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();
    boolean oneFound = false;

    if (descriptor instanceof EjbSessionDescriptor) {
      try {
        Context context = getVerifierContext();
        ClassLoader jcl = context.getClassLoader();
        Class c =
            Class.forName(
                descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());
        // walk up the class tree
        do {
          Class[] interfaces = c.getInterfaces();

          for (int i = 0; i < interfaces.length; i++) {
            if (interfaces[i].getName().equals("javax.ejb.SessionSynchronization")) {
              oneFound = true;
              break;
            }
          }
        } while ((c = c.getSuperclass()) != null);

      } catch (ClassNotFoundException e) {
        Verifier.debug(e);
        addErrorDetails(result, compName);
        result.failed(
            smh.getLocalString(
                getClass().getName() + ".failedException1",
                "Error: [ {0} ] class not found.",
                new Object[] {descriptor.getEjbClassName()}));
        return result;
      }

      // If an enterprise bean implements the javax.ejb.SessionSynchronization
      // interface, the Application Assembler can specify only the following
      // values for the transaction attributes of the bean's methods:
      //   Required, RequiresNew, Mandatory
      if (oneFound) {
        String transactionAttribute = "";
        ContainerTransaction containerTransaction = null;
        boolean oneFailed = false;
        if (!descriptor.getMethodContainerTransactions().isEmpty()) {
          for (Enumeration ee = descriptor.getMethodContainerTransactions().keys();
              ee.hasMoreElements(); ) {
            MethodDescriptor methodDescriptor = (MethodDescriptor) ee.nextElement();
            containerTransaction =
                (ContainerTransaction)
                    descriptor.getMethodContainerTransactions().get(methodDescriptor);

            if (!(containerTransaction != null && properAttribDefined(containerTransaction))) {
              transactionAttribute = containerTransaction.getTransactionAttribute();
              addErrorDetails(result, compName);
              result.failed(
                  smh.getLocalString(
                      getClass().getName() + ".failed",
                      "Error: TransactionAttribute [ {0} ] for method [ {1} ] is not valid.",
                      new Object[] {transactionAttribute, methodDescriptor.getName()}));
            }
          }
        }
      }
    }

    if (result.getStatus() != Result.FAILED) {
      addGoodDetails(result, compName);
      result.passed(
          smh.getLocalString(
              getClass().getName() + ".passed",
              "TransactionAttributes are defined properly for the bean"));
    }
    return result;
  }
  /**
   * run an individual home method test
   *
   * @param method the home method to test
   * @param descriptor the deployment descriptor for the entity bean
   * @param result the result object
   */
  protected void runIndividualHomeMethodTest(
      Method method, EjbDescriptor descriptor, Result result) {

    Method m;
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    try {
      // retrieve the remote interface methods
      ClassLoader jcl = getVerifierContext().getClassLoader();
      Class ejbClass = Class.forName(descriptor.getEjbClassName(), false, jcl);

      // Bug: 4952890. first character of this name should be converted to UpperCase.
      String methodName =
          method
              .getName()
              .replaceFirst(
                  method.getName().substring(0, 1), method.getName().substring(0, 1).toUpperCase());
      String expectedMethodName = "ejbHome" + methodName;
      do {
        // retrieve the EJB Class Methods
        m = getMethod(ejbClass, expectedMethodName, method.getParameterTypes());
      } while (((ejbClass = ejbClass.getSuperclass()) != null) && (m == null));

      if (m != null) {
        int modifiers = m.getModifiers();
        if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
          addGoodDetails(result, compName);
          result.addGoodDetails(
              smh.getLocalString(
                  getClass().getName() + ".passed",
                  "For method [ {1} ] in Home Interface [ {0} ], ejbHome method is public and not static",
                  new Object[] {method.getDeclaringClass().getName(), method.getName()}));
          result.setStatus(Result.PASSED);
          // return true;
        } else {
          addErrorDetails(result, compName);
          result.addErrorDetails(
              smh.getLocalString(
                  getClass().getName() + ".notApplicable",
                  "Error : For method [ {1} ] defined in Home Interface [ {0} ], the ejbHome method is either static or not public",
                  new Object[] {method.getDeclaringClass().getName(), method.getName()}));
          result.setStatus(Result.FAILED);
          // return false;
        }
      } else {
        addErrorDetails(result, compName);
        result.addErrorDetails(
            smh.getLocalString(
                getClass().getName() + ".failed",
                "Error : For method [ {1} ] defined in Home Interface [ {0} ], no ejbHome name matching method was found",
                new Object[] {method.getDeclaringClass().getName(), method.getName()}));
        result.setStatus(Result.FAILED);
        // return true;
      }
    } catch (ClassNotFoundException e) {
      Verifier.debug(e);
      addErrorDetails(result, compName);
      result.failed(
          smh.getLocalString(
              getClass().getName() + ".failedException",
              "Error: Home interface [ {0} ] does not exist or is not loadable within bean [ {1} ]",
              new Object[] {getClassName(descriptor), descriptor.getName()}));
      // return false;
      result.setStatus(Result.FAILED);
    }
  }