/// <summary>
        /// Creates IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="spatialElement">
        /// The spatial element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        /// <param name="setter">
        /// The IFCPlacementSetter.
        /// </param>
        /// <returns>
        /// True if created successfully, false otherwise.
        /// </returns>
        static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, IFCPlacementSetter setter)
        {
            IList<CurveLoop> curveLoops = null;
            try
            {
                SpatialElementBoundaryOptions options = ExporterIFCUtils.GetSpatialElementBoundaryOptions(exporterIFC, spatialElement);
                curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                //Some spatial elements are not placed that have no boundary loops. Don't export them.
                return false;
            }

            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.Level != null ? spatialElement.Level.Id : ElementId.InvalidElementId;
            double scale = exporterIFC.LinearScale;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;
            if (ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_AREA, out dArea))
                dArea *= (scale * scale);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            bool isArea = spatialElement is Area;
            if (!isArea)
            {
                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NUMBER, out strSpaceNumber))
                    strSpaceNumber = null;

                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NAME, out strSpaceName))
                    strSpaceName = null;

                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, out strSpaceDesc))
                    strSpaceDesc = null;
            }
            else
            {
                // Default to true to preserve previous behavior.
                bool? exportGSADesignGrossArea = ExporterCacheManager.ExportOptionsCache.ExportGSAGrossDesignArea;
                if (!exportGSADesignGrossArea.HasValue || exportGSADesignGrossArea.Value)
                {
                    Element level = document.GetElement(levelId);
                    if (level != null)
                    {
                        strSpaceNumber = level.Name + " GSA Design Gross Area";
                    }
                }
            }

            string name = strSpaceNumber;
            string longName = strSpaceName;
            string desc = strSpaceDesc;

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.GetPlacement();
            ElementType elemType = document.GetElement(spatialElement.GetTypeId()) as ElementType;
            IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement, true) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal;

            double roomHeight = 0.0;

            roomHeight = GetHeight(spatialElement, scale, levelId, levelInfo);
            if (roomHeight <= 0.0)
                return false;

            double bottomOffset;
            ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset);

            XYZ zDir = new XYZ(0, 0, 1);
            XYZ orig = new XYZ(0, 0, levelInfo.Elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }

            IFCAnyHandle spaceHnd = null;
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                extraParams.SetLocalPlacement(localPlacement);
                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                using (IFCTransaction transaction2 = new IFCTransaction(file))
                {
                    IFCAnyHandle repHnd = null;
                    if (!ExporterCacheManager.ExportOptionsCache.Use2DRoomBoundaryForRoomVolumeCreation && geomElem != null)
                    {
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporterOptions.BodyTessellationLevel.Coarse;
                        repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, spatialElement,
                            catId, geomElem, bodyExporterOptions, null, extraParams);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            extraParams.ClearOpenings();
                    }
                    else
                    {
                        IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, zDir, roomHeight);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return false;
                        IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                            shapeRep, ElementId.InvalidElementId);

                        HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                        bodyItems.Add(shapeRep);
                        shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, spatialElement, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                        shapeReps.Add(shapeRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomElem, Transform.Identity);
                        if (boundingBoxRep != null)
                            shapeReps.Add(boundingBoxRep);

                        repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                    }

                    extraParams.ScaledHeight = roomHeight;
                    extraParams.ScaledArea = dArea;

                    string spatialElementName = NamingUtil.GetNameOverride(spatialElement, name);
                    string spatialElementDescription = NamingUtil.GetDescriptionOverride(spatialElement, desc);
                    string spatialElementObjectType = NamingUtil.GetObjectTypeOverride(spatialElement, null);

                    double? spaceElevationWithFlooring = null;
                    double elevationWithFlooring = 0.0;
                    if (ParameterUtil.GetDoubleValueFromElement(spatialElement, "IfcElevationWithFlooring", out elevationWithFlooring) == true)
                        spaceElevationWithFlooring = elevationWithFlooring;
                    spaceHnd = IFCInstanceExporter.CreateSpace(file, GUIDUtil.CreateGUID(spatialElement),
                                                  exporterIFC.GetOwnerHistoryHandle(),
                                                  spatialElementName,spatialElementDescription, spatialElementObjectType,
                                                  extraParams.GetLocalPlacement(), repHnd, longName, Toolkit.IFCElementComposition.Element,
                                                  internalOrExternal, spaceElevationWithFlooring);

                    transaction2.Commit();
                }

                productWrapper.AddSpace(spaceHnd, levelInfo, extraParams, true);
            }

            // Save room handle for later use/relationships
            ExporterCacheManager.SpatialElementHandleCache.Register(spatialElement.Id, spaceHnd);
            exporterIFC.RegisterSpatialElementHandle(spatialElement.Id, spaceHnd);

            // Find Ceiling as a Space boundary and keep the relationship in a cache for use later
            Boolean ret = getCeilingSpaceBoundary(spatialElement);

            if (!MathUtil.IsAlmostZero(dArea) && !(ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE) &&
                !ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2 && !ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                ExporterIFCUtils.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export BaseQuantities for SpatialElement
            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && !(ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE))
            {
                // Skip this step. The "standard" quantities will be exported at the end of export element process in exportElement (Exporter.cs)
                // ExporterIFCUtils.CreateNonCOBIERoomQuantities(exporterIFC, spaceHnd, spatialElement, dArea, roomHeight);
            }

            // Create general classification for Spatial element from ClassificationCode(s). This is not done here but rather at the end of exportElement process
            // ClassificationUtil.CreateClassification(exporterIFC, file, spatialElement, spaceHnd, "");

            // Export Classifications for SpatialElement for GSA/COBIE.
            if (ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE)
            {
                CreateCOBIESpaceClassifications(exporterIFC, file, spaceHnd, document.ProjectInformation, spatialElement);
            }

            return true;
        }