コード例 #1
0
ファイル: BreadthFirstSearch.cs プロジェクト: TheByte/sones
        /// <summary>
        /// Sucht im Graphen nach Knoten "myEnd" ausgehend von der Knotenmenge "myEdge", bis zur max. Tiefe "myMaxDepth".
        /// </summary>
        /// <param name="myTypeAttribute">Kante über die gesucht werden soll</param>
        /// <param name="myDBContext"></param>
        /// <param name="myStart">Startknoten</param>
        /// <param name="myEnd">gesuchter Knoten</param>
        /// <param name="myEdge">Menge an Knoten, ausgehend vom Startknoten welche mittels einer Funktion eingeschränkt wurde</param>
        /// <param name="myMaxDepth">max. Tiefe</param>
        /// <returns>true wenn gesuchter Knoten min. 1 mal gefunden, false sonst</returns>
        public bool Find(TypeAttribute myTypeAttribute, DBContext myDBContext, DBObjectStream myStart, DBObjectStream myEnd, IReferenceEdge myEdge, byte myMaxDepth)
        {
            #region data
            //queue for BFS
            Queue<ObjectUUID> queue = new Queue<ObjectUUID>();

            //Dictionary to store visited TreeNodes
            BigHashSet<ObjectUUID> visitedNodes = new BigHashSet<ObjectUUID>();

            //current depth
            byte depth = 2;

            //first node in path tree, the start of the select
            ObjectUUID root = myStart.ObjectUUID;

            //constrainted set of nodes, of start node
            HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();

            //target node, the target of the select
            ObjectUUID target = myEnd.ObjectUUID;

            //dummy node to check in which level the BFS is
            ObjectUUID dummy = null;

            //add root to visitedNodes
            visitedNodes.Add(root);

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObject;
            #endregion data

            #region validate root
            //check if root has edge
            var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), root);
            if (dbo.Failed())
            {
                throw new NotImplementedException();
            }

            if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
            {
                return false;
            }
            #endregion validate root

            #region get friends of startElement and check if they are the target and valid
            //instead of inserting only the startObject, we are using the startObject and the friends of the startObject (which could be restricted)
            var firstUUIDs = myEdge.GetAllReferenceIDs();

            for (int i = 0; i < firstUUIDs.Count(); i++)
            {
                var element = firstUUIDs.ElementAt(i);

                if (element != null)
                {
                    //create a new node and set root = parent
                    var currentNode = element;

                    #region check if the child is the target
                    //start and target are conntected directly
                    if (currentNode.Equals(myEnd.ObjectUUID))
                    {
                        //add node (which coud be the target) to startFriends (if start and target are directly connected, the target in the rootFriends list is needed)
                        rootFriends.Add(currentNode);

                        return true;
                    }
                    #endregion check if the child is the target

                    //check if element has edge
                    var dbobject = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentNode);
                    if (dbobject.Failed())
                    {
                        continue;
                    }

                    if (!dbobject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        continue;
                    }

                    //enqueue node to start from left side
                    queue.Enqueue(currentNode);

                    //add node to visitedNodes
                    visitedNodes.Add(currentNode);

                    //add node to startFriends
                    rootFriends.Add(currentNode);
                }
            }
            #endregion get friends of startElement and check if they are the target and valid

            //enqueue dummy
            queue.Enqueue(dummy);

            #region BFS

            //if there is more than one object in the queue and the actual depth is less than MaxDepth
            while ((queue.Count > 1) && (depth <= myMaxDepth))
            {
                //get the first Object of the queue
                ObjectUUID nodeOfQueue = queue.Dequeue();

                #region check if nodeOfQueue is a dummy
                //if nodeOfQueue is a dummy, this level is completely worked off
                if (nodeOfQueue == null)
                {
                    depth++;

                    queue.Enqueue(nodeOfQueue);

                    continue;
                }
                #endregion check if current is a dummy

                //load DBObject
                currentDBObject = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), nodeOfQueue);
                if (currentDBObject.Failed())
                {
                    throw new NotImplementedException();
                }

                if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                {
                    #region EdgeType is ASetOfReferencesEdgeType
                    if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                        ObjectUUID currentNode;

                        foreach (ObjectUUID obj in objectUUIDs)
                        {
                            #region obj is target
                            //if the child is the target
                            if (target.Equals(obj))
                            {
                                return true;
                            }
                            #endregion obj is target
                            #region never seen before
                            else if (!visitedNodes.Contains(obj))
                            {
                                //create new node and set nodeOfQueue as parent
                                currentNode = new ObjectUUID(obj.ToString());

                                //mark the node as visited
                                visitedNodes.Add(currentNode);

                                //put created node in queue
                                queue.Enqueue(currentNode);
                            }
                            #endregion never seen before
                        }
                    }
                    #endregion EdgeType is ASetOfReferencesEdgeType
                    #region EdgeType is ASingleReferenceEdgeType
                    else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
                        ObjectUUID objectUUID = objectUUIDs.First<ObjectUUID>();
                        ObjectUUID currentNode;

                        #region obj is target
                        //if the child is the target
                        if (target.Equals(objectUUID))
                        {
                            return true;
                        }
                        #endregion obj is target
                        #region never seen before
                        else if (!visitedNodes.Contains(objectUUID))
                        {
                            //create new node and set nodeOfQueue as parent
                            currentNode = new ObjectUUID(objectUUID.ToString());

                            //mark the node as visited
                            visitedNodes.Add(currentNode);

                            //put created node in queue
                            queue.Enqueue(currentNode);
                        }
                        #endregion never seen before
                    }
                    #endregion EdgeType is ASingleReferenceEdgeType
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            #endregion BFS

            return false;
        }
