CollectionProperty to store Node or NodeGroup
Define, populate, draw

Here I've extended answer from link posted in question with example on how to define, register and populate a collection xxxx on the scene object, containing all nodes from all materials in blend file.

Prepends the draw method to the text editor footer.

Note code is also updated for version 2.8x.

import bpy


class MyPropertyGroup(bpy.types.PropertyGroup):
    material : bpy.props.PointerProperty(
        name="Material",
        type=bpy.types.Material,
    )

    @property
    def node(self):
        mat = self.material
        if mat:
            return mat.node_tree.nodes.get(self.name)


# draw function
def draw(self, context):
    scene = context.scene
    layout = self.layout

    # NOTE: item is an instance of MyPropertyGroup
    for item in scene.xxxx:
        layout.prop(item, "material")
        node_selection_active = item.material is not None and item.material.use_nodes
        row = layout.row()
        row.enabled = node_selection_active
        if node_selection_active:
            row.prop_search(item, "name", item.material.node_tree, "nodes")
        else:
            row.prop(item, "name")

#register the class
bpy.utils.register_class(MyPropertyGroup)

# make it a collection on the scene for example        
bpy.types.Scene.xxxx = bpy.props.CollectionProperty(type=MyPropertyGroup)

# test it, get the scene
scene = bpy.context.scene
# clear it
scene.xxxx.clear()
# populate it with all nodes of all materials.
for m in bpy.data.materials:
    if m.use_nodes:
        for n in m.node_tree.nodes:
            item = scene.xxxx.add()
            item.name = n.name
            item.material = m
# draw in footer            
bpy.types.TEXT_HT_footer.prepend(draw)