whole_func_string: function applyPlugins(plugins = [], id, level, stats, ...rest) {
    if (!Array.isArray(plugins) || !plugins.every((p) => typeof p === 'function')) {
      throw new Error('Plugins MUST be an array of functions');
    }
    const args = Object.freeze(rest.map((arg) => Object.freeze(arg)));
    // mutable context object that passes into plugin function and
    // should be modified with new args or stats
    // id, level and initial arguments array MUST not be modified
    const ctx = {
      get id() {
        return id
      },
      get level() {
        return level
      },
      get arguments() {
        return args
      },
      stats,
      args: rest
    };
  
    plugins.forEach((pluginFn) => {
      pluginFn(ctx);
    });
    const resArgs = Array.isArray(ctx.args) && ctx.args.length ? ctx.args : ctx.arguments;
    return [id, level, ctx.stats, ...resArgs];
  }
func_code_string: function applyPlugins(plugins = [], id, level, stats, ...rest) {
    if (!Array.isArray(plugins) || !plugins.every((p) => typeof p === 'function')) {
      throw new Error('Plugins MUST be an array of functions');
    }
    const args = Object.freeze(rest.map((arg) => Object.freeze(arg)));
    // mutable context object that passes into plugin function and
    // should be modified with new args or stats
    // id, level and initial arguments array MUST not be modified
    const ctx = {
      get id() {
        return id
      },
      get level() {
        return level
      },
      get arguments() {
        return args
      },
      stats,
      args: rest
    };
  
    plugins.forEach((pluginFn) => {
      pluginFn(ctx);
    });
    const resArgs = Array.isArray(ctx.args) && ctx.args.length ? ctx.args : ctx.arguments;
    return [id, level, ctx.stats, ...resArgs];
  }
func_documentation_string: Run all plugins. Must return always non empty array with [id, level, stats, ...rest]
  
  @param {[]} plugins
  @param {string} id
  @param {string} level
  @param {{}} stats
  @param {*} rest
  @return {[]}