def METHOD_NAME(string_operation, markers, stack):
    def check_marker_format(marker):
        """
        Checks if marker has proper suffix.
        """
        for s in OperationFactory.__suffix:
            if marker.endswith(s):
                return
        raise NotSupportedOperationException(
            "Incorrect marker format {}, suffix is missing.".format(marker)
        )
    def check_pair_consistency(stack, marker):
        """
        Checks if markers do not cross.
        You can pop from stack only if end
        marker match previous one.
        Example OK:
            MACRO1.BEGIN
                MACRO2.BEGIN
                MACRO2.END
            MACRO1.END
        Example NOT OK:
            MACRO1.BEGIN
                MACRO2.BEGIN
            MACRO1.END
                MACRO2.END
        """
        top = stack[-1][0]
        if top.endswith(OperationFactory.__suffix[0]):
            top = top[: -len(OperationFactory.__suffix[0])]
        if marker.endswith(OperationFactory.__suffix[-1]):
            marker = marker[: -len(OperationFactory.__suffix[-1])]
        if top != marker:
            raise NotSupportedOperationException(
                "Cannot cross markers: {0}, {1}".format(top, marker)
            )
    """
    Creates the object based on the pre-formatted string.
    The string needs to be in the specific format. Each specific value
    in the string has to be separated with a `;`. The first field
    has to be the name of the operation, the rest are operation
    specific values.
    :param string_operation: The string describing the operation.
    :param markers: The dict describing the pair marker-engine.
    :param stack: The stack describing the order of engine changes.
    :return: The specific object instantiated based on the string.
    """
    id_ = string_operation.split(";")[0]
    id_case_sensitive = id_.lower().capitalize()
    # checks if id_ is one of memoryoperation classes
    mem_ops = getattr(memoryoperations, id_case_sensitive, None)
    # if class is not one of memoryoperations
    # it means it can be user defined marker
    if mem_ops is None:
        check_marker_format(id_)
        # if id_ is section BEGIN
        if id_.endswith(OperationFactory.__suffix[0]):
            # BEGIN defined by user
            marker_name = id_.partition(".")[0]
            if markers is not None and marker_name in markers:
                engine = markers[marker_name]
                try:
                    mem_ops = getattr(memoryoperations, engine)
                except AttributeError:
                    raise NotSupportedOperationException(
                        "Not supported reorder engine: {}".format(engine)
                    )
            # BEGIN but not defined by user
            else:
                mem_ops = stack[-1][1]
            if issubclass(mem_ops, memoryoperations.ReorderBase):
                stack.append((id_, mem_ops))
        # END section
        elif id_.endswith(OperationFactory.__suffix[-1]):
            check_pair_consistency(stack, id_)
            stack.pop()
            mem_ops = stack[-1][1]
    # here we have proper memory operation to perform,
    # it can be Store, Fence, ReorderDefault etc.
    id_ = mem_ops.__name__
    if id_ not in OperationFactory.__factories:
        OperationFactory.__factories[id_] = mem_ops.Factory()
    return OperationFactory.__factories[id_].create(string_operation)