docs: public static ClassNode lowestUpperBound(ClassNode a, ClassNode b) {
          ClassNode lub = lowestUpperBound(a, b, null, null);
          if (lub==null || !lub.isUsingGenerics()) return lub;
          // types may be parameterized. If so, we must ensure that generic type arguments
          // are made compatible
  
          if (lub instanceof LowestUpperBoundClassNode) {
              // no parent super class representing both types could be found
              // or both class nodes implement common interfaces which may have
              // been parameterized differently.
              // We must create a classnode for which the "superclass" is potentially parameterized
              // plus the interfaces
              ClassNode superClass = lub.getSuperClass();
              ClassNode psc = superClass.isUsingGenerics()?parameterizeLowestUpperBound(superClass, a, b, lub):superClass;
  
              ClassNode[] interfaces = lub.getInterfaces();
              ClassNode[] pinterfaces = new ClassNode[interfaces.length];
              for (int i = 0, interfacesLength = interfaces.length; i < interfacesLength; i++) {
                  final ClassNode icn = interfaces[i];
                  if (icn.isUsingGenerics()) {
                      pinterfaces[i] = parameterizeLowestUpperBound(icn, a, b, lub);
                  } else {
                      pinterfaces[i] = icn;
                  }
              }
  
              return new LowestUpperBoundClassNode(((LowestUpperBoundClassNode)lub).name, psc, pinterfaces);
          } else {
              return parameterizeLowestUpperBound(lub, a, b, lub);
  
          }
      }