code: public X500Name commonAncestor(X500Name other) {
  
          if (other == null) {
              return null;
          }
          int otherLen = other.names.length;
          int thisLen = this.names.length;
          if (thisLen == 0 || otherLen == 0) {
              return null;
          }
          int minLen = (thisLen < otherLen) ? thisLen: otherLen;
  
          //Compare names from highest RDN down the naming tree
          //Note that these are stored in RDN[0]...
          int i=0;
          for (; i < minLen; i++) {
              if (!names[i].equals(other.names[i])) {
                  if (i == 0) {
                      return null;
                  } else {
                      break;
                  }
              }
          }
  
          //Copy matching RDNs into new RDN array
          RDN[] ancestor = new RDN[i];
          for (int j=0; j < i; j++) {
              ancestor[j] = names[j];
          }
  
          X500Name commonAncestor = null;
          try {
              commonAncestor = new X500Name(ancestor);
          } catch (IOException ioe) {
              return null;
          }
          return commonAncestor;
      }
docs: Return lowest common ancestor of this name and other name
  
  @param other another X500Name
  @return X500Name of lowest common ancestor; null if none