docs: def main(argv=None):
      """
      Entry point
  
      :param argv: Script arguments (None for sys.argv)
      :return: An exit code or None
      """
      # Prepare arguments
      parser = argparse.ArgumentParser(
          prog="pelix.shell.xmpp",
          parents=[make_common_parser()],
          description="Pelix XMPP Shell",
      )
  
      group = parser.add_argument_group("XMPP options")
      group.add_argument("-j", "--jid", dest="jid", help="Jabber ID")
      group.add_argument("--password", dest="password", help="JID password")
      group.add_argument("-s", "--server", dest="server", help="XMPP server host")
      group.add_argument(
          "-p",
          "--port",
          dest="port",
          type=int,
          default=5222,
          help="XMPP server port",
      )
      group.add_argument(
          "--tls",
          dest="use_tls",
          action="store_true",
          help="Use a STARTTLS connection",
      )
      group.add_argument(
          "--ssl",
          dest="use_ssl",
          action="store_true",
          help="Use an SSL connection",
      )
  
      # Parse them
      args = parser.parse_args(argv)
  
      # Handle common arguments
      init = handle_common_arguments(args)
  
      # Quiet down the SleekXMPP logger
      if not args.verbose:
          logging.getLogger("sleekxmpp").setLevel(logging.WARNING)
  
      if not args.server and not args.jid:
          _logger.error("No JID nor server given. Abandon.")
          sys.exit(1)
  
      # Get the password if necessary
      password = args.password
      if args.jid and args.password is None:
          try:
              import getpass
          except ImportError:
              _logger.error(
                  "getpass() unavailable: give a password in command line"
              )
          else:
              try:
                  password = getpass.getpass()
              except getpass.GetPassWarning:
                  pass
  
      # Get the server from the JID, if necessary
      server = args.server
      if not server:
          server = sleekxmpp.JID(args.jid).domain
  
      # Set the initial bundles
      bundles = [
          "pelix.ipopo.core",
          "pelix.shell.core",
          "pelix.shell.ipopo",
          "pelix.shell.console",
          "pelix.shell.xmpp",
      ]
      bundles.extend(init.bundles)
  
      # Use the utility method to create, run and delete the framework
      framework = pelix.framework.create_framework(
          remove_duplicates(bundles), init.properties
      )
      framework.start()
  
      # Instantiate a Remote Shell
      with use_ipopo(framework.get_bundle_context()) as ipopo:
          ipopo.instantiate(
              pelix.shell.FACTORY_XMPP_SHELL,
              "xmpp-shell",
              {
                  "shell.xmpp.server": server,
                  "shell.xmpp.port": args.port,
                  "shell.xmpp.jid": args.jid,
                  "shell.xmpp.password": password,
                  "shell.xmpp.tls": args.use_tls,
                  "shell.xmpp.ssl": args.use_ssl,
              },
          )
  
      # Instantiate configured components
      init.instantiate_components(framework.get_bundle_context())
  
      try:
          framework.wait_for_stop()
      except KeyboardInterrupt:
          framework.stop()