parse nodes in FBXTree.Objects.AnimationCurve and connect them up to previously parsed AnimationCurveNodes. Each AnimationCurve holds data for a single animated axis ( e.g. times and values of x rotation)
556496
function ( curveNodesMap ) {

			var rawCurves = fbxTree.Objects.AnimationCurve;

			// TODO: Many values are identical up to roundoff error, but won't be optimised
			// e.g. position times: [0, 0.4, 0. 8]
			// position values: [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.235384487103147e-7, 93.67520904541016, -0.9982695579528809]
			// clearly, this should be optimised to
			// times: [0], positions [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809]
			// this shows up in nearly every FBX file, and generally time array is length > 100

			for ( var nodeID in rawCurves ) {

				var animationCurve = {

					id: rawCurves[ nodeID ].id,
					times: rawCurves[ nodeID ].KeyTime.a.map( convertFBXTimeToSeconds ),
					values: rawCurves[ nodeID ].KeyValueFloat.a,

				};

				var relationships = connections.get( animationCurve.id );

				if ( relationships !== undefined ) {

					var animationCurveID = relationships.parents[ 0 ].ID;
					var animationCurveRelationship = relationships.parents[ 0 ].relationship;

					if ( animationCurveRelationship.match( /X/ ) ) {

						curveNodesMap.get( animationCurveID ).curves[ 'x' ] = animationCurve;

					} else if ( animationCurveRelationship.match( /Y/ ) ) {

						curveNodesMap.get( animationCurveID ).curves[ 'y' ] = animationCurve;

					} else if ( animationCurveRelationship.match( /Z/ ) ) {

						curveNodesMap.get( animationCurveID ).curves[ 'z' ] = animationCurve;

					} else if ( animationCurveRelationship.match( /d|DeformPercent/ ) && curveNodesMap.has( animationCurveID ) ) {

						curveNodesMap.get( animationCurveID ).curves[ 'morph' ] = animationCurve;

					}

				}

			}

		}
1346550
function (node, T_x, T_y, nodeToExpand, single, animate, layoutBy) {
    var childrenList = cy.collection();
    if(node.isParent()){
       childrenList = node.children(":visible");
    }
    var self = this;
    
    /*
     * If the node is simple move itself directly else move it by moving its children by a self recursive call
     */
    if (childrenList.length == 0) {
      var newPosition = {x: node._private.position.x + T_x, y: node._private.position.y + T_y};
      if (!single || !animate) {
        node._private.position.x = newPosition.x;
        node._private.position.y = newPosition.y;
      }
      else {
        this.animatedlyMovingNodeCount++;
        node.animate({
          position: newPosition,
          complete: function () {
            self.animatedlyMovingNodeCount--;
            if (self.animatedlyMovingNodeCount > 0 || !nodeToExpand.hasClass('cy-expand-collapse-collapsed-node')) {

              return;
            }
            
            // If all nodes are moved we are ready to expand so call expand node base function
            self.expandNodeBaseFunction(nodeToExpand, single, layoutBy);

          }
        }, {
          duration: 1000
        });
      }
    }
    else {
      for (var i = 0; i < childrenList.length; i++) {
        this.fishEyeViewMoveNode(childrenList[i], T_x, T_y, nodeToExpand, single, animate, layoutBy);
      }
    }
  }
