public async Task <VicGovResiEnvelopeOutputs> Handler(VicGovResiEnvelopeInputs args, ILambdaContext context)
        {
            // Preload dependencies (if they exist),
            // so that they are available during model deserialization.

            var sw          = System.Diagnostics.Stopwatch.StartNew();
            var asmLocation = this.GetType().Assembly.Location;
            var asmDir      = Path.GetDirectoryName(asmLocation);

            // Explicitly load the dependencies project, it might have types
            // that aren't used in the function but are necessary for correct
            // deserialization.
            var asmName = Path.GetFileNameWithoutExtension(asmLocation);
            var depPath = Path.Combine(asmDir, $"{asmName}.Dependencies.dll");

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

            // Load all reference assemblies.
            Console.WriteLine($"Loading all referenced assemblies.");
            foreach (var asm in this.GetType().Assembly.GetReferencedAssemblies())
            {
                try
                {
                    Assembly.Load(asm);
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Failed to load {asm.FullName}");
                    Console.WriteLine(e.Message);
                }
            }
            sw.Stop();
            Console.WriteLine($"Time to load assemblies: {sw.Elapsed.TotalSeconds})");

            if (this.store == null)
            {
                this.store = new S3ModelStore <VicGovResiEnvelopeInputs>(RegionEndpoint.USWest1);
            }

            var l      = new InvocationWrapper <VicGovResiEnvelopeInputs, VicGovResiEnvelopeOutputs>(store, VicGovResiEnvelope.Execute);
            var output = await l.InvokeAsync(args);

            return(output);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A VicGovResiEnvelopeOutputs instance containing computed results and the model with any new elements.</returns>
        public static VicGovResiEnvelopeOutputs Execute(Dictionary <string, Model> inputModels, VicGovResiEnvelopeInputs input)
        {
            // Get site model dependency
            var siteModel   = inputModels["Site"];
            var siteElement = getSite(siteModel);

            // Get Setbacks
            double sideSetback     = GetSideSetbackFromBldgHeight(input.ProposedBuildingHeights);
            string allotmentType   = input.AllotmentDesignation.ToString();
            string facingCondition = input.BuildingFacing.ToString();
            double frontSetback    = GetFrontSetback(allotmentType, facingCondition, sideSetback);
            double maxHeight       = GetMaxHeightAllowance(input.ProposedBuildingHeights);
            var    output          = new VicGovResiEnvelopeOutputs(sideSetback, frontSetback);


            // Boundary & sort
            var         perimeter           = siteElement.Perimeter.Offset(sideSetback * -1);
            var         siteArea            = siteElement.Area;
            var         siteBoundaryProfile = new Profile(perimeter);
            List <Line> lotBoundarySegments = siteBoundaryProfile.Segments();

            // Create lotBoundary as Curve object
            var lotBoundaryCurveLoop = CreatePolylineFromLineSegments(lotBoundarySegments);

            // Get front & back lot edge and render to Hypar
            Vector3 frontLotClosestPt         = input.FrontBoundary;
            var     frontBoundary             = CurveClosestPt(lotBoundarySegments, frontLotClosestPt);
            var     rearBoundary              = CurveFurthestPt(lotBoundarySegments, frontLotClosestPt);
            var     sideBoundary              = lotBoundarySegments.ElementAt(1);
            var     frontBoundaryLength       = frontBoundary.Length();
            var     frontBoundaryLengthHalved = frontBoundaryLength / 2;

            // Create front offset
            var translationVec                = rearBoundary.PointAt(0.5) - frontBoundary.PointAt(0.5);
            var unitTranslationVec            = translationVec.Unitized();
            var frontSetbackTranslationVector = unitTranslationVec * frontSetback;
            var frontBoundaryXformed          = frontBoundary.TransformedLine(new Transform(frontSetbackTranslationVector));

            // Draw lot centreline
            var lotCentreLine = new Line(frontBoundaryXformed.PointAt(0.5), rearBoundary.PointAt(0.5));

            // Create planning Envelope Polygon
            var planningEnvelopePolgyon = CreatePlanningEnvelopePolygon(input.ProposedBuildingHeights, frontBoundaryLengthHalved).First();

            // Orient envelope to lot centreline
            planningEnvelopePolgyon.Transform(new Transform(lotCentreLine.TransformAt(0)));

            // Create envelope geom representation
            var envelopeProfile        = new Profile(planningEnvelopePolgyon);
            var sweep                  = new Elements.Geometry.Solids.Sweep(envelopeProfile, lotBoundaryCurveLoop, 0, 0, 0, false);
            var extrude                = new Elements.Geometry.Solids.Extrude(envelopeProfile, lotCentreLine.Length(), lotCentreLine.Direction(), false);
            var geometryRepresentation = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
            {
                extrude
            });
            var envelopeMaterial = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.6), 0.0f, 0.0f);
            var envelopes        = new List <Envelope>()
            {
                new Envelope(envelopeProfile, 0, maxHeight, lotCentreLine.Direction(), 0.0, new Transform(0, 0, 0), envelopeMaterial, geometryRepresentation, false, Guid.NewGuid(), "")
            };

            output.Model.AddElements(envelopes);
            return(output);
        }