gt:             if (p == fn.length()-1) break;
context: /*
   * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package com.sun.tools.sjavac.comp;
  
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.net.URI;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  import javax.tools.*;
  import javax.tools.JavaFileObject.Kind;
  
  import com.sun.tools.javac.file.JavacFileManager;
  import com.sun.tools.javac.util.DefinedBy;
  import com.sun.tools.javac.util.DefinedBy.Api;
  import com.sun.tools.javac.util.ListBuffer;
  
  /**
   * Intercepts reads and writes to the file system to gather
   * information about what artifacts are generated.
   *
   * Traps writes to certain files, if the content written is identical
   * to the existing file.
   *
   * Can also blind out the filemanager from seeing certain files in the file system.
   * Necessary to prevent javac from seeing some sources where the source path points.
   *
   *  <p><b>This is NOT part of any supported API.
   *  If you write code that depends on this, you do so at your own risk.
   *  This code and its internal interfaces are subject to change or
   *  deletion without notice.</b>
   */
  @com.sun.tools.javac.api.ClientCodeWrapper.Trusted
  public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
  
      // Set of sources that can be seen by javac.
      Set<URI> visibleSources = new HashSet<>();
      // Map from modulename:packagename to artifacts.
      Map<String,Set<URI>> packageArtifacts = new HashMap<>();
      // Where to print informational messages.
      PrintWriter stdout;
  
      public SmartFileManager(JavaFileManager fileManager) {
          super(fileManager);
      }
  
      public void setVisibleSources(Set<URI> s) {
          visibleSources = s;
      }
  
      public void cleanArtifacts() {
          packageArtifacts = new HashMap<>();
      }
  
      public void setLog(PrintWriter pw) {
          stdout = pw;
      }
  
      /**
       * Set whether or not to use ct.sym as an alternate to rt.jar.
       */
      public void setSymbolFileEnabled(boolean b) {
          if (!(fileManager instanceof JavacFileManager))
              throw new IllegalStateException();
          ((JavacFileManager) fileManager).setSymbolFileEnabled(b);
      }
  
      @DefinedBy(Api.COMPILER)
      public String inferBinaryName(Location location, JavaFileObject file) {
          return super.inferBinaryName(location, locUnwrap(file));
      }
  
  
      public Map<String,Set<URI>> getPackageArtifacts() {
          return packageArtifacts;
      }
  
      @Override @DefinedBy(Api.COMPILER)
      public Iterable<JavaFileObject> list(Location location,
                                           String packageName,
                                           Set<Kind> kinds,
                                           boolean recurse) throws IOException {
          // TODO: Do this lazily by returning an iterable with a filtering Iterator
          // Acquire the list of files.
          Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
          if (visibleSources.isEmpty()) {
              return locWrapMany(files, location);
          }
          // Now filter!
          ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<>();
          for (JavaFileObject f : files) {
              URI uri = f.toUri();
              String t = uri.toString();
              if (t.startsWith("jar:")
                  || t.endsWith(".class")
                  || visibleSources.contains(uri)) {
                  filteredFiles.add(f);
              }
          }
  
          return locWrapMany(filteredFiles, location);
      }
  
      @Override @DefinedBy(Api.COMPILER)
      public JavaFileObject getJavaFileForInput(Location location,
                                                String className,
                                                Kind kind) throws IOException {
          JavaFileObject file = super.getJavaFileForInput(location, className, kind);
          file = locWrap(file, location);
          if (file == null || visibleSources.isEmpty()) {
              return file;
          }
  
          if (visibleSources.contains(file.toUri())) {
              return file;
          }
          return null;
      }
  
      @Override @DefinedBy(Api.COMPILER)
      public JavaFileObject getJavaFileForOutput(Location location,
                                                 String className,
                                                 Kind kind,
                                                 FileObject sibling) throws IOException {
          JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
          file = locWrap(file, location);
          if (file == null) return file;
          int dp = className.lastIndexOf('.');
          String pkg_name = "";
          if (dp != -1) {
              pkg_name = className.substring(0, dp);
          }
          // When modules are in use, then the mod_name might be something like "jdk_base"
          String mod_name = "";
          addArtifact(mod_name+":"+pkg_name, file.toUri());
          return file;
      }
  
      @Override @DefinedBy(Api.COMPILER)
      public FileObject getFileForInput(Location location,
                                        String packageName,
                                        String relativeName) throws IOException {
          FileObject file =  super.getFileForInput(location, packageName, relativeName);
          file = locWrap(file, location);
          if (file == null || visibleSources.isEmpty()) {
              return file;
          }
  
          if (visibleSources.contains(file.toUri())) {
              return file;
          }
          return null;
      }
  
      @Override @DefinedBy(Api.COMPILER)
      public FileObject getFileForOutput(Location location,
                                         String packageName,
                                         String relativeName,
                                         FileObject sibling) throws IOException {
          FileObject superFile = super.getFileForOutput(location, packageName, relativeName, sibling);
          FileObject file = locWrap(superFile, location);
          if (file == null) return file;
  
          if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) && superFile instanceof JavaFileObject) {
             file = new SmartFileObject((JavaFileObject) file, stdout);
             packageName = ":" + packageNameFromFileName(relativeName);
          }
          if (packageName.equals("")) {
              packageName = ":";
          }
          addArtifact(packageName, file.toUri());
          return file;
      }
  
      private static String packageNameFromFileName(String fn) {
          StringBuilder sb = new StringBuilder();
          int p = fn.indexOf('_'), pp = 0;
          while (p != -1) {
              if (sb.length() > 0) sb.append('.');
              sb.append(fn.substring(pp,p));
  