docs: def snake_case_methods(cls, debug=False):
      """
      A class decorator adding snake_case methods
      that alias capitalized ROOT methods. cls must subclass
      a ROOT class and define the _ROOT class variable.
      """
      if not CONVERT_SNAKE_CASE:
          return cls
      # get the ROOT base class
      root_base = cls._ROOT
      members = inspect.getmembers(root_base)
      # filter out any methods that already exist in lower and uppercase forms
      # i.e. TDirectory::cd and Cd...
      names = {}
      for name, member in members:
          lower_name = name.lower()
          if lower_name in names:
              del names[lower_name]
          else:
              names[lower_name] = None
  
      for name, member in members:
          if name.lower() not in names:
              continue
          # Don't touch special methods or methods without cap letters
          if name[0] == '_' or name.islower():
              continue
          # Is this a method of the ROOT base class?
          if not inspect.ismethod(member) and not inspect.isfunction(member):
              continue
          # convert CamelCase to snake_case
          new_name = camel_to_snake(name)
          # Use a __dict__ lookup rather than getattr because we _want_ to
          # obtain the _descriptor_, and not what the descriptor gives us
          # when it is `getattr`'d.
          value = None
          skip = False
          for c in cls.mro():
              # skip methods that are already overridden
              if new_name in c.__dict__:
                  skip = True
                  break
              if name in c.__dict__:
                  value = c.__dict__[name]
                  break
          # <neo>Woah, a use for for-else</neo>
          else:
              # Weird. Maybe the item lives somewhere else, such as on the
              # metaclass?
              value = getattr(cls, name)
          if skip:
              continue
          setattr(cls, new_name, value)
      return cls