// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'configuration.dart';
import 'path.dart';
import 'runtime_updater.dart';
import 'utils.dart';

const _defaultTestSelectors = const [
  'samples',
  'standalone',
  'corelib_2',
  'co19',
  'language',
  'language_2',
  'isolate',
  'vm',
  'html',
  'benchmark_smoke',
  'utils',
  'lib',
  'lib_2',
  'analyze_library',
  'service',
  'kernel',
  'observatory_ui'
];

/// Specifies a single command line option.
///
/// The name of the specification is used as the key for the option in the Map
/// returned from the [TestOptionParser] parse method.
class _Option {
  // TODO(rnystrom): Some string options use "" to mean "no value" and others
  // use null. Clean that up.
  _Option(this.name, this.description,
      {String abbr, List<String> values, String defaultsTo})
      : abbreviation = abbr,
        values = values ?? [],
        defaultValue = defaultsTo,
        type = _OptionValueType.string;

  _Option.bool(this.name, this.description, [this.abbreviation])
      : values = [],
        defaultValue = false,
        type = _OptionValueType.bool;

  _Option.int(this.name, this.description, {String abbr, int defaultsTo})
      : abbreviation = abbr,
        values = [],
        defaultValue = defaultsTo,
        type = _OptionValueType.int;

  final String name;
  final String description;
  final String abbreviation;
  final List<String> values;
  final Object defaultValue;
  final _OptionValueType type;

  /// Gets the shortest command line argument used to refer to this option.
  String get shortCommand => abbreviation != null ? "-$abbreviation" : command;

  /// Gets the canonical long command line argument used to refer to this
  /// option.
  String get command => "--${name.replaceAll('_', '-')}";
}

enum _OptionValueType { bool, int, string }

