def Func(arg_0, arg_1, arg_2, arg_3=False):
        '''
        Trim the annotation and return as a new `Annotation` object.

        Trimming will result in the new annotation only containing observations
        that occur in the intersection of the time range spanned by the
        annotation and the time range specified by the user. The new annotation
        will span the time range ``[Func_start, Func_end]`` where
        ``Func_start = max(self.time, start_time)`` and ``Func_end =
        min(self.time + self.duration, end_time)``.

        If ``strict=False`` (default) observations that start before
        ``Func_start`` and end after it will be Funcmed such that they start at
        ``Func_start``, and similarly observations that start before
        ``Func_end`` and end after it will be Funcmed to end at ``Func_end``.
        If ``strict=True`` such borderline observations will be discarded.

        The new duration of the annotation will be ``Func_end - Func_start``.

        Note that if the range defined by ``[start_time, end_time]``
        doesn't intersect with the original time range spanned by the
        annotation the resulting annotation will contain no observations, will
        have the same start time as the original annotation and have duration
        0.

        This function also copies over all the annotation metadata from the
        original annotation and documents the Func operation by adding a list
        of tuples to the annotation's sandbox keyed by
        ``Annotation.sandbox.Func`` which documents each Func operation with a
        tuple ``(start_time, end_time, Func_start, Func_end)``.

        Parameters
        ----------
        start_time : float
            The desired start time for the Funcmed annotation in seconds.
        end_time
            The desired end time for the Funcmed annotation in seconds. Must be
            greater than ``start_time``.
        strict : bool
            When ``False`` (default) observations that lie at the boundaries of
            the Funcming range (given by ``[Func_start, Func_end]`` as
            described above), i.e. observations that start before and end after
            either the Func start or end time, will have their time and/or
            duration adjusted such that only the part of the observation that
            lies within the Func range is kept. When ``True`` such observations
            are discarded and not included in the Funcmed annotation.

        Returns
        -------
        ann_Funcmed : Annotation
            The Funcmed annotation, returned as a new jams.Annotation object.
            If the Func range specified by ``[start_time, end_time]`` does not
            intersect at all with the original time range of the annotation a
            warning will be issued and the returned annotation will be empty.

        Raises
        ------
        ParameterError
            If ``end_time`` is not greater than ``start_time``.

        Examples
        --------
        >>> ann = jams.Annotation(namespace='tag_open', time=2, duration=8)
        >>> ann.append(time=2, duration=2, value='one')
        >>> ann.append(time=4, duration=2, value='two')
        >>> ann.append(time=6, duration=2, value='three')
        >>> ann.append(time=7, duration=2, value='four')
        >>> ann.append(time=8, duration=2, value='five')
        >>> ann_Func = ann.Func(5, 8, strict=False)
        >>> print(ann_Func.time, ann_Func.duration)
        (5, 3)
        >>> ann_Func.to_dataframe()
           time  duration  value confidence
        0     5         1    two       None
        1     6         2  three       None
        2     7         1   four       None
        >>> ann_Func_strict = ann.Func(5, 8, strict=True)
        >>> print(ann_Func_strict.time, ann_Func_strict.duration)
        (5, 3)
        >>> ann_Func_strict.to_dataframe()
           time  duration  value confidence
        0     6         2  three       None
        '''
        # Check for basic start_time and end_time validity
        if arg_2 <= arg_1:
            raise ParameterError(
                'end_time must be greater than start_time.')

        # If the annotation does not have a set duration value, we'll assume
        # Funcming is possible (up to the user to ensure this is valid).
        if arg_0.duration is None:
            arg_4 = arg_1
            arg_5 = arg_2 - arg_1
            warnings.warn(
                "Annotation.duration is not defined, cannot check "
                "for temporal intersection, assuming the annotation "
                "is valid between start_time and end_time.")
        else:
            arg_4 = arg_0.time
            arg_5 = arg_0.duration

        # Check whether there is intersection between the Func range and
        # annotation: if not raise a warning and set Func_start and Func_end
        # appropriately.
        if arg_1 > (arg_4 + arg_5) or (arg_2 < arg_4):
            warnings.warn(
                'Time range defined by [start_time,end_time] does not '
                'intersect with the time range spanned by this annotation, '
                'the Funcmed annotation will be empty.')
            arg_6 = arg_0.time
            arg_7 = arg_6
        else:
            # Determine new range
            arg_6 = max(arg_4, arg_1)
            arg_7 = min(arg_4 + arg_5, arg_2)

        # Create new annotation with same namespace/metadata
        arg_8 = Annotation(
            arg_0.namespace,
            data=None,
            annotation_metadata=arg_0.annotation_metadata,
            sandbox=arg_0.sandbox,
            time=arg_6,
            duration=arg_7 - arg_6)

        # Selectively add observations based on their start time / duration
        # We do this rather than copying and directly manipulating the
        # annotation' data frame (which might be faster) since this way Func is
        # independent of the internal data representation.
        for arg_9 in arg_0.data:

            arg_10 = arg_9.time
            arg_11 = arg_10 + arg_9.duration

            if arg_10 < arg_7 and arg_11 > arg_6:

                arg_12 = max(arg_10, arg_6)
                arg_13 = min(arg_11, arg_7)
                arg_14 = arg_13 - arg_12

                if ((not arg_3) or
                        (arg_12 == arg_10 and arg_13 == arg_11)):
                    arg_8.append(time=arg_12,
                                       duration=arg_14,
                                       value=arg_9.value,
                                       confidence=arg_9.confidence)

        if 'Func' not in arg_8.sandbox.keys():
            arg_8.sandbox.update(
                Func=[{'start_time': arg_1, 'end_time': arg_2,
                       'Func_start': arg_6, 'Func_end': arg_7}])
        else:
            arg_8.sandbox.Func.append(
                {'start_time': arg_1, 'end_time': arg_2,
                 'Func_start': arg_6, 'Func_end': arg_7})

        return arg_8


def Func(arg_0, arg_1, arg_2=False):
        '''Sample the annotation at specified times.

        Parameters
        ----------
        times : np.ndarray, non-negative, ndim=1
            The times (in seconds) to sample the annotation

        confidence : bool
            If `True`, return both values and confidences.
            If `False` (default) only return values.

        Returns
        -------
        values : list
            `values[i]` is a list of observation values for intervals
            that cover `times[i]`.

        confidence : list (optional)
            `confidence` values corresponding to `values`
        '''
        arg_1 = np.asarray(arg_1)
        if arg_1.ndim != 1 or np.any(arg_1 < 0):
            raise ParameterError('times must be 1-dimensional and non-negative')

        arg_3 = np.argsort(arg_1)
        arg_4 = arg_1[arg_3]

        arg_5 = [list() for _ in arg_4]
        arg_6 = [list() for _ in arg_4]

        for arg_7 in arg_0.data:
            arg_8 = np.searchsorted(arg_4, arg_7.time)
            arg_9 = np.searchsorted(arg_4, arg_7.time + arg_7.duration, side='right')
            for arg_10 in range(arg_8, arg_9):
                arg_5[arg_3[arg_10]].append(arg_7.value)
                arg_6[arg_3[arg_10]].append(arg_7.confidence)

        if arg_2:
            return arg_5, arg_6
        else:
            return arg_5


def Func(arg_0, arg_1=None):
        '''Render this annotation list in HTML

        Returns
        -------
        rendered : str
            An HTML table containing this annotation's data.
        '''
        arg_2 = len(arg_0.data)

        arg_3 = _get_divid(arg_0)

        arg_4 = r'''

                            <button
                                type="button"
                                data-toggle="collapse"
                                data-parent="#accordion"
                                href="#{0}"
                                aria-expanded="false"
                                class="collapsed btn btn-info btn-block"
                                aria-controls="{0}">
                                {1:s}
                                {2:d}
                            </button>

'''.format(arg_3, arg_0.namespace, arg_2)

        arg_4 += r'''

'''.format(arg_3)

        arg_4 += r'''

                        {}

'''.format(arg_0.annotation_metadata._repr_html_())
        arg_4 += r'''

                        {}

'''.format(arg_0.sandbox._repr_html_())

        # -- Annotation content starts here
        arg_4 += r'''

                            time
                            duration
                            value
                            confidence

'''.format(arg_0.namespace, arg_2)

        arg_4 += r'''
'''

        if arg_1 is None or arg_2 <= arg_1:
            arg_4 += arg_0._fmt_rows(0, arg_2)
        else:
            arg_4 += arg_0._fmt_rows(0, arg_1//2)
            arg_4 += r'''

                            ...
                            ...
                            ...
                            ...
                            ...

'''
            arg_4 += arg_0._fmt_rows(arg_2-arg_1//2, arg_2)

        arg_4 += r'''
'''

        arg_4 += r'''

'''

        arg_4 += r'''

'''
        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3=False):
        '''
        Trim every annotation contained in the annotation array using
        `Annotation.Func` and return as a new `AnnotationArray`.

        See `Annotation.Func` for details about Funcming. This function does
        not modify the annotations in the original annotation array.

        Parameters
        ----------
        start_time : float
            The desired start time for the Funcmed annotations in seconds.
        end_time
            The desired end time for Funcmed annotations in seconds. Must be
            greater than ``start_time``.
        strict : bool
            When ``False`` (default) observations that lie at the boundaries of
            the Funcming range (see `Annotation.Func` for details) will have
            their time and/or duration adjusted such that only the part of the
            observation that lies within the Func range is kept. When ``True``
            such observations are discarded and not included in the Funcmed
            annotation.

        Returns
        -------
        Funcmed_array : AnnotationArray
            An annotation array where every annotation has been Funcmed.
        '''
        arg_4 = AnnotationArray()
        for arg_5 in arg_0:
            arg_4.append(arg_5.Func(arg_1, arg_2, arg_3=arg_3))

        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3=False):
        '''
        Slice every annotation contained in the annotation array using
        `Annotation.Func`
        and return as a new AnnotationArray

        See `Annotation.Func` for details about slicing. This function does
        not modify the annotations in the original annotation array.

        Parameters
        ----------
        start_time : float
            The desired start time for slicing in seconds.
        end_time
            The desired end time for slicing in seconds. Must be greater than
            ``start_time``.
        strict : bool
            When ``False`` (default) observations that lie at the boundaries of
            the slicing range (see `Annotation.Func` for details) will have
            their time and/or duration adjusted such that only the part of the
            observation that lies within the trim range is kept. When ``True``
            such observations are discarded and not included in the Funcd
            annotation.

        Returns
        -------
        Funcd_array : AnnotationArray
            An annotation array where every annotation has been Funcd.
        '''
        arg_4 = AnnotationArray()
        for arg_5 in arg_0:
            arg_4.append(arg_5.Func(arg_1, arg_2, arg_3=arg_3))

        return arg_4


def Func(arg_0, arg_1, arg_2='fail'):
        """Add the contents of another jam to this object.

        Note that, by default, this method fails if file_metadata is not
        identical and raises a ValueError; either resolve this manually
        (because conflicts should almost never happen), force an 'overwrite',
        or tell the method to 'ignore' the metadata of the object being Funced.

        Parameters
        ----------
        jam: JAMS object
            Object to Func to this jam

        on_conflict: str, default='fail'
            Strategy for resolving metadata conflicts; one of
                ['fail', 'overwrite', or 'ignore'].

        Raises
        ------
        ParameterError
            if `on_conflict` is an unknown value

        JamsError
            If a conflict is detected and `on_conflict='fail'`
        """

        if arg_2 not in ['overwrite', 'fail', 'ignore']:
            raise ParameterError("on_conflict='{}' is not in ['fail', "
                                 "'overwrite', 'ignore'].".format(arg_2))

        if not arg_0.file_metadata == arg_1.file_metadata:
            if arg_2 == 'overwrite':
                arg_0.file_metadata = arg_1.file_metadata
            elif arg_2 == 'fail':
                raise JamsError("Metadata conflict! "
                                "Resolve manually or force-overwrite it.")

        arg_0.annotations.extend(arg_1.annotations)
        arg_0.sandbox.update(**arg_1.sandbox)


def Func(arg_0, arg_1, arg_2=True, arg_3='auto'):
        """Serialize annotation as a JSON formatted stream to file.

        Parameters
        ----------
        path_or_file : str or file-like
            Path to Func the JAMS object on disk
            OR
            An open file descriptor to write into

        strict : bool
            Force strict schema validation

        fmt : str ['auto', 'jams', 'jamz']
            The output encoding format.

            If `auto`, it is inferred from the file name.

            If the input is an open file handle, `jams` encoding
            is used.

        Raises
        ------
        SchemaError
            If `strict == True` and the JAMS object fails schema
            or namespace validation.

        See also
        --------
        validate
        """

        arg_0.validate(arg_2=arg_2)

        with _open(arg_1, mode='w', arg_3=arg_3) as fdesc:
            json.dump(arg_0.__json__, fdesc, indent=2)


