whole_func_string: async function() {
        this.__repositories = [];
        this.__libraries = {};
        this.__latestCompatible = {};
        const localPathRepoName = this.self(arguments).localPathRepoName;
  
        let repos_cache = this.getCache().repos;
  
        // implicit qx contrib update
        if (repos_cache.list.length === 0 || this.getCache().version !== qx.tool.cli.ConfigSchemas.lockfile.version) {
          //await (new qx.tool.cli.commands.contrib.Update({quiet:true})).process();
        }
  
        let qooxdoo_version = await this.getUserQxVersion();
        let num_compat_repos = await this.__createIndexes(qooxdoo_version);
        if (this.argv.verbose) {
          console.log(`>>> We have ${num_compat_repos} contrib repositories which contain libraries compatible with qooxdoo version ${qooxdoo_version}`);
        }
  
        if (num_compat_repos === 0 && !this.argv.all && !this.argv.quiet) {
          console.info(
            `Currently, no contrib libraries with releases compatible with qooxdoo version ${qooxdoo_version} exist.`
          );
          return;
        }
  
        // detailed repo information
        let repo = this.argv.repository;
        if (repo) {
          if (!repos_cache.list.includes(repo)) {
            throw new qx.tool.cli.Utils.UserError(
              `Repository ${repo} does not exist or is not a qooxdoo contrib repo.`
            );
          }
          if (this.__libraries[repo] && this.__libraries[repo].length) {
            let columnify_options = {
              columnSplitter: "   ",
              config: {
                description: {maxWidth: 60},
                compatibility : {
                  dataTransform: function(data) {
                    switch (data) {
                      case "false": return "not compatible / untested";
                      case "true": return "√";
                      default: return "";
                    }
                  }
                }
              }
            };
            if (!this.argv.quiet) {
              console.info(columnify(this.__libraries[repo], columnify_options));
            }
          } else if (this.argv.verbose) {
            console.info(`Repository ${repo} does not contain suitable contrib libraries.`);
          }
          return;
        }
  
        // list output
        let columns = this.argv.short ?
          ["uri", "installedVersion", "latestVersion", "latestCompatible"] :
          ["uri", "name", "description", "installedVersion", "latestVersion", "latestCompatible"];
        if (this.argv.namespace || this.argv.installed) {
          columns.splice(1, 0, "namespace");
        }
        let columnify_options = {
          showHeaders: !this.argv.noheaders,
          columnSplitter: "   ",
          columns,
          config: {
            name: {maxWidth:25},
            description: {maxWidth: 60},
            installedVersion: {
              headingTransform : () => "INSTALLED",
              dataTransform: data => (data === "false" ? "" : data)
            },
            latestVersion: {
              headingTransform : () => "LATEST",
              dataTransform: data => (data === "false" ? "-" : data)
            },
            latestCompatible : {
              headingTransform : () => "COMPATIBLE",
              dataTransform: data => (data === "false" ? "-" : data)
            }
          }
        };
        // filter by compatibility unless --all
        let list =
          this.argv.all ?
            this.__repositories :
            this.__repositories.filter(item => item.latestCompatible || (this.argv.installed && item.name === localPathRepoName));
        // sort
        list.sort((l, r) => {
          l = l.name.toLowerCase();
          r = r.name.toLowerCase();
          return l < r ? -1 : l > r ? 1 : 0;
        });
        // list all libraries contained in a repo
        let expanded_list = [];
        for (let repo of list) {
          let repo_libs = [];
          if (!qx.lang.Type.isArray(this.__libraries[repo.name])) {
            continue;
          }
          for (let library of this.__libraries[repo.name]) {
            if (!semver.valid(library.version)) {
              console.warn(`>>> Ignoring '${repo.name}' ${library.name}': invalid version format '${library.version}'.`);
              continue;
            }
            if (repo.name === localPathRepoName || semver.eq(library.version, repo.latestVersion)) {
              let uri = repo.name === this.self(arguments).localPathRepoName ?
                library.path :
                path.join(repo.name, library.path || "");
              repo_libs.push({
                type: "library",
                uri,
                namespace: library.namespace,
                name: library.name,
                description: library.summary || repo.description,
                installedVersion: library.installedVersion,
                latestVersion: repo.latestVersion,
                latestCompatible: repo.latestCompatible
              });
            }
          }
  
          // add title to multiple-library repos
          if (repo_libs.length > 1 && !(this.argv["only-libraries"] || this.argv.short || repo.name === localPathRepoName)) {
            expanded_list.push({
              type: "repository",
              uri: repo.name,
              name: "",
              description: repo.description,
              installedVersion: "",
              latestVersion: repo.latestVersion,
              latestCompatible: repo.latestCompatible
            });
            if (!this.argv.json && !this.argv.installed && !this.argv.match) {
              // add an indent to group libraries in a repository
              repo_libs = repo_libs.map(lib => {
                lib.uri = "| " + lib.uri;
                return lib;
              });
            }
          }
          expanded_list = expanded_list.concat(repo_libs);
        }
        // filter by regular expression if requested
        if (this.argv.match) {
          let exp = new RegExp(this.argv.match, "i");
          expanded_list = expanded_list.filter(lib => lib.uri.match(exp) || lib.name.match(exp) || lib.description.match(exp));
        }
  
        // show only installed libraries if requested
        if (this.argv.installed) {
          expanded_list = expanded_list.filter(lib => Boolean(lib.installedVersion));
        }
  
        // output list
        if (this.argv.json) {
          // as JSON
          console.info(JSON.stringify(expanded_list, null, 2));
        } else if (!this.argv.quiet) {
          // as columns
          console.info(columnify(expanded_list, columnify_options));
          if (!this.argv.noheaders) {
            console.info();
            console.info("Note on columns: LATEST: Latest release that can be installed with this CLI;");
            console.info("                 COMPATIBLE: Latest release that is semver-compatible with the qooxdoo version used.");
            if (!this.argv.all) {
              console.info("To see all libraries, including potentially incompatible ones, use 'qx contrib list --all'.");
            }
          }
        }
  
        // save to cache
        this.getCache().compat[qooxdoo_version] = this.__latestCompatible[qooxdoo_version];
        await this.saveCache();
      }
