<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create(self, name, sources=None, destinations=None, services=None, action='allow', log_options=None, authentication_options=None, connection_tracking=None, is_disabled=False, vpn_policy=None, mobile_vpn=False, add_pos=None, after=None, before=None, sub_policy=None, comment=None, **kw):
 """ Create a layer 3 firewall rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param action: allow,continue,discard,refuse,enforce_vpn, apply_vpn,forward_vpn, blacklist (default: allow) :type action: Action or str :param LogOptions log_options: LogOptions object :param ConnectionTracking connection_tracking: custom connection tracking settings :param AuthenticationOptions authentication_options: options for auth if any :param PolicyVPN,str vpn_policy: policy element or str href; required for enforce_vpn, use_vpn and apply_vpn actions :param bool mobile_vpn: if using a vpn action, you can set mobile_vpn to True and omit the vpn_policy setting if you want this VPN to apply to any mobile VPN based on the policy VPN associated with the engine :param str,Element sub_policy: sub policy required when rule has an action of 'jump'. Can be the FirewallSubPolicy element or href. :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :param str comment: optional comment for this rule :raises MissingRequiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: the created ipv4 rule :rtype: IPv4Rule """

        rule_values = self.update_targets(sources, destinations, services)
        rule_values.update(name=name, comment=comment)

        if isinstance(action, Action):
            rule_action = action
        else:
            rule_action = Action()
            rule_action.action = action

        if not rule_action.action in self._actions:
            raise CreateRuleFailed('Action specified is not valid for this '
                'rule type; action: {}'.format(rule_action.action))

        if rule_action.action in ('apply_vpn', 'enforce_vpn', 'forward_vpn'):
            if vpn_policy is None and not mobile_vpn:
                raise MissingRequiredInput('You must either specify a vpn_policy or set '
                    'mobile_vpn when using a rule with a VPN action')
            if mobile_vpn:
                rule_action.mobile_vpn = True
            else:
                try:
                    vpn = element_resolver(vpn_policy) # VPNPolicy
                    rule_action.vpn = vpn
                except ElementNotFound:
                    raise MissingRequiredInput('Cannot find VPN policy specified: {}, '
                        .format(vpn_policy))
        
        elif rule_action.action == 'jump':
            try:
                rule_action.sub_policy = element_resolver(sub_policy)
            except ElementNotFound:
                raise MissingRequiredInput('Cannot find sub policy specified: {} '
                    .format(sub_policy))
        
        #rule_values.update(action=rule_action.data)

        log_options = LogOptions() if not log_options else log_options
        
        if connection_tracking is not None:
            rule_action.connection_tracking_options.update(**connection_tracking)
        
        auth_options = AuthenticationOptions() if not authentication_options \
            else authentication_options

        rule_values.update(
            action=rule_action.data,
            options=log_options.data,
            authentication_options=auth_options.data,
            is_disabled=is_disabled)

        params = None
        href = self.href
        if add_pos is not None:
            href = self.add_at_position(add_pos)
        elif before or after:
            params = self.add_before_after(before, after)
        
        return ElementCreator(
            self.__class__,
            exception=CreateRuleFailed,
            href=href,
            params=params,
            json=rule_values)