public List<ReferenceType> visibleClasses() {
    List<ReferenceType> classes = null;
    try {
      Cache local = (Cache) getCache();

      if (local != null) {
        classes = local.visibleClasses;
      }
      if (classes == null) {
        JDWP.ClassLoaderReference.VisibleClasses.ClassInfo[] jdwpClasses =
            JDWP.ClassLoaderReference.VisibleClasses.process(vm, this).classes;
        classes = new ArrayList<ReferenceType>(jdwpClasses.length);
        for (int i = 0; i < jdwpClasses.length; ++i) {
          classes.add(vm.referenceType(jdwpClasses[i].typeID, jdwpClasses[i].refTypeTag));
        }
        classes = Collections.unmodifiableList(classes);
        if (local != null) {
          local.visibleClasses = classes;
          if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
            vm.printTrace(
                description()
                    + " temporarily caching visible classes (count = "
                    + classes.size()
                    + ")");
          }
        }
      }
    } catch (JDWPException exc) {
      throw exc.toJDIException();
    }
    return classes;
  }