def METHOD_NAME(self, node, options=None):
    '''Checks that the supplied node is a valid target for a loop
    transformation.
    :param node: target PSyIR node.
    :type node: subclass of :py:class:`psyclone.psyir.nodes.Node`
    :param options: a dictionary with options for transformations.
    :type options: Optional[Dict[str, Any]]
    :param bool options["node-type-check"]: this flag controls if the \
        type of the nodes enclosed in the loop should be tested to \
        avoid including unsupported nodes in a transformation.
    :raises TransformationError: if the supplied node is not a (fully- \
            formed) Loop.
    :raises TransformationError: if any of the nodes within the loop are \
            of an unsupported type.
    :raises TransformationError: if the loop is of 'null' type.
    :raises TransformationError: if the supplied options are not a \
            dictionary.
    '''
    # pylint: disable=too-many-branches
    if not isinstance(node, Loop):
        raise TransformationError(
            f"Target of {self.name} transformation must be a sub-class of "
            f"Loop but got '{type(node).__name__}'")
    # The loop must be fully-formed.
    if len(node.children) != 4:
        raise TransformationError(
            f"Error in {self.name} transformation. The target loop "
            f"must have four children but found: "
            f"{[type(child).__name__ for child in node.children]}.")
    if not options:
        options = {}
    if not isinstance(options, dict):
        raise TransformationError(
            f"Transformation validate method 'options' argument must be a "
            f"dictionary but found '{type(options).__name__}'.")
    # Check that the proposed region contains only supported node types
    if options.get("node-type-check", True):
        # Stop at any instance of Kern to avoid going into the
        # actual kernels, e.g. in Nemo inlined kernels
        flat_list = [item for item in node.walk(object, stop_type=Kern)
                     if not isinstance(item, Schedule)]
        for item in flat_list:
            if isinstance(item, self.excluded_node_types):
                raise TransformationError(
                    f"Nodes of type '{type(item).__name__}' cannot be "
                    f"enclosed by a {self.name} transformation")
    # Disable warning to avoid circular dependency
    # pylint: disable=import-outside-toplevel
    from psyclone.domain.common.psylayer import PSyLoop
    # A 'null' loop is one which exists in the PSyIR hierarchy (mainly for
    # halo-exchange logic) but does *not* correspond to an actual loop
    # in the code that is generated for the PSy layer.
    # TODO 1756: PSyLoop is a PSy-layer concept and 'null' is only defined
    # in LFRic. Maybe a generic transformation validation is not the best
    # place for this check.
    if isinstance(node, PSyLoop) and node.loop_type == 'null':
        raise TransformationError(
            f"Cannot apply a {self.name} transformation to a 'null' loop.")