docs: public static long computeSerialVersionUID(TypeElement type, TypeEnvironment environment) {
  
          TypeElement javaIoSerializable = environment.getElementUtils().getTypeElement("java.io.Serializable");
  
          if (!environment.getTypeUtils().isAssignable(type.asType(), javaIoSerializable.asType())) {
              return 0L;
          }
  //        if (!Serializable.class.isAssignableFrom(cl) || Proxy.isProxyClass(cl))
  //        {
  //            return 0L;
  //        }
  
          try {
              ByteArrayOutputStream bout = new ByteArrayOutputStream();
              DataOutputStream dout = new DataOutputStream(bout);
  
              dout.writeUTF(type.getQualifiedName().toString());
  
              int classMods = asReflectiveModifiers(type, Modifier.PUBLIC, Modifier.FINAL, Modifier.ABSTRACT);
              if (type.getKind() == ElementKind.INTERFACE) {
                  classMods |= java.lang.reflect.Modifier.INTERFACE;
              }
  //            int classMods = cl.getModifiers() &
  //                (java.lang.reflect.Modifier.PUBLIC | java.lang.reflect.Modifier.FINAL |
  //                    java.lang.reflect.Modifier.INTERFACE | java.lang.reflect.Modifier.ABSTRACT);
  
              /*
               * compensate for javac bug in which ABSTRACT bit was set for an
               * interface only if the interface declared methods
               */
              if (type.getKind() == ElementKind.INTERFACE) {
                  if (ElementFilter.methodsIn(type.getEnclosedElements()).size() > 0) {
                      classMods |= java.lang.reflect.Modifier.ABSTRACT;
                  } else {
                      classMods &= ~java.lang.reflect.Modifier.ABSTRACT;
                  }
              }
  //            Method[] methods = cl.getDeclaredMethods();
  //            if ((classMods & Modifier.INTERFACE) != 0) {
  //                classMods = (methods.length > 0) ?
  //                    (classMods | Modifier.ABSTRACT) :
  //                    (classMods & ~Modifier.ABSTRACT);
  //            }
  
              dout.writeInt(classMods);
  
              if (!(type.asType() instanceof javax.lang.model.type.ArrayType)) {
  //            if (!cl.isArray()) {
                  /*
                   * compensate for change in 1.2FCS in which
                   * Class.getInterfaces() was modified to return Cloneable and
                   * Serializable for array classes.
                   */
                  List<? extends TypeMirror> interfaces = type.getInterfaces();
                  String[] ifaceNames = new String[interfaces.size()];
                  for (int i = 0; i < interfaces.size(); i++) {
                      ifaceNames[i] = ((TypeElement) ((DeclaredType) interfaces.get(i)).asElement()).getQualifiedName()
                              .toString();
                  }
  //                Class[] interfaces = cl.getInterfaces();
  //                String[] ifaceNames = new String[interfaces.length];
  //                for (int i = 0; i < interfaces.length; i++) {
  //                    ifaceNames[i] = interfaces[i].getName();
  //                }
                  Arrays.sort(ifaceNames);
                  for (int i = 0; i < ifaceNames.length; i++) {
                      dout.writeUTF(ifaceNames[i]);
                  }
              }
  
              List<? extends VariableElement> fields = ElementFilter.fieldsIn(type.getEnclosedElements());
              MemberSignature[] fieldSigs = new MemberSignature[fields.size()];
              for (int i = 0; i < fields.size(); i++) {
                  fieldSigs[i] = new MemberSignature(fields.get(i));
              }
  //            Field[] fields = cl.getDeclaredFields();
  //            MemberSignature[] fieldSigs = new MemberSignature[fields.length];
  //            for (int i = 0; i < fields.length; i++) {
  //                fieldSigs[i] = new MemberSignature(fields[i]);
  //            }
  
              Arrays.sort(fieldSigs, new Comparator<MemberSignature>() {
                  public int compare(MemberSignature o1, MemberSignature o2) {
                      String name1 = o1.name;
                      String name2 = o2.name;
                      return name1.compareTo(name2);
                  }
              });
              for (int i = 0; i < fieldSigs.length; i++) {
                  MemberSignature sig = fieldSigs[i];
                  int mods = asReflectiveModifiers(sig.member, Modifier.PUBLIC, Modifier.PRIVATE, Modifier.PROTECTED,
                          Modifier.STATIC, Modifier.FINAL, Modifier.VOLATILE, Modifier.TRANSIENT);
  //                int mods = sig.member.getModifiers() &
  //                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
  //                        Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
  //                        Modifier.TRANSIENT);
  
                  if (((mods & java.lang.reflect.Modifier.PRIVATE) == 0) ||
                          ((mods & (java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.TRANSIENT)) == 0)) {
                      dout.writeUTF(sig.name);
                      dout.writeInt(mods);
                      dout.writeUTF(sig.signature);
                  }
              }
  
              boolean hasStaticInitializer = false;
              for (Element e : type.getEnclosedElements()) {
                  if (e.getKind() == ElementKind.STATIC_INIT) {
                      hasStaticInitializer = true;
                      break;
                  }
              }
              if (hasStaticInitializer) {
                  dout.writeUTF("<clinit>");
                  dout.writeInt(java.lang.reflect.Modifier.STATIC);
                  dout.writeUTF("()V");
              }
  //            if (hasStaticInitializer(cl)) {
  //                dout.writeUTF("<clinit>");
  //                dout.writeInt(Modifier.STATIC);
  //                dout.writeUTF("()V");
  //            }
  
              List<ExecutableElement> ctors = ElementFilter.constructorsIn(type.getEnclosedElements());
              MemberSignature[] consSigs = new MemberSignature[ctors.size()];
              int i = 0;
              for (ExecutableElement ctor : ctors) {
                  consSigs[i++] = new MemberSignature(ctor);
              }
  //            Constructor[] cons = cl.getDeclaredConstructors();
  //            MemberSignature[] consSigs = new MemberSignature[cons.length];
  //            for (int i = 0; i < cons.length; i++) {
  //                consSigs[i] = new MemberSignature(cons[i]);
  //            }
  
              Arrays.sort(consSigs, new Comparator<MemberSignature>() {
                  public int compare(MemberSignature o1, MemberSignature o2) {
                      String sig1 = o1.signature;
                      String sig2 = o2.signature;
                      return sig1.compareTo(sig2);
                  }
              });
  //            Arrays.sort(consSigs, new Comparator() {
  //                public int compare(Object o1, Object o2) {
  //                    String sig1 = ((MemberSignature) o1).signature;
  //                    String sig2 = ((MemberSignature) o2).signature;
  //                    return sig1.compareTo(sig2);
  //                }
  //            });
  
              for (MemberSignature sig : consSigs) {
                  int mods = asReflectiveModifiers(sig.member, Modifier.PUBLIC, Modifier.PRIVATE, Modifier.PROTECTED,
                          Modifier.STATIC, Modifier.FINAL, Modifier.SYNCHRONIZED, Modifier.NATIVE, Modifier.ABSTRACT,
                          Modifier.STRICTFP);
                  if ((mods & java.lang.reflect.Modifier.PRIVATE) == 0) {
                      dout.writeUTF("<init>");
                      dout.writeInt(mods);
                      dout.writeUTF(sig.signature.replace('/', '.'));
                  }
              }
  //            for (int i = 0; i < consSigs.length; i++) {
  //                MemberSignature sig = consSigs[i];
  //                int mods = sig.member.getModifiers() &
  //                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
  //                        Modifier.STATIC | Modifier.FINAL |
  //                        Modifier.SYNCHRONIZED | Modifier.NATIVE |
  //                        Modifier.ABSTRACT | Modifier.STRICT);
  //                if ((mods & Modifier.PRIVATE) == 0) {
  //                    dout.writeUTF("<init>");
  //                    dout.writeInt(mods);
  //                    dout.writeUTF(sig.signature.replace('/', '.'));
  //                }
  //            }
  
              List<ExecutableElement> methods = ElementFilter.methodsIn(type.getEnclosedElements());
              MemberSignature[] methSigs = new MemberSignature[methods.size()];
              i = 0;
              for (ExecutableElement m : methods) {
                  methSigs[i++] = new MemberSignature(m);
              }
  //            MemberSignature[] methSigs = new MemberSignature[methods.length];
  //            for (int i = 0; i < methods.length; i++) {
  //                methSigs[i] = new MemberSignature(methods[i]);
  //            }
  
              Arrays.sort(methSigs, new Comparator<MemberSignature>() {
                  public int compare(MemberSignature ms1, MemberSignature ms2) {
                      int comp = ms1.name.compareTo(ms2.name);
                      if (comp == 0) {
                          comp = ms1.signature.compareTo(ms2.signature);
                      }
                      return comp;
                  }
              });
  //            Arrays.sort(methSigs, new Comparator() {
  //                public int compare(Object o1, Object o2) {
  //                    MemberSignature ms1 = (MemberSignature) o1;
  //                    MemberSignature ms2 = (MemberSignature) o2;
  //                    int comp = ms1.name.compareTo(ms2.name);
  //                    if (comp == 0) {
  //                        comp = ms1.signature.compareTo(ms2.signature);
  //                    }
  //                    return comp;
  //                }
  //            });
  
              for (MemberSignature sig : methSigs) {
                  int mods = asReflectiveModifiers(sig.member, Modifier.PUBLIC, Modifier.PRIVATE, Modifier.PROTECTED,
                          Modifier.STATIC, Modifier.FINAL, Modifier.SYNCHRONIZED, Modifier.NATIVE, Modifier.ABSTRACT,
                          Modifier.STRICTFP);
                  if ((mods & java.lang.reflect.Modifier.PRIVATE) == 0) {
                      dout.writeUTF(sig.name);
                      dout.writeInt(mods);
                      dout.writeUTF(sig.signature.replace('/', '.'));
                  }
              }
  //            for (int i = 0; i < methSigs.length; i++) {
  //                MemberSignature sig = methSigs[i];
  //                int mods = sig.member.getModifiers() &
  //                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
  //                        Modifier.STATIC | Modifier.FINAL |
  //                        Modifier.SYNCHRONIZED | Modifier.NATIVE |
  //                        Modifier.ABSTRACT | Modifier.STRICT);
  //                if ((mods & Modifier.PRIVATE) == 0) {
  //                    dout.writeUTF(sig.name);
  //                    dout.writeInt(mods);
  //                    dout.writeUTF(sig.signature.replace('/', '.'));
  //                }
  //            }
  //
              dout.flush();
  
              MessageDigest md = MessageDigest.getInstance("SHA");
              byte[] hashBytes = md.digest(bout.toByteArray());
              long hash = 0;
              for (i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
                  hash = (hash << 8) | (hashBytes[i] & 0xFF);
              }
              return hash;
          } catch (IOException | NoSuchAlgorithmException ex) {
              throw new IllegalStateException(
                      "Could not compute default serialization UID for class: " + type.getQualifiedName().toString(), ex);
          }
      }