Determine a list of pairs (nonspeech interval, fragment index),
        such that the nonspeech interval contains exactly one fragment
        ending inside it (within the given tolerance) and
        adjacent to the next fragment.

        :param nonspeech_intervals: the list of nonspeech intervals to be examined
        :type  nonspeech_intervals: list of :class:`~aeneas.exacttiming.TimeInterval`
        :param tolerance: the tolerance to be applied when checking if the end point
                          falls within a given nonspeech interval
        :type  tolerance: :class:`~aeneas.exacttiming.TimeValue`
        :rtype: list of (:class:`~aeneas.exacttiming.TimeInterval`, int)

def fragments_ending_inside_nonspeech_intervals(
        self,
        nonspeech_intervals,
        tolerance
    ):
        """
        Determine a list of pairs (nonspeech interval, fragment index),
        such that the nonspeech interval contains exactly one fragment
        ending inside it (within the given tolerance) and
        adjacent to the next fragment.

        :param nonspeech_intervals: the list of nonspeech intervals to be examined
        :type  nonspeech_intervals: list of :class:`~aeneas.exacttiming.TimeInterval`
        :param tolerance: the tolerance to be applied when checking if the end point
                          falls within a given nonspeech interval
        :type  tolerance: :class:`~aeneas.exacttiming.TimeValue`
        :rtype: list of (:class:`~aeneas.exacttiming.TimeInterval`, int)
        """
        self.log(u"Called fragments_ending_inside_nonspeech_intervals")
        self.log([u"  List begin: %.3f", self.begin])
        self.log([u"  List end:   %.3f", self.end])
        nsi_index = 0
        frag_index = 0
        nsi_counter = [(n, []) for n in nonspeech_intervals]
        # NOTE the last fragment is not eligible to be returned
        while (nsi_index < len(nonspeech_intervals)) and (frag_index < len(self) - 1):
            nsi = nonspeech_intervals[nsi_index]
            if nsi.end > self.end:
                self.log(u"    nsi ends after self.end => breaking")
                break
            nsi_shadow = nsi.shadow(tolerance)
            frag = self[frag_index]
            self.log([u"  nsi        %s", nsi])
            self.log([u"  nsi_shadow %s", nsi_shadow])
            self.log([u"  frag       %s", frag.interval])
            if not frag.is_head_or_tail:
                self.log(u"    Fragment is not HEAD or TAIL => inspecting it")
                if nsi_shadow.contains(frag.end):
                    if nsi_shadow.contains(frag.begin):
                        #
                        #      *************** nsi shadow
                        #      | *********** | nsi
                        #      |   ***X      | frag (X=frag.end)
                        #
                        # NOTE this case might happen as the following:
                        #
                        #      *************** nsi shadow
                        #      |     ***     | nsi
                        #      | **X         | frag (X=frag.end)
                        #
                        #      so we must invalidate the nsi if this happens
                        #
                        nsi_counter[nsi_index] = (None, [])
                        nsi_index += 1
                        frag_index += 1
                        self.log(u"    nsi_shadow entirely contains frag => invalidate nsi, and skip to next fragment, nsi")
                    else:
                        #
                        #      *************** nsi shadow
                        #      | *********** | nsi
                        # *****|***X         | frag (X=frag.end)
                        #
                        nsi_counter[nsi_index][1].append(frag_index)
                        frag_index += 1
                        self.log(u"    nsi_shadow contains frag end only => save it and go to next fragment")
                elif nsi_shadow.begin > frag.end:
                    #
                    #      *************** nsi shadow
                    #      | *********** | nsi
                    # **X  |             | frag (X=frag.end)
                    #
                    frag_index += 1
                    self.log(u"    nsi_shadow begins after frag end => skip to next fragment")
                else:
                    #
                    #       ***************    nsi shadow
                    #       | *********** |    nsi
                    #       |        *****|**X frag (X=frag.end)
                    #
                    nsi_index += 1
                    self.log(u"    nsi_shadow ends before frag end => skip to next nsi")
            else:
                self.log(u"    Fragment is HEAD or TAIL => skipping it")
                frag_index += 1
            self.log(u"")
        tbr = [(n, c[0]) for (n, c) in nsi_counter if len(c) == 1]
        self.log([u"Returning: %s", tbr])
        return tbr