public getContentsUri(): string {
   if (!this.structure || !this.techName)
     throw FileSystemError.FileNotFound(this.path)
   const include = ADTClient.classIncludes(this.structure).get(this
     .techName as classIncludes)
   if (!include) throw FileSystemError.FileNotFound(this.path)
   return include
 }
    async _writeFile(uri: vscode.Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): Promise<void> {
        const exists = await _.exists(uri.fsPath);
        if (!exists) {
            if (!options.create) {
                throw vscode.FileSystemError.FileNotFound();
            }

            await _.mkdir(path.dirname(uri.fsPath));
        } else {
            if (!options.overwrite) {
                throw vscode.FileSystemError.FileExists();
            }
        }

        return _.writefile(uri.fsPath, content as Buffer);
    }
    function massageError(error: Error & { code?: string }): Error {
        if (error.code === 'ENOENT') {
            return vscode.FileSystemError.FileNotFound();
        }

        if (error.code === 'EISDIR') {
            return vscode.FileSystemError.FileIsADirectory();
        }

        if (error.code === 'EEXIST') {
            return vscode.FileSystemError.FileExists();
        }

        if (error.code === 'EPERM' || error.code === 'EACCESS') {
            return vscode.FileSystemError.NoPermissions();
        }

        return error;
    }
  public async getChildren(
    client: ADTClient
  ): Promise<AbapNodeComponentByCategory[]> {
    if (this.isLeaf()) throw FileSystemError.FileNotADirectory(this.vsName)
    if (!this.structure) await this.loadMetadata(client)
    if (!this.structure) throw FileSystemError.FileNotFound(this.vsName)

    const ns: NodeStructureMapped = {
      categories: new Map(),
      objectTypes: new Map(),
      nodes: []
    }
    const main = this.selfLeafNode()
    main.OBJECT_URI = ADTClient.mainInclude(this.structure)
    const sources = ADTClient.classIncludes(this.structure)
    this.structure.includes.forEach(i => {
      const node = {
        EXPANDABLE: "",
        OBJECT_NAME: this.name + "." + i["class:includeType"],
        OBJECT_TYPE: i["adtcore:type"],
        OBJECT_URI: sources.get(i["class:includeType"] as classIncludes) || "",
        OBJECT_VIT_URI: "",
        TECH_NAME: i["class:includeType"] // bit of a hack, used to match include metadata
      }
      if (node.OBJECT_URI) {
        if (i["abapsource:sourceUri"] === "source/main") ns.nodes.unshift(node)
        else ns.nodes.push(node)
      }
    })

    const aggregated = aggregateNodes(ns, this.type)
    for (const cat of aggregated)
      for (const type of cat.types)
        for (const incl of type.objects)
          if (isClassInclude(incl)) incl.setParent(this)

    return aggregated
  }
    async _rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean; }): Promise<void> {
        const exists = await _.exists(newUri.fsPath);
        if (exists) {
            if (!options.overwrite) {
                throw vscode.FileSystemError.FileExists();
            } else {
                await _.rmrf(newUri.fsPath);
            }
        }

        const parentExists = await _.exists(path.dirname(newUri.fsPath));
        if (!parentExists) {
            await _.mkdir(path.dirname(newUri.fsPath));
        }

        return _.rename(oldUri.fsPath, newUri.fsPath);
    }