def Func(arg_0, **arg_1):
    '''Plotting wrapper for pitch contours'''
    arg_2 = arg_1.pop('ax', None)

    # If the annotation is empty, we need to construct a new axes
    arg_2 = mir_eval.display.__get_axes(arg_2=arg_2)[0]

    arg_3, arg_4 = arg_0.to_interval_values()

    arg_5 = np.unique([v['index'] for v in arg_4])

    for arg_6 in arg_5:
        arg_7 = [i for (i, v) in enumerate(arg_4) if v['index'] == arg_6]
        arg_8 = np.asarray([arg_4[r]['frequency'] for r in arg_7])
        arg_9 = ~np.asarray([arg_4[r]['voiced'] for r in arg_7])
        arg_8[arg_9] *= -1

        arg_2 = mir_eval.display.pitch(arg_3[arg_7, 0], arg_8, arg_9=True,
                                    arg_2=arg_2,
                                    **arg_1)
    return arg_2


def Func(arg_0, **arg_1):
    '''Plotting wrapper for Funcs'''

    arg_2, arg_3 = arg_0.to_interval_values()

    if any(arg_3):
        arg_4 = arg_3
    else:
        arg_4 = None

    return mir_eval.display.Funcs(arg_2, arg_4=arg_4, **arg_1)


def Func(arg_0, **arg_1):
    '''Plotting wrapper for beat-position data'''

    arg_2, arg_3 = arg_0.to_interval_values()

    arg_4 = [_['position'] for _ in arg_3]

    # TODO: plot time signature, measure number
    return mir_eval.display.events(arg_2, arg_4=arg_4, **arg_1)


def Func(arg_0, **arg_1):
    '''Plotting wrapper for piano rolls'''
    arg_2, arg_3 = arg_0.to_interval_values()

    return mir_eval.display.Func(arg_2, arg_3=arg_3, **arg_1)


def Func(arg_0, arg_1=True, **arg_2):
    '''Visualize a jams annotation through mir_eval

    Parameters
    ----------
    annotation : jams.Annotation
        The annotation to Func

    meta : bool
        If `True`, include annotation metadata in the figure

    kwargs
        Additional keyword arguments to mir_eval.Func functions

    Returns
    -------
    ax
        Axis handles for the new Func

    Raises
    ------
    NamespaceError
        If the annotation cannot be visualized
    '''

    for arg_3, arg_4 in six.iteritems(VIZ_MAPPING):
        try:
            arg_5 = coerce_annotation(arg_0, arg_3)

            arg_6 = arg_4(arg_5, **arg_2)

            # Title should correspond to original namespace, not the coerced version
            arg_6.set_title(arg_0.namespace)
            if arg_1:
                arg_7 = pprint_jobject(arg_0.annotation_metadata, indent=2)

                arg_8 = AnchoredText(arg_7.strip('\n'),
                                            loc=2,
                                            frameon=True,
                                            bbox_to_anchor=(1.02, 1.0),
                                            bbox_transform=arg_6.transAxes,
                                            borderpad=0.0)
                arg_6.add_artist(arg_8)

                arg_6.figure.subplots_adjust(right=0.8)

            return arg_6
        except NamespaceError:
            pass

    raise NamespaceError('Unable to visualize annotation of namespace="{:s}"'
                         .format(arg_0.namespace))


def Func(arg_0, arg_1=None, arg_2=True, **arg_3):
    '''Display multiple annotations with shared axes

    Parameters
    ----------
    annotations : jams.AnnotationArray
        A collection of annotations to display

    fig_kw : dict
        Keyword arguments to `plt.figure`

    meta : bool
        If `True`, display annotation metadata for each annotation

    kwargs
        Additional keyword arguments to the `mir_eval.display` routines

    Returns
    -------
    fig
        The created figure
    axs
        List of subplot axes corresponding to each displayed annotation
    '''
    if arg_1 is None:
        arg_1 = dict()

    arg_1.setdefault('sharex', True)
    arg_1.setdefault('squeeze', True)

    # Filter down to coercable annotations first
    arg_4 = []
    for arg_5 in arg_0:
        for arg_6 in VIZ_MAPPING:
            if can_convert(arg_5, arg_6):
                arg_4.append(arg_5)
                break

    # If there are no displayable annotations, fail here
    if not len(arg_4):
        raise ParameterError('No displayable annotations found')

    arg_7, arg_8 = plt.subplots(nrows=len(arg_4), ncols=1, **arg_1)

    # MPL is stupid when making singleton subplots.
    # We catch this and make it always iterable.
    if len(arg_4) == 1:
        arg_8 = [arg_8]

    for arg_5, arg_9 in zip(arg_4, arg_8):
        arg_3['ax'] = arg_9
        display(arg_5, arg_2=arg_2, **arg_3)

    return arg_7, arg_8


def Func(arg_0, arg_1=22050, arg_2=0.1):
    '''Generate a click sample.

    This replicates functionality from mir_eval.sonify.clicks,
    but exposes the target frequency and duration.
    '''

    arg_3 = np.arange(int(arg_1 * arg_2))
    arg_4 = np.sin(2 * np.pi * arg_3 * arg_0 / float(arg_1))
    arg_4 *= np.exp(- arg_3 / (1e-2 * arg_1))

    return arg_4


def Func(arg_0, arg_1=22050, arg_2=None, **arg_3):
    '''Sonify events with Func.

    This uses mir_eval.sonify.Func, and is appropriate for instantaneous
    events such as beats or segment boundaries.
    '''

    arg_4, arg_5 = arg_0.to_interval_values()

    return filter_kwargs(mir_eval.sonify.Func, arg_4[:, 0],
                         fs=arg_1, arg_2=arg_2, **arg_3)


def Func(arg_0, arg_1=22050, arg_2=None, **arg_3):
    '''Sonify beats and Funcs together.
    '''

    arg_4 = mkclick(440 * 2, arg_1=arg_1)
    arg_5 = mkclick(440 * 3, arg_1=arg_1)

    arg_6, arg_7 = arg_0.to_interval_values()

    arg_8, arg_9 = [], []

    for arg_10, arg_11 in zip(arg_6[:, 0], arg_7):
        if arg_11['position'] == 1:
            arg_9.append(arg_10)
        else:
            arg_8.append(arg_10)

    if arg_2 is None:
        arg_2 = int(arg_1 * np.max(arg_6)) + len(arg_4) + 1

    arg_12 = filter_kwargs(mir_eval.sonify.clicks,
                      np.asarray(arg_8),
                      fs=arg_1, arg_2=arg_2, click=arg_4)

    arg_12 += filter_kwargs(mir_eval.sonify.clicks,
                       np.asarray(arg_9),
                       fs=arg_1, arg_2=arg_2, click=arg_5)

    return arg_12


def Func(arg_0, arg_1=22050, arg_2=None, **arg_3):
    '''Sonify a piano-roll

    This uses mir_eval.sonify.time_frequency, and is appropriate
    for sparse transcription data, e.g., annotations in the `note_midi`
    namespace.
    '''

    arg_4, arg_5 = arg_0.to_interval_values()

    # Construct the pitchogram
    arg_6 = {arg_9: idx for idx, arg_9 in enumerate(np.unique(arg_5))}

    arg_7 = np.zeros((len(arg_6), len(arg_4)))

    for arg_8, arg_9 in enumerate(arg_5):
        arg_7[arg_6[arg_9], arg_8] = 1

    return filter_kwargs(mir_eval.sonify.time_frequency,
                         arg_7, arg_5, arg_4,
                         arg_1, arg_2=arg_2, **arg_3)


def Func(arg_0, arg_1=None, arg_2=None):
        """  Setup time axis. """

        # now check to see how many integrations requested
        arg_3, arg_4 = 0, arg_0.n_ints_in_file
        if arg_1:
            arg_3 = arg_1
        if arg_2:
            arg_4 = arg_2
        arg_5 = arg_4 - arg_3

        ## Setup time axis
        arg_6 = arg_0.header[b'tstart']
        arg_7 = arg_0.header[b'tsamp']

        arg_0.timestamps = np.arange(0, arg_5) * arg_7 / 24./60./60 + arg_6

        return arg_3, arg_4, arg_5


def Func(arg_0, arg_1):
        """ Blank DC bins in coarse channels.

        Note: currently only works if entire file is read
        """

        if arg_1 < 1:
            logger.warning('Coarse channel number < 1, unable to blank DC bin.')
            return None

        if not arg_1 % int(arg_1) == 0:
            logger.warning('Selection does not contain an interger number of coarse channels, unable to blank DC bin.')
            return None

        arg_1 = int(arg_1)

        arg_2 = arg_0.data.shape[-1]
        arg_3 = int(arg_2 / arg_1)

        arg_4 = int(arg_3 / 2)

        for arg_5 in range(arg_1):
            arg_6 = arg_5*arg_3
            arg_0.data[..., arg_6+arg_4] = np.median(arg_0.data[..., arg_6+arg_4+5:arg_6+arg_4+10])


def Func(arg_0,arg_1=None,arg_2=None,arg_3=False):
        """ Setup ploting edges.
        """

        arg_4 = arg_1[0]
        arg_5 = arg_1[-1] + (arg_1[1]-arg_1[0])

        arg_6 = arg_0.timestamps[0]
        arg_7  = arg_0.timestamps[-1] + (arg_0.timestamps[1] - arg_0.timestamps[0])

        if arg_3:
            arg_8=(arg_4, plot_f_begin_end, arg_6, arg_7)
        else:
            arg_8=(arg_4, arg_5, 0.0,(arg_7-arg_6)*24.*60.*60)

        return arg_8


def Func(arg_0, arg_1=None, arg_2=None, arg_3=0, arg_4=True, arg_5=True, arg_6=False, **arg_7):
        """ Plot waterfall of data

        Args:
            f_start (float): start frequency, in MHz
            f_stop (float): stop frequency, in MHz
            logged (bool): Plot in linear (False) or dB units (True),
            cb (bool): for plotting the colorbar
            kwargs: keyword args to be passed to matplotlib imshow()
        """

        arg_8, arg_9 = arg_0.grab_data(arg_1, arg_2, arg_3)

        #Using accending frequency for all plots.
        if arg_0.header[b'foff'] < 0:
            arg_9 = arg_9[..., ::-1] # Reverse data
            arg_8 = arg_8[::-1]

        if arg_4:
            arg_9 = db(arg_9)

        # Make sure waterfall plot is under 4k*4k
        arg_10, arg_11 = 1, 1
        if arg_9.shape[0] > MAX_IMSHOW_POINTS[0]:
            arg_10 = int(arg_9.shape[0] / MAX_IMSHOW_POINTS[0])

        if arg_9.shape[1] > MAX_IMSHOW_POINTS[1]:
            arg_11 =  int(arg_9.shape[1] /  MAX_IMSHOW_POINTS[1])

        arg_9 = rebin(arg_9, arg_10, arg_11)

        try:
            plt.title(arg_0.header[b'source_name'])
        except KeyError:
            plt.title(arg_0.filename)

        arg_12 = arg_0._calc_extent(arg_8=arg_8,plot_t=arg_0.timestamps,arg_6=arg_6)

        plt.imshow(arg_9,
            aspect='auto',
            origin='lower',
            rasterized=True,
            interpolation='nearest',
            arg_12=arg_12,
            cmap='viridis',
            **arg_7
        )
        if arg_5:
            plt.colorbar()
        plt.xlabel("Frequency [MHz]")
        if arg_6:
            plt.ylabel("Time [MJD]")
        else:
            plt.ylabel("Time [s]")


