def _get_task_name_from_execution_history(execution_history, arn):
    """
    * Given an execution history object returned by the StepFunctions API and an optional
    * Activity or Lambda ARN returns the most recent task name started for the given ARN,
    * or if no ARN is supplied, the most recent task started.
    *
    * IMPORTANT! If no ARN is supplied, this message assumes that the most recently started
    * execution is the desired execution. This WILL BREAK parallel executions, so always supply
    * this if possible.
    *
    * @param {dict} executionHistory The execution history returned by getExecutionHistory,
    * assumed to be sorted so most recent executions come last
    * @param {string} arn An ARN to an Activity or Lambda to find. See "IMPORTANT!"
    * @throws If no matching task is found
    * @returns {string} The matching task name
    """
    events_by_id = {}
    for event in execution_history['events']:
        events_by_id[event['id']] = event
    for step in execution_history['events']:
        lambda_of_type_and_matching_arn = step['type'
            ] == 'LambdaFunctionScheduled' and step[
            'lambdaFunctionScheduledEventDetails']['resource'] == arn or step[
            'type'] == 'ActivityScheduled' and step[
            'activityScheduledEventDetails']['resource'] == arn
        if (arn is not None and lambda_of_type_and_matching_arn and 
            'stateEnteredEventDetails' in events_by_id[step['previousEventId']]
            ):
            return events_by_id[step['previousEventId']][
                'stateEnteredEventDetails']['name']
        if step['type'] == 'TaskStateEntered':
            return step['stateEnteredEventDetails']['name']
    raise LookupError('No task found for ' + arn)
