@SmoothFunction
  @NotCacheable
  public static Array<SFile> files(NativeApiImpl nativeApi, FilesParameters params) {
    Path path = validatedPath("dir", params.dir());
    FileSystem fileSystem = nativeApi.projectFileSystem();

    if (path.isRoot()) {
      throw new CannotListRootDirError();
    }

    if (path.firstPart().equals(SMOOTH_DIR)) {
      throw new IllegalReadFromSmoothDirError(path);
    }

    switch (fileSystem.pathState(path)) {
      case DIR:
        return readFiles(nativeApi, fileSystem, path);
      case FILE:
        throw new NoSuchDirButFileError(path);
      case NOTHING:
        throw new NoSuchDirError(path);
      default:
        throw new Message(FATAL, "Broken 'files' function implementation: unreachable case");
    }
  }
  @Override
  public void save(Name name, SString string) {
    Path artifactPath = artifactPath(name);
    Path targetPath = targetPath(string);

    smoothFileSystem.delete(artifactPath);
    smoothFileSystem.createLink(artifactPath, targetPath);
  }
 private static Array<SFile> readFiles(NativeApiImpl nativeApi, FileSystem fileSystem, Path path) {
   ArrayBuilder<SFile> fileArrayBuilder = nativeApi.arrayBuilder(SFile.class);
   FileReader reader = new FileReader(nativeApi);
   for (Path filePath : fileSystem.filesFromRecursive(path)) {
     fileArrayBuilder.add(reader.createFile(filePath, path.append(filePath)));
   }
   return fileArrayBuilder.build();
 }