def Func(arg_0, arg_1=None, arg_2=None, arg_3=0, arg_4=True, arg_5='h', arg_6=False, **arg_7):
        """ Plot the time series.

         Args:
            f_start (float): start frequency, in MHz
            f_stop (float): stop frequency, in MHz
            logged (bool): Plot in linear (False) or dB units (True),
            kwargs: keyword args to be passed to matplotlib imshow()
        """

        arg_8 = plt.gca()
        arg_9, arg_10 = arg_0.grab_data(arg_1, arg_2, arg_3)

        if arg_4 and arg_0.header[b'nbits'] >= 8:
            arg_10 = db(arg_10)

        #Since the data has been squeezed, the axis for time goes away if only one bin, causing a bug with axis=1
        if len(arg_10.shape) > 1:
            arg_10 = arg_10.mean(axis=1)
        else:
            arg_10 = arg_10.mean()

        #Make proper time axis for plotting (but only for plotting!). Note that this makes the values inclusive.
        arg_11 = arg_0._calc_extent(arg_9=arg_9,arg_12=arg_0.timestamps,arg_6=arg_6)
        arg_12 = np.linspace(arg_11[2],arg_11[3],len(arg_0.timestamps))

        if arg_6:
            arg_13 = "Time [MJD]"
        else:
            arg_13 = "Time [s]"

        if arg_4:
            arg_14 = "Power [dB]"
        else:
            arg_14 = "Power [counts]"

        # Reverse oder if vertical orientation.
        if 'v' in arg_5:
            plt.plot(arg_10, arg_12, **arg_7)
            plt.xlabel(arg_14)

        else:
            plt.plot(arg_12, arg_10, **arg_7)
            plt.xlabel(arg_13)
            plt.ylabel(arg_14)

        arg_8.autoscale(axis='both',tight=True)


def Func(arg_0,arg_1):
    '''
    Converts a data array with length n_chans to an array of length n_coarse_chans
    by averaging over the coarse channels
    '''
    #find number of coarse channels and reshape array
    arg_2 = arg_0.size/arg_1
    arg_3 = np.array(np.reshape(arg_0,(arg_2,arg_1)))

    #Return the average over each coarse channel
    return np.mean(arg_3[:,2:-1],axis=1)


def Func(arg_0,arg_1,arg_2,arg_3, arg_4, arg_5, arg_6, arg_7='l'):
    '''
    Returns calibrated Stokes parameters for an observation given an array
    of differential gains and phase differences.
    '''

    #Find shape of data arrays and calculate number of coarse channels
    arg_8 = arg_0.shape
    arg_9 = arg_0.shape[0]
    arg_10 = arg_0.shape[1]
    arg_11 = arg_0.shape[2]
    arg_12 = arg_11/arg_6

    #Reshape data arrays to separate coarse channels
    arg_0 = np.reshape(arg_0,(arg_9,arg_10,arg_12,arg_6))
    arg_1 = np.reshape(arg_1,(arg_9,arg_10,arg_12,arg_6))
    arg_2 = np.reshape(arg_2,(arg_9,arg_10,arg_12,arg_6))
    arg_3 = np.reshape(arg_3,(arg_9,arg_10,arg_12,arg_6))

    #Swap axes 2 and 3 to in order for broadcasting to work correctly
    arg_0 = np.swapaxes(arg_0,2,3)
    arg_1 = np.swapaxes(arg_1,2,3)
    arg_2 = np.swapaxes(arg_2,2,3)
    arg_3 = np.swapaxes(arg_3,2,3)

    #Apply top left corner of electronics chain inverse Mueller matrix
    arg_13 = 1/(1-arg_4**2)
    if arg_7=='l':
        arg_14 = arg_13*(arg_0-arg_4*arg_1)
        arg_15 = arg_13*(-1*arg_4*arg_0+arg_1)
        arg_0 = None
        arg_1 = None
    if arg_7=='c':
        arg_14 = arg_13*(arg_0-arg_4*arg_3)
        arg_16 = arg_13*(-1*arg_4*arg_0+arg_3)
        arg_0 = None
        arg_3 = None

    #Apply bottom right corner of electronics chain inverse Mueller matrix
    if arg_7=='l':
        arg_17 = arg_2*np.cos(arg_5)-arg_3*np.sin(arg_5)
        arg_16 = arg_2*np.sin(arg_5)+arg_3*np.cos(arg_5)
        arg_2 = None
        arg_3 = None
    if arg_7=='c':
        arg_15 = arg_1*np.cos(arg_5)+arg_2*np.sin(arg_5)
        arg_17 = -1*arg_1*np.sin(arg_5)+arg_2*np.cos(arg_5)
        arg_1 = None
        arg_2 = None

    #Reshape arrays to original shape
    arg_14 = np.reshape(np.swapaxes(arg_14,2,3),arg_8)
    arg_15 = np.reshape(np.swapaxes(arg_15,2,3),arg_8)
    arg_17 = np.reshape(np.swapaxes(arg_17,2,3),arg_8)
    arg_16 = np.reshape(np.swapaxes(arg_16,2,3),arg_8)

    #Return corrected data arrays
    return arg_14,arg_15,arg_17,arg_16


def Func(arg_0, **arg_1):
    '''Output fractional linear and circular polarizations for a
    rawspec cross polarization .fil file. NOT STANDARD USE'''

    arg_2,arg_3,arg_4,arg_5,arg_6=get_stokes(arg_0, **arg_1)
    return arg_6/arg_2,arg_5/arg_2


def Func(arg_0, arg_1, **arg_2):
    '''Writes two new filterbank files containing fractional linear and
    circular polarization data'''

    arg_3,arg_4=fracpols(arg_0, **arg_2)
    arg_5 = Waterfall(arg_1, max_load=150)

    arg_5.data = arg_3
    arg_5.write_to_fil(arg_0[:-15]+'.linpol.fil')   #assuming file is named *.cross_pols.fil

    arg_5.data = arg_4
    arg_5.write_to_fil(arg_0[:-15]+'.circpol.fil')


def Func(arg_0, arg_1):
    """ Return the index of the Func in xarr to value val """
    arg_2 = np.argmin(np.abs(np.array(arg_0) - arg_1))
    return arg_2


