/// <summary>
        /// Traverses Depth-First through the bpmn XML file, collecting and linking all Elements.
        /// </summary>
        /// <param name="xNode">The XML node to start with</param>
        /// <param name="parent">The parent <see cref="BpmnElement"/></param>
        /// <param name="callingElements">A list to add all <see cref="BpmnElement"/> with a valid 'CalledElement' or 'Process' property.</param>
        private void RecursiveElements(XElement xNode, BpmnElement parent, ICollection <BpmnElement> callingElements)
        {
            var element = new BpmnElement(xNode);

            if (element.CalledElement != null)
            {
                callingElements.Add(element);
            }
            else if (element.Process != null)
            {
                callingElements.Add(element);
            }

            // Only xml nodes with an id can be bpmn elements
            if (element.Id != null)
            {
                try {
                    Elements.Add(element.Id, element);
                    // some tools prefix the ids with a namespace prefix but don't use this namespace to reference it
                    // so if the id contains a prefix, it is mapped with and without it
                    var prefix = xNode.GetPrefixOfNamespace(xNode.Name.Namespace);
                    if (prefix != null)
                    {
                        Elements.Add(prefix + ":" + element.Id, element);
                    }
                } catch (ArgumentException) {
                    Messages.Add("Error while trying to add second Element with the same id: " + element.Id);
                }
            }

            // Double-link bpmn element to the given parent element
            if (parent != null)
            {
                parent.AddChild(element);
            }
            element.Parent = parent;

            // Call all xml children
            foreach (var xChild in xNode.Elements())
            {
                var nameSpace = xChild.Name.Namespace;
                var localName = xChild.Name.LocalName;
                if (nameSpace.Equals(BpmnNM.Bpmn))
                {
                    // Add all bpmn elements to the dictionary
                    RecursiveElements(xChild, element, callingElements);
                }
                else if (nameSpace.Equals(BpmnNM.BpmnDi))
                {
                    // Parse a diagram as whole
                    if (localName == BpmnDiConstants.BpmnDiagramElement)
                    {
                        var diagram = BuildDiagram(xChild);
                        if (diagram.Plane != null)
                        {
                            Diagrams.Add(diagram);
                        }
                        else
                        {
                            Messages.Add("The plane for diagram + " + diagram.Id + " was not correctly parsed.");
                        }
                    }
                }
                else
                {
                    element.ForeignChildren.Add(xChild);
                }
            }
        }