docs: def list_solvers(args=None):
      """Entry point for listing available solvers."""
      parser = argparse.ArgumentParser(
          description='''List LP solver available in PSAMM. This will produce a
                         list of all of the available LP solvers in prioritized
                         order. Addtional requirements can be imposed with the
                         arguments (e.g. integer=yes to select only solvers that
                         support MILP problems). The list will also be influenced
                         by the PSAMM_SOLVER environment variable which can be
                         used to only allow specific solvers (e.g.
                         PSAMM_SOLVER=cplex).''')
      parser.add_argument(
          'requirement', nargs='*', type=str,
          help='Additional requirements on the selected solvers')
      parsed_args = parser.parse_args(args)
  
      requirements = {}
      for arg in parsed_args.requirement:
          try:
              key, value = parse_solver_setting(arg)
          except ValueError as e:
              parser.error(str(e))
          else:
              requirements[key] = value
  
      solvers = list(filter_solvers(_solvers, requirements))
      solver_names = set(solver['name'] for solver in solvers)
  
      # Obtain solver priority from environment variable, if specified.
      priority = {}
      if 'PSAMM_SOLVER' in os.environ:
          names = os.environ['PSAMM_SOLVER'].split(',')
          for i, solver_name in enumerate(names):
              priority[solver_name] = len(names) - i
          solvers = [s for s in solvers if s['name'] in priority]
          solver_names = set(priority)
      else:
          # Use built-in priorities
          for solver in solvers:
              priority[solver['name']] = solver['priority']
  
      solvers = sorted(solvers, key=lambda s: priority.get(s['name'], 0),
                       reverse=True)
  
      status = 0
  
      if len(solvers) > 0:
          print('Prioritized solvers:')
          for solver in solvers:
              print('Name: {}'.format(solver['name']))
              print('Priority: {}'.format(solver['priority']))
              print('MILP (integer) problem support: {}'.format(
                  solver['integer']))
              print('QP (quadratic) problem support: {}'.format(
                  solver['quadratic']))
              print('Rational solution: {}'.format(solver['rational']))
              print('Class: {}'.format(solver['class']))
              print()
      else:
          status = 1
          print('No solvers fullfil the requirements!')
          print()
  
      filtered_solvers_count = len(_solvers) - len(solvers)
      if filtered_solvers_count > 0 or len(_solver_import_errors) > 0:
          print('Unavailable solvers:')
          for solver in _solvers:
              if solver['name'] not in solver_names:
                  print('{}: Does not fullfil the specified requirements'.format(
                      solver['name']))
  
          for solver, error in iteritems(_solver_import_errors):
              print('{}: Error loading solver: {}'.format(solver, error))
  
      if status != 0:
          parser.exit(status)