func_code_string: async function() {
        this.__repositories = [];
        this.__libraries = {};
        this.__latestCompatible = {};
        const localPathRepoName = this.self(arguments).localPathRepoName;
  
        let repos_cache = this.getCache().repos;
  
        // implicit qx contrib update
        if (repos_cache.list.length === 0 || this.getCache().version !== qx.tool.cli.ConfigSchemas.lockfile.version) {
          //await (new qx.tool.cli.commands.contrib.Update({quiet:true})).process();
        }
  
        let qooxdoo_version = await this.getUserQxVersion();
        let num_compat_repos = await this.__createIndexes(qooxdoo_version);
        if (this.argv.verbose) {
          console.log(`>>> We have ${num_compat_repos} contrib repositories which contain libraries compatible with qooxdoo version ${qooxdoo_version}`);
        }
  
        if (num_compat_repos === 0 && !this.argv.all && !this.argv.quiet) {
          console.info(
            `Currently, no contrib libraries with releases compatible with qooxdoo version ${qooxdoo_version} exist.`
          );
          return;
        }
  
        // detailed repo information
        let repo = this.argv.repository;
        if (repo) {
          if (!repos_cache.list.includes(repo)) {
            throw new qx.tool.cli.Utils.UserError(
              `Repository ${repo} does not exist or is not a qooxdoo contrib repo.`
            );
          }
          if (this.__libraries[repo] && this.__libraries[repo].length) {
            let columnify_options = {
              columnSplitter: "   ",
              config: {
                description: {maxWidth: 60},
                compatibility : {
                  dataTransform: function(data) {
                    switch (data) {
                      case "false": return "not compatible / untested";
                      case "true": return "√";
                      default: return "";
                    }
                  }
                }
              }
            };
            if (!this.argv.quiet) {
              console.info(columnify(this.__libraries[repo], columnify_options));
            }
          } else if (this.argv.verbose) {
            console.info(`Repository ${repo} does not contain suitable contrib libraries.`);
          }
          return;
        }
  
        // list output
        let columns = this.argv.short ?
          ["uri", "installedVersion", "latestVersion", "latestCompatible"] :
          ["uri", "name", "description", "installedVersion", "latestVersion", "latestCompatible"];
        if (this.argv.namespace || this.argv.installed) {
          columns.splice(1, 0, "namespace");
        }
        let columnify_options = {
          showHeaders: !this.argv.noheaders,
          columnSplitter: "   ",
          columns,
          config: {
            name: {maxWidth:25},
            description: {maxWidth: 60},
            installedVersion: {
              headingTransform : () => "INSTALLED",
              dataTransform: data => (data === "false" ? "" : data)
            },
            latestVersion: {
              headingTransform : () => "LATEST",
              dataTransform: data => (data === "false" ? "-" : data)
            },
            latestCompatible : {
              headingTransform : () => "COMPATIBLE",
              dataTransform: data => (data === "false" ? "-" : data)
            }
          }
        };
        // filter by compatibility unless --all
        let list =
          this.argv.all ?
            this.__repositories :
            this.__repositories.filter(item => item.latestCompatible || (this.argv.installed && item.name === localPathRepoName));
        // sort
        list.sort((l, r) => {
          l = l.name.toLowerCase();
          r = r.name.toLowerCase();
          return l < r ? -1 : l > r ? 1 : 0;
        });
        // list all libraries contained in a repo
        let expanded_list = [];
        for (let repo of list) {
          let repo_libs = [];
          if (!qx.lang.Type.isArray(this.__libraries[repo.name])) {
            continue;
          }
          for (let library of this.__libraries[repo.name]) {
            if (!semver.valid(library.version)) {
              console.warn(`>>> Ignoring '${repo.name}' ${library.name}': invalid version format '${library.version}'.`);
              continue;
            }
            if (repo.name === localPathRepoName || semver.eq(library.version, repo.latestVersion)) {
              let uri = repo.name === this.self(arguments).localPathRepoName ?
                library.path :
                path.join(repo.name, library.path || "");
              repo_libs.push({
                type: "library",
                uri,
                namespace: library.namespace,
                name: library.name,
                description: library.summary || repo.description,
                installedVersion: library.installedVersion,
                latestVersion: repo.latestVersion,
                latestCompatible: repo.latestCompatible
              });
            }
          }
  
          // add title to multiple-library repos
          if (repo_libs.length > 1 && !(this.argv["only-libraries"] || this.argv.short || repo.name === localPathRepoName)) {
            expanded_list.push({
              type: "repository",
              uri: repo.name,
              name: "",
              description: repo.description,
              installedVersion: "",
              latestVersion: repo.latestVersion,
              latestCompatible: repo.latestCompatible
            });
            if (!this.argv.json && !this.argv.installed && !this.argv.match) {
              // add an indent to group libraries in a repository
              repo_libs = repo_libs.map(lib => {
                lib.uri = "| " + lib.uri;
                return lib;
              });
            }
          }
          expanded_list = expanded_list.concat(repo_libs);
        }
        // filter by regular expression if requested
        if (this.argv.match) {
          let exp = new RegExp(this.argv.match, "i");
          expanded_list = expanded_list.filter(lib => lib.uri.match(exp) || lib.name.match(exp) || lib.description.match(exp));
        }
  
        // show only installed libraries if requested
        if (this.argv.installed) {
          expanded_list = expanded_list.filter(lib => Boolean(lib.installedVersion));
        }
  
        // output list
        if (this.argv.json) {
          // as JSON
          console.info(JSON.stringify(expanded_list, null, 2));
        } else if (!this.argv.quiet) {
          // as columns
          console.info(columnify(expanded_list, columnify_options));
          if (!this.argv.noheaders) {
            console.info();
            console.info("Note on columns: LATEST: Latest release that can be installed with this CLI;");
            console.info("                 COMPATIBLE: Latest release that is semver-compatible with the qooxdoo version used.");
            if (!this.argv.all) {
              console.info("To see all libraries, including potentially incompatible ones, use 'qx contrib list --all'.");
            }
          }
        }
  
        // save to cache
        this.getCache().compat[qooxdoo_version] = this.__latestCompatible[qooxdoo_version];
        await this.saveCache();
      }
func_documentation_string: Lists contrib libraries compatible with the current project