/// Parses command line arguments and produces a test runner configuration.
class OptionsParser {
  static final List<_Option> _options = [
    new _Option('mode', 'Mode in which to run the tests.',
        abbr: 'm',
        values: ['all']..addAll(Mode.names),
        defaultsTo: Mode.debug.name),
    new _Option(
        'compiler',
        '''Specify any compilation step (if needed).

none:          Do not compile the Dart code (run native Dart code
               on the VM).
               (Only valid with runtimes vm, flutter, or drt.)

precompiler:   Compile into AOT snapshot before running the test.
               (Only valid with runtime dart_precompiled.)

dart2js:       Compile dart code to JavaScript by running dart2js.
               (Only valid with runtimes: d8, drt, chrome, safari,
               ie9, ie10, ie11, firefox, opera, chromeOnAndroid,
               and none [compile only].)

dart2analyzer: Perform static analysis on Dart code by running the
               analyzer.
               (Only valid with runtime none.)

app_jit:       Compile the Dart code into an app snapshot before
               running test.
               (Only valid with dart_app runtime.)

dartk:         Compile the Dart source into Kernel before running
               test.

dartkp:        Compile the Dart source into Kernel and then Kernel
               into AOT snapshot before running the test.
               (Only valid with runtime dart_precompiled.)''',
        abbr: 'c',
        values: Compiler.names,
        defaultsTo: Compiler.none.name),
    new _Option(
        'runtime',
        '''Where the tests should be run.
vm:               Run Dart code on the standalone dart vm.

flutter:          Run Dart code on the flutter engine.

dart_precompiled: Run a precompiled snapshot on a variant of the
                  standalone dart VM lacking a JIT.

d8:               Run JavaScript from the command line using v8.

jsshell:          Run JavaScript from the command line using
                  Firefox js-shell.

drt:              Run Dart or JavaScript in the headless version
                  of Chrome, Content shell.

ContentShellOnAndroid: Run Dart or JavaScript in content shell
                  on Android.

ff:
chrome:
safari:
ie9:
ie10:
ie11:
opera:
chromeOnAndroid:  Run JavaScript in the specified browser.

self_check:       Pass each test or its compiled output to every
                  file under `pkg` whose name ends with
                  `_self_check.dart`. Each test is given to the
                  self_check tester as a filename on stdin using
                  the batch-mode protocol.

none:             No runtime, compile only. (For example, used
                  for dart2analyzer static analysis tests).''',
        abbr: 'r',
        values: Runtime.names,
        defaultsTo: Runtime.vm.name),
    new _Option(
        'arch',
        '''The architecture to run tests for.

Allowed values are:
all
ia32, x64
arm, armv6, armv5te, arm64,
simarm, simarmv6, simarmv5te, simarm64,
simdbc, simdbc64''',
        abbr: 'a',
        values: ['all']..addAll(Architecture.names),
        defaultsTo: Architecture.x64.name),
    new _Option('system', 'The operating system to run tests on.',
        abbr: 's', values: System.names, defaultsTo: Platform.operatingSystem),
    new _Option.bool('checked', 'Run tests in checked mode.'),
    new _Option.bool('strong', 'Run tests in strong mode.'),
    new _Option.bool('host_checked', 'Run compiler in checked mode.'),
    new _Option.bool('minified', 'Enable minification in the compiler.'),
    new _Option.bool(
        'csp', 'Run tests under Content Security Policy restrictions.'),
    new _Option.bool(
        'fast_startup', 'Pass the --fast-startup flag to dart2js.'),
    new _Option.bool('enable_asserts',
        'Pass the --enable-asserts flag to dart2js or to the vm.'),
    new _Option.bool(
        'preview_dart_2', 'Pass the --preview-dart-2 flag to analyzer.'),
    // TODO(sigmund): replace dart2js_with_kernel with preview-dart-2.
    new _Option.bool(
        'dart2js_with_kernel', 'Pass the --use-kernel flag to dart2js.'),
    new _Option.bool('dart2js_with_kernel_in_ssa',
        'Pass the --use-kernel-in-ssa flag to dart2js.'),
    new _Option.bool('hot_reload', 'Run hot reload stress tests.'),
    new _Option.bool(
        'hot_reload_rollback', 'Run hot reload rollback stress tests.'),
    new _Option.bool('use_blobs',
        'Use mmap instead of shared libraries for precompilation.'),
    new _Option.int('timeout', 'Timeout in seconds.', abbr: 't'),
    new _Option(
        'progress',
        '''Progress indication mode.

Allowed values are:
compact, color, line, verbose, silent, status, buildbot, diff
''',
        abbr: 'p',
        values: Progress.names,
        defaultsTo: Progress.compact.name),
    new _Option('step_name', 'Step name for use by -pbuildbot.'),
    new _Option.bool('report',
        'Print a summary report of the number of tests, by expectation.'),
    new _Option.int('tasks', 'The number of parallel tasks to run.',
        abbr: 'j', defaultsTo: Platform.numberOfProcessors),
    new _Option.int('shards',
        'The number of instances that the tests will be sharded over.',
        defaultsTo: 1),
    new _Option.int(
        'shard', 'The index of this instance when running in sharded mode.',
        defaultsTo: 1),
    new _Option.bool('help', 'Print list of options.', 'h'),
    new _Option.bool('verbose', 'Verbose output.', 'v'),
    new _Option.bool('verify-ir', 'Verify kernel IR.'),
    new _Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.'),
    new _Option.bool('list', 'List tests only, do not run them.'),
    new _Option.bool('list_status_files',
        'List status files for test-suites. Do not run any test suites.'),
    new _Option.bool('report_in_json',
        'When listing with --list, output result summary in JSON.'),
    new _Option.bool('time', 'Print timing information after running tests.'),
    new _Option('dart', 'Path to dart executable.'),
    new _Option('flutter', 'Path to flutter executable.'),
    new _Option('drt', 'Path to content shell executable.'),
    new _Option('firefox', 'Path to firefox browser executable.'),
    new _Option('chrome', 'Path to chrome browser executable.'),
    new _Option('safari', 'Path to safari browser executable.'),
    new _Option.bool('use_sdk', '''Use compiler or runtime from the SDK.

Normally, the compiler or runtimes in PRODUCT_DIR is tested, with
this option, the compiler or runtime in PRODUCT_DIR/dart-sdk/bin
is tested.

(Note: currently only implemented for dart2js.)'''),
    // TODO(rnystrom): This does not appear to be used. Remove?
    new _Option('build_directory',
        'The name of the build directory, where products are placed.'),
    new _Option('output_directory',
        'The name of the output directory for storing log files.',
        defaultsTo: "logs"),
    new _Option.bool('noBatch', 'Do not run tests in batch mode.', 'n'),
    new _Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.'),
    new _Option.bool(
        'append_logs', 'Do not delete old logs but rather append to them.'),
    new _Option.bool('write_debug_log',
        'Don\'t write debug messages to stdout but rather to a logfile.'),
    new _Option.bool('write_test_outcome_log',
        'Write test outcomes to a "${TestUtils.testOutcomeFileName}" file.'),
    new _Option.bool(
        'write_result_log',
        'Write test results to a "${TestUtils.resultLogFileName}" json file '
        'located at the debug_output_directory.'),
    new _Option.bool('reset_browser_configuration',
        '''Browser specific reset of configuration.

Warning: Using this option may remove your bookmarks and other
settings.'''),
    new _Option.bool('copy_coredumps',
        '''If we see a crash that we did not expect, copy the core dumps to
"/tmp".'''),
    new _Option(
        'local_ip',
        '''IP address the HTTP servers should listen on. This address is also
used for browsers to connect to.''',
        defaultsTo: '127.0.0.1'),
    new _Option.int('test_server_port', 'Port for test http server.',
        defaultsTo: 0),
    new _Option.int('test_server_cross_origin_port',
        'Port for test http server cross origin.',
        defaultsTo: 0),
    new _Option.int('test_driver_port', 'Port for http test driver server.',
        defaultsTo: 0),
    new _Option.int(
        'test_driver_error_port', 'Port for http test driver server errors.',
        defaultsTo: 0),
    new _Option('builder_tag',
        '''Machine specific options that is not captured by the regular test
options. Used to be able to make sane updates to the status files.'''),
    new _Option('vm_options', 'Extra options to send to the vm when running.'),
    new _Option(
        'dart2js_options', 'Extra options for dart2js compilation step.'),
    new _Option(
        'suite_dir', 'Additional directory to add to the testing matrix.'),
    new _Option('package_root', 'The package root to use for testing.'),
    new _Option('packages', 'The package spec file to use for testing.'),
    new _Option('exclude_suite',
        '''Exclude suites from default selector, only works when no selector
has been specified on the command line.'''),
    new _Option.bool('skip_compilation', '''
Skip the compilation step, using the compilation artifacts left in
the output folder from a previous run. This flag will often cause
false positves and negatives, but can be useful for quick and
dirty offline testing when not making changes that affect the
compiler.''')
  ];

