private Set<String> getEditorFieldCleanupExpressions() {
    Set<String> result = new LinkedHashSet<>();

    for (JClassType typeCandidate : model.getEditorType().getFlattenedSupertypeHierarchy()) {
      JClassType classType = typeCandidate.isClass();

      if (classType != null) {
        for (JField field : classType.getFields()) {
          JClassType fieldClassOrInterfaceType = field.getType().isClassOrInterface();

          if (fieldClassOrInterfaceType != null
              // field type assignable to HasCleanup ..
              && fieldClassOrInterfaceType.isAssignableTo(hasCleanupType)
              // .. but not assignable to Model
              && !fieldClassOrInterfaceType.isAssignableTo(baseModelType)) {
            result.add(
                String.format(
                    "getEditor().%s", //$NON-NLS-1$
                    field.getName()));
          }
        }
      }
    }

    return result;
  }
  private void writeCleanup() {
    logger.log(
        Type.DEBUG,
        "Starting to write cleanup impl. for editor " //$NON-NLS-1$
            + model.getEditorType().getQualifiedSourceName());

    sw.println();
    sw.println("@Override"); // $NON-NLS-1$
    sw.println("public void cleanup() {"); // $NON-NLS-1$
    sw.indent();

    // 1. clean up the Editor instance
    Set<String> editorFieldExpressions = getEditorFieldCleanupExpressions();

    for (String expr : editorFieldExpressions) {
      sw.println(String.format("if (%s != null) {", expr)); // $NON-NLS-1$
      sw.indent();

      sw.println(String.format("%s.cleanup();", expr)); // $NON-NLS-1$

      sw.outdent();
      sw.println("}"); // $NON-NLS-1$
    }

    // 2. clean up the edited Model object
    Set<String> modelExpressions = getModelCleanupExpressions();

    if (!modelExpressions.isEmpty()) {
      sw.println("if (getObject() != null) {"); // $NON-NLS-1$
      sw.indent();

      for (String expr : modelExpressions) {
        sw.println(String.format("%s.cleanup();", expr)); // $NON-NLS-1$
      }

      sw.outdent();
      sw.println("}"); // $NON-NLS-1$
    }

    sw.outdent();
    sw.println("}"); // $NON-NLS-1$
  }