def server_doc(self_or_cls, obj, doc=None):
        """
        Get a bokeh Document with the plot attached. May supply
        an existing doc, otherwise bokeh.io.curdoc() is used to
        attach the plot to the global document instance.
        """
        if not isinstance(obj, (Plot, BokehServerWidgets)):
            if not isinstance(self_or_cls, BokehRenderer) or self_or_cls.mode != 'server':
                renderer = self_or_cls.instance(mode='server')
            else:
                renderer = self_or_cls
            plot, _ =  renderer._validate(obj, 'auto')
        else:
            plot = obj

        root = plot.state
        if isinstance(plot, BokehServerWidgets):
            plot = plot.plot

        if doc is None:
            doc = plot.document
        else:
            plot.document = doc

        plot.traverse(lambda x: attach_periodic(x), [GenericElementPlot])
        doc.add_root(root)
        return doc