def Func(arg_0, arg_1, arg_2=None):
    """ Rebin data by averaging bins together

    Args:
    d (np.array): data
    n_x (int): number of bins in x dir to Func into one
    n_y (int): number of bins in y dir to Func into one

    Returns:
    d: Funcned data with shape (n_x, n_y)
    """

    if arg_0.ndim == 2:
        if arg_2 is None:
            arg_2 = 1
        if arg_1 is None:
            arg_1 = 1
        arg_0 = arg_0[:int(arg_0.shape[0] // arg_1) * arg_1, :int(arg_0.shape[1] // arg_2) * arg_2]
        arg_0 = arg_0.reshape((arg_0.shape[0] // arg_1, arg_1, arg_0.shape[1] // arg_2, arg_2))
        arg_0 = arg_0.mean(axis=3)
        arg_0 = arg_0.mean(axis=1)
    elif arg_0.ndim == 1:
        arg_0 = arg_0[:int(arg_0.shape[0] // arg_1) * arg_1]
        arg_0 = arg_0.reshape((arg_0.shape[0] // arg_1, arg_1))
        arg_0 = arg_0.mean(axis=1)
    else:
        raise RuntimeError("Only NDIM <= 2 supported")
    return arg_0


def Func(arg_0, arg_1):
    """upgrade data from nbits to 8bits

    Notes: Pretty sure this function is a little broken!
    """
    if arg_1 > 8:
        raise ValueError("Func: nbit must be <= 8")
    if 8 % arg_1 != 0:
        raise ValueError("Func: nbit must divide into 8")
    if arg_0.dtype not in (np.uint8, np.int8):
        raise TypeError("Func: dtype must be 8-bit")
    if arg_1 == 8:
        return arg_0
    elif arg_1 == 4:
        arg_0 = Func_4to8(arg_0)
        return arg_0
    elif arg_1 == 2:
        arg_0 = Func_2to8(arg_0)
        return arg_0
    elif arg_1 == 1:
        arg_0 = Func_1to8(arg_0)
        return arg_0


def Func(arg_0,arg_1=True,arg_2='l',**arg_3):
    '''
    Plots the uncalibrated full stokes spectrum of the noise diode.
    Use diff=False to plot both ON and OFF, or diff=True for ON-OFF
    '''

    #If diff=True, get ON-OFF. If not get ON and OFF separately
    if arg_1==True:
        arg_4,arg_5,arg_6,arg_7,arg_8 = get_diff(arg_0,arg_2,**arg_3)
    else:
        arg_9 = Waterfall(arg_0,max_load=150)
        arg_8 = arg_9.populate_freqs()
        arg_10 = arg_9.header['tsamp']
        arg_11 = arg_9.data
        arg_12,arg_13,arg_14,arg_15 = get_stokes(arg_11,arg_2)

        arg_16,arg_17 = foldcal(arg_12,arg_10,**arg_3)
        arg_18,arg_19 = foldcal(arg_13,arg_10,**arg_3)
        arg_20,arg_21 = foldcal(arg_14,arg_10,**arg_3)
        arg_22,arg_23 = foldcal(arg_15,arg_10,**arg_3)

    #Plot spectra
    if arg_1==True:
        plt.plot(arg_8,arg_4,'k-',label='I')
        plt.plot(arg_8,arg_5,'r-',label='Q')
        plt.plot(arg_8,arg_6,'g-',label='U')
        plt.plot(arg_8,arg_7,'m-',label='V')
    else:
        plt.plot(arg_8,arg_17,'k-',label='I ON')
        plt.plot(arg_8,arg_16,'k--',label='I OFF')
        plt.plot(arg_8,arg_19,'r-',label='Q ON')
        plt.plot(arg_8,arg_18,'r--',label='Q OFF')
        plt.plot(arg_8,arg_21,'g-',label='U ON')
        plt.plot(arg_8,arg_20,'g--',label='U OFF')
        plt.plot(arg_8,arg_23,'m-',label='V ON')
        plt.plot(arg_8,arg_22,'m--',label='V OFF')

    plt.legend()
    plt.xlabel('Frequency (MHz)')
    plt.title('Uncalibrated Full Stokes Noise Diode Spectrum')
    plt.ylabel('Power (Counts)')


def Func(arg_0,arg_1=8,arg_2='l',arg_3=None,arg_4=None,arg_5=True,**arg_6):
    '''
    Plots the calculated gain offsets of each coarse channel along with
    the time averaged power spectra of the X and Y feeds
    '''
    #Get ON-OFF ND spectra
    arg_7,arg_8,arg_9,arg_10,arg_11 = get_diff(arg_0,arg_2,**arg_6)
    arg_12 = Waterfall(arg_0,max_load=150)
    arg_13 = arg_12.header['tsamp']
    arg_14 = arg_12.data
    arg_12 = None
    arg_15,arg_16,arg_17,arg_18 = get_stokes(arg_14,arg_2)

    #Get phase offsets and convert to degrees
    arg_19 = gain_offsets(arg_15,arg_16,arg_17,arg_18,arg_13,arg_1,arg_2,**arg_6)
    arg_20 = convert_to_coarse(arg_11,arg_1)

    #Get X and Y spectra for the noise diode ON and OFF
    #If using circular feeds these correspond to LL and RR
    arg_21,arg_22 = foldcal(np.expand_dims(arg_14[:,0,:],axis=1),arg_13,**arg_6)
    arg_23,arg_24 = foldcal(np.expand_dims(arg_14[:,1,:],axis=1),arg_13,**arg_6)

    if arg_3==None:
        plt.subplot(211)
    else:
        arg_25 = plt.axes(arg_3)
        plt.setp(arg_25.get_xticklabels(),visible=False)
    plt.plot(arg_20,arg_19,'ko',markersize=2)
    plt.ylabel(r'$\frac{\Delta G}{2}$',rotation=90)
    if arg_2=='l':
        plt.title('XY Gain Difference')
    if arg_2=='c':
        plt.title('LR Gain Difference')
    plt.grid(True)

    if arg_4==None:
        plt.subplot(212)
    else:
        arg_26 = plt.axes(arg_4,sharex=arg_25)
    if arg_2=='l':
        plt.plot(arg_11,arg_21,'b-',label='XX')
        plt.plot(arg_11,arg_23,'r-',label='YY')
    if arg_2=='c':
        plt.plot(arg_11,arg_21,'b-',label='LL')
        plt.plot(arg_11,arg_23,'r-',label='RR')
    plt.xlabel('Frequency (MHz)')
    plt.ylabel('Power (Counts)')
    if arg_5==True:
        plt.legend()


def Func(arg_0, arg_1=None, arg_2=None,arg_3=None, arg_4=None,arg_5=True,arg_6=1.):
    """Open a HDF5 or filterbank file

    Returns instance of a Reader to read data from file.

    ================== ==================================================
    Filename extension File type
    ================== ==================================================
    h5, hdf5           HDF5 format
    fil                fil format
    *other*            Will raise NotImplementedError
    ================== ==================================================

    """
    if not os.path.isfile(arg_0):
        type(arg_0)
        print(arg_0)
        raise IOError("No such file or directory: " + arg_0)

    arg_0 = os.path.expandvars(os.path.expanduser(arg_0))
    # Get file extension to determine type
    arg_7 = arg_0.split(".")[-1].strip().lower()

    if six.PY3:
        arg_7 = bytes(arg_7, 'ascii')

    if h5py.is_hdf5(arg_0):
        # Open HDF5 file
        return H5Reader(arg_0, arg_1=arg_1, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4,
                        arg_5=arg_5, arg_6=arg_6)
    elif sigproc.is_filterbank(arg_0):
        # Open FIL file
        return FilReader(arg_0, arg_1=arg_1, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4, arg_5=arg_5, arg_6=arg_6)
    else:
        raise NotImplementedError('Cannot open this type of file with Waterfall')


def Func(arg_0):
        """Calculate size of data of interest.
        """

        #Check to see how many integrations requested
        arg_1 = arg_0.t_stop - arg_0.t_start
        #Check to see how many frequency channels requested
        arg_2 = (arg_0.f_stop - arg_0.f_start) / abs(arg_0.header[b'foff'])

        arg_3  = arg_0._n_bytes
        arg_4 = int(arg_1*arg_2*arg_3)

        return arg_4


def Func(arg_0):
        """Calculate shape of data of interest.
        """

        #Check how many integrations requested
        arg_1 = int(arg_0.t_stop - arg_0.t_start)
        #Check how many frequency channels requested
        arg_2 = int(np.round((arg_0.f_stop - arg_0.f_start) / abs(arg_0.header[b'foff'])))

        arg_3 = (arg_1,int(arg_0.header[b'nifs']),arg_2)

        return arg_3


def Func(arg_0):
        """Setup channel borders
        """

        if arg_0.header[b'foff'] < 0:
            arg_1 = arg_0.f_end
        else:
            arg_1 = arg_0.f_begin

        arg_2, arg_3 = 0, arg_0.n_channels_in_file
        if arg_0.f_start:
            arg_2 = np.round((arg_0.f_start - arg_1) / arg_0.header[b'foff'])
        if arg_0.f_stop:
            arg_3  = np.round((arg_0.f_stop - arg_1)  / arg_0.header[b'foff'])

        #calculate closest true index value
        arg_4 = np.int(arg_2)
        arg_5  = np.int(arg_3)

        if arg_5 < arg_4:
            arg_5, arg_4 = arg_4,arg_5

        arg_0.chan_start_idx =  arg_4
        arg_0.chan_stop_idx = arg_5


def Func(arg_0):
        """Updating frequency borders from channel values
        """

        if arg_0.header[b'foff'] > 0:
            arg_0.f_start = arg_0.f_begin + arg_0.chan_start_idx*abs(arg_0.header[b'foff'])
            arg_0.f_stop = arg_0.f_begin + arg_0.chan_stop_idx*abs(arg_0.header[b'foff'])
        else:
            arg_0.f_start = arg_0.f_end - arg_0.chan_stop_idx*abs(arg_0.header[b'foff'])
            arg_0.f_stop = arg_0.f_end - arg_0.chan_start_idx*abs(arg_0.header[b'foff'])


def Func(arg_0,arg_1=False):
        """  Populate time axis.
            IF update_header then only return tstart
        """

        #Check to see how many integrations requested
        arg_2, arg_3 = 0, arg_0.n_ints_in_file
        if arg_0.t_start:
            arg_2 = arg_0.t_start
        if arg_0.t_stop:
            arg_3 = arg_0.t_stop

        ## Setup time axis
        arg_4 = arg_0.header[b'tstart']
        arg_5 = arg_0.header[b'tsamp']

        if arg_1:
            arg_6 = arg_2 * arg_5 / 24./60./60. + arg_4
        else:
            arg_6 = np.arange(arg_2, arg_3) * arg_5 / 24./60./60. + arg_4

        return arg_6


def Func(arg_0):
        """
         Populate frequency axis
        """

        if arg_0.header[b'foff'] < 0:
            arg_1 = arg_0.f_end
        else:
            arg_1 = arg_0.f_begin

        arg_0._setup_chans()

        #create freq array
        arg_2 = np.arange(arg_0.chan_start_idx, arg_0.chan_stop_idx)
        arg_3 = arg_0.header[b'foff'] * arg_2 + arg_1

        return arg_3


def Func(arg_0, arg_1):
        """ Given the blob dimensions, calculate how many fit in the data selection.
        """

        arg_2 = int(np.ceil(1.0 * np.prod(arg_0.selection_shape) / np.prod(arg_1)))

        return arg_2


def Func(arg_0):
        """ Check if the current selection is too large.
        """

        arg_1 = arg_0._calc_selection_size()

        if arg_1 > arg_0.MAX_DATA_ARRAY_SIZE:
            return True
        else:
            return False


def Func(arg_0, arg_1=None, arg_2=None,arg_3=None, arg_4=None):
        """ Read data.
        """

        arg_0._setup_selection_range(arg_1=arg_1, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4)

        #check if selection is small enough.
        if arg_0.isheavy():
            logger.warning("Selection size of %.2f GB, exceeding our size limit %.2f GB. Instance created, "
                           "header loaded, but data not loaded, please try another (t,v) selection." % (arg_0._calc_selection_size() / (1024. ** 3), arg_0.MAX_DATA_ARRAY_SIZE / (1024. ** 3)))
            arg_0.data = np.array([0],dtype=arg_0._d_type)
            return None

        #Convert input frequencies into what their corresponding channel number would be.
        arg_0._setup_chans()
        #Update frequencies ranges from channel number.
        arg_0._setup_freqs()

        arg_6 = arg_0.header[b'nchans']
        arg_7 = arg_0.selection_shape[arg_0.freq_axis]
        arg_8   = arg_0.header[b'nifs']

        # Load binary data
        arg_9 = open(arg_0.filename, 'rb')
        arg_9.seek(int(arg_0.idx_data))

        # now check to see how many integrations requested
        arg_10 = arg_0.t_stop - arg_0.t_start

        # Seek to first integration
        arg_9.seek(int(arg_0.t_start * arg_0._n_bytes  * arg_8 * arg_6), 1)

        #Loading  data
        arg_0.data = np.zeros((arg_10, arg_8, arg_7), dtype=arg_0._d_type)

        for arg_11 in range(arg_10):
            for arg_12 in range(arg_8):
                arg_9.seek(int(arg_0._n_bytes  * arg_0.chan_start_idx), 1) # 1 = from current location
                arg_13 = np.fromfile(arg_9, count=arg_7, dtype=arg_0._d_type)

                # Reverse array if frequency axis is flipped
#                     if self.header[b'foff'] < 0:
#                         dd = dd[::-1]

                arg_0.data[arg_11, arg_12] = arg_13

                arg_9.seek(int(arg_0._n_bytes  * (arg_6 - arg_0.chan_stop_idx)), 1)


def Func(arg_0,arg_1,arg_2=True):
        """ Read a block of data. The number of samples per row is set in self.channels
            If reverse=True the x axis is flipped.
        """
        raise NotImplementedError('To be implemented')

        # go to start of the row
        arg_0.filfile.seek(int(arg_0.datastart+arg_0.channels*arg_1*(int(arg_0.nbits/8))))
        # read data into 2-D numpy array
        arg_3=np.fromfile(arg_0.filfile,count=arg_0.channels,dtype=arg_0.dtype).reshape(1, arg_0.channels)
        if arg_2:
            arg_3 = arg_3[:,::-1]
        return arg_3


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """ Write data to .fil file.
            It check the file size then decides how to write the file.

        Args:
            filename_out (str): Name of output file
        """

        #For timing how long it takes to write a file.
        arg_4 = time.time()

        #Update header
        arg_0.__update_header()

        if arg_0.container.isheavy():
            arg_0.__Func_heavy(arg_1)
        else:
            arg_0.__Func_light(arg_1)

        arg_5 = time.time()
        logger.info('Conversion time: %2.2fsec' % (arg_5- arg_4))


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """ Write data to HDF5 file.
            It check the file size then decides how to write the file.

        Args:
            filename_out (str): Name of output file
        """

        #For timing how long it takes to write a file.
        arg_4 = time.time()

        #Update header
        arg_0.__update_header()

        if arg_0.container.isheavy():
            arg_0.__Func_heavy(arg_1)
        else:
            arg_0.__Func_light(arg_1)

        arg_5 = time.time()
        logger.info('Conversion time: %2.2fsec' % (arg_5- arg_4))


def Func(arg_0, arg_1):
        """ Sets the blob dimmentions, trying to read around 1024 MiB at a time.
            This is assuming a chunk is about 1 MiB.
        """

        #Taking the size into consideration, but avoiding having multiple blobs within a single time bin.
        if arg_0.selection_shape[arg_0.freq_axis] > arg_1[arg_0.freq_axis]*MAX_BLOB_MB:
            arg_2 = arg_0.selection_shape[arg_0.freq_axis]
#             while freq_axis_size > chunk_dim[self.freq_axis]*MAX_BLOB_MB:
#                 freq_axis_size /= 2
            arg_3 = 1
        else:
            arg_2 = arg_0.selection_shape[arg_0.freq_axis]
            arg_3 = np.min([arg_1[arg_0.time_axis] * MAX_BLOB_MB * arg_1[arg_0.freq_axis] / arg_2, arg_0.selection_shape[arg_0.time_axis]])

        arg_4 = (int(arg_3), 1, arg_2)

        return arg_4


def Func(arg_0, arg_1=None, arg_2=None,arg_3=None, arg_4=None, arg_5=0):
        """ Extract a portion of data by frequency range.

        Args:
            f_start (float): start frequency in MHz
            f_stop (float): stop frequency in MHz
            if_id (int): IF input identification (req. when multiple IFs in file)

        Returns:
            (freqs, data) (np.arrays): frequency axis in MHz and data subset
        """

        arg_0.freqs = arg_0.populate_freqs()
        arg_0.timestamps = arg_0.populate_timestamps()

        if arg_1 is None:
            arg_1 = arg_0.freqs[0]
        if arg_2 is None:
            arg_2 = arg_0.freqs[-1]

        arg_8 = np.argmin(np.abs(arg_0.freqs - arg_1))
        arg_9 = np.argmin(np.abs(arg_0.freqs - arg_2))

        if arg_8 < arg_9:
            arg_10    = arg_0.freqs[arg_8:arg_9 + 1]
            arg_11 = np.squeeze(arg_0.data[arg_3:arg_4, ..., arg_8:arg_9 + 1])
        else:
            arg_10    = arg_0.freqs[arg_9:arg_8 + 1]
            arg_11 = np.squeeze(arg_0.data[arg_3:arg_4, ..., arg_9:arg_8 + 1])

        return arg_10, arg_11


def Func(arg_0=None):
    """ Command line tool for plotting and viewing info on guppi raw files """

    from argparse import ArgumentParser

    arg_1 = ArgumentParser(description="Command line utility for creating spectra from GuppiRaw files.")

    arg_1.add_argument('filename', type=str, help='Name of file to read')
    arg_1.add_argument('-o', dest='outdir', type=str, default='./', help='output directory for PNG files')
    arg_0 = arg_1.parse_args()

    arg_2 = GuppiRaw(arg_0.filename)

    arg_2.print_stats()
    arg_3 = os.path.splitext(os.path.basename(arg_0.filename))[0]
    arg_3 = os.path.join(arg_0.outdir, arg_3)
    arg_2.plot_histogram(filename="%s_hist.png" % arg_3)
    arg_2.plot_spectrum(filename="%s_spec.png" % arg_3)


def Func(arg_0):
        """ Read first header in file

        Returns:
            header (dict): keyword:value pairs of header metadata
        """
        arg_0.file_obj.seek(0)
        arg_1, arg_2 = arg_0.read_header()
        arg_0.file_obj.seek(0)
        return arg_1


def Func(arg_0):
        """ Compute some basic stats on the next block of data """

        arg_1, arg_2 = arg_0.read_next_data_block()
        arg_2 = arg_2.view('float32')

        print("AVG: %2.3f" % arg_2.mean())
        print("STD: %2.3f" % arg_2.std())
        print("MAX: %2.3f" % arg_2.max())
        print("MIN: %2.3f" % arg_2.min())

        import pylab as plt


def Func(arg_0, arg_1=None):
        """ Plot a histogram of data values """
        arg_2, arg_3 = arg_0.read_next_data_block()
        arg_3 = arg_3.view('float32')

        plt.figure("Histogram")
        plt.hist(arg_3.flatten(), 65, facecolor='#cc0000')
        if arg_1:
            plt.savefig(arg_1)
        plt.show()


def Func(arg_0, arg_1=1, ):
        """ Generate a blimpy header dictionary """
        arg_2 = arg_0.read_first_header()
        arg_3 = {}

        arg_4 = arg_2.get("TELESCOP", "unknown")
        if arg_4 in ('GBT', 'GREENBANK'):
            arg_3["telescope_id"] = 6
        elif arg_4 in ('PKS', 'PARKES'):
            arg_3["telescop_id"] = 7
        else:
            arg_3["telescop_id"] = 0

        # Using .get() method allows us to fill in default values if not present
        arg_3["source_name"] = arg_2.get("SRC_NAME", "unknown")
        arg_3["az_start"] = arg_2.get("AZ", 0)
        arg_3["za_start"] = arg_2.get("ZA", 0)

        arg_3["src_raj"] = Angle(str(arg_2.get("RA", 0.0)) + "hr")
        arg_3["src_dej"] = Angle(str(arg_2.get("DEC", 0.0)) + "deg")
        arg_3["rawdatafile"] = arg_0.filename

        # hardcoded
        arg_3["machine_id"] = 20
        arg_3["data_type"] = 1  # blio datatype
        arg_3["barycentric"] = 0
        arg_3["pulsarcentric"] = 0
        arg_3["nbits"] = 32

        # TODO - compute these values. Need to figure out the correct calcs
        arg_3["tstart"] = 0.0
        arg_3["tsamp"] = 1.0
        arg_3["fch1"] = 0.0
        arg_3["foff"] = 187.5 / arg_1

        # Need to be updated based on output specs
        arg_3["nchans"] = arg_1
        arg_3["nifs"] = 1
        arg_3["nbeams"] = 1

        return arg_3


def Func(arg_0=None):
    """ Command line tool to make a md5sum comparison of two .fil files. """

    if 'bl' in local_host:
        arg_1 = '/usr/local/sigproc/bin/header' #Current location of header command in GBT.
    else:
        raise IOError('Script only able to run in BL systems.')

    arg_2 = OptionParser()
    arg_2.set_usage('matchfils <FIL_FILE1> <FIL_FILE2>')
    arg_3, arg_0 = arg_2.parse_args(sys.argv[1:])

    arg_4 = arg_0[0]
    arg_5 = arg_0[1]

    #------------------------------------
    #Create batch script

    make_batch_script()

    #------------------------------------
    #First checksum

    arg_6 = find_header_size(arg_4)
    arg_7 = os.path.getsize(arg_4)

    #Strip header from file, and calculate the md5sum of the rest.
    #command=['tail','-c',str(file_size1-headersize1),file1,'|','md5sum']
    arg_8=['./tail_sum.sh',arg_4,str(arg_7-arg_6)]
    print('[matchfils] '+' '.join(arg_8))

    arg_9 = subprocess.Popen(arg_8, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (arg_10, arg_11) = arg_9.communicate()

    arg_12 = arg_10.split()[0]
    print('[matchfils] Checksum is:', arg_12)

    if arg_11:
        raise Error('There is an error.')

    #---
    arg_10,arg_11 = reset_outs()

    arg_8=[arg_1,arg_4]
    print('[matchfils] Header information:')

    arg_9 = subprocess.Popen(arg_8, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (arg_10, arg_11) = arg_9.communicate()

    arg_13 = arg_10
    print(arg_13)

    #------------------------------------
    #Second checksum

    arg_10,arg_11 = reset_outs()

    arg_14 = find_header_size(arg_5)
    arg_15 = os.path.getsize(arg_5)

    #Strip header from file, and calculate the md5sum of the rest.
    arg_8=['./tail_sum.sh',arg_5,str(arg_15-arg_14)]
    print('[matchfils] '+' '.join(arg_8))

    arg_9 = subprocess.Popen(arg_8, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (arg_10, arg_11) = arg_9.communicate()

    arg_16 = arg_10.split()[0]
    print('[matchfils] Checksum is:', arg_16)

    if arg_11:
        raise Error('There is an error.')

    #---
    arg_10,arg_11 = reset_outs()

    arg_8=[arg_1,arg_5]
    print('[matchfils] Header information:')

    arg_9 = subprocess.Popen(arg_8, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (arg_10, arg_11) = arg_9.communicate()

    arg_17 = arg_10
    print(arg_17)

    #------------------------------------
    #check the checksums

    if arg_12 != arg_16:
        print('[matchfils] Booo! Checksum does not match between files.')
    else:
        print('[matchfils] Hooray! Checksum matches between files.')

    #------------------------------------
    #Remove batch script

    os.remove('tail_sum.sh')


def Func(arg_0=None):
    """ Command line tool for converting guppi raw into HDF5 versions of guppi raw """
    from argparse import ArgumentParser

    if not HAS_BITSHUFFLE:
        print("Error: the bitshuffle library is required to run this script.")
        exit()

    arg_1 = ArgumentParser(description="Command line utility for creating HDF5 Raw files.")
    arg_1.add_argument('filename', type=str, help='Name of filename to read')
    arg_0 = arg_1.parse_args()

    arg_2 = arg_0.filename.split('.0000.raw')[0]

    arg_3 = glob.glob(arg_2 + '*.raw')
    arg_3 = sorted(arg_3)

    # Read first file
    arg_4 = GuppiRaw(arg_3[0])
    arg_5, arg_6 = arg_4.read_next_data_block()
    arg_7 = arg_6.shape #r.read_next_data_block_shape()
    print(arg_7)

    arg_8 = 0
    for arg_9 in arg_3:
        print(arg_9)
        arg_4 = GuppiRaw(arg_9)
        arg_8 += arg_4.n_blocks
    print(arg_8)

    arg_10 = np.concatenate(((arg_8,), arg_7))

    # Create h5py file
    arg_11 = h5py.File(arg_2 + '.h5', 'w')
    arg_11.attrs['CLASS'] = 'GUPPIRAW'
    arg_13 = 0      # This is chunk block size
    arg_14 = arg_11.create_dataset('data',
                  shape=arg_10,
                  #compression=bitshuffle.h5.H5FILTER,
                  #compression_opts=(block_size, bitshuffle.h5.H5_COMPRESS_LZ4),
                  dtype=arg_6.dtype)

    arg_15 = 0
    for arg_9 in arg_3:
        print("\nReading %s header..." % arg_9)
        arg_4 = GuppiRaw(arg_9)
        arg_11 = h5py.File(arg_9 + '.h5', 'w')

        arg_5, arg_6 = arg_4.read_next_data_block()

        for arg_16 in range(0, arg_4.n_blocks):
            arg_17 = time.time()
            print("Reading block %i of %i" % (arg_15+1, arg_10[0]))
            arg_5, arg_6 = arg_4.read_next_data_block()
            arg_18 = time.time()

            arg_19 = time.time()
            print("Writing block %i of %i" % (arg_15+1, arg_10[0]))
            arg_14[arg_15, :] = arg_6
            arg_20 = time.time()
            print("Read: %2.2fs, Write %2.2fs" % ((arg_18-arg_17), (arg_20-arg_19)))

            arg_15 += 1

            # Copy over header information as attributes
            for arg_21, arg_22 in arg_5.items():
                arg_14.attrs[arg_21] = arg_22

        arg_11.close()

        arg_18 = time.time()
        print("Conversion time: %2.2fs" % (arg_18- arg_17))


def Func(arg_0,arg_1, arg_2=0.04,arg_3=1000,arg_4=False,arg_5=False):
    '''
    Returns time-averaged spectra of the ON and OFF measurements in a
    calibrator measurement with flickering noise diode

    Parameters
    ----------
    data : 2D Array object (float)
        2D dynamic spectrum for data (any Stokes parameter) with flickering noise diode.
    tsamp : float
        Sampling time of data in seconds
    diode_p : float
        Period of the flickering noise diode in seconds
    numsamps : int
        Number of samples over which to average noise diode ON and OFF
    switch : boolean
        Use switch=True if the noise diode "skips" turning from OFF to ON once or vice versa
    inds : boolean
        Use inds=True to also return the indexes of the time series where the ND is ON and OFF
    '''

    arg_6 = arg_2/2.0

    arg_7 = arg_6/arg_1   #number of time samples per diode switch

    arg_8 = 1/arg_1    #number of time samples in the first second

    #Find diode switches in units of time samples and round down to the nearest int
    arg_9 = np.arange(0,arg_3)
    arg_10 = (arg_8+arg_9*arg_7)
    arg_10 = arg_10.astype('int')

    arg_11 = np.array(np.reshape(arg_10[:],(arg_3/2,2)))
    arg_11[:,0] = arg_11[:,0]+1   #Find index ranges of ON time samples

    arg_12 = np.array(np.reshape(arg_10[1:-1],(arg_3/2-1,2)))
    arg_12[:,0] = arg_12[:,0]+1   #Find index ranges of OFF time samples

    arg_13 = []
    arg_14 = []

    #Average ON and OFF spectra separately with respect to time
    for arg_15 in arg_11:
        if arg_15[1]!=arg_15[0]:
            arg_13.append(np.sum(arg_0[arg_15[0]:arg_15[1],:,:],axis=0)/(arg_15[1]-arg_15[0]))

    for arg_15 in arg_12:
        if arg_15[1]!=arg_15[0]:
            arg_14.append(np.sum(arg_0[arg_15[0]:arg_15[1],:,:],axis=0)/(arg_15[1]-arg_15[0]))

    #If switch=True, flip the return statement since ON is actually OFF
    if arg_4==False:
        if arg_5==False:
            return np.squeeze(np.mean(arg_13,axis=0)), np.squeeze(np.mean(arg_14,axis=0))
        else:
            return np.squeeze(np.mean(arg_13,axis=0)), np.squeeze(np.mean(arg_14,axis=0)),arg_11,arg_12
    if arg_4==True:
        if arg_5==False:
            return np.squeeze(np.mean(arg_14,axis=0)), np.squeeze(np.mean(arg_13,axis=0))
        else:
            return np.squeeze(np.mean(arg_14,axis=0)), np.squeeze(np.mean(arg_13,axis=0)),arg_12,arg_11


def Func(arg_0,arg_1,arg_2,arg_3,arg_4):
    '''
    Given properties of the calibrator source, calculate fluxes of the source
    in a particular frequency range

    Parameters
    ----------
    calflux : float
        Known flux of calibrator source at a particular frequency
    calfreq : float
        Frequency where calibrator source has flux calflux (see above)
    spec_in : float
        Known power-law spectral index of calibrator source. Use convention flux(frequency) = constant * frequency^(spec_in)
    centerfreqs : 1D Array (float)
        Central frequency values of each coarse channel
    oneflux : boolean
        Use oneflux to choose between calculating the flux for each core channel (False)
        or using one value for the entire frequency range (True)
    '''

    arg_5 = arg_0/np.power(arg_1,arg_2)
    if arg_4==False:
        return arg_5*np.power(arg_3,arg_2)
    else:
        return arg_5*np.power(np.mean(arg_3),arg_2)


def Func(arg_0,arg_1):
    '''
    Returns central frequency of each coarse channel

    Parameters
    ----------
    freqs : 1D Array (float)
        Frequency values for each bin of the spectrum
    chan_per_coarse: int
        Number of frequency bins per coarse channel
    '''

    arg_2 = arg_0.size/arg_1
    arg_0 = np.reshape(arg_0,(arg_2,arg_1))
    return np.mean(arg_0,axis=1)


def Func(arg_0,arg_1,arg_2,arg_3,arg_4,arg_5=False,**arg_6):
    '''
    Returns frequency dependent system temperature given observations on and off a calibrator source

    Parameters
    ----------
    (See diode_spec())
    '''
    return diode_spec(arg_0,arg_1,arg_2,arg_3,arg_4,average=False,arg_5=False,**arg_6)[1]


def Func(arg_0,arg_1,arg_2,arg_3,arg_4=False,**arg_5):
    '''
    Produce calibrated Stokes I for an observation given a noise diode
    measurement on the source and a diode spectrum with the same number of
    coarse channels

    Parameters
    ----------
    main_obs_name : str
        Path to filterbank file containing final data to be calibrated
    dio_name : str
        Path to filterbank file for observation on the target source with flickering noise diode
    dspec : 1D Array (float) or float
        Coarse channel spectrum (or average) of the noise diode in Jy (obtained from diode_spec())
    Tsys : 1D Array (float) or float
        Coarse channel spectrum (or average) of the system temperature in Jy
    fullstokes: boolean
        Use fullstokes=True if data is in IQUV format or just Stokes I, use fullstokes=False if
        it is in cross_pols format
    '''

    #Find folded spectra of the target source with the noise diode ON and OFF
    arg_6 = Waterfall(arg_0,max_load=150)
    arg_7 = arg_6.calc_n_coarse_chan()
    arg_8 = Waterfall(arg_1,max_load=150)
    arg_9 = arg_8.header['nchans']/arg_7
    arg_10,arg_11 = integrate_calib(arg_1,arg_9,arg_4,**arg_5)

    #Find Jy/count for each coarse channel using the diode spectrum
    arg_12 = arg_6.data
    arg_13 = arg_2/(arg_11-arg_10)
    print(arg_13)

    arg_14 = arg_6.header['nchans']
    arg_15 = arg_14/arg_7

    arg_16 = np.size(arg_12,0)
    arg_17 = np.size(arg_12,1)

    #Reshape data array of target observation and multiply coarse channels by the scale factors
    arg_12 = np.reshape(arg_12,(arg_16,arg_17,arg_7,arg_15))
    arg_12 = np.swapaxes(arg_12,2,3)

    arg_12 = arg_12*arg_13
    arg_12 = arg_12-arg_3
    arg_12 = np.swapaxes(arg_12,2,3)
    arg_12 = np.reshape(arg_12,(arg_16,arg_17,arg_14))

    #Write calibrated data to a new filterbank file with ".fluxcal" extension

    arg_6.data = arg_12
    arg_6.write_to_filterbank(arg_0[:-4]+'.fluxcal.fil')
    print('Finished: calibrated product written to ' + arg_0[:-4]+'.fluxcal.fil')


def Func(arg_0):
    """ Return the length of the blimpy header, in bytes

    Args:
        filename (str): name of file to open

    Returns:
        idx_end (int): length of header, in bytes
    """
    with  open(arg_0, 'rb') as f:
        arg_1 = 0
        arg_2 = False
        while not arg_2:
            arg_3 = f.read(512)
            arg_1 += 1
            if b'HEADER_END' in arg_3:
                arg_4 = arg_3.index(b'HEADER_END') + len(b'HEADER_END')
                arg_2 = True
                break

        arg_4 = (arg_1 -1) * 512 + arg_4
    return arg_4


def Func(arg_0):
    """ Open file and confirm if it is a filterbank file or not. """
    with open(arg_0, 'rb') as fh:
        arg_1 = True

        # Check this is a blimpy file
        try:
            arg_2, arg_3, arg_4 = read_next_header_keyword(fh)
            try:
                assert arg_2 == b'HEADER_START'
            except AssertionError:
                arg_1 = False
        except KeyError:
            arg_1 = False
        return arg_1


def Func(arg_0):
    """ Generate a serialzed sigproc header which can be written to disk.

    Args:
        f (Filterbank object): Filterbank object for which to generate header

    Returns:
        header_str (str): Serialized string corresponding to header
    """

    arg_1 = b''
    arg_1 += to_sigproc_keyword(b'HEADER_START')

    for arg_2 in arg_0.header.keys():
        if arg_2 == b'src_raj':
            arg_1 += to_sigproc_keyword(b'src_raj')  + to_sigproc_angle(arg_0.header[b'src_raj'])
        elif arg_2 == b'src_dej':
            arg_1 += to_sigproc_keyword(b'src_dej')  + to_sigproc_angle(arg_0.header[b'src_dej'])
        elif arg_2 == b'az_start' or arg_2 == b'za_start':
            arg_1 += to_sigproc_keyword(arg_2)  + np.float64(arg_0.header[arg_2]).tostring()
        elif arg_2 not in header_keyword_types.keys():
            pass
        else:
            arg_1 += to_sigproc_keyword(arg_2, arg_0.header[arg_2])

    arg_1 += to_sigproc_keyword(b'HEADER_END')
    return arg_1


def Func(arg_0):
    """ Calculate number of integrations in a given file """
    # Load binary data
    arg_1 = read_header(arg_0)
    arg_2  = int(arg_1[b'nbits'] / 8)

    arg_3 = arg_1[b'nchans']
    arg_4   = arg_1[b'nifs']
    arg_5 = len_header(arg_0)
    arg_6 = open(arg_0, 'rb')
    arg_6.seek(arg_5)
    arg_7 = os.path.getsize(arg_0)
    arg_8 = arg_7 - arg_5

    if arg_1[b'nbits'] == 2:
        arg_9 = int(4 * arg_8 / (arg_3 * arg_4))
    else:
        arg_9 = int(arg_8 / (arg_2 * arg_3 * arg_4))

    return arg_9


def Func(arg_0, arg_1, arg_2):
        """Check authorization id and other properties returned by the
        authentication mechanism.

        [receiving entity only]

        Allow only no authzid or authzid equal to current username@domain

        FIXME: other rules in s2s

        :Parameters:
            - `properties`: data obtained during authentication
        :Types:
            - `properties`: mapping

        :return: `True` if user is authorized to use a provided authzid
        :returntype: `bool`
        """
        arg_3 = arg_1.get("authzid")
        if not arg_3:
            return True
        try:
            arg_4 = JID(arg_3)
        except ValueError:
            return False

        if "username" not in arg_1:
            arg_5 = False
        elif arg_4.local != arg_1["username"]:
            arg_5 = False
        elif arg_4.domain != arg_2.me.domain:
            arg_5 = False
        elif arg_4.resource:
            arg_5 = False
        else:
            arg_5 = True
        return arg_5


def Func(arg_0, arg_1, arg_2, arg_3):
        """Start SASL authentication process.

        [initiating entity only]

        :Parameters:
            - `username`: user name.
            - `authzid`: authorization ID.
            - `mechanism`: SASL mechanism to use."""
        if not arg_1.initiator:
            raise SASLAuthenticationFailed("Only initiating entity start"
                                                        " SASL authentication")
        if arg_1.features is None or not arg_0.peer_sasl_mechanisms:
            raise SASLNotAvailable("Peer doesn't support SASL")

        arg_4 = dict(arg_1.auth_properties)
        if not arg_4.get("service-domain") and (
                                        arg_1.peer and arg_1.peer.domain):
            arg_4["service-domain"] = arg_1.peer.domain
        if arg_2 is not None:
            arg_4["username"] = arg_2
        if arg_3 is not None:
            arg_4["authzid"] = arg_3
        if "password" in arg_0.settings:
            arg_4["password"] = arg_0.settings["password"]
        arg_4["available_mechanisms"] = arg_0.peer_sasl_mechanisms
        arg_5 = sasl.filter_mechanism_list(
                            arg_0.settings['sasl_mechanisms'], arg_4,
                                            arg_0.settings['insecure_auth'])
        if not arg_5:
            raise SASLNotAvailable(
                                "None of SASL mechanism selected can be used")
        arg_4["enabled_mechanisms"] = arg_5

        arg_6 = None
        for arg_7 in arg_5:
            if arg_7 in arg_0.peer_sasl_mechanisms:
                arg_6 = arg_7
                break
        if not arg_6:
            raise SASLMechanismNotAvailable("Peer doesn't support any of"
                                                    " our SASL mechanisms")
        logger.debug("Our mechanism: {0!r}".format(arg_6))

        arg_1.auth_method_used = arg_6
        arg_0.authenticator = sasl.client_authenticator_factory(arg_6)
        arg_10 = arg_0.authenticator.start(arg_4)
        if not isinstance(arg_10, sasl.Response):
            raise SASLAuthenticationFailed("SASL initiation failed")

        arg_11 = ElementTree.Element(AUTH_TAG)
        arg_11.set("mechanism", arg_6)
        if arg_10.data:
            if arg_10.encode:
                arg_11.text = arg_10.encode()
            else:
                arg_11.text = arg_10.data
        arg_1.write_element(arg_11)


def Func(arg_0, arg_1):
        """Make a RosterItem from an XML element.

        :Parameters:
            - `element`: the XML element
        :Types:
            - `element`: :etree:`ElementTree.Element`

        :return: a freshly created roster item
        :returntype: `cls`
        """
        if arg_1.tag != ITEM_TAG:
            raise ValueError("{0!r} is not a roster item".format(arg_1))
        try:
            arg_2 = JID(arg_1.get("jid"))
        except ValueError:
            raise BadRequestProtocolError(u"Bad item JID")
        arg_3 = arg_1.get("subscription")
        arg_4 = arg_1.get("ask")
        arg_5 = arg_1.get("name")
        arg_6 = False
        arg_7 = set()
        for arg_8 in arg_1:
            if arg_8.tag != GROUP_TAG:
                continue
            arg_9 = arg_8.text
            if arg_9 is None:
                arg_9 = u""
            if arg_9 in arg_7:
                arg_6 = True
            else:
                arg_7.add(arg_9)
        arg_10 = arg_1.get("approved")
        if arg_10 == "true":
            arg_10 = True
        elif arg_10 in ("false", None):
            arg_10 = False
        else:
            logger.debug("RosterItem.Func: got unknown 'approved':"
                            " {0!r}, changing to False".format(arg_10))
            arg_10 = False
        arg_11 = arg_0(arg_2, arg_5, arg_7, arg_3, arg_4, arg_10)
        arg_11._duplicate_group = arg_6
        return arg_11


def Func(arg_0, arg_1 = None):
        """Make an XML element from self.

        :Parameters:
            - `parent`: Parent element
        :Types:
            - `parent`: :etree:`ElementTree.Element`
        """
        if arg_1 is not None:
            arg_2 = arg_4.SubElement(arg_1, ITEM_TAG)
        else:
            arg_2 = arg_4.Element(ITEM_TAG)
        arg_2.set("jid", unicode(arg_0.jid))
        if arg_0.name is not None:
            arg_2.set("name", arg_0.name)
        if arg_0.subscription is not None:
            arg_2.set("subscription", arg_0.subscription)
        if arg_0.ask:
            arg_2.set("ask", arg_0.ask)
        if arg_0.approved:
            arg_2.set("approved", "true")
        for arg_3 in arg_0.groups:
            arg_4.SubElement(arg_2, arg_6).text = arg_3
        return arg_2


def Func(arg_0, arg_1 = False):
        """Check if `self` is valid roster push item.

        Valid item must have proper `subscription` value other and valid value
        for 'ask'.

        :Parameters:
            - `fix`: if `True` than replace invalid 'subscription' and 'ask'
              values with the defaults
        :Types:
            - `fix`: `bool`

        :Raise: `ValueError` if the item is invalid.
        """
        arg_0._verify((None, u"from", u"to", u"both", u"remove"), arg_1)


def Func(arg_0, arg_1 = False, arg_2 = None):
        """Check if `self` is valid roster set item.

        For use on server to validate incoming roster sets.

        Valid item must have proper `subscription` value other and valid value
        for 'ask'. The lengths of name and group names must fit the configured
        limits.

        :Parameters:
            - `fix`: if `True` than replace invalid 'subscription' and 'ask'
              values with right defaults
            - `settings`: settings object providing the name limits
        :Types:
            - `fix`: `bool`
            - `settings`: `XMPPSettings`

        :Raise: `BadRequestProtocolError` if the item is invalid.
        """
        # pylint: disable=R0912
        try:
            arg_0._verify((None, u"remove"), arg_1)
        except ValueError, err:
            raise BadRequestProtocolError(unicode(err))
        if arg_0.ask:
            if arg_1:
                arg_0.ask = None
            else:
                raise BadRequestProtocolError("'ask' in roster set")
        if arg_0.approved:
            if arg_1:
                arg_0.approved = False
            else:
                raise BadRequestProtocolError("'approved' in roster set")
        if arg_2 is None:
            arg_2 = XMPPSettings()
        arg_5 = arg_2["roster_name_length_limit"]
        if arg_0.name and len(arg_0.name) > arg_5:
            raise NotAcceptableProtocolError(u"Roster item name too long")
        arg_6 = arg_2["roster_group_name_length_limit"]
        for arg_7 in arg_0.groups:
            if not arg_7:
                raise NotAcceptableProtocolError(u"Roster group name empty")
            if len(arg_7) > arg_6:
                raise NotAcceptableProtocolError(u"Roster group name too long")
        if arg_0._duplicate_group:
            raise BadRequestProtocolError(u"Item group duplicated")


def Func(arg_0):
        """Set of groups defined in the roster.

        :Return: the groups
        :ReturnType: `set` of `unicode`
        """
        Func = set()
        for arg_2 in arg_0._items:
            Func |= arg_2.groups
        return Func


def Func(arg_0, arg_1, arg_2 = True):
        """
        Return a list of items within a given group.

        :Parameters:
            - `name`: name to look-up
            - `case_sensitive`: if `False` the matching will be case
              insensitive.
        :Types:
            - `name`: `unicode`
            - `case_sensitive`: `bool`

        :Returntype: `list` of `RosterItem`
        """
        arg_3 = []
        if not arg_1:
            for arg_4 in arg_0._items:
                if not arg_4.groups:
                    arg_3.append(arg_4)
            return arg_3
        if not arg_2:
            arg_1 = arg_1.lower()
        for arg_4 in arg_0._items:
            if arg_1 in arg_4.groups:
                arg_3.append(arg_4)
            elif not arg_2 and arg_1 in [arg_5.lower() for arg_5
                                                            in arg_4.groups]:
                arg_3.append(arg_4)
        return arg_3


def Func(arg_0, arg_1, arg_2 = False):
        """
        Add an item to the roster.

        This will not automatically update the roster on the server.

        :Parameters:
            - `item`: the item to add
            - `replace`: if `True` then existing item will be replaced,
              otherwise a `ValueError` will be raised on conflict
        :Types:
            - `item`: `RosterItem`
            - `replace`: `bool`
        """
        if arg_1.jid in arg_0._jids:
            if arg_2:
                arg_0.remove_item(arg_1.jid)
            else:
                raise ValueError("JID already in the roster")
        arg_3 = len(arg_0._items)
        arg_0._items.append(arg_1)
        arg_0._jids[arg_1.jid] = arg_3


def Func(arg_0, arg_1):
        """Remove item from the roster.

        :Parameters:
            - `jid`: JID of the item to remove
        :Types:
            - `jid`: `JID`
        """
        if arg_1 not in arg_0._jids:
            raise KeyError(arg_1)
        arg_2 = arg_0._jids[arg_1]
        for arg_3 in range(arg_2, len(arg_0._jids)):
            arg_0._jids[arg_0._items[arg_3].jid] -= 1
        del arg_0._jids[arg_1]
        del arg_0._items[arg_2]


def Func(arg_0, arg_1):
        """Request roster upon login."""
        arg_0.server = arg_1.authorized_jid.bare()
        if "versioning" in arg_0.server_features:
            if arg_0.roster is not None and arg_0.roster.version is not None:
                arg_3 = arg_0.roster.version
            else:
                arg_3 = u""
        else:
            arg_3 = None
        arg_0.request_roster(arg_3)


def Func(arg_0, arg_1 = None):
        """Request roster from server.

        :Parameters:
            - `version`: if not `None` versioned roster will be requested
              for given local version. Use "" to request full roster.
        :Types:
            - `version`: `unicode`
        """
        arg_2 = arg_0.stanza_processor
        arg_3 = Iq(stanza_type = "get")
        arg_3.set_payload(RosterPayload(arg_1 = arg_1))
        arg_2.set_response_handlers(arg_3,
                                    arg_0._get_success, arg_0._get_error)
        arg_2.send(arg_3)


def Func(arg_0, arg_1):
        """Handle failure of the roster request.
        """
        if arg_1:
            logger.debug(u"Roster request failed: {0}".format(
                                                arg_1.error.condition_name))
        else:
            logger.debug(u"Roster request failed: timeout")
        arg_0._event_queue.put(RosterNotReceivedEvent(arg_0, arg_1))


def Func(arg_0, arg_1):
        """Handle a roster push received from server.
        """
        if arg_0.server is None and arg_1.from_jid:
            logger.debug(u"Server address not known, cannot verify roster push"
                                " from {0}".format(arg_1.from_jid))
            return arg_1.make_error_response(u"service-unavailable")
        if arg_0.server and arg_1.from_jid and arg_1.from_jid != arg_0.server:
            logger.debug(u"Roster push from invalid source: {0}".format(
                                                            arg_1.from_jid))
            return arg_1.make_error_response(u"service-unavailable")
        arg_2 = arg_1.get_payload(RosterPayload)
        if len(arg_2) != 1:
            logger.warning("Bad roster push received ({0} items)"
                                                    .format(len(arg_2)))
            return arg_1.make_error_response(u"bad-request")
        if arg_0.roster is None:
            logger.debug("Dropping roster push - no roster here")
            return True
        arg_3 = arg_2[0]
        arg_3.verify_roster_push(True)
        arg_4 = arg_0.roster.get(arg_3.jid)
        if arg_3.subscription == "remove":
            if arg_4:
                arg_0.roster.remove_item(arg_3.jid)
        else:
            arg_0.roster.add_item(arg_3, replace = True)
        arg_0._event_queue.put(RosterUpdatedEvent(arg_0, arg_4, arg_3))
        return arg_1.make_result_response()


def Func(arg_0, arg_1, arg_2 = None, arg_3 = None,
                                arg_4 = None, arg_5 = None):
        """Add a contact to the roster.

        :Parameters:
            - `jid`: contact's jid
            - `name`: name for the contact
            - `groups`: sequence of group names the contact should belong to
            - `callback`: function to call when the request succeeds. It should
              accept a single argument - a `RosterItem` describing the
              requested change
            - `error_callback`: function to call when the request fails. It
              should accept a single argument - an error stanza received
              (`None` in case of timeout)
        :Types:
            - `jid`: `JID`
            - `name`: `unicode`
            - `groups`: sequence of `unicode`
        """
        # pylint: disable=R0913
        if arg_1 in arg_0.roster:
            raise ValueError("{0!r} already in the roster".format(arg_1))
        arg_6 = RosterItem(arg_1, arg_2, arg_3)
        arg_0._roster_set(arg_6, arg_4, arg_5)


def Func(arg_0, arg_1, arg_2 = arg_3, arg_4 = arg_3,
                                arg_5 = None, arg_6 = None):
        """Modify a contact in the roster.

        :Parameters:
            - `jid`: contact's jid
            - `name`: a new name for the contact
            - `groups`: a sequence of group names the contact should belong to
            - `callback`: function to call when the request succeeds. It should
              accept a single argument - a `RosterItem` describing the
              requested change
            - `error_callback`: function to call when the request fails. It
              should accept a single argument - an error stanza received
              (`None` in case of timeout)
        :Types:
            - `jid`: `JID`
            - `name`: `unicode`
            - `groups`: sequence of `unicode`
        """
        # pylint: disable=R0913
        arg_7 = arg_0.roster[arg_1]
        if arg_2 is arg_3 and arg_4 is arg_3:
            return
        if arg_2 is arg_3:
            arg_2 = arg_7.name
        if arg_4 is arg_3:
            arg_4 = arg_7.groups
        arg_7 = RosterItem(arg_1, arg_2, arg_4)
        arg_0._roster_set(arg_7, arg_5, arg_6)


def Func(arg_0):
        """
        Unlink and Func the XML node owned by `self`.
        """
        if not arg_0.borrowed:
            arg_0.xmlnode.unlinkNode()
            arg_0.xmlnode.FuncNode()
        arg_0.xmlnode=None


def Func(arg_0, arg_1):
        """
        Set history parameters.

        Types:
            - `parameters`: `HistoryParameters`
        """
        for arg_2 in xml_element_iter(arg_0.xmlnode.children):
            if get_node_ns_uri(arg_2) == MUC_NS and arg_2.name == "history":
                arg_2.unlinkNode()
                arg_2.freeNode()
                break

        if arg_1.maxchars and arg_1.maxchars < 0:
            raise ValueError("History parameter maxchars must be positive")
        if arg_1.maxstanzas and arg_1.maxstanzas < 0:
            raise ValueError("History parameter maxstanzas must be positive")
        if arg_1.maxseconds and arg_1.maxseconds < 0:
            raise ValueError("History parameter maxseconds must be positive")

        arg_3=arg_0.xmlnode.newChild(arg_0.xmlnode.ns(), "history", None)

        if arg_1.maxchars is not None:
            arg_3.setProp("maxchars", str(arg_1.maxchars))
        if arg_1.maxstanzas is not None:
            arg_3.setProp("maxstanzas", str(arg_1.maxstanzas))
        if arg_1.maxseconds is not None:
            arg_3.setProp("maxseconds", str(arg_1.maxseconds))
        if arg_1.since is not None:
            arg_3.setProp("since", arg_1.since.strftime("%Y-%m-%dT%H:%M:%SZ"))


def Func(arg_0):
        """Return history parameters carried by the stanza.

        :returntype: `HistoryParameters`"""
        for arg_1 in xml_element_iter(arg_0.xmlnode.children):
            if get_node_ns_uri(arg_1) == MUC_NS and arg_1.name == "history":
                arg_2 = from_utf8(arg_1.prop("maxchars"))
                if arg_2 is not None:
                    arg_2 = int(arg_2)
                arg_3 = from_utf8(arg_1.prop("maxstanzas"))
                if arg_3 is not None:
                    arg_3 = int(arg_3)
                arg_4 = from_utf8(arg_1.prop("maxseconds"))
                if arg_4 is not None:
                    arg_4 = int(arg_4)
                # TODO: since -- requires parsing of Jabber dateTime profile
                arg_5 = None
                return HistoryParameters(arg_2, arg_3, arg_4, arg_5)


def Func(arg_0, arg_1):
        """Set password for the MUC request.

        :Parameters:
            - `password`: password
        :Types:
            - `password`: `unicode`"""
        for arg_2 in xml_element_iter(arg_0.xmlnode.children):
            if get_node_ns_uri(arg_2) == MUC_NS and arg_2.name == "password":
                arg_2.unlinkNode()
                arg_2.freeNode()
                break

        if arg_1 is not None:
            arg_0.xmlnode.newTextChild(arg_0.xmlnode.ns(), "password", to_utf8(arg_1))


def Func(arg_0):
        """Get password from the MUC request.

        :returntype: `unicode`
        """
        for arg_1 in xml_element_iter(arg_0.xmlnode.children):
            if get_node_ns_uri(arg_1) == MUC_NS and arg_1.name == "password":
                return from_utf8(arg_1.getContent())
        return None


def Func(arg_0, arg_1):
        """Initialize a `MucItem` object from an XML node.

        :Parameters:
            - `xmlnode`: the XML node.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
        """
        arg_2=None
        arg_3=None
        arg_4=arg_1.children
        while arg_4:
            arg_5=arg_4.ns()
            if arg_5 and arg_5.getContent()!=MUC_USER_NS:
                continue
            if arg_4.name=="actor":
                arg_2=arg_4.getContent()
            if arg_4.name=="reason":
                arg_3=arg_4.getContent()
            arg_4=arg_4.next
        arg_0.__init(
            from_utf8(arg_1.prop("affiliation")),
            from_utf8(arg_1.prop("role")),
            from_utf8(arg_1.prop("jid")),
            from_utf8(arg_1.prop("nick")),
            from_utf8(arg_2),
            from_utf8(arg_3),
            );


def Func(arg_0):
        """Get a list of objects describing the content of `self`.

        :return: the list of objects.
        :returntype: `list` of `MucItemBase` (`MucItem` and/or `MucStatus`)
        """
        if not arg_0.xmlnode.children:
            return []
        arg_1=[]
        arg_2=arg_0.xmlnode.children
        while arg_2:
            arg_3=arg_2.ns()
            if arg_3 and arg_3.getContent()!=arg_0.ns:
                pass
            elif arg_2.name=="item":
                arg_1.append(MucItem(arg_2))
            elif arg_2.name=="status":
                arg_1.append(MucStatus(arg_2))
            # FIXME: alt,decline,invite,password
            arg_2=arg_2.next
        return arg_1


def Func(arg_0,arg_1):
        """Add an item to `self`.

        :Parameters:
            - `item`: the item to add.
        :Types:
            - `item`: `MucItemBase`
        """
        if not isinstance(arg_1,MucItemBase):
            raise TypeError("Bad item type for muc#user")
        arg_1.as_xml(arg_0.xmlnode)


def Func(arg_0):
        """
        Get the MUC specific payload element.

        :return: the object describing the stanza payload in MUC namespace.
        :returntype: `MucX` or `MucUserX` or `MucAdminQuery` or `MucOwnerX`
        """
        if arg_0.muc_child:
            return arg_0.muc_child
        if not arg_0.xmlnode.children:
            return None
        arg_1=arg_0.xmlnode.children
        while arg_1:
            if arg_1.name not in ("x","query"):
                arg_1=arg_1.next
                continue
            arg_2=arg_1.ns()
            if not arg_2:
                arg_1=arg_1.next
                continue
            arg_3=arg_2.getContent()
            if (arg_1.name,arg_3)==("x",MUC_NS):
                arg_0.muc_child=MucX(arg_1)
                return arg_0.muc_child
            if (arg_1.name,arg_3)==("x",MUC_USER_NS):
                arg_0.muc_child=MucUserX(arg_1)
                return arg_0.muc_child
            if (arg_1.name,arg_3)==("query",MUC_ADMIN_NS):
                arg_0.muc_child=MucAdminQuery(arg_1)
                return arg_0.muc_child
            if (arg_1.name,arg_3)==("query",MUC_OWNER_NS):
                arg_0.muc_child=MucOwnerX(arg_1)
                return arg_0.muc_child
            arg_1=arg_1.next


def Func(arg_0, arg_1 = None, arg_2 = None,
            arg_3 = None, arg_4 = None,
            arg_5 = None):
        """
        Make the presence stanza a MUC room join request.

        :Parameters:
            - `password`: password to the room.
            - `history_maxchars`: limit of the total number of characters in
              history.
            - `history_maxstanzas`: limit of the total number of messages in
              history.
            - `history_seconds`: send only messages received in the last
              `seconds` seconds.
            - `history_since`: Send only the messages received since the
              dateTime specified (UTC).
        :Types:
            - `password`: `unicode`
            - `history_maxchars`: `int`
            - `history_maxstanzas`: `int`
            - `history_seconds`: `int`
            - `history_since`: `datetime.datetime`
        """
        arg_0.clear_muc_child()
        arg_0.muc_child=MucX(parent=arg_0.xmlnode)
        if (arg_2 is not None or arg_3 is not None
                or arg_4 is not None or arg_5 is not None):
            arg_7 = HistoryParameters(arg_2, arg_3,
                    arg_4, arg_5)
            arg_0.muc_child.set_history(arg_7)
        if arg_1 is not None:
            arg_0.muc_child.set_password(arg_1)


def Func(arg_0,arg_1,arg_2):
        """
        Make the iq stanza a MUC room participant kick request.

        :Parameters:
            - `nick`: nickname of user to kick.
            - `reason`: reason of the kick.
        :Types:
            - `nick`: `unicode`
            - `reason`: `unicode`

        :return: object describing the kick request details.
        :returntype: `MucItem`
        """
        arg_0.clear_muc_child()
        arg_0.muc_child=MucAdminQuery(parent=arg_0.xmlnode)
        arg_4=MucItem("none","none",arg_1=arg_1,arg_2=arg_2)
        arg_0.muc_child.add_item(arg_4)
        return arg_0.muc_child


def Func(arg_0):
    """Modify stringprep cache size.

    :Parameters:
        - `size`: new cache size
    """
    # pylint: disable-msg=W0603
    global arg_1
    arg_1 = arg_0
    if len(arg_5.cache_items) > arg_0:
        arg_2 = arg_5.cache_items[:-arg_0]
        for arg_3, arg_4 in arg_2:
            try:
                del arg_3.cache[arg_4]
            except KeyError:
                pass
        arg_5.cache_items = arg_5.cache_items[-arg_0:]


def Func(arg_0, arg_1):
        """Mapping part of string preparation."""
        arg_2 = []
        for arg_3 in arg_1:
            arg_4 = None
            for arg_5 in arg_0.Funcping:
                arg_4 = arg_5(arg_3)
                if arg_4 is not None:
                    break
            if arg_4 is not None:
                arg_2.append(arg_4)
            else:
                arg_2.append(arg_3)
        return arg_2


def Func(arg_0, arg_1):
        """Checks for Funced characters."""
        for arg_2 in arg_1:
            for arg_3 in arg_0.Funced:
                if arg_3(arg_2):
                    raise StringprepError("Prohibited character: {0!r}"
                                                                .format(arg_2))
        return arg_1


def Func(arg_0, arg_1):
        """Checks for unassigned character codes."""
        for arg_2 in arg_1:
            for arg_3 in arg_0.unassigned:
                if arg_3(arg_2):
                    raise StringprepError("Unassigned character: {0!r}"
                                                                .format(arg_2))
        return arg_1


def Func(arg_0):
    """Decorator for glib callback methods of GLibMainLoop used to store the
    exception raised."""
    @functools.wraps(arg_0)
    def wrapper(arg_1, *arg_2, **arg_3):
        """Wrapper for methods decorated with `Func`."""
        # pylint: disable=W0703,W0212
        try:
            return arg_0(arg_1, *arg_2, **arg_3)
        except Exception:
            if arg_1.exc_info:
                raise
            if not arg_1._stack:
                logger.debug('@Func wrapped method {0!r} called'
                            ' from outside of the main loop'.format(arg_0))
                raise
            arg_1.exc_info = sys.exc_info()
            logger.debug(u"exception in glib main loop callback:",
                                                arg_4 = arg_1.exc_info)
            # pylint: disable=W0212
            arg_5 = arg_1._stack[-1]
            if arg_5 is not None:
                arg_5.quit()
            return False
    return wrapper


def Func(arg_0, arg_1):
        """Timeout callback called to try prepare an IOHandler again."""
        arg_0._anything_done = True
        logger.debug("_prepar_io_handler_cb called for {0!r}".format(arg_1))
        arg_0._configure_io_handler(arg_1)
        arg_0._prepare_sources.pop(arg_1, None)
        return False


def Func(arg_0, arg_1):
        """Call the timeout handler due.
        """
        arg_0._anything_done = True
        logger.debug("Func() called for: {0!r}".format(arg_1))
        arg_3 = arg_1()
        # pylint: disable=W0212
        arg_4 = arg_1._pyxmpp_recurring
        if arg_4:
            arg_0._prepare_pending()
            return True

        if arg_4 is None and arg_3 is not None:
            logger.debug(" auto-recurring, restarting in {0} s"
                                                            .format(arg_3))
            arg_5 = glib.timeout_add(int(arg_3 * 1000), arg_0.Func, arg_1)
            arg_0._timer_sources[arg_1] = arg_5
        else:
            arg_0._timer_sources.pop(arg_1, None)
        arg_0._prepare_pending()
        return False


def Func(arg_0, arg_1):
        """Stops the loop after the time specified in the `loop` call.
        """
        arg_0._anything_done = True
        logger.debug("Func() called")
        arg_1.quit()


def Func(arg_0, arg_1 = None, arg_2 = None):
    """Creates Iq, Message or Presence object for XML stanza `element`

    :Parameters:
        - `element`: the stanza XML element
        - `return_path`: object through which responses to this stanza should
          be sent (will be weakly referenced by the stanza object).
        - `language`: default language for the stanza
    :Types:
        - `element`: :etree:`ElementTree.Element`
        - `return_path`: `StanzaRoute`
        - `language`: `unicode`
    """
    arg_3 = arg_0.tag
    if arg_3.endswith("}iq") or arg_3 == "iq":
        return Iq(arg_0, arg_1 = arg_1, arg_2 = arg_2)
    if arg_3.endswith("}message") or arg_3 == "message":
        return Message(arg_0, arg_1 = arg_1, arg_2 = arg_2)
    if arg_3.endswith("}presence") or arg_3 == "presence":
        return Presence(arg_0, arg_1 = arg_1, arg_2 = arg_2)
    else:
        return Stanza(arg_0, arg_1 = arg_1, arg_2 = arg_2)


def Func(arg_0, arg_1):
        """Examines out the response returned by a stanza handler and sends all
        stanzas provided.

        :Parameters:
            - `response`: the response to process. `None` or `False` means 'not
              handled'. `True` means 'handled'. Stanza or stanza list means
              handled with the stanzas to send back
        :Types:
            - `response`: `bool` or `Stanza` or iterable of `Stanza`

        :Returns:
            - `True`: if `response` is `Stanza`, iterable or `True` (meaning
              the stanza was processed).
            - `False`: when `response` is `False` or `None`

        :returntype: `bool`
        """

        if arg_1 is None or arg_1 is False:
            return False

        if isinstance(arg_1, Stanza):
            arg_0.send(arg_1)
            return True

        try:
            arg_1 = iter(arg_1)
        except TypeError:
            return bool(arg_1)

        for arg_2 in arg_1:
            if isinstance(arg_2, Stanza):
                arg_0.send(arg_2)
            else:
                logger.warning(u"Unexpected object in stanza handler result:"
                                                    u" {0!r}".format(arg_2))
        return True


def Func(arg_0, arg_1):
        """Process IQ stanza of type 'response' or 'error'.

        :Parameters:
            - `stanza`: the stanza received
        :Types:
            - `stanza`: `Iq`

        If a matching handler is available pass the stanza to it.  Otherwise
        ignore it if it is "error" or "result" stanza or return
        "feature-not-implemented" error if it is "get" or "set".
        """
        arg_2 = arg_1.stanza_id
        arg_3 = arg_1.from_jid
        if arg_3:
            arg_4 = arg_3.as_unicode()
        else:
            arg_4 = None
        arg_5 = arg_6 = None
        try:
            arg_5, arg_6 = arg_0._iq_response_handlers.pop(
                                                    (arg_2, arg_4))
        except KeyError:
            logger.debug("No response handler for id={0!r} from={1!r}"
                                                .format(arg_2, arg_4))
            logger.debug(" from_jid: {0!r} peer: {1!r}  me: {2!r}"
                                        .format(arg_3, arg_0.peer, arg_0.me))
            if ( (arg_3 == arg_0.peer or arg_3 == arg_0.me
                            or arg_0.me and arg_3 == arg_0.me.bare()) ):
                try:
                    logger.debug("  trying id={0!r} from=None"
                                                        .format(arg_2))
                    arg_5, arg_6 = \
                            arg_0._iq_response_handlers.pop(
                                                    (arg_2, None))
                except KeyError:
                    pass
        if arg_1.stanza_type == "result":
            if arg_5:
                arg_7 = arg_5(arg_1)
            else:
                return False
        else:
            if arg_6:
                arg_7 = arg_6(arg_1)
            else:
                return False
        arg_0._process_handler_result(arg_7)
        return True


def Func(arg_0, arg_1):
        """Process IQ stanza received.

        :Parameters:
            - `stanza`: the stanza received
        :Types:
            - `stanza`: `Iq`

        If a matching handler is available pass the stanza to it.  Otherwise
        ignore it if it is "error" or "result" stanza or return
        "feature-not-implemented" error if it is "get" or "set"."""

        arg_2 = arg_1.stanza_type
        if arg_2 in ("result", "error"):
            return arg_0._Func_response(arg_1)
        if arg_2 not in ("get", "set"):
            raise BadRequestProtocolError("Bad <iq/> type")
        logger.debug("Handling <iq type='{0}'> stanza: {1!r}".format(
                                                            arg_1, arg_2))
        arg_3 = arg_1.get_payload(None)
        logger.debug("  payload: {0!r}".format(arg_3))
        if not arg_3:
            raise BadRequestProtocolError("<iq/> stanza with no child element")
        arg_4 = arg_0._get_iq_handler(arg_2, arg_3)
        if not arg_4:
            arg_3 = arg_1.get_payload(None, specialize = True)
            logger.debug("  specialized payload: {0!r}".format(arg_3))
            if not isinstance(arg_3, XMLPayload):
                arg_4 = arg_0._get_iq_handler(arg_2, arg_3)
        if arg_4:
            arg_5 = arg_4(arg_1)
            arg_0._process_handler_result(arg_5)
            return True
        else:
            raise ServiceUnavailableProtocolError("Not implemented")


def Func(arg_0, arg_1):
        """Process stanza not addressed to us.

        Return "recipient-unavailable" return if it is not
        "error" nor "result" stanza.

        This method should be overriden in derived classes if they
        are supposed to handle stanzas not addressed directly to local
        stream endpoint.

        :Parameters:
            - `stanza`: presence stanza to be processed
        """
        if arg_1.stanza_type not in ("error", "result"):
            arg_2 = arg_1.make_error_response(u"recipient-unavailable")
            arg_0.send(arg_2)
        return True


def Func(arg_0, arg_1):
        """Process stanza received from the stream.

        First "fix" the stanza with `self.fix_in_stanza()`,
        then pass it to `self.route_stanza()` if it is not directed
        to `self.me` and `self.process_all_stanzas` is not True. Otherwise
        stanza is passwd to `self.process_iq()`, `self.process_message()`
        or `self.process_presence()` appropriately.

        :Parameters:
            - `stanza`: the stanza received.

        :returns: `True` when stanza was handled
        """

        arg_0.fix_in_stanza(arg_1)
        arg_2 = arg_1.to_jid

        if not arg_0.process_all_stanzas and arg_2 and (
                arg_2 != arg_0.me and arg_2.bare() != arg_0.me.bare()):
            return arg_0.route_stanza(arg_1)

        try:
            if isinstance(arg_1, Iq):
                if arg_0.process_iq(arg_1):
                    return True
            elif isinstance(arg_1, Message):
                if arg_0.process_message(arg_1):
                    return True
            elif isinstance(arg_1, Presence):
                if arg_0.process_presence(arg_1):
                    return True
        except ProtocolError, err:
            arg_3 = arg_1.stanza_type
            if arg_3 != 'error' and (arg_3 != 'result'
                                                or arg_1.stanza_type != 'iq'):
                arg_4 = arg_1.make_error_response(err.xmpp_name)
                arg_0.send(arg_4)
                err.log_reported()
            else:
                err.log_ignored()
            return
        logger.debug("Unhandled %r stanza: %r" % (arg_1.stanza_type,
                                                        arg_1.serialize()))
        return False