  /// For printing out reproducing command lines, we don't want to add these
  /// options.
  static final _blacklistedOptions = [
    'append_logs',
    'build_directory',
    'debug_output_directory',
    'chrome',
    'copy_coredumps',
    'dart',
    'flutter',
    'drt',
    'exclude_suite',
    'firefox',
    'local_ip',
    'progress',
    'report',
    'safari',
    'shard',
    'shards',
    'step_name',
    'tasks',
    'time',
    'verbose',
    'write_debug_log',
    'write_test_outcome_log',
    'write_result_log'
  ].toSet();

  /// Parses a list of strings as test options.
  ///
  /// Returns a list of configurations in which to run the tests.
  /// Configurations are maps mapping from option keys to values. When
  /// encountering the first non-option string, the rest of the arguments are
  /// stored in the returned Map under the 'rest' key.
  List<Configuration> parse(List<String> arguments) {
    var configuration = <String, dynamic>{};

    // Fill in configuration with arguments passed to the test script.
    for (var i = 0; i < arguments.length; i++) {
      var arg = arguments[i];

      // Help supersedes all other arguments.
      if (arg == "--help" || arg == "-h") {
        _printHelp();
        return null;
      }

      // Extract name and value for options.
      String command;
      String value;
      _Option option;

      if (arg.startsWith("--")) {
        // A long option name.
        var equals = arg.indexOf("=");
        if (equals != -1) {
          // A long option with a value, like "--arch=ia32".
          command = arg.substring(0, equals);
          value = arg.substring(equals + 1);
        } else {
          command = arg;
        }

        option = _findByName(command.substring(2));
      } else if (arg.startsWith("-")) {
        // An abbreviated option.
        if (arg.length == 1) {
          _fail('Missing option name after "-".');
        }

        command = arg.substring(0, 2);

        if (arg.length > 2) {
          // An abbreviated option followed by a value, like "-aia32".
          value = arg.substring(2);
        }

        option = _findByAbbreviation(command.substring(1));
      } else {
        // The argument does not start with "-" or "--" and is therefore not an
        // option. Use it as a test selector pattern.
        var patterns = configuration.putIfAbsent("selectors", () => <String>[]);
        patterns.add(arg);
        continue;
      }

      if (option == null) {
        _fail('Unknown command line option "$command".');
      }

      // If we need a value, look at the next argument.
      if (value == null && option.type != _OptionValueType.bool) {
        if (i + 1 >= arguments.length) {
          _fail('Missing value for command line option "$command".');
        }
        value = arguments[++i];
      }

      // Multiple uses of a flag are an error, because there is no naturally
      // correct way to handle conflicting options.
      if (configuration.containsKey(option.name)) {
        _fail('Already have value for command line option "$command".');
      }

      // Parse the value for the option.
      switch (option.type) {
        case _OptionValueType.bool:
          if (value != null) {
            _fail('Boolean flag "$command" does not take a value.');
          }

          configuration[option.name] = true;
          break;

        case _OptionValueType.int:
          try {
            configuration[option.name] = int.parse(value);
          } on FormatException {
            _fail('Integer value expected for option "$command".');
          }
          break;

        case _OptionValueType.string:
          // Validate against the allowed values.
          if (!option.values.isEmpty) {
            for (var v in value.split(",")) {
              if (!option.values.contains(v)) {
                _fail('Unknown value "$v" for command line option "$command".');
              }
            }
          }

          // TODO(rnystrom): Store as a list instead of a comma-delimited
          // string.
          configuration[option.name] = value;
          break;
      }
    }

    // Apply default values for unspecified options.
    for (var option in _options) {
      if (!configuration.containsKey(option.name)) {
        configuration[option.name] = option.defaultValue;
      }
    }

    return _createConfigurations(configuration);
  }

