code: func findEntities(paths, excludes []string) ([]*Table, []error, error) {
  	var entities []*Table
  	var warnings []error
  	for _, path := range paths {
  		fileSet := token.NewFileSet()
  		packages, err := parser.ParseDir(fileSet, path, func(fileInfo os.FileInfo) bool {
  			if len(excludes) == 0 {
  				return true
  			}
  			for _, exclude := range excludes {
  				if matched, _ := filepath.Match(exclude, fileInfo.Name()); matched {
  					return false
  				}
  			}
  			return true
  		}, 0)
  		if err != nil {
  			return nil, nil, err
  		}
  		erv := new(entityRecordingVisitor)
  		for _, pkg := range packages { // go through all the packages
  			for _, file := range pkg.Files { // go through all the files
  				packagePrefix, hasDosa := findDosaPackage(file)
  				//if erv.PackageName != "" { // skip packages that don't import 'dosa'
  				if hasDosa {
  					erv.packagePrefix = packagePrefix
  					for _, decl := range file.Decls { // go through all the declarations
  						ast.Walk(erv, decl)
  					}
  				}
  			}
  		}
  		entities = append(entities, erv.entities...)
  		warnings = append(warnings, erv.warnings...)
  	}
  
  	return entities, warnings, nil
  }
docs: // findEntities finds all entities in the given file paths. An error is
  // returned if there are naming collisions, otherwise, return a slice of
  // warnings (or nil).