コード例 #2
0
        protected Exceptional<Boolean> RemoveBackwardEdgesOnReferences(AAttributeAssignOrUpdate myAAttributeAssign, IReferenceEdge myReference, DBObjectStream myDBObject, DBContext myDBContext)
        {
            foreach (var item in myReference.GetAllReferenceIDs())
            {
                var streamExcept = myDBContext.DBObjectCache.LoadDBObjectStream(myAAttributeAssign.AttributeIDChain.LastAttribute.GetDBType(myDBContext.DBTypeManager), (ObjectUUID)item);

                if (!streamExcept.Success())
                    return new Exceptional<Boolean>(streamExcept.IErrors.First());

                var removeExcept = myDBContext.DBObjectManager.RemoveBackwardEdge(streamExcept.Value, myAAttributeAssign.AttributeIDChain.LastAttribute.RelatedGraphDBTypeUUID, myAAttributeAssign.AttributeIDChain.LastAttribute.UUID, myDBObject.ObjectUUID);

                if (!removeExcept.Success())
                    return new Exceptional<Boolean>(removeExcept.IErrors.First());
            }

            return new Exceptional<Boolean>(true);
        }
コード例 #3
0
ファイル: BidirectionalBFS.cs プロジェクト: TheByte/sones
        //Logger
        //private static Logger //_Logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// Please look at the class documentation for detailed description how this algorithm works.
        /// </summary>
        /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param>
        /// <param name="myDBContext">The DBContext holds the TypeManager and the ObjectCache</param>
        /// <param name="myStart">The start node</param>
        /// <param name="myEnd">The end node</param>
        /// <param name="shortestOnly">true, if only shortest path shall be found</param>
        /// <param name="findAll">if true and shortestOnly is true, all shortest paths will be found. if true, and shortest only is false, all paths will be searched</param>
        /// <param name="myMaxDepth">The maximum depth to search</param>
        /// <param name="myMaxPathLength">The maximum path length which shall be analyzed</param>
        /// <returns>A HashSet which contains all found paths. Every path is represented by a List of ObjectUUIDs</returns>m>
        public HashSet<List<ObjectUUID>> Find(TypeAttribute myTypeAttribute, DBContext myDBContext, DBObjectStream myStart, IReferenceEdge myEdge, DBObjectStream myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength)
        {
            #region declarations
            //queue for BFS
            var queueLeft  = new Queue<Node>();
            var queueRight = new Queue<Node>();

            //Dictionary to store visited TreeNodes
            var visitedNodesLeft  = new BigDictionary<ObjectUUID, Node>();
            var visitedNodesRight = new BigDictionary<ObjectUUID, Node>();

            //set current depth left
            byte depthLeft = 2;
            //set current depth right
            byte depthRight = 1;

            //maximum depth
            byte maxDepthLeft = 0;
            byte maxDepthRight = 0;

            #region initialize maxDepths
            //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
            if (myMaxDepth > myMaxPathLength)
            {
                myMaxDepth = myMaxPathLength;
            }

            //set depth for left side
            maxDepthLeft = Convert.ToByte(myMaxDepth / 2 + 1);

            //if myMaxDepth is 1 maxDepthRight keeps 0, just one side is searching
            if (myMaxDepth > 1)
            {
                //both sides have the same depth
                maxDepthRight = maxDepthLeft;
            }

            //if myMaxDepth is even, one side has to search in a greater depth
            if ((myMaxDepth % 2) == 0)
            {
                maxDepthRight = Convert.ToByte(maxDepthLeft - 1);
            }
            #endregion

            //shortest path length
            byte shortestPathLength = 0;

            //target node, the target of the select
            var target = new Node(myEnd.ObjectUUID);
            var root = new Node(myStart.ObjectUUID);
            HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();

            //dummy node to check in which level the BFS is
            var dummyLeft = new Node();
            var dummyRight = new Node();

            #region get friends of startElement and check if they are the target and valid
            //instead of inserting only the startObject, we are using the startObject and the friends of the startObject (which could be restricted)
            var firstUUIDs = myEdge.GetAllReferenceIDs();

            foreach (var element in firstUUIDs)
            {
                if (element != null)
                {
                    //create a new node and set root = parent
                    var currentNodeLeft = new Node(element);

                    #region check if the child is the target
                    //start and target are conntected directly
                    if (currentNodeLeft.Key == myEnd.ObjectUUID)
                    {
                        //set depthRight to zero
                        depthRight = 0;

                        //add node (which coud be the target) to startFriends (if start and target are directly connected, the target in the rootFriends list is needed)
                        rootFriends.Add(currentNodeLeft.Key);

                        shortestPathLength = Convert.ToByte(depthLeft);

                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                    }
                    #endregion check if the child is the target

                    //check if element has edge
                    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentNodeLeft.Key);
                    if (dbo.Failed())
                    {
                        continue;
                    }

                    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        continue;
                    }

                    //enqueue node to start from left side
                    queueLeft.Enqueue(currentNodeLeft);

                    //add node to visitedNodes
                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                    //add node to startFriends
                    rootFriends.Add(currentNodeLeft.Key);
                }
            }

            #endregion get friends of startElement and check if they are the target and valid

            //elements of myEdge doesn't have edge
            if (visitedNodesLeft.Count == 0)
            {
                return null;
            }

            //check if target already found
            if (shortestPathLength != 0)
            {
                return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
            }

            //enqueue dummyLeft to analyze the depth of the left side
            queueLeft.Enqueue(dummyLeft);

            //holds the key of the backwardedge
            var edgeKey = new EdgeKey(myTypeAttribute);

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObjectLeft;
            Exceptional<BackwardEdgeStream> currentDBObjectRight;
            #endregion declarations

            #region BidirectionalBFS
            //check if the EdgeType is ASetReferenceEdgeType
            #region EdgeType is ASetReferenceEdgeType
            if (myEdge is ASetOfReferencesEdgeType)
            {
                #region initialize variables
                //enqueue target node to start from right side
                queueRight.Enqueue(target);

                //enqueue dummyRight to analyze the depth of the right side
                queueRight.Enqueue(dummyRight);

                //add root and target to visitedNodes
                visitedNodesRight.Add(target.Key, target);
                #endregion initialize variables

                #region check if target has backwardedge
                var be = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), target.Key);
                if (be.Failed())
                {
                    throw new NotImplementedException();
                }

                if (!be.Value.ContainsBackwardEdge(edgeKey))
                {
                    return null;
                }
                #endregion check if target has backwardedge

                //if there is more than one object in the queue and the actual depth is less than MaxDepth
                while (((queueLeft.Count > 0) && (queueRight.Count > 0)) && ((depthLeft <= maxDepthLeft) || (depthRight <= maxDepthRight)))
                {
                    #region both queues contain objects and both depths are not reached
                    if (((queueLeft.Count > 0) && (queueRight.Count > 0)) && ((depthLeft <= maxDepthLeft) && (depthRight <= maxDepthRight)))
                    {
                        //hold the actual element of the queues
                        Node currentLeft;
                        Node currentRight;

                        #region check if there is a dummyNode at the beginning of a queue
                        //first of both queues are dummies
                        if ((queueLeft.First<Node>() == dummyLeft) && (queueRight.First<Node>() == dummyRight))
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthLeft == maxDepthLeft && depthRight == maxDepthRight)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;
                                ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }
                            else if (depthLeft == maxDepthLeft)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;

                                continue;
                            }
                            else if (depthRight == maxDepthRight)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }

                            //dequeue dummies
                            queueLeft.Dequeue();
                            queueRight.Dequeue();

                            //increase depth's
                            ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;
                            ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            //if both queues are empty -> break loop
                            if (queueLeft.Count == 0 && queueRight.Count == 0)
                            {
                                break;
                            }
                            //if left queue is empty enqueue right dummy and continue
                            else if (queueLeft.Count == 0)
                            {
                                queueRight.Enqueue(dummyRight);
                                continue;
                            }
                            //if right queue is empty enqueue left dummy and continue
                            else if (queueRight.Count == 0)
                            {
                                queueLeft.Enqueue(dummyLeft);
                                continue;
                            }
                            //enqueue both dummies
                            else
                            {
                                queueLeft.Enqueue(dummyLeft);
                                queueRight.Enqueue(dummyRight);
                            }
                        }
                        //first of left queue is a dummy
                        else if (queueLeft.First<Node>() == dummyLeft)
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthLeft == maxDepthLeft)
                            {
                                //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;

                                continue;
                            }

                            //dequeue dummy
                            queueLeft.Dequeue();

                            //increase depth
                            //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;

                            //if left queue is empty continue
                            if (queueLeft.Count == 0)
                            {
                                continue;
                            }
                            //enqueue dummy
                            else
                            {
                                queueLeft.Enqueue(dummyLeft);
                            }
                        }
                        //first of right queue is a dummy
                        else if (queueRight.First<Node>() == dummyRight)
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthRight == maxDepthRight)
                            {
                                //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }

                            //dequeue dummy
                            queueRight.Dequeue();

                            //increase depth
                            //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            //if right queue is empty continue
                            if (queueRight.Count == 0)
                            {
                                continue;
                            }
                            //enqueue dummy
                            else
                            {
                                queueRight.Enqueue(dummyRight);
                            }
                        }
                        #endregion check if there is a dummyNode at the beginning of a queue

                        #region get first nodes of the queues
                        //get the first Object of the queue
                        currentLeft = queueLeft.Dequeue();
                        //get the first Object of the queue
                        currentRight = queueRight.Dequeue();
                        #endregion get first nodes of the queues

                        #region load DBObjects
                        //load DBObject
                        currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                        if (currentDBObjectLeft.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        //load DBObject
                        currentDBObjectRight = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), new ObjectUUID(currentRight.Key.ToString().TrimStart()));
                        if (currentDBObjectRight.Failed())
                        {
                            throw new NotImplementedException();
                        }
                        #endregion load DBObjects

                        #region the edge and the backwardedge are existing
                        if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager))
                            && currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (var dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    //set currentLeft as parent of target
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much parents are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    //if find all shortest paths
                                    else if (shortestOnly && findAll)
                                    {
                                        //set maxDepth to actual depth
                                        maxDepthLeft = depthLeft;
                                        maxDepthRight = depthRight;

                                        if ((depthLeft + depthRight) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                        }
                                    }
                                    #endregion check how much parents are searched
                                }
                                #endregion if the child is the target
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set currentLeft as parent
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    //set currentNodeLeft as child
                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    //set currentNodeLeft as child of currentLeft
                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                    //and put node into the queue
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends

                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    //if find all shortest paths
                                    else if (shortestOnly && findAll)
                                    {
                                        //set maxDepth to actual depth
                                        maxDepthLeft = depthLeft;
                                        maxDepthRight = depthRight;

                                        if ((depthLeft + depthRight) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                        }
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    //set currentNodeRight as parent of current Right
                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends

                            #region build intersection of visitedNodesLeft and visitedNodesRight

                            //marks if intersection nodes are existing
                            bool foundIntersect = false;

                            foreach (var node in visitedNodesLeft)
                            {
                                if (visitedNodesRight[node.Key] != null)
                                {
                                    //set nodes children and parents
                                    node.Value.addChildren(visitedNodesRight[node.Key].Children);
                                    node.Value.addParents(visitedNodesRight[node.Key].Parents);

                                    //set nodes children and parents
                                    visitedNodesRight[node.Key].addChildren(node.Value.Children);
                                    visitedNodesRight[node.Key].addParents(node.Value.Parents);

                                    foundIntersect = true;
                                }
                            }
                            #endregion build intersection of visitedNodesLeft and visitedNodesRight

                            #region analyze intersection
                            //if intersection nodes existing
                            if (foundIntersect)
                            {
                                //only shortest path
                                if (shortestOnly && !findAll)
                                {
                                    //_Logger.Info("found shortest path..starting analyzer");

                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else if (shortestPathLength == 0)
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                }
                            }
                            #endregion analyze intersection
                        }
                        #endregion the edge and the backwardedge are existing
                        #region only the edge exists
                        else if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (ObjectUUID dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check if already visited
                                }
                                #endregion if the child is the target
                                #region already visited from right side
                                else if (visitedNodesRight.ContainsKey(dboLeft))
                                {
                                    //get node
                                    Node temp = visitedNodesRight[dboLeft];
                                    //add parent new
                                    temp.addParent(currentLeft);
                                    //add as child
                                    currentLeft.addChild(temp);

                                    visitedNodesRight.Remove(temp.Key);
                                    visitedNodesRight.Add(temp.Key, temp);

                                    if (visitedNodesLeft.Remove(temp.Key))
                                    {
                                        visitedNodesLeft.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from right side
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set found parents from left side as parents of matchNode
                                    //matchNode has now parents and children
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    //set currentNodeLeft as child of currentLeft
                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                    //and look what comes on the next level of depth
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends
                        }
                        #endregion only the edge exists
                        #region only the backwardedge exists
                        else if (currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from left side
                                else if (visitedNodesLeft.ContainsKey(dboRight))
                                {
                                    //get node
                                    Node temp = visitedNodesLeft[dboRight];
                                    temp.addChild(currentRight);
                                    currentRight.addParent(temp);

                                    visitedNodesLeft.Remove(temp.Key);
                                    visitedNodesLeft.Add(temp.Key, temp);

                                    if (visitedNodesRight.Remove(temp.Key))
                                    {
                                        visitedNodesRight.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from left side
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    //set currentNodeRight as parent of currentRight
                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends
                        }
                        #endregion only the backwardedge exists
                    }
                    #endregion  both queues contain objects and both depths are not reached

                    #region only left queue contain objects
                    else if ((queueLeft.Count > 0) && (depthLeft <= maxDepthLeft))
                    {
                        #region check if first element of queue is a dummy
                        //dummy
                        if (queueLeft.First<Node>().Key == null)
                        {
                            queueLeft.Dequeue();

                            //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;

                            if (queueLeft.Count == 0)
                            {
                                continue;
                            }
                            else if (depthLeft > maxDepthLeft)
                            {
                                continue;
                            }
                        }
                        #endregion check if first element of queue is a dummy

                        //get the first Object of the queue
                        Node currentLeft = queueLeft.Dequeue();

                        //load DBObject
                        currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                        if (currentDBObjectLeft.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (ObjectUUID dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from right side
                                else if (visitedNodesRight.ContainsKey(dboLeft))
                                {
                                    //get node
                                    Node temp = visitedNodesRight[dboLeft];
                                    //add parent new
                                    temp.addParent(currentLeft);
                                    //add as child
                                    currentLeft.addChild(temp);

                                    visitedNodesRight.Remove(temp.Key);
                                    visitedNodesRight.Add(temp.Key, temp);

                                    if (visitedNodesLeft.Remove(temp.Key))
                                    {
                                        visitedNodesLeft.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        if (shortestPathLength < (maxDepthLeft + maxDepthRight))
                                        {
                                            shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                        }
                                    }
                                }
                                #endregion already visited from right side
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set found parents from left side as parents of matchNode
                                    //matchNode has now parents and children
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);
                                    //and look what comes on the next level of depth
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends
                        }
                    }
                    #endregion only left queue contain objects

                    #region only right queue contain objects
                    else if ((queueRight.Count > 0) && (depthRight <= maxDepthRight))
                    {
                        //get the first Object of the queue
                        Node currentRight;

                        #region check if first element of the queue is a dummy
                        //dummy
                        if (queueRight.First<Node>().Key == null)
                        {
                            queueRight.Dequeue();

                            //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            if (queueRight.Count == 0)
                            {
                                continue;
                            }
                        }
                        #endregion check if first element of the queue is a dummy

                        currentRight = queueRight.Dequeue();

                        //load DBObject
                        currentDBObjectRight = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentRight.Key);
                        if (currentDBObjectRight.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        if (currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from left side
                                else if (visitedNodesLeft.ContainsKey(dboRight))
                                {
                                    //get node
                                    Node temp = visitedNodesLeft[dboRight];
                                    temp.addChild(currentRight);
                                    currentRight.addParent(temp);

                                    visitedNodesLeft.Remove(temp.Key);
                                    visitedNodesLeft.Add(temp.Key, temp);

                                    if (visitedNodesRight.Remove(temp.Key))
                                    {
                                        visitedNodesRight.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from left side
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);
                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends
                        }
                    }
                    #endregion only right queue contain objects

                    #region abort loop
                    else
                    {
                        break;
                    }
                    #endregion abort loop
                }
            }
            #endregion EdgeType is ASetReferenceEdgeType
            //check if the EdgeType is ASingleReferenceEdgeType
            #region EdgeType is ASingleReferenceEdgeType
            else if (myEdge is ASingleReferenceEdgeType)
            {
                #region initialize variables
                //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
                if (myMaxDepth > myMaxPathLength)
                {
                    myMaxDepth = myMaxPathLength;
                }

                //set depth for left side
                maxDepthLeft = myMaxDepth;
                #endregion initialize variables

                #region check if friends of root node have edge
                foreach (var node in visitedNodesLeft)
                {
                    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), node.Key);
                    if (dbo.Failed())
                    {
                        if (visitedNodesLeft.Count != 0)
                        {
                            visitedNodesLeft.Remove(node.Key);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }

                    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        if (visitedNodesLeft.Count != 0)
                        {
                            visitedNodesLeft.Remove(node.Key);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
                #endregion check if friends of root node have edge

                //if there is more than one object in the queue and the actual depth is less than MaxDepth
                while ((queueLeft.Count > 0) && (depthLeft <= maxDepthLeft))
                {
                    #region check if first element of queue is a dummy
                    //dummy
                    if (queueLeft.First<Node>().Key == null)
                    {
                        queueLeft.Dequeue();

                        //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                        depthLeft++;

                        if ((queueLeft.Count == 0) || (depthLeft > maxDepthLeft))
                        {
                            break;
                        }
                        else
                        {
                            queueLeft.Enqueue(dummyLeft);
                            continue;
                        }
                    }
                    #endregion check if first element of queue is a dummy

                    #region load DBObject
                    //get the first Object of the queue
                    var currentLeft = queueLeft.Dequeue();

                    //load DBObject
                    currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                    if (currentDBObjectLeft.Failed())
                    {
                        throw new NotImplementedException();
                    }
                    #endregion load DBObject

                    #region check if currentDBObjectLeft has attribute
                    if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        //get referenced ObjectUUID using the given Edge
                        var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
                        Node currentNodeLeft;

                        #region check left friend
                        var dboLeft = objectUUIDsLeft.First();

                        //create a new node and set currentLeft = parent
                        currentNodeLeft = new Node(dboLeft, currentLeft);

                        #region if the child is the target
                        if (currentNodeLeft.Key == myEnd.ObjectUUID)
                        {
                            //set currentLeft as parent of target
                            target.addParent(currentLeft);

                            //shortestPathLength is actual depth of left side plus 1 (because the depth starts with zero, but the pathLength with 1)
                            shortestPathLength = Convert.ToByte(depthLeft + 1);

                            return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                        }
                        #endregion if the child is the target
                        #region already visited
                        else if (visitedNodesLeft.ContainsKey(currentNodeLeft.Key))
                        {
                            //set currentLeft as parent
                            visitedNodesLeft[currentNodeLeft.Key].addParent(currentLeft);

                            //set currentNodeLeft as child
                            currentLeft.addChild(visitedNodesLeft[currentNodeLeft.Key]);
                        }
                        #endregion already visited
                        #region set as visited
                        else
                        {
                            //set currentNodeLeft as child of currentLeft
                            currentLeft.addChild(currentNodeLeft);

                            //never seen before
                            //mark the node as visited
                            visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                            //and put node into the queue
                            queueLeft.Enqueue(currentNodeLeft);
                        }
                        #endregion set as visited

                        #endregion check left friend
                    }
                    #endregion check if currentDBObjectLeft has attribute
                    #region abort loop
                    else
                    {
                        break;
                    }
                    #endregion abort loop
                }
            }
            #endregion EdgeType is ASingleReferenceEdgeType
            else
            {
                throw new NotImplementedException();
            }

            #region start TargetAnalyzer
            if (shortestOnly && findAll)
            {
                if (shortestPathLength > myMaxPathLength)
                {
                    shortestPathLength = myMaxPathLength;
                }

                return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
            }
            else
            {
                return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths();
            }
            #endregion start TargetAnalyzer

            #endregion BidirectionalBFS
        }