918243
function ParseVisualScenes (library_visual_scenes) {
  var visualScene = library_visual_scenes[0].visual_scene[0]
  var parsedJoints = {}

  // Some .dae files will export a shrunken model. Here's how to scale it
  var armatureScale = null
  visualScene.node.forEach(function (node) {
    // node.node is the location of all top level parent nodes
    if (node.node) {
      if (node.scale && node.scale.length > 0) {
        armatureScale = node.scale[0]._.split(' ').map(Number)
      }
      parsedJoints = parseJoints(node.node)
    }
    /*
    // Check for an instance controller. If one exists we have a skeleton
    if (node.instance_controller) {
    // TODO: Do I need to remove the leading `#` ?
    joints = node.instance_controller[0].skeleton
    }
    */
  })

  return {
    jointParents: parsedJoints,
    armatureScale: armatureScale
  }
}
320569
def connected_components(self) -> (dict, dict):
        """"""
        inclusions = utils.completed_graph(self.inclusions)  # allow bottom-up movement
        edges = utils.completed_graph(self.edges) if self.oriented else self.edges
        cc = {}  # maps cc root with nodes in the cc
        subroots = defaultdict(set)  # maps cc root with other roots of the cc
        walked_roots = set()  # all roots that have been walked already
        for root in self.roots:
            if root in walked_roots: continue  # this cc have been done already
            # walk in the graph starting at root
            cc[root] = set([root])
            walked = cc[root]
            stack = list(edges.get(root, ())) + list(inclusions.get(root, ()))
            while len(stack) > 0:
                *stack, curr = stack
                walked.add(curr)
                if curr in self.roots:  # don't do the walk for already found roots
                    walked_roots.add(curr)
                    subroots[root].add(curr)
                for succ in it.chain(edges.get(curr, ()), inclusions.get(curr, ())):
                    if succ not in walked:
                        stack.append(succ)
        return cc, dict(subroots)
467467
def parseNode(self):
		
		n = SGFParser.parseNode(self)			# process one Node as usual
		self.index = self.datalen				# set end of data
		return n
1187995
function Axes( graph ) {

	// INSTANCE ATTRIBUTES //

	this._parent = graph;
	this._root = undefined;
	this._children = {};
	this._config = [
		{
			"display": true,
			"scale": "x",
			"label": "x",
			"ticks": {
				"display": true,
				"num": 5,
				"format": null,
				"padding": 3,
				"innerSize": 6,
				"outerSize": 6,
				"rotation": 0,
				"direction": "out"
			},
			"orient": "bottom"
		},
		{
			"display": true,
			"scale": "y",
			"label": "y",
			"ticks": {
				"display": true,
				"num": 5,
				"format": null,
				"padding": 3,
				"innerSize": 6,
				"outerSize": 6,
				"rotation": 0,
				"direction": "out"
			},
			"orient": "left"
		}
	];

	// GENERATORS //

	this._xAxis = this.axis()
		.scale( graph._xScale )
		.orient( this._config[ 0 ].orient )
		.ticks( this._config[ 0 ].ticks.num )
		.innerTickSize( this._config[ 0 ].ticks.innerSize )
		.outerTickSize( this._config[ 0 ].ticks.outerSize )
		.tickPadding( this._config[ 0 ].ticks.padding )
		.tickFormat( this._config[ 0 ].ticks.format );

	this._yAxis = this.axis()
		.scale( graph._yScale )
		.orient( this._config[ 1 ].orient )
		.ticks( this._config[ 1 ].ticks.num )
		.innerTickSize( this._config[ 1 ].ticks.innerSize )
		.outerTickSize( this._config[ 1 ].ticks.outerSize )
		.tickPadding( this._config[ 1 ].ticks.padding )
		.tickFormat( this._config[ 1 ].ticks.format );

	// REGISTER //
	if ( graph._config.hasOwnProperty( 'axes' ) ) {
		graph._config.axes.push( this._config );
	} else {
		graph._config.axes = [ this._config ];
	}
	if ( graph._children.hasOwnProperty( 'axes' ) ) {
		graph._children.axes.push( this );
	} else {
		graph._children.axes = [ this ];
	}

	return this;

}
1349414
def parse(node)
      node.xpath('*').each do |node_child|
        case node_child.name
        when 'spTree'
          @shape_tree = ShapeTree.new(parent: self).parse(node_child)
        when 'bg'
          @background = Background.new(parent: self).parse(node_child)
        end
      end
      self
    end
