public static bool TryGetExtrusion(this Brep brep, out Extrusion extrusion)
        {
            if (brep.IsSurface)
            {
                return(brep.Faces[0].TryGetExtrusion(out extrusion));
            }

            extrusion = null;
            if (brep.Faces.Count < 3)
            {
                return(false);
            }

            // Requiere manifold breps
            if (brep.SolidOrientation == BrepSolidOrientation.None || brep.SolidOrientation == BrepSolidOrientation.Unknown)
            {
                return(false);
            }

            // If brep has more that 3 faces we should check if there are faces with interior loops
            if (brep.Faces.Count > 3 && brep.Faces.Where(face => face.Loops.Count != 1).Any())
            {
                return(false);
            }

            var candidateFaces = new List <int[]>();

            // Array with just planar faces sorted by its area to search for similar faces
            var planarFaces = brep.Faces.
                              Select(face => new PlanarBrepFace(face)).
                              Where(face => face.Plane.IsValid).
                              OrderByDescending(face => face.LoopArea).
                              ToArray();

            // A capped Extrusion converted to Brep has wall surfaces in face[0] to face[N-3], caps are face[N-2] and face[N-1]
            // I iterate in reverse order to be optimisitc, maybe brep comes from an Extrusion.ToBrep() call
            for (int f = planarFaces.Length - 1; f > 0; --f)
            {
                var planeF    = planarFaces[f].Plane;
                var loopF     = planarFaces[f].Loop;
                var centroidF = planarFaces[f].Centroid;

                // Check if they have same area.
                for (int g = f - 1; g >= 0 && RhinoMath.EpsilonEquals(planarFaces[f].LoopArea, planarFaces[g].LoopArea, RhinoMath.SqrtEpsilon); --g)
                {
                    // Planes should be parallel or anti-parallel
                    if (planeF.Normal.IsParallelTo(planarFaces[g].Plane.Normal, RhinoMath.DefaultAngleTolerance / 100.0) == 0)
                    {
                        continue;
                    }

                    // Here f, and g are perfect candidates to test adjacent faces for perpendicularity to them,
                    // but we may try to quick reject some candidates if it's obvious that doesn't match

                    // A "perfect" curve overlap match may be a test but is too much in this ocasion

                    // We expect same NURBS structure, so point count should match
                    if (loopF.Points.Count != planarFaces[g].Loop.Points.Count)
                    {
                        continue;
                    }

                    // Since we have computed the area the centroid comes for free.
                    // Centroids should also match
                    if (planeF.ClosestPoint(planarFaces[g].Centroid).DistanceToSquared(centroidF) > RhinoMath.SqrtEpsilon)
                    {
                        continue;
                    }

                    // Add result to candidates List reversing index order to keep extrusion creation direction
                    // Breps that come from a Extrusion have the Cap[0] before Cap[1]
                    candidateFaces.Add(new int[] { g, f });
                }
            }

            // No twin faces found
            if (candidateFaces.Count == 0)
            {
                return(false);
            }

            // Candidates are in 'LoopArea' order, we will find here smaller profiles sooner
            // This is good for beam like objects, bad for slab like objects.

            // On box-like Breps the result could be ambigous for the user so,
            // to give him some control on the result, we will prioritize first and last faces no matter their area.
            // First and Last are "special" because if somebody observe an extrusion-like Brep and sees
            // it as an extrusion he tends to categorize faces in one of the following schemas:
            // { Cap[0], Wall[0] .. Wall[N], Cap[1] }
            // { Cap[0], Cap[1], Wall[0] .. Wall[N] }
            // { Wall[0] .. Wall[N], Cap[0], Cap[1] }
            // So if he is using the join command to create a Brep from surfaces at the model,
            // it's natural to start or end the selection with one of the extrusion caps.
            // On horizontal extrusions, slab-like Breps, the user use to observe the model from above,
            // so probably he will end with the bottom cap.
            // Also Last face is a Cap in Breps that come from Extrusion
            // If caps and walls are interleaved, smallest pair of faces will be used as caps, producing beam-like extrusions.

            //  System.Linq.Enumerable.OrderBy performs a stable sort so only first and last face will be moved if found.
            foreach (var candidate in candidateFaces.OrderBy(pair => (planarFaces[pair[1]].Face.FaceIndex == brep.Faces.Count - 1) ? 0 : // Last,  in case it comes from Extrusion
                                                             (planarFaces[pair[0]].Face.FaceIndex == 0) ? 1 :                            // First, in case it comes from a JOIN command
                                                             int.MaxValue))                                                              // Others
            {
                var startFace = planarFaces[candidate[0]];
                var endFace   = planarFaces[candidate[1]];

                // If any face, ignorig twins candidates, does not degenrate
                // to a curve when projected to 'planeF', then brep is not an extrusion
                if
                (
                    brep.Faces.
                    Where(face => face.FaceIndex != startFace.Face.FaceIndex && face.FaceIndex != endFace.Face.FaceIndex).
                    Select(face => startFace.ProjectionDegenartesToCurve(face.UnderlyingSurface())).
                    Any(degenerateToCurve => degenerateToCurve == false)
                )
                {
                    return(false);
                }

                // We use the orginal OuterLoop as profile not the NURBS version of it
                // to keep the structure as much as possible
                var profile = startFace.Face.OuterLoop.To3dCurve();

                double height = startFace.Face.OrientationIsReversed ?
                                -startFace.Plane.DistanceTo(endFace.Plane.Origin) :
                                +startFace.Plane.DistanceTo(endFace.Plane.Origin);

                extrusion = Extrusion.Create(profile, height, true);
                return(extrusion is object);
            }

            return(false);
        }