code: public int constrains(GeneralNameInterface inputName)
              throws UnsupportedOperationException {
          int constraintType;
          if (inputName == null) {
              constraintType = NAME_DIFF_TYPE;
          } else if (inputName.getType() != NAME_DIRECTORY) {
              constraintType = NAME_DIFF_TYPE;
          } else { // type == NAME_DIRECTORY
              X500Name inputX500 = (X500Name)inputName;
              if (inputX500.equals(this)) {
                  constraintType = NAME_MATCH;
              } else if (inputX500.names.length == 0) {
                  constraintType = NAME_WIDENS;
              } else if (this.names.length == 0) {
                  constraintType = NAME_NARROWS;
              } else if (inputX500.isWithinSubtree(this)) {
                  constraintType = NAME_NARROWS;
              } else if (isWithinSubtree(inputX500)) {
                  constraintType = NAME_WIDENS;
              } else {
                  constraintType = NAME_SAME_TYPE;
              }
          }
          return constraintType;
      }
docs: Return constraint type:<ul>
  <li>NAME_DIFF_TYPE = -1: input name is different type from this name
  (i.e. does not constrain)
  <li>NAME_MATCH = 0: input name matches this name
  <li>NAME_NARROWS = 1: input name narrows this name
  <li>NAME_WIDENS = 2: input name widens this name
  <li>NAME_SAME_TYPE = 3: input name does not match or narrow this name,
  &       but is same type
  </ul>.  These results are used in checking NameConstraints during
  certification path verification.
  
  @param inputName to be checked for being constrained
  @returns constraint type above
  @throws UnsupportedOperationException if name is not exact match, but
  narrowing and widening are not supported for this name type.