908676
def _parse_loops_from_graph(self, graph):
        
        outtop = []
        outall = []
        for subg in networkx.strongly_connected_component_subgraphs(graph):
            if len(subg.nodes()) == 1:
                if len(list(subg.successors(list(subg.nodes())[0]))) == 0:
                    continue
            thisloop, allloops = self._parse_loop_graph(subg, graph)
            if thisloop is not None:
                outall += allloops
                outtop.append(thisloop)
        return outtop, outall
450472
function GraphNode() {
        this.position = new Float32Array(2);

        this.force = vec2.create();
        this.forcePrev = vec2.create();

        // If repulsionByDegree is true
        //  mass = inDegree + outDegree + 1
        // Else
        //  mass is manually set
        this.mass = 1;

        this.inDegree = 0;
        this.outDegree = 0;

        // Optional
        // this.size = 1;
    }
90716
def exist_node(self, graph, node, branch, turn, tick, extant):
        
        if (branch, turn, tick) in self._btts:
            raise TimeError
        self._btts.add((branch, turn, tick))
        self._nodes2set.append((self.pack(graph), self.pack(node), branch, turn, tick, extant))
798767
def parse_tree_to_objgraph(parser, parse_tree, file_name=None,
                           pre_ref_resolution_callback=None,
                           is_main_model=True, encoding='utf-8'):
    

    metamodel = parser.metamodel

    if metamodel.textx_tools_support:
        pos_rule_dict = {}
    pos_crossref_list = []

    def process_match(nt):
        """
        Process subtree for match rules.
        """
        if isinstance(nt, Terminal):
            return metamodel.convert(nt.value, nt.rule_name)
        else:
            # If RHS of assignment is NonTerminal it is a product of
            # complex match rule. Convert nodes to text and do the join.
            if len(nt) > 1:
                result = "".join([text(process_match(n)) for n in nt])
            else:
                result = process_match(nt[0])
            obj_processor = metamodel.obj_processors.get(nt.rule_name, None)
            if obj_processor:
                return obj_processor(result)
            else:
                return result

    def process_node(node):
        if isinstance(node, Terminal):
            from arpeggio import RegExMatch
            if metamodel.use_regexp_group and \
                    isinstance(node.rule, RegExMatch):
                if node.rule.regex.groups == 1:
                    value = node.extra_info.group(1)
                    return metamodel.convert(value, node.rule_name)
                else:
                    return metamodel.convert(node.value, node.rule_name)
            else:
                return metamodel.convert(node.value, node.rule_name)

        assert node.rule.root, \
            "Not a root node: {}".format(node.rule.rule_name)
        # If this node is created by some root rule
        # create metaclass instance.
        inst = None
        if not node.rule_name.startswith('__asgn'):
            # If not assignment
            # Get class
            mclass = node.rule._tx_class

            if mclass._tx_type == RULE_ABSTRACT:
                # If this meta-class is product of abstract rule replace it
                # with matched concrete meta-class down the inheritance tree.
                # Abstract meta-class should never be instantiated.
                if len(node) > 1:
                    try:
                        return process_node(
                            next(n for n in node
                                 if type(n) is not Terminal
                                 and n.rule._tx_class is not RULE_MATCH))
                    except StopIteration:
                        # All nodes are match rules, do concatenation
                        return ''.join(text(n) for n in node)
                else:
                    return process_node(node[0])
            elif mclass._tx_type == RULE_MATCH:
                # If this is a product of match rule handle it as a RHS
                # of assignment and return converted python type.
                return process_match(node)

            if parser.debug:
                parser.dprint("CREATING INSTANCE {}".format(node.rule_name))

            # If user class is given
            # use it instead of generic one
            if node.rule_name in metamodel.user_classes:
                user_class = metamodel.user_classes[node.rule_name]

                # Object initialization will be done afterwards
                # At this point we need object to be allocated
                # So that nested object get correct reference
                inst = user_class.__new__(user_class)

                # Initialize object attributes for user class
                parser.metamodel._init_obj_attrs(inst, user=True)
            else:
                # Generic class will call attributes init
                # from the constructor
                inst = mclass.__new__(mclass)

                # Initialize object attributes
                parser.metamodel._init_obj_attrs(inst)

            # Collect attributes directly on meta-class instance
            obj_attrs = inst

            inst._tx_position = node.position
            inst._tx_position_end = node.position_end

            # Push real obj. and dummy attr obj on the instance stack
            parser._inst_stack.append((inst, obj_attrs))

            for n in node:
                if parser.debug:
                    parser.dprint("Recursing into {} = '{}'"
                                  .format(type(n).__name__, text(n)))
                process_node(n)

            parser._inst_stack.pop()

            # If this object is nested add 'parent' reference
            if parser._inst_stack:
                if node.rule_name in metamodel.user_classes:
                    obj_attrs._txa_parent = parser._inst_stack[-1][0]
                else:
                    obj_attrs.parent = parser._inst_stack[-1][0]

            # If the class is user supplied we need to do
            # a proper initialization at this point.
            if node.rule_name in metamodel.user_classes:
                try:
                    # Get only attributes defined by the grammar as well
                    # as `parent` if exists
                    attrs = {}
                    if hasattr(obj_attrs, '_txa_parent'):
                        attrs['parent'] = obj_attrs._txa_parent
                        del obj_attrs._txa_parent
                    for a in obj_attrs.__class__._tx_attrs:
                        attrs[a] = getattr(obj_attrs, "_txa_%s" % a)
                        delattr(obj_attrs, "_txa_%s" % a)
                    inst.__init__(**attrs)
                except TypeError as e:
                    # Add class name information in case of
                    # wrong constructor parameters
                    e.args += ("for class %s" %
                               inst.__class__.__name__,)
                    parser.dprint(traceback.print_exc())
                    raise e

            # Special case for 'name' attrib. It is used for cross-referencing
            if hasattr(inst, 'name') and inst.name:
                # Objects of each class are in its own namespace
                if not id(inst.__class__) in parser._instances:
                    parser._instances[id(inst.__class__)] = {}
                parser._instances[id(inst.__class__)][inst.name] = inst

            if parser.debug:
                parser.dprint("LEAVING INSTANCE {}".format(node.rule_name))

        else:
            # Handle assignments
            attr_name = node.rule._attr_name
            op = node.rule_name.split('_')[-1]
            model_obj, obj_attr = parser._inst_stack[-1]
            cls = type(model_obj)
            metaattr = cls._tx_attrs[attr_name]

            # Mangle attribute name to prevent name clashing with property
            # setters on user classes
            if cls.__name__ in metamodel.user_classes:
                txa_attr_name = "_txa_%s" % attr_name
            else:
                txa_attr_name = attr_name

            if parser.debug:
                parser.dprint('Handling assignment: {} {}...'
                              .format(op, txa_attr_name))

            if op == 'optional':
                setattr(obj_attr, txa_attr_name, True)

            elif op == 'plain':
                attr_value = getattr(obj_attr, txa_attr_name)
                if attr_value and type(attr_value) is not list:
                    fmt = "Multiple assignments to attribute {} at {}"
                    raise TextXSemanticError(
                        message=fmt.format(
                            attr_name, parser.pos_to_linecol(node.position)),
                        err_type=MULT_ASSIGN_ERROR)

                # Convert tree bellow assignment to proper value
                value = process_node(node[0])

                if metaattr.ref and not metaattr.cont:
                    # If this is non-containing reference create ObjCrossRef
                    value = ObjCrossRef(obj_name=value, cls=metaattr.cls,
                                        position=node[0].position)
                    parser._crossrefs.append((model_obj, metaattr, value))
                    return model_obj

                if type(attr_value) is list:
                    attr_value.append(value)
                else:
                    setattr(obj_attr, txa_attr_name, value)

            elif op in ['list', 'oneormore', 'zeroormore']:
                for n in node:
                    # If the node is separator skip
                    if n.rule_name != 'sep':
                        # Convert node to proper type
                        # Rule links will be resolved later
                        value = process_node(n)

                        if metaattr.ref and not metaattr.cont:
                            # If this is non-containing reference
                            # create ObjCrossRef

                            value = ObjCrossRef(obj_name=value,
                                                cls=metaattr.cls,
                                                position=n.position)

                            parser._crossrefs.append((obj_attr, metaattr,
                                                      value))
                            continue

                        if not hasattr(obj_attr, txa_attr_name) or \
                                getattr(obj_attr, txa_attr_name) is None:
                            setattr(obj_attr, txa_attr_name, [])
                        getattr(obj_attr, txa_attr_name).append(value)
            else:
                # This shouldn't happen
                assert False

        # Collect rules for textx-tools
        if inst and metamodel.textx_tools_support:
            pos = (inst._tx_position, inst._tx_position_end)
            pos_rule_dict[pos] = inst

        return inst

    def call_obj_processors(metamodel, model_obj,
                            metaclass_of_grammar_rule=None):
        """
        Depth-first model object processing.
        """
        try:
            if metaclass_of_grammar_rule is None:
                metaclass_of_grammar_rule = \
                    metamodel[model_obj.__class__.__name__]
        except KeyError:
            raise TextXSemanticError(
                'Unknown meta-class "{}".'
                .format(model.obj.__class__.__name__))

        if metaclass_of_grammar_rule._tx_type is RULE_MATCH:
            # Object processors for match rules are already called
            # in `process_match`
            return

        many = [MULT_ONEORMORE, MULT_ZEROORMORE]

        # return value of obj_processor
        return_value_grammar = None
        return_value_current = None

        # enter recursive visit of attributes only, if the class of the
        # object being processed is a meta class of the current meta model
        if model_obj.__class__.__name__ in metamodel:
            current_metaclass_of_obj = metamodel[model_obj.__class__.__name__]

            for metaattr in current_metaclass_of_obj._tx_attrs.values():
                # If attribute is base type or containment reference go down
                if metaattr.cont:
                    attr = getattr(model_obj, metaattr.name)
                    if attr:
                        if metaattr.mult in many:
                            for idx, obj in enumerate(attr):
                                if obj:
                                    result = call_obj_processors(metamodel,
                                                                 obj,
                                                                 metaattr.cls)
                                    if result is not None:
                                        attr[idx] = result
                        else:
                            result = call_obj_processors(metamodel,
                                                         attr, metaattr.cls)
                            if result is not None:
                                setattr(model_obj, metaattr.name, result)

            # call obj_proc of the current meta_class if type == RULE_ABSTRACT
            if current_metaclass_of_obj._tx_fqn !=\
                    metaclass_of_grammar_rule._tx_fqn:
                assert RULE_ABSTRACT == metaclass_of_grammar_rule._tx_type
                obj_processor_current = metamodel.obj_processors.get(
                    current_metaclass_of_obj.__name__, None)
                if obj_processor_current:
                    return_value_current = obj_processor_current(model_obj)

        # call obj_proc of rule found in grammar
        obj_processor_grammar = metamodel.obj_processors.get(
            metaclass_of_grammar_rule.__name__, None)
        if obj_processor_grammar:
            return_value_grammar = obj_processor_grammar(model_obj)

        # both obj_processors are called, if two different processors
        # are defined for the object metaclass and the grammar metaclass
        # (can happen with type==RULE_ABSTRACT):
        # e.g.
        #   Base: Special1|Special2;
        #   RuleCurrentlyChecked: att_to_be_checked=[Base]
        # with object processors defined for Base, Special1, and Special2.
        #
        # Both processors are called, but for the return value the
        # obj_processor corresponding to the object (e.g. of type Special1)
        # dominates over the obj_processor of the grammar rule (Base).
        #
        # The order they are called is: first object (e.g., Special1), then
        # the grammar based metaclass object processor (e.g., Base).
        if return_value_current is not None:
            return return_value_current
        else:
            return return_value_grammar  # may be None

    model = process_node(parse_tree)
    # Register filename of the model for later use (e.g. imports/scoping).
    is_primitive_type = False
    try:
        model._tx_filename = file_name
    except AttributeError:
        # model is some primitive python type (e.g. str)
        is_primitive_type = True
        pass

    if pre_ref_resolution_callback:
        pre_ref_resolution_callback(model)

    for scope_provider in metamodel.scope_providers.values():
        from textx.scoping import ModelLoader
        if isinstance(scope_provider, ModelLoader):
            scope_provider.load_models(model, encoding=encoding)

    if not is_primitive_type:
        model._tx_reference_resolver = ReferenceResolver(
            parser, model, pos_crossref_list)
        model._tx_parser = parser

    if is_main_model:
        from textx.scoping import get_all_models_including_attached_models
        models = get_all_models_including_attached_models(model)
        # filter out all models w/o resolver:
        models = list(filter(
            lambda x: hasattr(x, "_tx_reference_resolver"), models))

        resolved_count = 1
        unresolved_count = 1
        while unresolved_count > 0 and resolved_count > 0:
            resolved_count = 0
            unresolved_count = 0
            # print("***RESOLVING {} models".format(len(models)))
            for m in models:
                resolved_count_for_this_model, delayed_crossrefs = \
                    m._tx_reference_resolver.resolve_one_step()
                resolved_count += resolved_count_for_this_model
                unresolved_count += len(delayed_crossrefs)
            # print("DEBUG: delayed #:{} unresolved #:{}".
            #      format(unresolved_count,unresolved_count))
        if (unresolved_count > 0):
            error_text = "Unresolvable cross references:"

            for m in models:
                for _, _, delayed \
                        in m._tx_reference_resolver.delayed_crossrefs:
                    line, col = parser.pos_to_linecol(delayed.position)
                    error_text += ' "{}" of class "{}" at {}'.format(
                        delayed.obj_name, delayed.cls.__name__, (line, col))
            raise TextXSemanticError(error_text, line=line, col=col)

        for m in models:
            # TODO: what does this check?
            assert not m._tx_reference_resolver.parser._inst_stack

        # cleanup
        for m in models:
            del m._tx_reference_resolver

        # final check that everything went ok
        for m in models:
            assert 0 == len(get_children_of_type(Postponed.__class__, m))

            # We have model loaded and all link resolved
            # So we shall do a depth-first call of object
            # processors if any processor is defined.
            if m._tx_metamodel.obj_processors:
                if parser.debug:
                    parser.dprint("CALLING OBJECT PROCESSORS")
                call_obj_processors(m._tx_metamodel, m)

    if metamodel.textx_tools_support \
            and type(model) not in PRIMITIVE_PYTHON_TYPES:
        # Cross-references for go-to definition language server support
        # Already sorted based on ref_pos_start attr
        # (required for binary search)
        model._pos_crossref_list = pos_crossref_list

        # Dict for storing rules where key is position of rule instance in text
        # Sorted based on nested rules
        model._pos_rule_dict = OrderedDict(sorted(pos_rule_dict.items(),
                                                  key=lambda x: x[0],
                                                  reverse=True))
    return model
