function SpyStrategyDispatcher(strategyArgs, matchersUtil) {
      const baseStrategy = new j$.SpyStrategy(strategyArgs);
      const argsStrategies = new StrategyDict(function () {
        return new j$.SpyStrategy(strategyArgs);
      }, matchersUtil);

      this.and = baseStrategy;

      this.exec = function (spy, args, invokeNew) {
        let strategy = argsStrategies.get(args);

        if (!strategy) {
          if (argsStrategies.any() && !baseStrategy.isConfigured()) {
            throw new Error(
              "Spy '" +
                strategyArgs.name +
                "' received a call with arguments " +
                j$.basicPrettyPrinter_(Array.prototype.slice.call(args)) +
                ' but all configured strategies specify other arguments.',
            );
          } else {
            strategy = baseStrategy;
          }
        }

        return strategy.exec(spy, args, invokeNew);
      };

      this.withArgs = function () {
        return { and: argsStrategies.getOrCreate(arguments) };
      };
    }
Specifies a strategy to be used for calls to the spy that have the
specified arguments.
@name Spy#withArgs
@since 3.0.0
@function
@param {...*} args - The arguments to match
@type {SpyStrategy}
@example
spyOn(someObj, 'func').withArgs(1, 2, 3).and.returnValue(42);
someObj.func(1, 2, 3); // returns 42