int mods = c.getModifiers(); if (!Modifier.isPublic(mods) && !Modifier.isProtected(mods)) {
if (!c.isPublicOrProtected()) {
  public static boolean japizeClass(String n)      throws NoSuchMethodException, IllegalAccessException {    try {      // De-mangle the class name.      if (n.charAt(0) == ',') n = n.substring(1);      n = n.replace(',', '.');      // Get a ClassWrapper to work on.      ClassWrapper c = getClassWrapper(n);      // Load the class and check its accessibility.      int mods = c.getModifiers();      if (!Modifier.isPublic(mods) && !Modifier.isProtected(mods)) {        progress('-');        return false;      }      // Construct the basic strings that will be used in the output.      String entry = toClassRoot(c.getName()) + "!";      String classEntry = entry;      String type;      if (c.isEnum()) {        type = "enum";      } else if (c.isAnnotation()) {        type = "annotation";      } else if (c.isInterface()) {        type = "interface";      } else {        type = "class";      }      type += getTypeParamStr(c);            if (c.isInterface()) {        mods |= Modifier.ABSTRACT; // Interfaces are abstract by definition,      } else {        // Classes that happen to be Serializable get their SerialVersionUID        // output as well. The separation by the '#' character from the rest        // of the type string has mnemonic value for Brits, as the SVUID is a        // special sort of 'hash' of the class.        if (c.isSerializable() && !c.isEnum() && serialIncluded(c)) {          Long svuid = c.getSerialVersionUID();          if (svuid == null) lintPrint(c.getName() + " has a blank final serialVersionUID");          type += "#" + svuid;        }      }      // Iterate over the class's superclasses adding them to its "type" name,      // skipping any superclasses that are not public/protected.      int smods = mods;      ClassType supt = c.getSuperclass();      while (supt != null) {        ClassWrapper sup = supt.getWrapper();        smods = sup.getModifiers();        if (!Modifier.isPublic(smods) && !Modifier.isProtected(smods)) {          lintPrint(c.getName() + " has non-public class " + sup.getName() + " among its superclasses");          progress('^');        } else {          type += ":" + supt.getJavaRepr(c);        }        if (sup.getSuperclass() == null) {          supt = null;        } else {          supt = (ClassType) sup.getSuperclass().bind(supt);        }      }      type += mkIfaceString(c, "");      // Skip things that aren't entirely visible as defined below.      if (!isEntirelyVisible(c)) return false;      // Print out the japi entry for the class itself.      printEntry(entry, type, mods, c.isDeprecated(), false, false);      // Get the class's members.      BoundMemberSet members = getFieldsAndCalls(c, null);      BoundField[] fields = members.getFields();      BoundCall[] calls = members.getCalls();      // Iterate over the fields in the class.      for (int i = 0; i < fields.length; i++) {        // Get the modifiers and type of the field.        mods = fields[i].getModifiers();        // Fields of interfaces are *always* public, static and final, although        // wrapper implementations are inconsistent about telling us this.        if (fields[i].getDeclaringClass().isInterface()) {          mods |= Modifier.PUBLIC | Modifier.FINAL | Modifier.STATIC;        }        type = fields[i].getType().getTypeSig(c);        if (fields[i].getName().equals("serialVersionUID") &&            fields[i].getDeclaringClass() == c) {          if (c.isInterface()) {            lintPrint("Useless serialVersionUID field in interface " + c.getName());          } else if (!Modifier.isStatic(fields[i].getModifiers()) ||                     !Modifier.isFinal(fields[i].getModifiers())) {            lintPrint("serialVersionUID field in " + c.getName() + " not 'static final'");          } else if (!c.isSerializable()) {            lintPrint("serialVersionUID field in non-serializable class " + c.getName());          }        }        // If the field is nonfinal and either public or static, the class it's declared        // in can affect the behavior of code that uses it. However, we don't want to        // expose nonpublic classes so we find the nearest public/protected class instead.        // FIXME: difficult outstanding bug here: A and B both extend (nonpublic) C,        // C has a static field f. A.f and B.f are the same field but with this        // algorithm you can't tell that. What to do, what to do?        if (!Modifier.isFinal(fields[i].getModifiers()) &&            (Modifier.isPublic(fields[i].getModifiers()) ||             Modifier.isStatic(fields[i].getModifiers()))) {          ClassWrapper wrapper = c;          String declaringName = wrapper.getName();          while (!wrapper.equals(fields[i].getDeclaringClass())) {            wrapper = wrapper.getSuperclass().getWrapper();            if (Modifier.isPublic(wrapper.getModifiers()) ||                Modifier.isProtected(wrapper.getModifiers())) {              declaringName = wrapper.getName();            }          }          type += '=' + declaringName;        }        // A static, final field is a primitive constant if it is initialized to        // a compile-time constant.        if (fields[i].isPrimitiveConstant()) {          Object o = fields[i].getPrimitiveValue();          // Character values get int-ized to keep the output nice and 7bit.          if (o instanceof Character) {            type += ":" + (int)((Character)o).charValue();                    // String values get newlines and backslashes escaped to stop them from          // going onto a second line.          } else if (o instanceof String) {            String val = (String)o;            StringBuffer sb = new StringBuffer('\"');            int p = 0, q = 0;            while (q >= 0) {              q = val.indexOf("\n", p);              int r = val.indexOf("\\", p);              if (r >= 0 && (r < q || q < 0)) q = r;              if (q >= 0) {                sb.append(val.substring(p, q));                sb.append('\\');                if (val.charAt(q) == '\\') sb.append('\\'); else sb.append('n');                p = ++q;              }            }            sb.append(val.substring(p));            type += ":" + sb;          // Floats and doubles get their toRaw*Bits() value printed as well as          // their actual value.          } else if (o instanceof Float) {            type += ':' + o.toString() + '/' +                Integer.toHexString(Float.floatToRawIntBits(                                    ((Float) o).floatValue()));          } else if (o instanceof Double) {            type += ':' + o.toString() + '/' +                Long.toHexString(Double.doubleToRawLongBits(                                 ((Double) o).doubleValue()));          // Other types just get output.          } else {            type += ":" + o;          }        }        // Skip things that aren't entirely visible as defined below.        if (!isEntirelyVisible(fields[i])) continue;        // Output the japi entry for the field.        printEntry(classEntry + "#" + fields[i].getName(), type, mods,                   fields[i].isDeprecated() || c.isDeprecated(), fields[i].isEnumField(), false);      }      // Iterate over the methods and constructors in the class.      for (int i = 0; i < calls.length; i++) {        // Skip calls called <init> and <clinit>. Constructors are handled        // with an empty method name, and class initializers are never part of        // the public API.        // This code is probably dead since I'm pretty sure ClassFile knows to        // give us these in the right form.        if ("<init>".equals(calls[i].getName()) ||            "<clinit>".equals(calls[i].getName())) {          continue;        }        // Skip methods in interfaces that are also defined identically in        // Object. Specifically, it needs to be defined in Object with        // *exactly* the same parameter types, return types *and* thrown        // exceptions (because it *is* legal for an interface to specify,        // say, "Object clone();" and thereby specify that implementors must        // not throw CloneNotSupportedException from their clone method.        // Surprisingly, Cloneable doesn't do this...)        if (c.isInterface() &&            objCalls.contains(getObjComparableString(calls[i]))) {          progress(';');          continue;        }        // Skip things that aren't entirely visible as defined below.        if (!isEntirelyVisible(calls[i])) continue;        // Construct the name of the method, of the form Class!method(params).        entry = classEntry + calls[i].getName() + "(";        Type[] params = calls[i].getParameterTypes();        String comma = "";        for (int j = 0; j < params.length; j++) {          entry += comma + params[j].getTypeSig(calls[i]);          comma = ",";        }        entry += ")";        if (!calls[i].isVisible14()) {          entry += "+";        } else if (!calls[i].isVisible15()) {          entry += "-";          // Find the next call that would be included. If it has the exact same          // nonGenericSig, we need a double-minus instead of a          // single one.          if (i < calls.length) {            for (int j = i + 1; j < calls.length; j++) {              if (!calls[j].getNonGenericSig().equals(calls[i].getNonGenericSig())) break;              // All the reasons we might skip an item above, we skip it here as well.              if ("<init>".equals(calls[j].getName()) ||                  "<clinit>".equals(calls[j].getName())) {                continue;              }              if (c.isInterface() &&                  objCalls.contains(getObjComparableString(calls[j]))) {                continue;              }              if (!isEntirelyVisible(calls[j])) continue;              entry += "-";              break;            }          }        }        // Construct the "type" field, of the form returnType*exception*except2...        type = "";        // ... but if it's a generic method it gets the type parameters first        type += getTypeParamStr(calls[i]);        Type rtnType = calls[i].getReturnType();        type += (rtnType == null) ? "constructor" : rtnType.getTypeSig(calls[i]);        boolean isStub = false;        NonArrayRefType[] excps = calls[i].getExceptionTypes();        for (int j = 0; j < excps.length; j++) {          if (includeException(excps, j)) type += "*" + excps[j].getJavaRepr(calls[i]);          if (excps[j] instanceof ClassType &&              ((ClassType) excps[j]).getName().endsWith(".NotImplementedException")) {            isStub = true;          }        }        // Get the modifiers for this method. Methods of interfaces are        // by definition public and abstract, although wrapper implementations        // are inconsistent about telling us this.        int mmods = calls[i].getModifiers();        if (c.isInterface()) {          mmods |= Modifier.ABSTRACT | Modifier.PUBLIC;        }        // Methods of final classes are by definition final        if (Modifier.isFinal(c.getModifiers())) {          mmods |= Modifier.FINAL;        }        // Constructors are never final. The verifier should enforce this        // so this should always be a no-op, except for when the line above        // set it.        if ("".equals(calls[i].getName())) {          mmods &= ~Modifier.FINAL;        }        // Print the japi entry for the method.        printEntry(entry, type, mmods, calls[i].isDeprecated() || c.isDeprecated(), false, isStub);      }      // Return true because we did parse this class.      progress('+');      return true;    } catch (ClassNotFoundException e) {      System.err.println("\nFailed to Japize " + n + ": " + e);      e.printStackTrace();    } catch (RuntimeException e) {      System.err.println("\nFailed to Japize " + n + ": " + e);      e.printStackTrace();    }    return false;  }