/// <summary>
    /// Get the quadrant specification
    /// </summary>
    /// <returns>The quadrants.</returns>
    protected override List <List <MazeNode> > GetQuadrants(List <MazeNode> mazeBase)
    {
        // Get start/end
        MazeNode start = mazeBase.Find(x => x.Identifier == "start");
        MazeNode end   = mazeBase.Find(x => x.Identifier == "end");

        // Get the 6 extremes
        MazeNode front = mazeBase[0];
        MazeNode back  = mazeBase[0];
        MazeNode up    = mazeBase[0];
        MazeNode down  = mazeBase[0];
        MazeNode left  = mazeBase[0];
        MazeNode right = mazeBase[0];

        for (int i = 0; i < mazeBase.Count; i++)
        {
            if (mazeBase[i].Position.z > front.Position.z)
            {
                front = mazeBase[i];
            }
            if (mazeBase[i].Position.z < back.Position.z)
            {
                back = mazeBase[i];
            }
            if (mazeBase[i].Position.y > up.Position.y)
            {
                up = mazeBase[i];
            }
            if (mazeBase[i].Position.y < down.Position.y)
            {
                down = mazeBase[i];
            }
            if (mazeBase[i].Position.x < left.Position.x)
            {
                left = mazeBase[i];
            }
            if (mazeBase[i].Position.x > right.Position.x)
            {
                right = mazeBase[i];
            }
        }
        // Set tolerance
        float tol = Scale.ComponentMin() * .05f;
        List <List <MazeNode> > quadrants = null;

        // First, remove some base connections around start/end to make the entry/exit symmetric
        foreach (MazeNode baseNode in new List <MazeNode>(2)
        {
            start, end
        })
        {
            // front/back and up/down
            List <MazeNode> keepList = new List <MazeNode>(2);
            for (int iUpDown = 0; iUpDown <= 1; iUpDown++)
            {
                MazeNode targetNode = baseNode;
                foreach (MazeNode neigh in baseNode.AllNeighbors)
                {
                    switch (iUpDown)
                    {
                    case 0: { if (neigh.Position.y > targetNode.Position.y)
                              {
                                  targetNode = neigh;
                              }
                              break; }

                    case 1: { if (neigh.Position.y < targetNode.Position.y)
                              {
                                  targetNode = neigh;
                              }
                              break; }
                    }
                }
                if (nQuadrants == 4)
                {
                    baseNode.RemoveBaseConnectionByReference(targetNode);
                }
                else if (nQuadrants == 2)
                {
                    keepList.Add(targetNode);
                }
            }
            if (nQuadrants == 2)
            {
                List <MazeNode> removeList = new List <MazeNode>(baseNode.AllNeighbors);
                removeList.Remove(keepList[0]);
                removeList.Remove(keepList[1]);
                baseNode.RemoveBaseConnectionByReference(removeList);
            }
        }

        // Replace all nodes on quadrant boundaries with a boundary specific node that is closeby, moved in the direction of the quadrant
        List <MazeNode> newNodes    = new List <MazeNode>();
        List <MazeNode> oldNodes    = new List <MazeNode>();
        int             nBoundaries = -1;

        if (nQuadrants == 2)
        {
            nBoundaries = 0;
        }
        else if (nQuadrants == 4)
        {
            nBoundaries = 1;
        }
        for (int iBoundary = 0; iBoundary <= nBoundaries; iBoundary++) // 0 = up/down boundary, 1 = left/right boundary
        {
            foreach (MazeNode node in mazeBase)
            {
                if (node == start || node == end)
                {
                    continue;
                }
                bool comparison = false;
                switch (iBoundary)
                {
                case 0: comparison = node.Position.y > back.Position.y - tol && node.Position.y < back.Position.y + tol; break;

                case 1: comparison = node.Position.x > back.Position.x - tol && node.Position.x < back.Position.x + tol; break;
                }
                if (comparison)
                {
                    // Create new node nodes
                    for (int iNewNode = 0; iNewNode <= 1; iNewNode++) // iBoundary = 0: 0/1 = up/down, iBoundary = 1: 0/1 = left/right
                    {
                        List <MazeNode> newNodeNeighbors = new List <MazeNode>();
                        MazeNode        targetNeigh      = node;
                        foreach (MazeNode neigh in node.AllNeighbors)
                        {
                            bool neighComparison = false;
                            switch (iBoundary)
                            {
                            case 0:
                                switch (iNewNode)
                                {
                                case 0: neighComparison = (neigh.Position.y > targetNeigh.Position.y - tol); break;         // Up

                                case 1: neighComparison = (neigh.Position.y < targetNeigh.Position.y + tol); break;         // Down
                                }
                                break;

                            case 1:
                                switch (iNewNode)
                                {
                                case 0: neighComparison = (neigh.Position.x < targetNeigh.Position.x + tol); break;         // Left

                                case 1: neighComparison = (neigh.Position.x > targetNeigh.Position.x - tol); break;         // Right
                                }
                                break;
                            }
                            if (neighComparison)
                            {
                                targetNeigh = neigh;
                                newNodeNeighbors.Add(neigh);
                            }
                        }
                        Vector3 newNodeDirection = (targetNeigh.Position - node.Position).normalized;
                        switch (iBoundary)
                        {
                        case 0: newNodeDirection.x = 0; break;

                        case 1: newNodeDirection.y = 0; break;
                        }
                        Vector3  currPosition = node.Position + newNodeDirection * tol * 2;
                        Vector3  randJitter   = new Vector3(Random.Range(-(jitter * Scale.x), jitter * Scale.x), Random.Range(-(jitter * Scale.y), jitter * Scale.y), Random.Range(-(jitter * Scale.z), jitter * Scale.z));
                        MazeNode newNode      = new MazeNode(currPosition + randJitter, node.Identifier + (iNewNode + 1));
                        newNode.AddBaseConnectionByReference(newNodeNeighbors);
                        newNodes.Add(newNode);
                    }
                    // Store old node to remove later
                    oldNodes.Add(node);
                }
            }
        }
        // Add new nodes
        foreach (MazeNode node in newNodes)
        {
            mazeBase.Add(node);
        }
        // Remove old node from mazeBase and sever connections
        foreach (MazeNode node in oldNodes)
        {
            mazeBase.Remove(node);
            node.RemoveBaseConnectionByReference(node.AllNeighbors);
        }

        // Get 2 quadrants
        if (nQuadrants == 2)
        {
            quadrants = new List <List <MazeNode> >(2);
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count)));
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count)));

            // Get the quadrants
            foreach (MazeNode node in mazeBase)
            {
                // quadrant 1
                if (node.Position.y > back.Position.y - tol)
                {
                    quadrants[0].Add(node);
                }

                // quadrant 2
                if (node.Position.y < back.Position.y + tol)
                {
                    quadrants[1].Add(node);
                }
            }

            foreach (List <MazeNode> quadrant in quadrants)
            {
                quadrant.TrimExcess();
            }
        }

        // Get 4 quadrants
        else if (nQuadrants == 4)
        {
            // Get the quadrants
            quadrants = new List <List <MazeNode> >(4);
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count / 2)));
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count / 2)));
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count / 2)));
            quadrants.Add(new List <MazeNode>(Mathf.RoundToInt(mazeBase.Count / 2)));

            // get the quadrants
            foreach (MazeNode node in mazeBase)
            {
                // quadrant 1
                if (node.Position.x > back.Position.x - tol &&
                    node.Position.y > back.Position.y - tol)
                {
                    quadrants[0].Add(node);
                }

                // quadrant 2
                if (node.Position.x > back.Position.x - tol &&
                    node.Position.y < back.Position.y + tol)
                {
                    quadrants[1].Add(node);
                }

                // quadrant 3
                if (node.Position.x < back.Position.x + tol &&
                    node.Position.y < back.Position.y + tol)
                {
                    quadrants[2].Add(node);
                }

                // quadrant 4
                if (node.Position.x < back.Position.x + tol &&
                    node.Position.y > back.Position.y - tol)
                {
                    quadrants[3].Add(node);
                }
            }
            foreach (List <MazeNode> quadrant in quadrants)
            {
                quadrant.TrimExcess();
            }
        }

        //// Remove certain base connections that fall on the border between quadrants
        //// These are 4 sections:
        //// - the N connections upwards/downwards of the most front and the most back node (for nQuadrants = 2 and 4)
        //// - the N connections forwards/backwords of the most left and the most right node (for nQuadrants = 4)
        //// The N, per section, excluding the center node of each section, is 2^nDivisions
        //int halfNToRemove = Mathf.RoundToInt(Mathf.Pow(2, nDivisions) / 2);
        //MazeNode currentNode;
        //MazeNode targetNode;

        //// front/back sections
        //foreach (MazeNode baseNode in new List<MazeNode>(2) { front, back })
        //{
        //    // front/back and up/down
        //    for (int iUpDown = 0; iUpDown <= 1; iUpDown++)
        //    {
        //        currentNode = baseNode;
        //        targetNode = baseNode;
        //        for (int iN = 0; iN < halfNToRemove; iN++)
        //        {
        //            foreach (MazeNode neigh in currentNode.AllNeighbors)
        //            {
        //                switch (iUpDown)
        //                {
        //                    case 0: { if (neigh.Position.y > targetNode.Position.y) targetNode = neigh; break; }
        //                    case 1: { if (neigh.Position.y < targetNode.Position.y) targetNode = neigh; break; }
        //                }
        //            }
        //            currentNode.RemoveBaseConnectionByReference(targetNode);
        //            currentNode = targetNode;
        //        }
        //    }
        //}
        //// left/right sections
        //if (nQuadrants == 4)
        //{
        //    foreach (MazeNode baseNode in new List<MazeNode>(2) { left, right })
        //    {
        //        // front/back and up/down
        //        for (int iForwBackw = 0; iForwBackw <= 1; iForwBackw++)
        //        {
        //            currentNode = baseNode;
        //            targetNode = baseNode;
        //            for (int iN = 0; iN < halfNToRemove; iN++)
        //            {
        //                foreach (MazeNode neigh in currentNode.AllNeighbors)
        //                {
        //                    switch (iForwBackw)
        //                    {
        //                        case 0: { if (neigh.Position.z > targetNode.Position.z) targetNode = neigh; break; }
        //                        case 1: { if (neigh.Position.z < targetNode.Position.z) targetNode = neigh; break; }
        //                    }
        //                }
        //                currentNode.RemoveBaseConnectionByReference(targetNode);
        //                currentNode = targetNode;
        //            }
        //        }
        //    }
        //}

        return(quadrants);
    }