111891
def parse(node)
      node.xpath('*').each do |node_child|
        case node_child.name
        when 'blip'
          @file_reference = FileReference.new(parent: self).parse(node_child)
        when 'tile'
          @tile = Tile.new(OOXMLCoordinates.parse(node_child, x_attr: 'tx', y_attr: 'ty'),
                           OOXMLCoordinates.parse(node_child, x_attr: 'sx', y_attr: 'sy'),
                           parent: self).parse(node_child)
        end
      end
      self
    end
857656
def parse(node)
      node.attributes.each_key do |key|
        case key
        when 'showGridLines'
          @show_gridlines = attribute_enabled?(node, key)
        when 'showRowColHeaders'
          @show_row_column_headers = attribute_enabled?(node, key)
        end
      end

      node.xpath('*').each do |node_child|
        case node_child.name
        when 'pane'
          @pane = Pane.new(parent: self).parse(node_child)
        end
      end
      self
    end
42981
function flipNode(node) {
  var rules = node.rules || node.keyframes || [];

  rules.forEach(function (rule, i, all) {
    if (rule.declarations) {
      if (isFlippable(rule, all[i - 1])) {
        processDeclarations(rule.declarations);
      }
    } else {
      flipNode(rule);
    }
  });
}
228254
def parse(self, data):
        
        graph = self._init_graph()
        # loop over links and create networkx graph
        # Add only working nodes with working links
        for link in data.get_inner_links():
            if link.status != libcnml.libcnml.Status.WORKING:
                continue
            interface_a, interface_b = link.getLinkedInterfaces()
            source = interface_a.ipv4
            dest = interface_b.ipv4
            # add link to Graph
            graph.add_edge(source, dest, weight=1)
        return graph
