<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def plug(update_kwargs=True, **plugs_map):
 """Creates a decorator that passes in plugs when invoked. This function returns a decorator for a function that will replace positional arguments to that function with the plugs specified. See the module docstring for details and examples. Note this decorator does not work with class or bound methods, but does work with @staticmethod. Args: update_kwargs: If true, makes the decorated phase take this plug as a kwarg. **plugs_map: Dict mapping name to Plug type. Returns: A PhaseDescriptor that will pass plug instances in as kwargs when invoked. Raises: InvalidPlugError: If a type is provided that is not a subclass of BasePlug. """

  for a_plug in plugs_map.values():
    if not (isinstance(a_plug, PlugPlaceholder)
            or issubclass(a_plug, BasePlug)):
      raise InvalidPlugError(
          'Plug %s is not a subclass of plugs.BasePlug nor a placeholder '
          'for one' % a_plug)

  def result(func):
    """Wrap the given function and return the wrapper.

    Args:
      func: The function to wrap.

    Returns:
      A PhaseDescriptor that, when called will invoke the wrapped function,
        passing plugs as keyword args.

    Raises:
      DuplicatePlugError:  If a plug name is declared twice for the
          same function.
    """
    phase = openhtf.core.phase_descriptor.PhaseDescriptor.wrap_or_copy(func)
    duplicates = (frozenset(p.name for p in phase.plugs) &
                  frozenset(plugs_map))
    if duplicates:
      raise DuplicatePlugError(
          'Plugs %s required multiple times on phase %s' % (duplicates, func))

    phase.plugs.extend([
        PhasePlug(name, a_plug, update_kwargs=update_kwargs)
        for name, a_plug in six.iteritems(plugs_map)])
    return phase
  return result