code: func (t *TreeUpload) statPath(fullPath string, fi os.FileInfo) (nod *node, err error) {
  	defer func() {
  		if err == nil && nod != nil {
  			t.stattedc <- nod
  		}
  	}()
  	if t.up.Client.IsIgnoredFile(fullPath) {
  		return nil, nil
  	}
  	if fi == nil {
  		fi, err = t.up.lstat(fullPath)
  		if err != nil {
  			return nil, err
  		}
  	}
  	n := &node{
  		tu:       t,
  		fullPath: fullPath,
  		fi:       fi,
  	}
  	n.cond.L = &n.mu
  
  	if !fi.IsDir() {
  		return n, nil
  	}
  	f, err := t.up.open(fullPath)
  	if err != nil {
  		return nil, err
  	}
  	fis, err := f.Readdir(-1)
  	f.Close()
  	if err != nil {
  		return nil, err
  	}
  	sort.Sort(byTypeAndName(fis))
  	for _, fi := range fis {
  		depn, err := t.statPath(filepath.Join(fullPath, filepath.Base(fi.Name())), fi)
  		if err != nil {
  			return nil, err
  		}
  		if depn != nil {
  			n.children = append(n.children, depn)
  		}
  	}
  	return n, nil
  }
docs: // fi is optional (will be statted if nil)