public static async Task<PathInfo> FromFSPath(string path)
 {
     if (PathInfoCache.Contains(path))
     {
         return PathInfoCache.Get(path) as PathInfo;
     }
     string[] sections;
     var sectionCount = parsePathIntoParts(path, out sections);
     switch (sectionCount)
     {
         case -1:
             return null;
         case 0:
             {
                 if (PathInfoCache.Contains(""))
                 {
                     return PathInfoCache.Get("") as PathInfo;
                 }
                 else
                 {
                     PathInfoCache[""] = new RootInfo();
                     return PathInfoCache.Get("") as PathInfo;
                 }
             }
         case 1:
             {
                 var org = new OrgInfo(sections[0]);
                 if (await org.Exists())
                 {
                     return org;
                 }
                 var user = new UserInfo(sections[0]);
                 if (await user.Exists())
                 {
                     return user;
                 }
                 return null;
             }
         case 2:
             {
                 var repo = new RepoInfo(sections[0], sections[1]);
                 return await repo.Exists() ? repo : null;
             }
         default:
             {
                 var filepath = Path.Combine(sections.Skip(2).Take(sections.Length - 2).ToArray());
                 var folder = new FolderInfo(sections[0], sections[1], filepath, null);
                 if (await folder.Exists())
                 {
                     return folder;
                 }
                 var file = new FileInfo(sections[0], sections[1], filepath, null);
                 if (await file.Exists())
                 {
                     return file;
                 }
                 return null;
             }
     }
 }