public async Task <StructureByEnvelopeOutputs> Handler(StructureByEnvelopeInputs args, ILambdaContext context)
        {
            if (this.store == null)
            {
                // Preload the dependencies (if they exist),
                // so that they are available during model deserialization.
                var asmLocation = this.GetType().Assembly.Location;
                var asmDir      = Path.GetDirectoryName(asmLocation);
                var asmName     = Path.GetFileNameWithoutExtension(asmLocation);
                var depPath     = Path.Combine(asmDir, $"{asmName}.Dependencies.dll");

                if (File.Exists(depPath))
                {
                    Console.WriteLine($"Loading dependencies from assembly: {depPath}...");
                    Assembly.LoadFrom(depPath);
                    Console.WriteLine("Dependencies assembly loaded.");
                }

                this.store = new S3ModelStore <StructureByEnvelopeInputs>(RegionEndpoint.USWest1);
            }

            var l      = new InvocationWrapper <StructureByEnvelopeInputs, StructureByEnvelopeOutputs>(store, StructureByEnvelope.Execute);
            var output = await l.InvokeAsync(args);

            return(output);
        }
        /// <summary>
        /// The StructureByEnvelope function.
        /// </summary>
        /// <param name="model">The model.
        /// Add elements to the model to have them persisted.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A StructureByEnvelopeOutputs instance containing computed results.</returns>
        public static StructureByEnvelopeOutputs Execute(Dictionary <string, Model> models, StructureByEnvelopeInputs input)
        {
            List <Level>    levels    = null;
            List <Envelope> envelopes = null;
            var             model     = new Model();

            var envelopeModel = models[ENVELOPE_MODEL_NAME];

            envelopes = envelopeModel.AllElementsOfType <Envelope>().Where(e => e.Direction.IsAlmostEqualTo(Vector3.ZAxis)).ToList();
            if (envelopes.Count() == 0)
            {
                throw new Exception("No element of type 'Envelope' could be found in the supplied model.");
            }
            var levelsModel = models[LEVELS_MODEL_NAME];

            levels = levelsModel.AllElementsOfType <Level>().ToList();

            List <Line> xGrids;
            List <Line> yGrids;

            var gridRotation = CreateGridsFromBoundary(envelopes.First().Profile.Perimeter,
                                                       input.GridXAxisInterval > 0 ? input.GridXAxisInterval : 4,
                                                       input.GridYAxisInterval > 0 ? input.GridYAxisInterval : 4,
                                                       out xGrids,
                                                       out yGrids,
                                                       model);

            levels.Sort(new LevelComparer());

            Level  last             = null;
            var    gridXMaterial    = new Material("GridX", Colors.Red);
            double lumpingTolerance = 2.0;

            foreach (var envelope in envelopes)
            {
                // Inset the footprint just a bit to keep the
                // beams out of the plane of the envelope. Use the biggest
                // beam that we have.
                var footprint = envelope.Profile.Perimeter.Offset(-0.25)[0];

                // Trim all the grid lines by the boundary
                var boundarySegments = footprint.Segments();
                var trimmedXGrids    = TrimGridsToBoundary(xGrids, boundarySegments, model);
                var trimmedYGrids    = TrimGridsToBoundary(yGrids, boundarySegments, model);

                // Trim all the grids against the other grids
                var xGridSegments = TrimGridsWithOtherGrids(trimmedXGrids, trimmedYGrids);
                var yGridSegments = TrimGridsWithOtherGrids(trimmedYGrids, trimmedXGrids);

                var e = envelope.Elevation;
                if (last != null)
                {
                    e = last.Elevation;
                }

                List <Vector3> columnLocations = new List <Vector3>();
                columnLocations.AddRange(CalculateColumnLocations(xGridSegments, e, lumpingTolerance));
                columnLocations.AddRange(CalculateColumnLocations(yGridSegments, e, lumpingTolerance));

                var envLevels = levels.Where(l => l.Elevation >= envelope.Elevation &&
                                             l.Elevation <= envelope.Elevation + envelope.Height).Skip(1).ToList();

                if (envLevels.Count == 0)
                {
                    continue;
                }

                last = envLevels.Last();

                List <Beam> masterFraming = null;
                foreach (var l in envLevels)
                {
                    if (masterFraming == null)
                    {
                        masterFraming = CreateFramingPlan(l.Elevation, xGridSegments, yGridSegments, boundarySegments);
                        model.AddElements(masterFraming);
                    }
                    else
                    {
                        var instances = CreateFramingPlanInstance(masterFraming, l.Elevation);
                        model.AddElements(instances, false);
                    }
                }

                var colProfile = new Profile(Polygon.Rectangle(11 * mToIn, 18 * mToIn));

                GeometricElement masterColumn = null;
                foreach (var lc in columnLocations)
                {
                    if (masterColumn == null)
                    {
                        masterColumn = new Column(Vector3.Origin,
                                                  envLevels.Last().Elevation - lc.Z,
                                                  colProfile,
                                                  BuiltInMaterials.Steel,
                                                  new Transform(lc),
                                                  0,
                                                  0,
                                                  gridRotation);
                        model.AddElement(masterColumn);
                    }
                    else
                    {
                        // var displace = Vector3.Origin - masterColumn.Transform.Origin - lc;
                        masterColumn.IsElementDefinition = true;
                        var instance = masterColumn.CreateInstance(new Transform(lc), "");//new ElementInstance(masterColumn, new Transform(lc));
                        model.AddElement(instance, false);
                    }
                }
            }

            var output = new StructureByEnvelopeOutputs(_longestGridSpan);

            output.Model = model;
            return(output);
        }