  /// Prints [message] and exits with a non-zero exit code.
  void _fail(String message) {
    print(message);
    exit(1);
  }

  /// Given a set of parsed option values, returns the list of command line
  /// arguments that would reproduce that configuration.
  List<String> _reproducingCommand(Map<String, dynamic> data) {
    var arguments = <String>[];

    for (var option in _options) {
      var name = option.name;
      if (!data.containsKey(name) || _blacklistedOptions.contains(name)) {
        continue;
      }

      var value = data[name];
      if (data[name] == option.defaultValue ||
          (name == 'packages' &&
              value ==
                  TestUtils.dartDirUri.resolve('.packages').toFilePath())) {
        continue;
      }

      arguments.add(option.shortCommand);
      if (option.type != _OptionValueType.bool) {
        arguments.add(value.toString());
      }
    }

    return arguments;
  }

  List<Configuration> _createConfigurations(
      Map<String, dynamic> configuration) {
    var selectors = _expandSelectors(configuration);

    // Put observatory_ui in a configuration with its own packages override.
    // Only one value in the configuration map is mutable:
    if (selectors.containsKey('observatory_ui')) {
      if (selectors.length == 1) {
        configuration['packages'] = TestUtils.dartDirUri
            .resolve('runtime/observatory/.packages')
            .toFilePath();
      } else {
        // Make a new configuration whose selectors map only contains
        // observatory_ui, and remove observatory_ui from the original
        // selectors. The only mutable value in the map is the selectors, so a
        // shallow copy is safe.
        var observatoryConfiguration =
            new Map<String, dynamic>.from(configuration);
        var observatorySelectors = {
          'observatory_ui': selectors['observatory_ui']
        };
        selectors.remove('observatory_ui');

        // Set the packages flag.
        observatoryConfiguration['packages'] = TestUtils.dartDirUri
            .resolve('runtime/observatory/.packages')
            .toFilePath();

        return _expandConfigurations(configuration, selectors)
          ..addAll(_expandConfigurations(
              observatoryConfiguration, observatorySelectors));
      }
    }

    return _expandConfigurations(configuration, selectors);
  }

