def scan
      raise IOError, "There's a invalid or missing file" if @file.nil?

      unmarked_group_found  = false
      multiple_marked_found = false

      result = Hash.new { |hash, key| hash[key] = [] }
      result.tap do |effect|
        begin
          Timeout.timeout(@config.scan_timeout) do
            detect_groups unless @groups_detected
          end
        rescue Timeout::Error
          raise_watcher :timed_out_watcher
          return effect
        end

        @groups.each_pair do |_label, group|
          marks = Hash.new { |hash, key| hash[key] = [] }
          group.marks.each_pair do |line, value|
            value.each do |mark|
              marks[line] << mark.value if mark.marked?(config.intensity_percentual) && mark.value
            end

            multiple_marked_found = true if marks[line].size > 1
            unmarked_group_found  = true if marks[line].empty?
          end

          effect[group.label.to_sym] = marks
        end

        raise_watcher :scan_unmarked_watcher, effect if unmarked_group_found

        raise_watcher :scan_multiple_marked_watcher, effect if multiple_marked_found

        if unmarked_group_found || multiple_marked_found
          raise_watcher :scan_mark_watcher, effect, unmarked_group_found, multiple_marked_found
        end
      end
    end
def scan
      raise IOError, "There's a invalid or missing file" if @file.nil?

      unmarked_group_found  = false
      multiple_marked_found = false

      result = Hash.new { |hash, key| hash[key] = [] }
      result.tap do |effect|
        begin
          Timeout.timeout(@config.scan_timeout) do
            detect_groups unless @groups_detected
          end
        rescue Timeout::Error
          raise_watcher :timed_out_watcher
          return effect
        end

        @groups.each_pair do |_label, group|
          marks = Hash.new { |hash, key| hash[key] = [] }
          group.marks.each_pair do |line, value|
            value.each do |mark|
              marks[line] << mark.value if mark.marked?(config.intensity_percentual) && mark.value
            end

            multiple_marked_found = true if marks[line].size > 1
            unmarked_group_found  = true if marks[line].empty?
          end

          effect[group.label.to_sym] = marks
        end

        raise_watcher :scan_unmarked_watcher, effect if unmarked_group_found

        raise_watcher :scan_multiple_marked_watcher, effect if multiple_marked_found

        if unmarked_group_found || multiple_marked_found
          raise_watcher :scan_mark_watcher, effect, unmarked_group_found, multiple_marked_found
        end
      end
    end
rubocop:disable Metrics/MethodLength
 rubocop:disable Metrics/CyclomaticComplexity
 rubocop:disable Metrics/PerceivedComplexity