382507
def parse(node)
      @fill_color = DocxColor.new(parent: self).parse(node)
      node.xpath('*').each do |node_child|
        case node_child.name
        when 'xfrm'
          @shape_size = DocxShapeSize.new(parent: self).parse(node_child)
        when 'prstGeom'
          @preset_geometry = PresetGeometry.new(parent: self).parse(node_child)
        when 'txbx'
          @text_box = TextBox.parse_list(node_child)
        when 'ln'
          @line = DocxShapeLine.new(parent: self).parse(node_child)
        when 'blipFill'
          @blip_fill = BlipFill.new(parent: self).parse(node_child)
        when 'custGeom'
          @preset_geometry = PresetGeometry.new(parent: self).parse(node_child)
          @preset_geometry.name = :custom
          @custom_geometry = OOXMLCustomGeometry.new(parent: self).parse(node_child)
        end
      end
      self
    end
801010
def make_axes():
    """"""

    @axisfn()
    def child(node):
        return node.childNodes

    @axisfn()
    def descendant(node):
        for child in node.childNodes:
            for node in descendant_or_self(child):
                yield node

    @axisfn()
    def parent(node):
        if node.parentNode is not None:
            yield node.parentNode

    @axisfn(reverse=True)
    def ancestor(node):
        while node.parentNode is not None:
            node = node.parentNode
            yield node

    @axisfn()
    def following_sibling(node):
        while node.nextSibling is not None:
            node = node.nextSibling
            yield node

    @axisfn(reverse=True)
    def preceding_sibling(node):
        while node.previousSibling is not None:
            node = node.previousSibling
            yield node

    @axisfn()
    def following(node):
        while node is not None:
            while node.nextSibling is not None:
                node = node.nextSibling
                for n in descendant_or_self(node):
                    yield n
            node = node.parentNode

    @axisfn(reverse=True)
    def preceding(node):
        while node is not None:
            while node.previousSibling is not None:
                node = node.previousSibling
                # Could be more efficient here.
                for n in reversed(list(descendant_or_self(node))):
                    yield n
            node = node.parentNode

    @axisfn(principal_node_type=xml.dom.Node.ATTRIBUTE_NODE)
    def attribute(node):
        if node.attributes is not None:
            return (node.attributes.item(i)
                    for i in xrange(node.attributes.length))
        return ()

    @axisfn()
    def namespace(node):
        raise XPathNotImplementedError("namespace axis is not implemented")

    @axisfn()
    def self(node):
        yield node

    @axisfn()
    def descendant_or_self(node):
        yield node
        for child in node.childNodes:
            for node in descendant_or_self(child):
                yield node

    @axisfn(reverse=True)
    def ancestor_or_self(node):
        return chain([node], ancestor(node))

    # Place each axis function defined here into the 'axes' dict.
    for axis in locals().values():
        axes[axis.__name__] = axis