  /// Recursively expands a configuration with multiple values per key into a
  /// list of configurations with exactly one value per key.
  List<Configuration> _expandConfigurations(
      Map<String, dynamic> data, Map<String, RegExp> selectors) {
    var result = <Configuration>[];

    // Handles a string option containing a space-separated list of words.
    listOption(String name) {
      var value = data[name] as String;
      if (value == null) return const <String>[];
      return value
          .split(" ")
          .map((s) => s.trim())
          .where((s) => s.isNotEmpty)
          .toList();
    }

    var dart2jsOptions = listOption("dart2js_options");
    var vmOptions = listOption("vm_options");

    // JSON reporting implies listing and reporting.
    if (data['report_in_json'] as bool) {
      data['list'] = true;
      data['report'] = true;
    }

    // Use verbose progress indication for verbose output unless buildbot
    // progress indication is requested.
    if ((data['verbose'] as bool) &&
        (data['progress'] as String) != 'buildbot') {
      data['progress'] = 'verbose';
    }

    // Expand runtimes.
    for (var runtimeName in (data["runtime"] as String).split(",")) {
      var runtime = Runtime.find(runtimeName);

      // Start installing the runtime if needed.
      if (runtime == Runtime.drt &&
          !(data["list"] as bool) &&
          !(data["list_status_files"] as bool)) {
        updateContentShell(data["drt"] as String);
      }

      // Expand architectures.
      var architectures = data["arch"] as String;
      if (architectures == "all") {
        architectures = "ia32,x64,simarm,simarm64,simdbc64";
      }

      for (var architectureName in architectures.split(",")) {
        var architecture = Architecture.find(architectureName);

        // Expand compilers.
        var compilers = data["compiler"] as String;
        for (var compilerName in compilers.split(",")) {
          var compiler = Compiler.find(compilerName);

          // Expand modes.
          var modes = data["mode"] as String;
          if (modes == "all") modes = "debug,release,product";
          for (var modeName in modes.split(",")) {
            var mode = Mode.find(modeName);

            var configuration = new Configuration(
                architecture: architecture,
                compiler: compiler,
                mode: mode,
                progress: Progress.find(data["progress"] as String),
                runtime: runtime,
                system: System.find(data["system"] as String),
                selectors: selectors,
                appendLogs: data["append_logs"] as bool,
                batch: !(data["noBatch"] as bool),
                batchDart2JS: data["dart2js_batch"] as bool,
                copyCoreDumps: data["copy_coredumps"] as bool,
                hotReload: data["hot_reload"] as bool,
                hotReloadRollback: data["hot_reload_rollback"] as bool,
                isChecked: data["checked"] as bool,
                isStrong: data["strong"] as bool,
                isHostChecked: data["host_checked"] as bool,
                isCsp: data["csp"] as bool,
                isMinified: data["minified"] as bool,
                isVerbose: data["verbose"] as bool,
                listTests: data["list"] as bool,
                listStatusFiles: data["list_status_files"] as bool,
                previewDart2: data["preview_dart_2"] as bool,
                printTiming: data["time"] as bool,
                printReport: data["report"] as bool,
                reportInJson: data["report_in_json"] as bool,
                resetBrowser: data["reset_browser_configuration"] as bool,
                skipCompilation: data["skip_compilation"] as bool,
                useBlobs: data["use_blobs"] as bool,
                useSdk: data["use_sdk"] as bool,
                useFastStartup: data["fast_startup"] as bool,
                useEnableAsserts: data["enable_asserts"] as bool,
                useDart2JSWithKernel: data["dart2js_with_kernel"] as bool,
                useDart2JSWithKernelInSsa:
                    data["dart2js_with_kernel_in_ssa"] as bool,
                writeDebugLog: data["write_debug_log"] as bool,
                writeTestOutcomeLog: data["write_test_outcome_log"] as bool,
                writeResultLog: data["write_result_log"] as bool,
                drtPath: data["drt"] as String,
                chromePath: data["chrome"] as String,
                safariPath: data["safari"] as String,
                firefoxPath: data["firefox"] as String,
                dartPath: data["dart"] as String,
                dartPrecompiledPath: data["dart_precompiled"] as String,
                flutterPath: data["flutter"] as String,
                taskCount: data["tasks"] as int,
                timeout: data["timeout"] as int,
                shardCount: data["shards"] as int,
                shard: data["shard"] as int,
                stepName: data["step_name"] as String,
                testServerPort: data["test_server_port"] as int,
                testServerCrossOriginPort:
                    data['test_server_cross_origin_port'] as int,
                testDriverErrorPort: data["test_driver_error_port"] as int,
                localIP: data["local_ip"] as String,
                dart2jsOptions: dart2jsOptions,
                vmOptions: vmOptions,
                packages: data["packages"] as String,
                packageRoot: data["package_root"] as String,
                suiteDirectory: data["suite_dir"] as String,
                builderTag: data["builder_tag"] as String,
                outputDirectory: data["output_directory"] as String,
                reproducingArguments: _reproducingCommand(data));

            if (configuration.validate()) {
              result.add(configuration);
            }
          }
        }
      }
    }

    return result;
  }

  /// Expands the test selectors into a suite name and a simple regular
  /// expression to be used on the full path of a test file in that test suite.
  ///
  /// If no selectors are explicitly given, uses the default suite patterns.
  Map<String, RegExp> _expandSelectors(Map<String, dynamic> configuration) {
    var selectors = configuration['selectors'];

    if (selectors == null) {
      if (configuration['suite_dir'] != null) {
        var suitePath = new Path(configuration['suite_dir'] as String);
        selectors = [suitePath.filename];
      } else {
        selectors = _defaultTestSelectors.toList();
      }

      var excludeSuites = configuration['exclude_suite'] != null
          ? configuration['exclude_suite'].split(',')
          : [];
      for (var exclude in excludeSuites) {
        if ((selectors as List).contains(exclude)) {
          selectors.remove(exclude);
        } else {
          print("Warning: default selectors does not contain $exclude");
        }
      }
    }

    var selectorMap = <String, RegExp>{};
    for (var i = 0; i < (selectors as List).length; i++) {
      var pattern = selectors[i] as String;
      var suite = pattern;
      var slashLocation = pattern.indexOf('/');
      if (slashLocation != -1) {
        suite = pattern.substring(0, slashLocation);
        pattern = pattern.substring(slashLocation + 1);
        pattern = pattern.replaceAll('*', '.*');
      } else {
        pattern = ".?";
      }
      if (selectorMap.containsKey(suite)) {
        print("Error: '$suite/$pattern'.  Only one test selection"
            " pattern is allowed to start with '$suite/'");
        exit(1);
      }
      selectorMap[suite] = new RegExp(pattern);
    }

    return selectorMap;
  }

  /// Print out usage information.
  void _printHelp() {
    var buffer = new StringBuffer();

    buffer.writeln('''usage: dart test.dart [options] [selector]

The optional selector limits the tests that will be run.
For example, the selector "language/issue", or equivalently
"language/*issue*", limits to test files matching the regexp
".*issue.*\\.dart" in the "tests/language" directory.

Options:''');

    for (var option in _options) {
      if (option.abbreviation != null) {
        buffer.write("-${option.abbreviation}, ");
      } else {
        buffer.write("    ");
      }

      buffer.write(option.command);

      switch (option.type) {
        case _OptionValueType.bool:
          // No value.
          break;
        case _OptionValueType.int:
          buffer.write("=<integer>");
          break;
        case _OptionValueType.string:
          if (option.values.length > 6) {
            // If there are many options, they won't fit nicely in one line and
            // should be instead listed in the description.
            buffer.write("=<...>");
          } else if (option.values.isNotEmpty) {
            buffer.write("=<${option.values.join('|')}>");
          } else {
            buffer.write("=<string>");
          }
          break;
      }

      if (option.type != _OptionValueType.bool &&
          option.defaultValue != null &&
          option.defaultValue != "") {
        buffer.write(" (defaults to ${option.defaultValue})");
      }

      buffer.writeln();
      buffer
          .writeln("      ${option.description.replaceAll('\n', '\n      ')}");
      buffer.writeln();
    }

    print(buffer);
  }

  _Option _findByAbbreviation(String abbreviation) {
    for (var option in _options) {
      if (abbreviation == option.abbreviation) return option;
    }

    return null;
  }

  _Option _findByName(String name) {
    for (var option in _options) {
      if (name == option.name) return option;

      // Allow hyphens instead of underscores as the separator since they are
      // more common for command line flags.
      if (name == option.name.replaceAll("_", "-")) return option;
    }

    return null;
  }
}
