ConvertTo-ModuleService
Exports a Powershell module as a series of ASP.NET handlers

function ConvertTo-ModuleService {             
                
    <#
    .Synopsis
        Export a PowerShell module as a series of ASP.NET Handlers
    .Description
        Exports a Powershell module as a series of ASP.NET handlers        
    .Example
        Import-Module Pipeworks -Force -PassThru | ConvertTo-ModuleService -Force -Allowdownload
    .Link
        Invoke-WebCommand
    #>            
    [OutputType([Nullable])]            
    param(            
    #|Options Get-Module | Select-Object -ExpandProperty Name            
    # The name of the module to export            
    [ValidateScript({            
        if (-not (Get-Module "$_")) {            
            $isavailable = Get-Module -ListAvailable "$_"            
            if ($isavailable) {            
                $isavailable | Import-Module -Global            
            }            
        }            
    return $true            
    })]                    
    [Parameter(Mandatory=$true,Position=0,ParameterSetName='LoadedModule',ValueFromPipelineByPropertyName=$true)]            
    [string]            
    $Name,                   
                    
    # The order in which to display the commands            
    [Parameter(Position=2)]            
    [string[]]            
    $CommandOrder,               
                
    # The Google Analytics ID used for the module            
    [string]            
    $AnalyticsId,            
                       
    # The directory where the generated module will be stored.            
    # If no directory is specified, the module will be put in Inetpub\wwwroot\ModuleName            
    [string]            
    $OutputDirectory,            
                
    # If set, will overwrite files found in the output directory            
    [Switch]            
    $Force,            
                        
    # If set, will allow the module to be downloaded            
    [Parameter(Position=1)]            
    [switch]$AllowDownload,                
                
    # If set, will make changes to the web.config file to work for Intranet sites (anonymous authentication will be disabled, and windows authentication will be enabled).            
    [Switch]$AsIntranetSite,            
                
    # The Kerberos realm to use for authentication.            
    # Only works with -AsIntranetSite.            
    # If provided, Kerberos authentication will be used instead of NTLM.            
    # This is both faster, and more secure.            
    [string]$Realm,            
                
    # If provided, will run the site under an app pool with the credential            
    [Management.Automation.PSCredential]            
    $AppPoolCredential,            
                
    # The port an intranet site should run on.            
    [Uint32]$Port,            
                
    # If a download URL is present, a download link will redirect to that URL.            
    [uri]$DownloadUrl,            
                    
    # If set, the blog page will become the homepage of the module            
    [Switch]$AsBlog,            
                
    # If set, will add a URL rewriter rule to accept any URL that is not a real file.            
    [Switch]$AcceptAnyUrl,            
                
    # If this is set, will use this module URL as the module service URL.            
    [Uri]$ModuleUrl,                
                    
                
    # If set, will render a CSS style            
    [Hashtable]$Style,            
                
    # If set, will create appSettings in a web.config file.  This can be used to store common settings, like connection data.            
    [Hashtable]$ConfigSetting = @{},            
                
    # The margin on either side of the module content.  Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercent = 3,            
                
    # The margin on the left side of the module content. Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercentLeft = 3,            
                
    # The margin on the left side of the module content. Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercentRight = 3,            
                
    # The schematics used to produce the module service.            
    # Schematics let you quickly and easily give a look or feel around data or commands, and let you parameterize your deployment with the pipeworks manifest.            
    [Alias('Schematic')]            
    [string[]]            
    $UseSchematic,                
                    
    # If set, will run commands in a runspace for each user.  If not set, users will run in a pool            
    [Switch]            
    $IsolateRunspace,            
                
    # The size of the runspace pool that will handle request.  The more runspaces in the pool, the more concurrent users            
    [Uint16]            
    $PoolSize = 4,            
                
    # If set, will reset IIS            
    [Switch]            
    $IISReset,            
            
                
    # The maximum amount of that a page can run before it times out.            
    [Timespan]            
    $ExecutionTimeout = [Timespan]::FromSeconds(120),            
            
    # The maximum request length.            
    [Uint32]            
    $MaximumRequestLength = 640kb,            
            
    # If set, will show the default browser when the conversion is complete            
    [Switch]            
    $Show,            
            
    # If provided, will visit this URL after the conversion is complete.            
    [Uri]            
    [Alias('Page', 'ShowPage')]            
    $Do,            
            
    # If set, will run as a background job            
    [Switch]            
    $AsJob,            
            
    # If provided, will run as a background job, with the throttle being the maximum number of background jobs            
    [Uint32]            
    $Throttle,            
            
    # The amount of time static content will be cached for.  By default, one week.            
    [Timespan]            
    $CacheStaticContentFor = [Timespan]::FromDays(7),            
            
    # If set, will not clean the output directory.  If you are trying to nest multiple pipeworks sites, this would be the way to go.            
    [Switch]            
    $DoNotClean,            
            
    # If set, the module will be assumed to be nested beneath another module, and no DefaultDocument will be added to the web.config            
    [Switch]            
    $IsNested            
    )            
                
                
    begin {             
        # First up we define a lot of code that will be used throughout any module service.            
            
            
            
            
        #region AsJobOrElevate            
                    
        # Drop into (almost) any script to let it be run as a background job, or auto-elevate to an admin.            
        $asJobOrElevate = {            
            param($CommandInfo, [switch]$OnlyCommand, [string[]]$AdditionalModules, [Hashtable]$Parameter, [Switch]$RequireAdmin)            
                        
            $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()            
            $isAdmin = (New-Object Security.Principal.WindowsPrincipal $currentUser).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)            
                        
            if ($AsJob -or $Throttle -or (-not $isAdmin) -and $requireAdmin) {                       
                if ($onlyCommand) {                         
                    $AdditionalModules = $AdditionalModules | Select-Object -Unique            
                    $myDefinition = [ScriptBLock]::Create("
$(if ($AdditionalModules) {
"
    Import-Module '$($AdditionalModules -join ("','"))'
"})
                    
function $commandInfo {
$($commandInfo | Select-Object -ExpandProperty Definition)
}

")                                    
                } else {            
                    $myModule = $CommandInfo.ScriptBlock.Module            
            
                    $AdditionalModules += $myModule | Split-Path            
                    $AdditionalModules += $myModule.RequiredModules | Split-Path            
                    $AdditionalModules = $AdditionalModules | Select-Object -Unique            
                    $myDefinition = [ScriptBLock]::Create("

$(if ($AdditionalModules) {
"
    Import-Module '$($AdditionalModules -join ("','"))'
"})

")                               
                }            
            $null = $Parameter.Remove('AsJob')                                                
            $null = $Parameter.Remove('Throttle')            
            $null = $Parameter.Remove('RequireAdmin')                                                
            $myJob= [ScriptBLock]::Create("" + {                                    
param([Hashtable]$parameter)                                     
                                                
} + $myDefinition + "                        
                                    
            $commandInfo `@parameter                        
")                  
            
            
                        
            if ($Throttle) {            
            
                $jobLaunched=  $false            
                            
                do {            
                    if ($myJobs) {            
                        $myJobs |             
                            Receive-Job            
                    }            
            
                                
                    $runningJobs = $myJobs |             
                        Where-Object { $_.State -ne 'Running' }            
if ($runningJobs) {            
                        $runningJobs |             
                            Remove-Job -Force            
                    }            
                            
                                
            
                    if ($myJobs.Count -lt $throttle) {            
                        $null = Start-Job -Name "${MyCmd}_Background_Job" -ScriptBlock $myJob -ArgumentList $Parameter            
                        $JobLaunched = $true            
                    }            
            
                    $myJobs =  Get-Job -Name "${MyCmd}_Background_Job" -ErrorAction SilentlyContinue            
                    Write-Progress "Waiting for Jobs to Complete" "$($myJobs.Count) Running" -Id $ProgressId              
                } until ($jobLaunched)            
                            
                $myJobs =  Get-Job -Name "${MyCmd}_Background_Job" -ErrorAction SilentlyContinue            
                $myJobs  |             
                    Wait-Job |             
                    Receive-Job            
                return             
            } elseif ($asJob) {            
                return Start-Job -ScriptBlock $myJob -ArgumentList $Parameter -Name "${CommandInfo}_Background_Job"            
                            
            } elseif ((-not $isAdmin) -and $RequireAdmin) {            
                $fullCommand =             
"
`$parameter = $(Write-PowerShellHashtable -InputObject $parameter)
& { $myJob } `$parameter

"            
            
                $encodedCommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($fullCommand))            
            
            
                return  Start-Process powershell -Verb Runas -ArgumentList '-encodedCommand', $encodedCommand -PassThru            
                            
            }            
        }            
        }            
        #endregion AsJobOrElevate            
                    
                    
        # All command services have to have a lot packed into each runspace, so a bit has to happen to set things up            
                    
        # - An InitialSessionState has to be created for the new runspace            
        # - Potentially harmful or useless low-rights commands are removed from the runspace            
        # - "Common" Functions are embedded into each handler            
            
        #region ResolveFinalUrl            
                    
        # This allows us to determine the real URL the service is being called by, including parts from URL redirection            
$resolveFinalUrl = {            
# The tricky part is resolving the real URL of the service.            
# Split out the protocol            
$resolveUrlStartedAt = [DateTime]::Now            
$protocol = $request['Server_Protocol'].Split("/", [StringSplitOptions]::RemoveEmptyEntries)[0]              
# And what it thinks it called the server            
$serverName= $request['Server_Name']                                 
$port = $request.Url.Port            
            
# And the relative path beneath that URL            
$shortPath = [IO.Path]::GetDirectoryName($request['PATH_INFO'])                        
# Put them all together            
            
if (($protocol -eq 'http' -and $port -eq 80) -or             
    ($protocol -eq 'https' -and $port -eq 443)) {            
$remoteCommandUrl =             
    $Protocol + '://' + $ServerName.Replace('\', '/').TrimEnd('/') + '/' + $shortPath.Replace('\','/').TrimStart('/')            
} else {            
$remoteCommandUrl =             
    $Protocol + '://' + $ServerName.Replace('\', '/').TrimEnd('/') + ':' + $port + '/' + $shortPath.Replace('\','/').TrimStart('/')            
            
}            
            
# Now, if the pages was anything but Default, add the .ashx reference            
$finalUrl =             
    if ($request['Url'].EndsWith("Default.ashx", [StringComparison]"InvariantCultureIgnoreCase")) {            
        $u = $request['Url'].ToString()            
        $remoteCommandUrl.TrimEnd("/") + "/"             
        # $remoteCommandUrl.TrimEnd("/") + $u.Substring($u.LastIndexOf("/"))            
            
                    
    } elseif ($request['Url'].EndsWith("Module.ashx", [StringComparison]"InvariantCultureIgnoreCase")) {            
        $u = $request['Url'].ToString()            
        $remoteCommandUrl.TrimEnd("/") + $u.Substring($u.LastIndexOf("/"))            
    } else {            
        $remoteCommandUrl.TrimEnd("/") + "/"            
    }                
                
            
$fullUrl = "$($request.Url)"            
if ($request -and $request.Params -and $request.Params["HTTP_X_ORIGINAL_URL"]) {            
                        
    #region Determine the Relative Path, Full URL, and Depth            
    $originalUrl = $context.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]            
    $urlString = $request.Url.ToString().TrimEnd("/")            
    $pathInfoUrl = $urlString.Substring(0,             
        $urlString.LastIndexOf("/"))            
                                                                        
    $protocol = ($request['Server_Protocol'].Split("/",             
        [StringSplitOptions]"RemoveEmptyEntries"))[0]             
    $serverName= $request['Server_Name']                                 
                        
    $port=  $request.Url.Port            
    $fullOriginalUrl =             
        if (($Protocol -eq 'http' -and $port -eq 80) -or            
            ($Protocol -eq 'https' -and $port -eq 443)) {            
            $protocol+ "://" + $serverName + $originalUrl             
        } else {            
            $protocol+ "://" + $serverName + ':' + $port + $originalUrl             
        }            
                                                                
    $rindex = $fullOriginalUrl.IndexOf($pathInfoUrl, [StringComparison]"InvariantCultureIgnoreCase")            
    $relativeUrl = $fullOriginalUrl.Substring(($rindex + $pathInfoUrl.Length))            
    $rootUrl = $fullOriginalUrl.Substring(0, $pathInfoUrl.Length)            
    if ($relativeUrl -like "*/*") {            
        $depth = @($relativeUrl -split "/" -ne "").Count - 1                                
        if ($fullOriginalUrl.EndsWith("/")) {             
            $depth++            
        }                                                    
    } else {            
        $depth  = 0            
    }            
            
    $RelativeDepth = "../" * $depth            
    #endregion Determine the Relative Path, Full URL, and Depth            
    $fullUrl = $fullOriginalUrl            
}            
if (-not $rootUrl) {            
    $rootUrl =  $fullurl.Substring(0,             
        $fullUrl.LastIndexOf("/"))                 
}            
$serviceUrl = $fullUrl            
            
$timeSpentResolvingURL = [DateTime]::now - $resolveUrlStartedAt            
        }            
                          
        #endregion ResolveFinalUrl            
            
            
        #region UnpackItem            
            
        # This allows us to take items with compressed data and expand them            
        $unpackItem = {            
            $item = $_            
            $item.psobject.properties |                                     
                Where-Object {             
                    ('Timestamp', 'RowKey', 'TableName', 'PartitionKey' -notcontains $_.Name) -and            
                    (-not "$($_.Value)".Contains(' '))             
                }|                                    
                ForEach-Object {            
                    try {            
                        $expanded = Expand-Data -CompressedData $_.Value            
                        $item | Add-Member NoteProperty $_.Name $expanded -Force            
                    } catch{            
                        Write-Verbose $_            
                                
                    }            
                }            
                            
            $item.psobject.properties |                                     
                Where-Object {             
                    ('Timestamp', 'RowKey', 'TableName', 'PartitionKey' -notcontains $_.Name) -and            
                    (-not "$($_.Value)".Contains('<'))             
                }|                                               
                ForEach-Object {            
                    try {            
                        $fromMarkdown = ConvertFrom-Markdown -Markdown $_.Value            
                        $item | Add-Member NoteProperty $_.Name $fromMarkdown -Force            
                    } catch{            
                        Write-Verbose $_            
                                
                    }            
                }            
            
            $item                                     
        }            
        #endregion UnpackItem            
            
            
        #region RefreshLatest            
        $refreshLatest = {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
                        
                        
                        
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)                                                                       
            
            $latest =             
                Search-AzureTable -TableName $pipeworksManifest.Table.Name -Filter "PartitionKey eq '$PartitionKey'" -Select Timestamp, DatePublished, PartitionKey, RowKey -StorageAccount $storageAccount -StorageKey $storageKey |            
                Sort-Object -Descending {            
                    if ($_.DatePublished) {            
                        [DateTime]$_.DatePublished            
                    } else {            
                        [DateTime]$_.Timestamp            
                    }            
                } |            
                Select-Object -First 1 |            
                Get-AzureTable -TableName $pipeworksManifest.Table.Name                        
                        
                                                                                                              
        }            
        #endregion RefreshLatest            
            
        # Writing the handler for a command actually involves writing several handlers,            
        # so we'll make this it's own little inline tool.            
        $writeSimpleHandler = {            
                    
param($cSharp, [Switch]$ShareRunspace, [Uint16]$PoolSize, [Switch]$ImportsPipeworks, [string[]]$EmbeddedCommand)             
            
            
                    
        # Blacklist "bad" functions, and directory traversal            
        $functionBlackList = 65..90 |             
            ForEach-Object -Begin {            
                "ImportSystemModules", "Disable-PSRemoting", "Restart-Computer", "Clear-Host", "cd..", "cd\\", "more"            
            } -Process {             
                [string][char]$_ + ":"             
            }            
                
            
        if (-not $script:FunctionsInEveryRunspace) {            
            $script:FunctionsInEveryRunspace = 'ConvertFrom-Markdown', 'Confirm-Person', 'Get-Person', 'Get-Web', 'Get-PipeworksManifest', 'Get-WebConfigurationSetting', 'Get-FunctionFromScript', 'Get-Walkthru',             
    'Get-WebInput', 'New-RssItem', 'Invoke-WebCommand', 'Out-RssFeed', 'Request-CommandInput', 'New-Region', 'New-WebPage', 'Out-Html',             
    'Write-Css', 'Write-Host', 'Write-Link', 'Write-ScriptHTML', 'Write-WalkthruHTML', 'Write-PowerShellHashtable', 'Compress-Data',             
    'Expand-Data', 'Import-PSData', 'Export-PSData', 'ConvertTo-ServiceUrl', 'Get-SecureSetting', 'Search-Engine', 'Get-Hash'            
            
            
        }            
             
        $embedSection = ""            
        if (-not $ImportsPipeworks) {            
                            
                     
                    
            
            if (-not $EmbeddedCommand) {            
                $EmbeddedCommand = $script:FunctionsInEveryRunspace            
            }            
            
            $EmbeddedCommand = $EmbeddedCommand | Select-Object -Unique            
            
            
            $embedSection += foreach ($func in (Get-Command -Name $EmbeddedCommand -CommandType Function)) {            
            
@"
        string compressed$($func.Name.Replace('-', ''))Defintion = "$(Compress-Data -String $func.Definition.ToString())";
        byte[] binaryDataFor$($func.Name.Replace('-', '')) = System.Convert.FromBase64String(compressed$($func.Name.Replace('-', ''))Defintion);
        System.IO.MemoryStream memoryStreamFor$($func.Name.Replace('-', '')) = new System.IO.MemoryStream(); 
        memoryStreamFor$($func.Name.Replace('-', '')).Write(binaryDataFor$($func.Name.Replace('-', '')), 0, binaryDataFor$($func.Name.Replace('-', '')).Length);
        memoryStreamFor$($func.Name.Replace('-', '')).Seek(0, 0);
        System.IO.Compression.GZipStream decompressorFor$($func.Name.Replace('-', '')) = 
            new System.IO.Compression.GZipStream(memoryStreamFor$($func.Name.Replace('-', '')), System.IO.Compression.CompressionMode.Decompress);
        System.IO.StreamReader readerFor$($func.Name.Replace('-', '')) = new System.IO.StreamReader(decompressorFor$($func.Name.Replace('-', '')));
        string decompressedDefinitionFor$($func.Name.Replace('-', '')) = readerFor$($func.Name.Replace('-', '')).ReadToEnd();
        SessionStateFunctionEntry $($func.Name.Replace('-',''))Command = new SessionStateFunctionEntry(
            "$($func.Name)", decompressedDefinitionFor$($func.Name.Replace('-', ''))
        );
        iss.Commands.Add($($func.Name.Replace('-',''))Command);

        memoryStreamFor$($func.Name.Replace('-', '')).Close();
        memoryStreamFor$($func.Name.Replace('-', '')).Dispose();
        decompressorFor$($func.Name.Replace('-', '')).Close();
        decompressorFor$($func.Name.Replace('-', '')).Dispose();
        readerFor$($func.Name.Replace('-', '')).Close();
                
"@            
            
        }                           
        # Web handlers are essentially embedded C#, compiled on their first use.   The webCommandSequence class,            
        # defined within this quite large herestring, is a bridge used to invoke PowerShell within a web handler.            
                    
        }            
        $webCmdSequence = @"
public class WebCommandSequence {
    public static InitialSessionState InitializeRunspace(string[] module) {
        InitialSessionState iss = InitialSessionState.CreateDefault();
        
        if (module != null) {
            iss.ImportPSModule(module);
        }
        $embedSection
        
        string[] commandsToRemove = new String[] { "$($functionBlacklist -join '","')"};
        foreach (string cmdName in commandsToRemove) {
            iss.Commands.Remove(cmdName, null);
        }
        
        
        return iss;
        
    }
    


    public static void InvokeScript(string script, 
        HttpContext context, 
        object arguments,
        bool throwError,
        bool shareRunspace) {

        PowerShell psCmd = PowerShell.Create();                   
        psCmd.Commands.Clear();
        bool justLoaded = false;
        Runspace runspace;
        RunspacePool runspacePool;
        PSInvocationSettings invokeWithHistory = new PSInvocationSettings();
        invokeWithHistory.AddToHistory = true;
        PSInvocationSettings invokeWithoutHistory = new PSInvocationSettings();
        invokeWithHistory.AddToHistory = false;
        
        if (! shareRunspace) {

            if (context.Session["UserRunspace"] == null) {                        
                justLoaded = true;
                InitialSessionState iss = WebCommandSequence.InitializeRunspace(null);
                Runspace rs = RunspaceFactory.CreateRunspace(iss);
                rs.ApartmentState = System.Threading.ApartmentState.STA;            
                rs.ThreadOptions = PSThreadOptions.ReuseThread;
                rs.Open();                
                psCmd.Runspace = rs;
                context.Session.Add("UserRunspace",psCmd.Runspace);
                psCmd.
                    AddCommand("Set-ExecutionPolicy", false).
                    AddParameter("Scope", "Process").
                    AddParameter("ExecutionPolicy", "Bypass").
                    AddParameter("Force", true).
                    Invoke(null, invokeWithoutHistory);
                psCmd.Commands.Clear();
            }

        

            runspace = context.Session["UserRunspace"] as Runspace;
            if (context.Application["Runspaces"] == null) {
                context.Application["Runspaces"] = new Hashtable();
            }
            if (context.Application["RunspaceAccessTimes"] == null) {
                context.Application["RunspaceAccessTimes"] = new Hashtable();
            }
            if (context.Application["RunspaceAccessCount"] == null) {
                context.Application["RunspaceAccessCount"] = new Hashtable();
            }

            Hashtable runspaceTable = context.Application["Runspaces"] as Hashtable;
            Hashtable runspaceAccesses = context.Application["RunspaceAccessTimes"] as Hashtable;
            Hashtable runspaceAccessCounter = context.Application["RunspaceAccessCount"] as Hashtable;

            if (! runspaceAccessCounter.Contains(runspace.InstanceId.ToString())) {
                runspaceAccessCounter[runspace.InstanceId.ToString()] = (int)0;
            }
            runspaceAccessCounter[runspace.InstanceId.ToString()] = ((int)runspaceAccessCounter[runspace.InstanceId.ToString()]) + 1;

            runspaceAccesses[runspace.InstanceId.ToString()] = DateTime.Now;


                    
            if (! runspaceTable.Contains(runspace.InstanceId.ToString())) {
                runspaceTable[runspace.InstanceId.ToString()] = runspace;
            }


            runspace.SessionStateProxy.SetVariable("Request", context.Request);
            runspace.SessionStateProxy.SetVariable("Response", context.Response);
            runspace.SessionStateProxy.SetVariable("Session", context.Session);
            runspace.SessionStateProxy.SetVariable("Server", context.Server);
            runspace.SessionStateProxy.SetVariable("Cache", context.Cache);
            runspace.SessionStateProxy.SetVariable("Context", context);
            runspace.SessionStateProxy.SetVariable("Application", context.Application);
            runspace.SessionStateProxy.SetVariable("JustLoaded", justLoaded);
            runspace.SessionStateProxy.SetVariable("IsSharedRunspace", false);
            psCmd.Runspace = runspace;
            psCmd.AddScript(@"
`$timeout = (Get-Date).AddMinutes(-20)
`$oneTimeTimeout = (Get-Date).AddMinutes(-1)
foreach (`$key in @(`$application['Runspaces'].Keys)) {
    if ('Closed', 'Broken' -contains `$application['Runspaces'][`$key].RunspaceStateInfo.State) {
        `$application['Runspaces'][`$key].Dispose()
        `$application['Runspaces'].Remove(`$key)
        continue
    }
    
    if (`$application['RunspaceAccessTimes'][`$key] -lt `$Timeout) {
        
        `$application['Runspaces'][`$key].CloseAsync()
        continue
    }    
}
").Invoke();

            psCmd.Commands.Clear();
            psCmd.AddScript(script, false);
            
            if (arguments is IDictionary) {
                psCmd.AddParameters((arguments as IDictionary));
            } else if (arguments is IList) {
                psCmd.AddParameters((arguments as IList));
            }
            Collection<PSObject> results = psCmd.Invoke();        

        } else {
            if (context.Application["RunspacePool"] == null) {                        
                justLoaded = true;
                InitialSessionState iss = WebCommandSequence.InitializeRunspace(null);
                RunspacePool rsPool = RunspaceFactory.CreateRunspacePool(iss);
                rsPool.SetMaxRunspaces($PoolSize);
                rsPool.ApartmentState = System.Threading.ApartmentState.STA;            
                rsPool.ThreadOptions = PSThreadOptions.ReuseThread;
                rsPool.Open();                
                psCmd.RunspacePool = rsPool;
                context.Application.Add("RunspacePool",rsPool);
                
                /*
                // Initialize the pool
                Collection<IAsyncResult> resultCollection = new Collection<IAsyncResult>();
                for (int i =0; i < $poolSize; i++) {
                    PowerShell execPolicySet = PowerShell.Create().
                        AddScript(@"
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force 

#INSERTEVERYSECTIONIFNEEDED



", false);
                    execPolicySet.RunspacePool = rsPool;
                    resultCollection.Add(execPolicySet.BeginInvoke());
                }
                
                foreach (IAsyncResult lastResult in resultCollection) {
                    if (lastResult != null) {
                        lastResult.AsyncWaitHandle.WaitOne();
                    }
                }
                */
                
                
                
                
                
                psCmd.Commands.Clear();
            }
            

            psCmd.RunspacePool = context.Application["RunspacePool"] as RunspacePool;
            
            
            string newScript = @"param(`$Request, `$Response, `$Server, `$session, `$Cache, `$Context, `$Application, `$JustLoaded, `$IsSharedRunspace, [Parameter(ValueFromRemainingArguments=`$true)]`$args)
            
            
            " + script;            
            psCmd.AddScript(newScript, false);

            if (arguments is IDictionary) {
                psCmd.AddParameters((arguments as IDictionary));
            } else if (arguments is IList) {
                psCmd.AddParameters((arguments as IList));
            }            
            
            psCmd.AddParameter("Request", context.Request);
            psCmd.AddParameter("Response", context.Response);
            psCmd.AddParameter("Session", context.Session);
            psCmd.AddParameter("Server", context.Server);
            psCmd.AddParameter("Cache", context.Cache);
            psCmd.AddParameter("Context", context);
            psCmd.AddParameter("Application", context.Application);
            psCmd.AddParameter("JustLoaded", justLoaded);
            psCmd.AddParameter("IsSharedRunspace", true);
            
            Collection<PSObject> results;
            try {
                results = psCmd.Invoke();        
            } catch (Exception ex) {               
                if (
                    (String.Compare(ex.GetType().FullName, "System.Management.Automation.ParameterBindingValidationException") == 0) || 
                    (String.Compare(ex.GetType().FullName, "System.Management.Automation.RuntimeException") == 0)
                   ) {
                    // Parameter validation exception: clean it up a little.
                    ErrorRecord errRec = ex.GetType().GetProperty("ErrorRecord").GetValue(ex, null) as ErrorRecord;
                    if (errRec != null) {
                        try {
                            context.Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                        } catch {
                        
                        }
                        context.Response.Write("<span class='ui-state-error' color='red'>" + errRec.InvocationInfo.PositionMessage + "</span><br/>");
                    }                    
                } else {
                    throw ex;
                }
            }
            
                        
            psCmd.Dispose();
            
        }
        
        
      
        foreach (ErrorRecord err in psCmd.Streams.Error) {
            
            
            if (throwError) {
                if (err.Exception != null) {
                    if (err.Exception.GetType().GetProperty("ErrorRecord") != null) {
                        ErrorRecord errRec = err.Exception.GetType().GetProperty("ErrorRecord").GetValue(err.Exception, null) as ErrorRecord;
                        if (errRec != null) {
                            //context.Response.StatusCode = (int)System.Net.HttpStatusCode.PreconditionFailed;
                            //context.Response.StatusDescription = errRec.InvocationInfo.PositionMessage;
                            context.Response.Write("<span class='ui-state-error' style='line-height:200%' color='red'>" + err.Exception.ToString() + errRec.InvocationInfo.PositionMessage + "</span><br/>");
                        }                        
                        //context.Response.Flush();           
                    } else {
                        context.AddError(err.Exception);            
                    }   
                }
            } else {
                context.Response.Write("<span class='ui-state-error' style='line-height:200%' color='red'>" + err.Exception.ToString() + err.InvocationInfo.PositionMessage + "</span><br/>");                
            }            
        }
        
        if (psCmd.InvocationStateInfo.Reason != null) {
            if (throwError) {                
                context.AddError(psCmd.InvocationStateInfo.Reason);
            } else {                
                context.Response.Write("<span class='ui-state-error' style='line-height:200%' color='red'>" + psCmd.InvocationStateInfo.Reason + "</span>");
            }
        }

        
    
    }

}
"@                  
            
        $webCommandSequence = $webCmdSequence            
            
            
if ($pipeworksManifest.Every -and $pipeworksManifest.Every -is [Hashtable]) {            
    $everySection = ""            
            
            
    $n = 1            
    foreach ($kv in $pipeworksManifest.Every.GetEnumerator()) {            
        $interval = $kv.Key            
        $everyAction = $kv.Value            
        $everySection += "
`$everyTimer${n} = New-Object Timers.Timer -Property @{
    Interval = ([Timespan]'$interval').TotalMilliseconds
}

`$global:firstPulse = Get-Date

Register-ObjectEvent -InputObject `$everyTimer${n} -EventName Elapsed -SourceIdentifier EveryAction${n} -Action {
    $everyAction
    
}

`$everyTimer${n}.Start()
"                
        $n++            
    }            
            
    $webCommandSequence = $webCommandSequence.Replace('#INSERTEVERYSECTIONIFNEEDED', $everySection.Replace('"', '""'))            
}            
            
            
            
            
            
@"
<%@ WebHandler Language="C#" Class="Handler" %>
<%@ Assembly Name="System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
using System;
using System.Web;
using System.Web.SessionState;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

$webCommandSequence

public class Handler : IHttpHandler, IRequiresSessionState  {        
    public void ProcessRequest (HttpContext context) {
        $cSharp
    }
    
    public bool IsReusable {
    	get {
    	    return true;
    	}
    }
}    
"@                
}            
            
                            
                
    }            
    process {                 
                
        $theModule = Get-Module $name            
        $theModulePaths = @($theModule| Split-Path)            
        $theModulePaths += @($theModule.RequiredModules | Split-Path)            
        $launched = . $asJobOrElevate $MyInvocation.MyCommand -additionalModules $theModulePaths -Parameter $psBoundParameters -RequireAdmin            
            
        if ($launched) { return $launched}             
            
        if ($psCmdlet.ParameterSetName -eq 'LoadedModule') {            
                    
                    
        $module = Get-Module $name | Select-Object -First 1                   
        if (-not $module ) { return }             
                    
        # Skip "accidental" modules            
        if ($module.Path -like "*.ps1") { return }             
                    
                    
                    
        $global:PipeworksManifest = $null            
                    
                    
        if (-not $psBoundParameters.outputDirectory) {            
            $outputDirectory = "${env:SystemDrive}\inetpub\wwwroot\$($Module.Name)\"                        
            $outDirWasSet = $false                
        } else {            
            $outDirWasSet = $true            
        }            
            
        if ((Test-Path $outputDirectory) -and (-not $force)) {            
            Write-Error "$outputDirectory exists, use -Force to overwrite"            
            return            
        }            
        if (-not $DoNotClean) {            
            Write-Progress "Cleaning Output Directory" "$outputDirectory"            
            Remove-Item $outputDirectory -Recurse -Force -ErrorVariable Issues            
        }            
                    
        $null = New-Item -Path $outputDirectory -Force -ItemType Directory                    
        Push-Location $outputDirectory            
        $null = New-Item -Path "$outputDirectory\bin" -Force -ItemType Directory                    
                    
            
            
            
        # Urls to Rewrite stores the result. Each handler will need to rewrite several URLs for the functionality to work as expected            
        $urlsToRewrite = @{}            
                    
        # To create a web command, we actually need to create several handlers and pages, depending on the options specified.            
                    
                                                
        $moduleNumber = 0            
        $realModule  = $module            
            
                    
            
            
        foreach ($m in $realModule) {             
            if (-not $m) { continue }                   
            $moduleRoot = Split-Path $m.Path                                 
            
                        
            $ManifestPath = Join-Path $moduleRoot "$($module.Name).psd1"            
            
            if (-not (Test-Path $ManifestPath)) {            
"
# Module Manifest autogenerated by PowerShell Pipeworks.
@{
    ModuleVersion = 0.1
    ModuleToProcess = '$($module.Path | Split-Path -Leaf)'
}" |            
    Set-Content $manifestPath            
            }            
            
            #region Initialize Pipeworks Manifest            
            $pipeworksManifestPath = Join-Path $moduleRoot "$($module.Name).Pipeworks.psd1"            
            $pipeworksManifest = if (Test-Path $pipeworksManifestPath) {            
                try {                                 
                    & ([ScriptBlock]::Create(            
                        "data -SupportedCommand Add-Member, New-WebPage, New-Region, Write-CSS, Write-Ajax, Out-Html, Write-Link { $(
                            [ScriptBlock]::Create([IO.File]::ReadAllText($pipeworksManifestPath))                    
                        )}"))                        
                } catch {            
                    Write-Error "Could not read pipeworks manifest"             
                }                                                            
            }            
                        
            if (-not $pipeworksManifest) {             
                $pipeworksManifest = @{            
                    Pages = @{}            
                    Posts = @{}            
                    WebCommands = @{}                            
                    Assets = @{}            
                    Javascript = @{}            
                    Download = @{}            
                    CSS = @{}            
                }            
            }            
                        
                        
            if ($pipeworksManifest.Css) {            
                foreach ($cssItem in $pipeworksManifest.Css.GetEnumerator()) {            
                    if ($cssItem.Value -like "*.less") {            
                        if ($cssItem.Value -like "http*:*") {            
                            # Public LESS file, download and compile            
                            $lessCssFile = Get-Web -Url "$($cssItem.Value)" -UseWebRequest            
            
                            $compiledLess = Use-Less -LessCss $lessCssFile            
            
                            $lessDest = Join-Path "$moduleRoot\CSS" (([uri]$cssItem.Value).Segments[-1] -ireplace "\.less", ".css")            
            
                            if (-not (Test-Path "$moduleRoot\CSS")) {            
                                $null = New-Item -ItemType Directory -Path "$moduleRoot\CSS" -Force            
                            }            
            
                            [IO.File]::WriteAllText($lessDest, $compiledLess)            
            
                        } elseif ($cssItem.Value -like "/*") {            
                            # Private LESS file, resolve and compile            
                            $lessCssFile = [IO.File]::ReadAllText((Join-Path $moduleRoot $cssItem.Value))            
            
                            $compiledLess = Use-Less -LessCss $lessCssFile            
            
                            $lessDest = (Join-Path $moduleRoot $cssItem.Value) -ireplace "\.less", ".css"            
                            [IO.File]::WriteAllText($lessDest, $compiledLess)            
                        }            
                    }            
                }            
            }            
            
            
            #region Inherit Settings from the Pipeworks Manifest            
            if (-not ($Style -and $PipeworksManifest.Style)) {            
                $Style = $PipeworksManifest.Style            
            }            
                        
                        
            # If there's no CSS style set, create a default one            
            if (-not $Style) {            
                $Style = @{            
                    Body = @{            
                        'Font-Family' = "'Segoe UI', 'Segoe UI Symbol', Helvetica, Arial, sans-serif"            
                    }            
                }            
            }            
                        
                        
            if (-not $psBoundParameters.MarginPercent -or ($psBoundParameters.MarginPercentLeft -and $psBoundParameters.MarginPercentRight)) {            
                $marginPercentLeftString = "3%"            
                $marginPercentRightString= "3%"            
            } else {            
                if ($psBoundParameters.MarginPercent) {            
                    $marginPercentLeftString = $MarginPercent + "%"            
                    $marginPercentRightString = $MarginPercent + "%"            
                } else {            
                    $marginPercentLeftString = $MarginPercentLeft+ "%"            
                    $marginPercentRightString = $MarginPercentRight+ "%"            
                }            
            }             
                        
                        
                        
            if ($pipeworksManifest.SecureSetting) {                        
                foreach ($configSettingName in $pipeworksManifest.SecureSetting) {            
                    if (-not $configSettingName) { continue }                            
                    $settingValue = Get-SecureSetting -Name $configSettingName -ValueOnly -Type String            
                    if ($settingValue) {            
                        $configSetting[$configSettingName] = $settingValue            
                    }            
                }            
            }            
                        
            if ($pipeworksManifest.SecureSettings) {                        
                foreach ($configSettingName in $pipeworksManifest.SecureSettings) {            
                    if (-not $configSettingName) { continue }                            
                    $settingValue = Get-SecureSetting -Name $configSettingName -ValueOnly -Type String            
                    if ($settingValue) {            
                        $configSetting[$configSettingName] = $settingValue            
                    }            
                }            
            }            
                                                
                        
            # If there's no analyticsId provided, and one exists in the pipeworks manifest, use it            
            if (-not $analyticsId -and $pipeworksManifest.AnalyticsId) {            
                $analyticsId = $pipeworksManifest.AnalyticsId            
            }            
                        
            if (-not $AsIntranetSite -and $pipeworksManifest.AsIntranetSite) {            
                $AsIntranetSite = $true            
            }            
            
            if ($pipeworksManifest.AppPoolUser) {            
                if ($pipeworksManifest.AppPoolPasswordSetting -and (Get-SecureSetting -Name $pipeworksManifest.AppPoolPasswordsetting)) {            
                    $newCred = New-Object Management.Automation.PSCredential $pipeworksManifest.AppPoolUser, (ConvertTo-SecureString -AsPlainText -Force (Get-SecureSetting $pipeworksManifest.AppPoolPasswordSetting -ValueOnly))            
                    $appPoolCredential = $newCred            
                } elseif (Get-SecureSetting -Name "${Module}AppPoolPassword") {            
                    $newCred = New-Object Management.Automation.PSCredential $pipeworksManifest.AppPoolUser, (ConvertTo-SecureString -AsPlainText -Force (Get-SecureSetting "${Module}AppPoolPassword" -ValueOnly))            
                    $appPoolCredential = $newCred            
                } else {            
                    $cred = Get-Credential -UserName $pipeworksManifest.AppPoolUser            
                    Add-SecureSetting -Name "${Module}AppPoolPassword" -String $cred.GetNetworkCredential().Password            
                    $AppPoolCredential = $cred            
                }            
                            
            }            
            
            if (-not $AllowDownload -and $pipeworksManifest.AllowDownload) {            
                $AllowDownload = $true            
            }            
            
            
            if (-not $port -and ($pipeworksManifest.Port -as [uint32])) {            
                $port = $pipeworksManifest.Port            
            }            
                        
                        
            $moduleBlogTitle =             
                if ($pipeworksManifest.Blog.Name) {            
                    $pipeworksManifest.Blog.Name            
                } else {            
                    $module.Name            
                }            
                        
            $moduleBlogDescription =             
                if ($pipeworksManifest.Blog.Description) {            
                    $pipeworksManifest.Blog.Description            
                } else {            
                    $module.Description            
                }            
                        
            $moduleBlogLink =             
                if ($pipeworksManifest.Blog.Link) {            
                    $pipeworksManifest.Blog.Link            
                } else {            
                    "Blog.html"            
                }            
            
            if (-not $PipeworksManifest.Pages) {            
                $PipeworksManifest.Pages = @{}            
            }            
                        
            if (-not $PipeworksManifest.Javascript) {            
                $PipeworksManifest.Javascript= @{}            
            }            
                        
            if (-not $PipeworksManifest.CssFile) {            
                $PipeworksManifest.CssFile = @{}            
            }            
                        
            if (-not $PipeworksManifest.AssetFile) {            
                $PipeworksManifest.AssetFile = @{}            
            }            
            #region Inherit Settings from the Pipeworks Manifest            
            #endregion Initialize Pipeworks Manifest            
                            
            # Run the ezformat file, if present (and EZOut is loaded)            
            if ((Test-Path "$moduleRoot\$($m.Name).ezformat.ps1") -and (Get-Module EZOut)) {                            
                & "$moduleRoot\$($m.Name).ezformat.ps1"            
            }            
            $realModulePath = $m.Path            
            $moduleNumber++            
                        
            if ($AllowDownload) {            
                # If AllowDownload is set, create a .zip file to hold the module            
                Write-Progress "Creating download" "Adding $($m) to zip file"            
                $moduleZip = Join-Path $outputdirectory "$($m.Name).$($m.Version).Zip"            
                if ($moduleNumber -eq 1 -and (Test-Path $moduleZip)) {                                
                    Remove-Item $moduleZip -Force            
                }            
                            
                $tempModulePath = New-Item "$env:Temp\TempModule$(Get-Random)" -ItemType Directory            
                $tempModuleDir = New-Item "$tempModulePath\$($m.Name)" -ItemType Directory            
                            
                            
                            
                            
                # By looping thru all files with Get-ChildItem, hidden files get skipped.            
                $moduleFiles  =             
                    @(Get-ChildItem -Path $moduleRoot -Recurse |                                
                        Where-Object { -not $_.psIsContainer } |             
                        Copy-Item -Destination {                                                            
                            $newPath = $_.FullName.Replace($moduleRoot, $tempModuleDir)            
                                        
                            $newDir = $newPAth  |Split-Path            
                            if (-not (Test-Path $newDir)) {            
                                $null = New-Item -ItemType Directory -Path "$newDir" -Force            
                            }            
                                        
                                        
                            Write-Progress "Copying $($req.name)" "$newPath"            
                            $newPath                         
                                        
                        }  -passThru)            
                # $null = Copy-ToZip -File $tempModuleDir -ZipFile $moduleZip -HideProgress            
                            
                            
                if ($m.RequiredModules) {            
                    foreach ($requiredModuleInfo in $m.RequiredModules) {            
                                    
                        $requiredRoot = ($requiredModuleInfo | Split-Path)            
                        $tempRequiredModuledir = New-Item "$tempModulePath\$($requiredModuleInfo.Name)" -ItemType Directory            
                        $moduleFiles += Get-ChildItem $requiredRoot -Recurse |             
                            Where-Object { -not $_.psIsContainer } |             
                            Copy-Item -Destination {            
                                $newPAth  = $_.FullName.Replace($requiredRoot, $tempRequiredModuleDir)            
                                $newDir = $newPAth  |Split-Path             
                                if (-not (Test-Path $newDir)) {            
                                    $null = New-Item -ItemType Directory -Path "$newDir" -Force            
                                }            
                                            
                                            
                                Write-Progress "Copying $($req.name)" "$newPath"            
                                $newPath                         
                            } -passthru            
                                        
                    }            
                }            
                $moduleList = @($RealModule.RequiredModules |             
                    Select-Object -ExpandProperty Name) + $realModule.Name            
                                    
            
                            
                # Add an installer            
                $installer = @'
echo "Installing modules from %~dp0"
'@            
            
                $allUsersInstaller = @'
echo "Installing modules from %~dp0"
'@            
            
                $modulePaths = @()            
                foreach ($m in $moduleList) {            
                    $modulePaths += ('.\' + $m)            
                    $installer += @"

xcopy "%~dp0$m" "%userprofile%\Documents\WindowsPowerShell\Modules\$m" /y /s /i /d 

"@            
            
                    $allUsersInstaller += @"
xcopy "%~dp0$m" "%windir%\system32\WindowsPowerShell\v1.0\Modules\$m" /y /s /i /d 
"@            
                }            
            
                            
                                                
                # Add shortcut items, if found in the pipeworks manifest            
                if ($pipeworksManifest.Shortcut) {            
                    $shortcutsFile =             
                        "`$moduleName = '$($realModule.Name)'" + {            
            
$shell = New-Object -ComObject WScript.Shell            
$startRoot = "$home\AppData\Roaming\Microsoft\Windows\Start Menu\Programs"            
$moduleSubFolder = Join-Path $startRoot $moduleName            
if (-not (Test-Path $moduleSubFolder)) {            
    $null = New-Item -ItemType Directory -Path $moduleSubFolder            
}            
            
$modulefolder = Join-Path "$home\Documents\WindowsPowerShell\Modules" $moduleName                                        
            
                        }            
                                
                    $installer += @'

powershell -ExecutionPolicy Bypass -File "%~dp0AddShortcuts.ps1"

'@                               
                    foreach ($shortcutInfo in $pipeworksManifest.ShortCut.Getenumerator()) {            
                        if ($shortcutInfo.Value -notlike "http*") {                                    
                            $shortcutsFile += @"

`$sh = `$shell.CreateShortcut("`$moduleSubFolder\$($shortcutInfo.Key).lnk")                           
`$sh.WorkingDirectory = `$moduleFolder
`$sh.TargetPath = "`$psHome\powershell.exe"
`$sh.Arguments = '-executionpolicy bypass -windowstyle minimized -sta -command `$moduleDir = Join-Path `$env:UserProfile ''Documents\WindowsPowerShell\Modules'';Push-Location `$moduleDir;Import-Module `"$($modulePaths -join "`",`"")`";Pop-Location;$($shortcutInfo.Value)'
`$sh.Save()
"@            
                        } else {            
                            $shortcutsFile += @"

`$sh = `$shell.CreateShortcut("`$moduleSubFolder\$($shortcutInfo.Key).url")               
`$sh.TargetPath = "$($shortcutInfo.Value)"
`$sh.Save()
"@            
                        }            
                    }            
                                
                                
                                
                    $shortcutsFile |            
                        Set-Content "$tempModulePath\AddShortcuts.ps1"                          
                }            
                            
                $installer |            
                    Set-Content "$tempModulePath\Install.cmd"                          
                            
                $allUsersInstaller |            
                    Set-Content "$tempModulePath\InstallForAllUsers.cmd"                          
                            
                            
                Get-ChildItem $tempModulePath -Recurse |            
                    Out-Zip -zipFile $moduleZip -commonRoot $tempModulePath |            
                    Out-Null            
                            
                            
                if (Test-Path $moduleZip) {            
                            
                    # If there's a module.zip, it might have the wrong ACLs to be served up.  So make it allow anonymous access            
                    $acl =             
                        Get-Acl -Path $moduleZip            
                    $everyone =            
                        New-Object Security.Principal.SecurityIdentifier ([Security.Principal.WellKnownSidType]"WorldSid", $null)            
                    $allowAnonymous =             
                        New-Object Security.AccessControl.FileSystemAccessrule ($everyone , "ReadAndExecute","allow")                             
                    $acl.AddAccessRule($allowAnonymous )            
                    Set-Acl -Path $moduleZip -AclObject $acl            
                                
                    Remove-Item $tempModulePath -Recurse -Force            
                }                            
            }            
        }                              
            
        Write-Progress "Creating Module Service" "Copying $($Module.name)"            
            
        $moduleDir = (Split-Path $Module.Path)            
            
        $moduleFiles=  Get-ChildItem -Path $moduleDir -Recurse -Force |            
            Where-Object {             
                            
                $dotdirs = @($_.FullName -split "\\" -like ".*")            
                            
                            
                -not $_.psIsContainer -and -not $dotDirs            
            
            }             
                    
        foreach ($moduleFile in $moduleFiles) {            
            $moduleFile |             
                Copy-Item -Destination {                            
                    $relativePath = $_.FullName.Replace("$moduleDir\", "")            
                    $newPath = "$outputDirectory\bin\$($Module.Name)\$relativePath"                            
                    $null = try {            
                        New-Item -ItemType File -Path "$outputDirectory\bin\$($Module.Name)\$relativePath" -Force            
                    } catch {            
                        # Swallowing the error from creating a new file avoids the case where a file could not be removed,            
                        # and thus a terminating error stops the pipeline            
                        $_            
                    }            
                    Write-Progress "Copying $($req.name)" "$newPath"            
                    $newPath                         
                } -Force #-ErrorAction SilentlyContinue            
        }            
                     
                        
            
            
            
            $modulePath =  if ($module.Path -like "*.psm1") {            
                $module.Path.Substring(0, $module.Path.Length - ".psm1".Length) + ".psd1"            
            } else {            
                            
                $module.Path            
            }            
                        
            $moduleFile = [IO.Path]::GetFileName($modulePath)            
            $importChunk = @"
`$searchDirectory = if (`$request -and `$request.Params -and `$request.Params['PATH_TRANSLATED']) {
    `$([IO.Path]::GetDirectoryName(`$Request['PATH_TRANSLATED']))
} else {
    `$Request | Out-HTML
    return
    ''
}

`$searchOrder = @()
while (`$searchDirectory) {
    if (-not "`$searchDirectory`") {
        break
    }
    Set-Location `$searchDirectory 
    `$searchOrder += "`$searchDirectory\bin\$($Module.Name)"
    if (([IO.Directory]::Exists("`$searchDirectory\bin\$($Module.Name)"))) {
        #ImportRequiredModulesFirst
        Import-Module "`$searchDirectory\bin\$($Module.Name)\$moduleFile"
        break
    }
    `$searchDirectory = `$searchDirectory | Split-Path   
}
"@            
            
        if ($Module.RequiredModules) {            
            $importRequired = foreach ($req in $Module.RequiredModules) {            
                # Make this callstack aware later            
            
                $moduleDir = (Split-Path $req.Path)            
            
                $moduleFiles =             
                Get-ChildItem -Path $moduleDir -Recurse -Force |                               
                    Where-Object {                             
                        $dotdirs = @($_.FullName -split "\\" -like ".*")            
                            
                            
                        -not $_.psIsContainer -and -not $dotDirs            
            
                    }             
                                
                foreach ($moduleFile in $moduleFiles) {             
                    $moduleFile |             
                        Copy-Item -Destination {            
                                    
                                    
                            $relativePath = $_.FullName.Replace("$moduleDir\", "")            
                            $newPath = "$outputDirectory\bin\$($req.Name)\$relativePath"                                    
                            $null = New-Item -ItemType File -Path "$outputDirectory\bin\$($req.Name)\$relativePath" -Force            
                            Write-Progress "Copying $($req.name)" "$newPath"            
                            $newPath             
                                    
                        } -Force #-ErrorAction SilentlyContinue            
                }            
                $reqDir = Split-Path $req.Path             
                "$(' ' * 8)Import-Module `"`$searchDirectory\bin\$($req.Name)\$($req.Name)`""            
            }                           
            $importChunk = $importChunk.Replace("#ImportRequiredModulesFirst",             
                $importRequired -join ([Environment]::NewLine))            
        }            
            
        $ModuleBranding =             
            if ($pipeworksManifest.Branding) {            
                if (-not "$($pipeworksManifest.Branding)".Trim()) {            
                    $pipeworksManifest.Branding            
                } else {            
                    ConvertFrom-Markdown $pipeworksManifest.Branding -ShowData                            
                }            
                            
            } elseif ($module.CompanyName -eq 'Start-Automating') {            
@"
<div style='text-align:right'>

<div style='font-size:.75em;text-align:right;'>
Provided By 
<a href='http://start-automating.com'>
<img src='http://StartAutomating.com/Assets/StartAutomating_100_Transparent.png' alt='Start-Automating' style='vertical-align:middle;width:60px;height:60px;border:0' />
</a>

</div>

<div style='font-size:.75em;text-align:right;'>
Powered With
<a href='http://powershellpipeworks.com'>
<img src='http://powershellpipeworks.com/assets/powershellpipeworks_150.png' alt='PowerShell Pipeworks' style='vertical-align:middle;width:60px;height:60px;border:0' />
</a>

</div>
</div>
"@            
            } else {            
@"
<div style='font-size:.75em;text-align:right'>
Powered With
<a href='http://powershellpipeworks.com'>
<img src='http://powershellpipeworks.com/assets/powershellpipeworks_150.png' alt='PowerShell Pipeworks' align='middle' style='width:60px;height:60px;border:0' />
</a>

</div>
"@            
            }             
            
        $initModuleDefaults = [ScriptBlock]::Create(@"
if (-not `$global:PipeworksManifest) {
    if (`$PipeworksManifest) {
        `$global:PipeworksManifest = `$PipeworksManifest
    } else {
        `$global:PipeworksManifest = @{}
    }
    
}
if (-not `$global:PipeworksManifest.Style) {
    `$global:PipeworksManifest.Style = @{
        Body = @{
            'Font-Family' = "'Segoe UI', 'Segoe UI Symbol', Helvetica, Arial, sans-serif"            
            'color' = '#0248B2'
            'background-color' = '#FFFFFF'
        }
        'a' = @{
            'color' = '#012456'
        }
    }
    
}

if (-not `$global:PipeworksManifest.Css) {
    `$global:PipeworksManifest.Css = @{}
}

if (-not `$global:SiteForegroundColor) {
    `$global:SiteForegroundColor = `$global:PipeworksManifest.Style.Body.Color
}

if (-not `$global:SiteBackgroundColor) {
    `$global:SiteBackgroundColor = `$global:PipeworksManifest.Style.Body.'background-color'
}

if (-not `$global:SiteLinkColor) {
    `$global:SiteLinkColor = `$global:PipeworksManifest.Style.a.Color
}

if (-not `$global:PipeworksManifest.ModuleTemplate ) {
    `$global:PipeworksManifest.ModuleTemplate = 'Module'    
}

if (-not `$global:PipeworksManifest.CommandTemplate) {
    `$global:PipeworksManifest.CommandTemplate = 'Command'    
}

if (-not `$global:PipeworksManifest.TopicTemplate) {
    `$global:PipeworksManifest.TopicTemplate = 'Topic'    
}

if (-not `$global:PipeworksManifest.TemplateFiles) {
    `$global:PipeworksManifest.TemplateFiles = @{}
    Get-ChildItem "Templates" |
        Where-Object { `$_.Extension -eq '.pswt' -or `$_.Extension -eq '.dwt' } |
        Foreach-Object {
            if (`$_.Extension -eq '.pswt') {
                `$TemplateName = `$_.Name.Substring(0,`$_.Name.Length - `$_.Extension.Length)
                `$TemplateText = [IO.File]::ReadAllText(`$_.FullName)
                `$global:PipeworksManifest.TemplateFiles.`$TemplateName = `$TemplateText
            }
        }
        
        
}

if (-not `$global:PipeworksManifest.UseJQueryUI -and -not `$global:PipeworksManifest.UseBootstrap) {
    #`$global:PipeworksManifest.UseJQueryUI = `$true
    `$global:PipeworksManifest.Css['PipeworksCss'] = 'css/$($module).css'
}

if (-not `$global:PipeworksManifest.Ajax) {
    `$global:PipeworksManifest.NoAjax = `$true
}
"@)                    
                    
        # Create the embed command.            
        $embedCommand = $importChunk            
        $embedCommand = $embedCommand + @"
`$embedCommandStartedAt = [DateTime]::Now
if (-not `$global:RealModule -or `$global:RealModule.Name -ne '$($module.Name)') {
`$realModule = `$module = Get-Module `"$($module.Name)`" | Select-Object -First 1
if (-not `$module) { `$response.Write(`$searchOrder -join '<BR/>'); `$response.Flush()  } 
`$moduleRoot = [IO.Path]::GetDirectoryName(`$module.Path)

`$global:RealModule = `$Module
`$global:PipeworksManifest = `$null
`$script:CachedTopics = @{}
`$script:CachedWalkthrus = @{}
`$cmdTabs = @{}
`$navBarData = @{}
`$navBarUrls = @{}
`$navBarOrder = @{}
`$coreAboutTopic = `$null
`$otherAboutTopics = `$null
`$walkThrus = @{}
`$aboutTopics = @()
`$aboutTopicsByName = @{}
`$allAboutFiles = `$null
`$canCacheGroups = `$false
} else {
    `$module = `$global:RealModule
}
`$moduleCommands = `$module.ExportedCommands.Values
`$moduleCompany = `$module.CompanyName
`$global:ModuleMaker = `$Module.CompanyName
`$pipeworksManifestPath = `$moduleRoot + '\' + "`$(`$module.Name).Pipeworks.psd1"
if (-not `$global:PipeworksManifest -and ([IO.File]::Exists(`$pipeworksManifestPath))) {
try {                     
    `$global:pipeworksManifest = & ([ScriptBlock]::Create(
        "data -SupportedCommand Add-Member, New-WebPage, New-Region, Write-CSS, Write-Ajax, Out-Html, Write-Link { `$(
            [ScriptBlock]::Create([IO.File]::ReadAllText(`$pipeworksManifestPath))                    
        )}"))            
} catch {
    Write-Error "Could not read pipeworks manifest" 
}                                                
}


`$timeSpentEmbeddingCommand = [DateTime]::Now - `$embedCommandStartedAt
$initModuleDefaults


`$script:CachedBrandingSlot = @'
$ModuleBranding
'@
"@            
                    
        $embedCommand = [ScriptBlock]::Create($embedCommand)              
        $moduleRoot = (Split-Path $module.Path)                    
            
            
        if (-not $PipeworksManifest.UseJQueryUI -and -not $PipeworksManifest.UseBootstrap) {            
            if (-not (Test-Path "$OutputDirectory\css\")) {            
                $null= New-Item -ItemType Directory -Path "$OutputDirectory\css\" -Force            
            }            
            
            $pipeworksRoot = $MyInvocation.MYCommand.ScriptBlock.Module | Split-Path            
            $lessCss = ([IO.File]::ReadAllText((Join-Path $pipeworksRoot "css\Pipeworks.less")))            
            
            
            $options = @{}            
            
            if ($pipeworksManifest.style.body.'background-color'){            
                $options['Background'] = $pipeworksManifest.style.body.'background-color'            
            }            
            if ($pipeworksManifest.style.body.'color'){            
                $options['Foreground'] = $pipeworksManifest.style.body.'color'            
            }            
            
            if ($pipeworksManifest.style.body.'font-Family') {            
                $options['fontFamily'] = $pipeworksManifest.style.body.'font-Family'            
            }            
            
            
            $myCss = Use-Less -LessCss $lessCss -Option $options            
            [IO.File]::WriteAllText("$OutputDirectory\css\$($module).css", $myCss)            
        }            
                    
        #region Check for the presence of directories, and put items within them into the manifest            
                    
                    
        # Pick out all possible cultures            
        $cultureNames = [Globalization.CultureInfo]::GetCultures([Globalization.CultureTypes]::AllCultures) |             
            Select-Object -ExpandProperty Name            
            
            
        $tokensInPages = New-Object Collections.ArrayList            
        # Pages fall back on culture            
        Write-Progress "Importing Pages" " "             
        $pagePaths  = @((Join-Path $moduleRoot "Pages"))            
            
            
        foreach ($cultureName in $cultureNames) {            
            if (-not $cultureName) { continue }             
            $pagePaths+= @((Join-Path $cultureName "Pages"))            
        }            
            
            
            
                    
                   
            
        foreach ($pagePath in $pagePaths) {            
            if (Test-Path $pagePath) {            
                Get-ChildItem $pagePath -Recurse |            
                    Where-Object {                                    
                        (-not $_.PSIsContainer) -and            
                        '.htm', '.html', '.ashx','.aspx',            
                            '.jpg', '.gif', '.jpeg', '.js', '.css',             
                            '.ico',            
                            '.png', '.mpeg','.mp4',              
                            '.mp3', '.wav', '.pspage', '.docx', '.pptx', '.xlsx', '.md', '.psmd', '.pdf'            
                            '.pspg', '.ps1' -contains $_.Extension            
                    } |             
                    ForEach-Object -Process {            
                        if ($_.Extension -ne '.ps1') {            
                            # These are simple, just make the page            
                            if ($_.Extension -ne '.pspage' -and             
                                $_.Extension -ne '.html' -and             
                                $_.Extension -ne '.psmd' -and             
                                $_.Extension -ne '.md') {            
            
                                $bytes = try { [IO.File]::ReadAllBytes($_.Fullname) } catch { }            
                                if ($bytes) {            
                                    $pipeworksManifest.Pages[$_.Fullname.Replace(($module | Split-Path), "").Replace("Pages\","").TrimStart("\")] = $bytes            
                                }            
            
                            } else {            
                                $text = [IO.File]::ReadAllText($_.Fullname)            
                                $pipeworksManifest.Pages[$_.Fullname.Replace(($module | Split-Path), "").Replace("Pages\","").TrimStart("\")] = $text             
                                                
                                            
            
                                            
                            }            
                                        
                        } else {            
                                        
                            # Embed the ps1 file contents within a <| |>, but escape the <| |> contained within            
                            $fileContents = "$([IO.File]::ReadAllText($_.Fullname))"            
                            if ($fileContents) {            
                                $sb = [ScriptBlock]::Create($fileContents)                                            
                                $t = [Management.Automation.PSParser]::Tokenize($sb, [ref]$null)            
                                $null = $tokensInPages.AddRange($t)            
                            }            
                            $fileContents = $fileContents.Replace("<|", "<|").Replace("|>", "|>")            
                            $pipeworksManifest.Pages[($_.Fullname.Replace(($module | Split-Path), "").Replace("Pages\","")).Replace(".ps1", ".pspage").TrimStart("\")] = "<| $fileContents
|>"            
                                        
                                        
                        }            
                                    
                    }            
                                
            }            
        }            
                    
        # Posts also fall back on culture            
        $pagePaths  = (Join-Path $moduleRoot "Posts"),                        
            (Join-Path $moduleRoot "Blog")            
                                    
        foreach ($cultureName in $cultureNames) {            
            if (-not $cultureName) { continue }             
            $pagePaths+= @((Join-Path $cultureName "Blog"))            
            $pagePaths+= @((Join-Path $cultureName "Posts"))            
        }            
            
            
        foreach ($pagePath in $pagePaths) {            
            if (Test-Path $pagePath) {            
                Get-ChildItem $pagePath |            
                    Where-Object {                                    
                        $_.Name -like "*.post.psd1" -or            
                        $_.Name -like "*.pspost" -or            
                        $_.Name -like "*.html"            
                    } |             
                    ForEach-Object -Begin {            
                        if (-not $PipeworksManifest.Posts) {            
                            $PipeworksManifest.Posts = @{}            
                        }            
                    } -Process {            
                        $pipeworksManifest.Posts[$_.Name.Replace(".post.psd1","").Replace(".pspost","").Replace(".html","")] = ".\$($_.Directory.Name)\$($_.Name)"            
                    }            
                                
            }            
        }            
            
            
            
                    
        $jsPaths = (Join-Path $moduleRoot "JS"),                        
            (Join-Path $moduleRoot "Javascript")            
                    
        foreach ($cultureName in $cultureNames) {            
            if (-not $cultureName) { continue }             
            $jsPaths += @((Join-Path $cultureName "JS"))            
            $jsPaths += @((Join-Path $cultureName "JavaScript"))            
        }            
        foreach ($jsPath in $jsPaths) {            
            if (Test-Path $jsPath) {            
                Get-ChildItem $jsPath |            
                    Where-Object {                                    
                        $_.Name -like "*.js"            
                    } |             
                    ForEach-Object -Process {                                                        
                        if (-not $_.psiscontainer) {                                                    
                            $pipeworksManifest.Javascript[$_.Fullname.Replace(($module | Split-Path), "")] = [IO.File]::ReadAllBytes($_.Fullname)            
                        }            
                    }            
                                
            }            
        }            
                    
        $cssPaths = @(Join-Path $moduleRoot "CSS")            
            
        foreach ($cultureName in $cultureNames) {            
            if (-not $cultureName) { continue }             
            $cssPaths += @((Join-Path $cultureName "CSS"))                        
        }            
            
        foreach ($cssPath in $cssPaths) {            
            if (Test-Path $cssPath) {            
                Get-ChildItem $cssPath -Recurse |            
                    ForEach-Object -Process {                                                        
                        if (-not $_.psiscontainer) {                                                    
                            $pipeworksManifest.CssFile[$_.Fullname.Replace(($module | Split-Path), "")] = [IO.File]::ReadAllBytes($_.Fullname)            
                        }            
                    }            
                                
            }            
        }            
                    
        $pipeworksRoot = Get-Module Pipeworks | Split-Path            
                    
        $assetPaths = (Join-Path $moduleRoot "Asset"),                        
            (Join-Path $moduleRoot "Assets"),            
            (Join-Path $moduleRoot "Resource"),            
            (Join-Path $moduleRoot "Resources"),            
            (Join-Path $moduleRoot "Image"),            
            (Join-Path $moduleRoot "Images"),            
            (Join-Path $moduleRoot "IMG"),            
            (Join-Path $pipeworksRoot "Template"),            
            (Join-Path $pipeworksRoot "Templates"),            
            (Join-Path $moduleRoot "Template"),            
            (Join-Path $moduleRoot "Templates")            
                        
                    
        foreach ($cultureName in $cultureNames) {            
            if (-not $cultureName) { continue }             
            $assetPaths  += @((Join-Path $cultureName "Asset"))                                    
            $assetPaths  += @((Join-Path $cultureName "Assets"))                       
            $assetPaths  += @((Join-Path $cultureName "Resource"))                        
            $assetPaths  += @((Join-Path $cultureName "Resources"))                        
            $assetPaths  += @((Join-Path $cultureName "Image"))                        
            $assetPaths  += @((Join-Path $cultureName "Images"))                        
            $assetPaths  += @((Join-Path $cultureName "IMG"))                        
        }            
            
            
        foreach ($assetPath in $assetPaths) {            
            if (Test-Path $assetPath ) {            
                Get-ChildItem $assetPath  -Recurse |            
                    ForEach-Object -Process {                 
                        $fileInfo  = $_            
                        if (-not $_.psiscontainer) {                                                                     
                            $pipeworksManifest.AssetFile[$_.Fullname.Replace($moduleRoot, "").Replace($pipeworksRoot, "")] = [IO.File]::ReadAllBytes($_.Fullname)            
                        }            
                    }            
                                
            }            
        }            
        #endregion Check for the presence of directories, and put items within them into the manifest            
                    
        if ($pipeworksManifest.UseJQuery -and             
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*jquery.min.js*")) {            
            $latestJQuery =             
                Get-Web -Url "http://jquery.com/download/" -Tag 'a' |             
                Where-Object {$_.Xml.Href -like "*.min.js" } |             
                Select-Object -First 1 |             
                ForEach-Object  { $_.Xml.Href } |             
                Get-Web -Url {$_ } -UseWebRequest -AsByte            
            
            
            $jQueryFile = New-item -ItemType File -Path $moduleRoot\JS\jquery.min.js -Force            
            
            [IO.File]::WriteAllBytes($jQueryFile.FullName, $latestJQuery)            
                        
            
            $pipeworksManifest.Javascript["JS\jquery.min.js"] = $latestJQuery            
        }            
            
        if ($PipeworksManifest.UseTableSorter -and             
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*tablesorter*")) {            
                $tableSorterFile = New-item -ItemType File -Path $moduleRoot\JS\tablesorter.min.js -Force            
                Get-Web http://tablesorter.com/__jquery.tablesorter.min.js |            
                    Set-Content $moduleRoot\JS\tablesorter.min.js            
            
            $pipeworksManifest.Javascript["JS\tablesorter.min.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\tablesorter.min.js")                            
        }            
            
        if (($pipeworksManifest.UseRaphael  -or $pipeworksManifest.UseGRaphael )-and             
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*raphael*")) {            
                        
            $raphael = New-item -ItemType File -Path $moduleRoot\JS\raphael-min.js -Force            
            Get-Web -Url http://raphaeljs.com/raphael.js -UseWebRequest -HideProgress |            
                Set-Content $raphael.Fullname -Encoding UTF8                            
            
            $pipeworksManifest.Javascript["JS\raphael-min.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\raphael-min.js")                            
        }            
            
        if ($pipeworksManifest.UseGRaphael -and             
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*g.raphael*")) {            
                        
            $raphael = New-item -ItemType File -Path $moduleRoot\JS\g.raphael.js -Force            
            Get-Web -url http://g.raphaeljs.com/g.raphael.js -UseWebRequest -HideProgress |            
                Set-Content $raphael.Fullname                            
            
            
            $raphaelBar = New-item -ItemType File -Path $moduleRoot\JS\g.bar.js -Force            
            Get-Web -url http://g.raphaeljs.com/g.bar.js -UseWebRequest -HideProgress |            
                Set-Content $raphaelBar.Fullname                            
            
            $raphaelLine = New-item -ItemType File -Path $moduleRoot\JS\g.line.js -Force            
            Get-Web -url http://g.raphaeljs.com/g.line.js -UseWebRequest -HideProgress |            
                Set-Content $raphaelLine.Fullname                            
            
            $raphaelPie = New-item -ItemType File -Path $moduleRoot\JS\g.pie.js -Force            
            Get-Web -url http://g.raphaeljs.com/g.pie.js -UseWebRequest -HideProgress|            
                Set-Content $raphaelPie.Fullname                            
            
            $pipeworksManifest.Javascript["JS\g.raphael.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\g.raphael.js")                            
            $pipeworksManifest.Javascript["JS\g.line.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\g.line.js")                            
            $pipeworksManifest.Javascript["JS\g.pie.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\g.pie.js")                            
            $pipeworksManifest.Javascript["JS\g.bar.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\g.bar.js")                            
        }            
            
            
        if (($pipeworksManifest.UseShiv -or $pipeworksManifest.UseShiv) -and            
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*shiv*")) {            
            $shiv = @{            
                "https://github.com/aFarkas/html5shiv/blob/master/dist/html5shiv.js?raw=true" = "JS\html5shiv.js"            
            }            
            
                        
            $pipeworksManifest.Download+=$shiv            
        }            
            
            
                    
            
        if (($pipeworksManifest.Bootstrap -or $pipeworksManifest.UseBootstrap) -and            
            -not ($pipeworksManifest.'JavaScript'.Keys -like "*bootstrap*")) {            
                        
                        
            $textColor = if ($pipeworksManifest.Style.Body.color) {            
                $pipeworksManifest.Style.Body.color            
            } else {            
                "#0248b2"            
            }            
            
            
            $linkColor =  if ($pipeworksManifest.Style.a.color) {            
                $pipeworksManifest.Style.a.color            
            } else {            
                "#0248b2"            
            }             
            
            $backgroundColor = if ($pipeworksManifest.Style.body.'background-color') {            
                $pipeworksManifest.Style.body.'background-color'            
            } else {            
                "#ffffff"            
            }            
                        
                        
            $fontFamily = if ($pipeworksManifest.Style.body.'font-family') {            
                $pipeworksManifest.Style.body.'font-family'            
            } else {            
                "'Segoe UI', Helvetica, Arial, sans-serif"            
            }             
            
            $fontSize = if ($pipeworksManifest.Style.body.'font-size') {            
                $pipeworksManifest.Style.body.'font-size'            
            } else {            
                '15px'            
            }            
                        
            $lineHeight = if ($pipeworksManifest.Style.body.'line-height') {            
                $pipeworksManifest.Style.body.'line-height'            
            } else {            
                '21px'            
            }             
            
            # Download a customized bootstrap, containing their core color scheme.            
            $r =            
                Get-web -Url "http://bootstrap.herokuapp.com/" -Method POST -Parameter @{            
                    js = '["bootstrap-transition.js","bootstrap-modal.js","bootstrap-dropdown.js","bootstrap-scrollspy.js","bootstrap-tab.js","bootstrap-tooltip.js","bootstrap-popover.js","bootstrap-affix.js","bootstrap-alert.js","bootstrap-button.js","bootstrap-collapse.js","bootstrap-carousel.js","bootstrap-typeahead.js"]'            
                    css= '["reset.less","scaffolding.less","grid.less","layouts.less","type.less","code.less","labels-badges.less","tables.less","forms.less","buttons.less","sprites.less","button-groups.less","navs.less","navbar.less","breadcrumbs.less","pagination.less","pager.less","thumbnails.less","alerts.less","progress-bars.less","hero-unit.less","media.less","tooltip.less","popovers.less","modals.less","dropdowns.less","accordion.less","carousel.less","wells.less","close.less","utilities.less","component-animations.less","responsive-utilities.less","responsive-767px-max.less","responsive-768px-979px.less","responsive-1200px-min.less","responsive-navbar.less"]'            
                    vars="{
`"@bodyBackground`":`"$backgroundColor`",
`"@inputBackground`":`"$backgroundColor`",
`"@inputText`":`"$fgColor`",
`"@tableBackground`":`"$backgroundColor`",
`"@heroUnitBackground`":`"$backgroundColor`",
`"@heroUnitHeadingColor`":`"$textColor`",
`"@heroLeadColor`":`"$textColor`",
`"@infoBackground`":`"$backgroundColor`",
`"@infoText`":`"$textColor`",
`"@placeHolderText`":`"$textColor`",
`"@headingsColor`":`"$textColor`",
`"@tableBackgroundAccount`":`"$backgroundColor`",
`"@tableBackgroundHover`":`"$textColor`",
`"@navbarBackground`":`"$backgroundColor`",
`"@navbarBackgroundHighlight`":`"$backgroundColor`",
`"@navbarSearchBackground`":`"$backgroundColor`",
`"@navbarLinkBackgroundActive`":`"$textColor`",
`"@navbarSearchBackgroundFocus`":`"$textColor`",
`"@navbarText`":`"$textColor`",
`"@navbarBrandColor`":`"$textColor`",
`"@navbarLinkColor`":`"$linkColor`",
`"@navbarLinkColorHover`":`"$textColor`",
`"@navbarLinkColorActive`":`"$textColor`",
`"@dropDownBackground`":`"$backgroundColor`",
`"@textColor`":`"$textColor`",
`"@dropdownBackground`":`"$backgroundColor`",
`"@dropdownLinkColor`":`"$linkColor`",
`"@dropdownLinkColorHover`":`"$backgroundColor`",
`"@dropdownLinkBackgroundHover`":`"$linkColor`",
`"@btnPrimaryBackground`":`"$LinkColor`",
`"@btnPrimaryBackgroundHighlight`":`"$backgroundColor`",
`"@formActionsBackground`":`"$backgroundColor`",
`"@linkColor`":`"$linkColor`",
`"@sansFontFamily`":`"$fontFamily`",
`"@monoFontFamily`":`"Menlo, Monaco, 'Consolas'`",
`"@baseFontSize`":`"$FontSize`",
`"@baseLineHeight`":`"$LineHeight`"}"            
                    img='["glyphicons-halflings.png","glyphicons-halflings-white.png"]'            
} -AsByte -UseWebRequest            
            
            
            [IO.File]::WriteAllBytes("$moduleRoot\BootStrap.zip", $r)            
            Expand-Zip -ZipPath "$moduleRoot\BootStrap.zip" -OutputPath "$moduleRoot"            
            Remove-Item "$moduleRoot\bootstrap.zip"                                                
            
            
            # Replace cases of the input foreground with the real text color            
            if ($backgroundColor -eq '#555555') {            
                Write-Warning "The specific background color of #555555 will be replaced by the textColor: $textColor, because Bootstrap's customization engine doesn't allow customization of the input text color."            
            }            
            
            $bsCss = [IO.File]::ReadAllText("$ModuleRoot\css\bootstrap.css")            
            [IO.File]::WriteAllText("$ModuleRoot\css\bootstrap.css", $bsCss.Replace('#555555', $textColor))            
            
            $latestJQuery =             
                Get-Web -Url "http://jquery.com/download/" -Tag 'a' |             
                Where-Object {$_.Xml.Href -like "*.min.js" } |             
                Select-Object -First 1 |             
                ForEach-Object  { $_.Xml.Href } |             
                Get-Web -Url {$_ } -UseWebRequest -AsByte            
            
            
            $jQueryFile = New-item -ItemType File -Path $moduleRoot\JS\jquery.min.js -Force            
            
            [IO.File]::WriteAllBytes($jQueryFile.FullName, $latestJQuery)            
                        
            
            $pipeworksManifest.Javascript["JS\jquery.min.js"] = $latestJQuery            
            
            
            $pipeworksManifest.Javascript["JS\bootstrap.min.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\bootstrap.min.js")                            
            $pipeworksManifest.Javascript["JS\bootstrap.js"] = [IO.File]::ReadAllBytes("$moduleRoot\JS\bootstrap.js")                            
            $pipeworksManifest.Javascript["CSS\bootstrap.css"] = [IO.File]::ReadAllBytes("$moduleRoot\CSS\bootstrap.css")                            
            $pipeworksManifest.Javascript["CSS\bootstrap.min.css"] = [IO.File]::ReadAllBytes("$moduleRoot\CSS\bootstrap.min.css")                            
            $pipeworksManifest.Javascript["IMG\glyphicons-halflings-white.png"] = [IO.File]::ReadAllBytes("$moduleRoot\IMG\glyphicons-halflings-white.png")                            
            $pipeworksManifest.Javascript["IMG\glyphicons-halflings.png"] = [IO.File]::ReadAllBytes("$moduleRoot\IMG\glyphicons-halflings.png")                            
        }            
            
            
            
        #region GitIt            
        if ($pipeworksManifest.GitIt) {                        
            
            if (-not $gitIt) {            
            
            }            
            
            
            foreach ($git in $pipeworksManifest.GitIt) {            
                if ($git -is [Hashtable]) {            
                    foreach ($kv in $git.GetEnumerator()) {            
                        $gitAt = $kv.Key.Tostring().Replace("\","/")            
                        if ($gitAt -notlike "*/*/*") {            
                            Write-Error "Each key in $GitAt must include author and project"            
                            return            
                        }            
            
            
                        if ($gitAt.EndsWith('*')) {            
                            $treeUrl = "https://github.com/$($gitAt.TrimEnd('*/'))/tree"            
                            $gitHtml = Get-Web -Url $treeUrl  -UseWebRequest            
                        } else {            
                            $gitBits = $gitAt -split '\/'            
                            $gitUrl = 'https://raw.github.com/' +             
                                $gitBits[0] +             
                                '/' +             
                                $gitBits[1] +             
                                '/master/' +             
                                ($gitBits[2..($gitBits.Length - 1)] -join '/')            
                            $gitTo = $kv.Value.ToString().Replace('/', '\')            
                            $downloadedfile = New-item -ItemType File -Path "${moduleRoot}/$($gitTo.Replace('\', '/').TrimStart('/'))" -Force                
                            $content = Get-Web -Url $gitUrl -UseWebRequest -AsByte            
            
                            if (-not $content) {            
                                Write-Error "$GitAt not on GitHub"            
                                continue            
                            }            
                            [IO.File]::WriteAllBytes($downloadedfile.Fullname, $content)                            
                           
                            $pipeworksManifest.AssetFile[$kv.Value] = [IO.File]::ReadAllBytes($downloadedfile.Fullname)            
                        }            
                                    
                                    
                            
                                    
                    }            
                }            
            }            
            
        }            
            
                            
        #endregion GitIt            
            
        #region Download            
        if ($pipeworksManifest.Download -and $pipeworksManifest.Download -as [Hashtable]) {            
            foreach ($kv in $pipeworksManifest.Download.GetEnumerator()) {            
                if (-not $kv.Key) { continue }             
                $downloadedfile = New-item -ItemType File -Path "${moduleRoot}/$($kv.value)" -Force            
                $content = $null            
                            
                $content = Get-Web -Url $kv.Key -AsByte -UseWebRequest            
                if ($kv.key -like "*.min.js") {            
                    $null = $content             
                }            
                if (-not $content) {            
                    continue            
                }            
                [IO.File]::WriteAllBytes($downloadedfile.Fullname, $content)                            
                           
                $pipeworksManifest.AssetFile[$kv.Value] = [IO.File]::ReadAllBytes("${moduleRoot}/$($kv.Value.ToString().Replace('\','/'))")            
            }            
        }            
                    
        #endregion Download            
                            
        #region Embedded Javascript, CSS, and Assets            
                    
        foreach ($directlyEmbeddedFileTable in 'Javascript', 'CssFile', 'AssetFile') {            
            foreach ($fileAndData in $pipeworksManifest.$directlyEmbeddedFileTable.GetEnumerator()) {            
                if (-not $fileAndData.Key) { continue }             
                try {            
                $null = New-Item "$outputDirectory\$($fileAndData.Key)" -ItemType File -Force            
                [IO.File]::WriteAllBytes("$outputDirectory\$($fileAndData.Key)", $fileAndData.Value)            
                } catch {            
                    $null = $_            
                }            
            }            
        }            
                    
                    
        #endregion            
                    
                    
        #region Object Pages            
        if ($pipeworksManifest.ObjectPages) {            
            foreach ($objectPageInfo in $pipeworksManifest.ObjectPages.GetEnumerator()) {            
                $pagename = $objectPageInfo.Key            
                $value = $objectPageInfo.Value                            
                $webOBjectPage = @"
`$storageAccount  = Get-WebConfigurationSetting -Setting `$pipeworksManifest.Table.StorageAccountSetting 
`$storageKey= Get-WebConfigurationSetting -Setting `$pipeworksManifest.Table.StorageKeySetting 
`$part, `$row  = '$($objectPageInfo.Value.Id)' -split '\:'
`$lMargin = '$marginPercentLeftString'
`$rMargin = '$marginPercentRightString'
`$pageName = '$($value.Title)'
"@ + {            
            
if (-not $session["ObjectPage$($PageName)"]) {            
    $session["ObjectPage$($PageName)"] =             
        Show-WebObject -StorageAccount $storageAccount -StorageKey $storageKey -Table $pipeworksManifest.Table.Name -Part $part -Row $row |            
        New-Region -Style @{            
            'Margin-Left' = $lMargin            
            'Margin-Right' = $rMargin            
            'Margin-Top' = '2%'            
        } |            
        New-WebPage  -Title $pageName            
                    
}            
            
$session["ObjectPage$($PageName)"] | Out-HTML -WriteResponse            
            
                }                            
                $pipeworksManifest.Pages["$pagename.pspage"] = "<|
$webObjectPage
|>"                                                    
            }            
        }            
                    
                    
        #endregion Object Pages            
                    
                    
        #region Embed RSS Icon            
        [IO.File]::WriteAllBytes("$outputDirectory\rss.png",             
            [Convert]::FromBase64String("                    
            iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABGdBTUEAAK/
            INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAA
            JDSURBVHjajJJNSBRhGMd/887MzrQxRSLbFuYhoUhEKsMo8paHUKFLdBDrU
            Idunvq4RdClOq8Hb0FBSAVCUhFR1CGD/MrIJYqs1kLUXd382N356plZFOrU
            O/MMz/vO83+e93n+f+1zF+kQBoOQNLBJg0CTj7z/rvWjGbEOIwKp9O7Wkht
            Qc/wMWrlIkP8Kc1lMS8eyFHpkpo5SgWCCVO7Z5JARhuz1Qg29fh87u6/9VW
            L1/SPc4Qy6n8c0FehiXin6dcCQaylDMhqGz8ydS2hKkmxNkWxowWnuBLHK6
            G2C8X6UJkBlxUmNqLYyNbzF74QLDrgFgh9LLE0NsPKxjW1Hz2EdPIubsOFd
            H2HgbwAlC4S19dT13o+3pS+vcSfvUcq9YnbwA6muW9hNpym/FWBxfh0CZkK
            GkPBZeJFhcWQAu6EN52QGZ/8prEKW+cdXq0039UiLXhUYzdjebOJQQI30UX
            p6mZn+Dtam32Afu0iyrgUvN0r+ZQbr8HncSpUVJfwRhBWC0hyGV8CxXBL5S
            WYf9sYBidYLIG2V87/ifVjTWAX6AlxeK2C0X8e58hOr/Qa2XJ3iLMWxB1h7
            2tHs7bgryzHAN2o2gJorTrLxRHVazd0o4TXiyV2Yjs90uzauGvvppmqcLjw
            mbZ3V7BO2HOrBnbgrQRqWUgTZ5+Snx4WeKfzCCrmb3axODKNH+vvUyWjqyK
            4DiKQ0eXSpFsgVvLJQWpH+xSpr4otg/HI0TR/t97cxTUS+QxIMRTLi/9ZYJ
            PI/AgwAoc3W7ZrqR2IAAAAASUVORK5CYII="))            
        #endregion Embed RSS Icon            
            
        #region HTML Based Blog            
                    
        # The value of the post field can either be a hashtable containing these items, or a relative path to a .post.psd1 containing            
        # these items.            
        $hasPosts = $false            
        if ($PipeworksManifest.Posts -and             
            $PipeworksManifest.Posts.GetType() -eq [Hashtable] ) {            
            if (-not $hasPosts) {                            
                            
            }            
            $hasPosts = $true            
                        
            $getPostFileNames = {            
                param($post)            
                            
                $replacedPostTitle = $post.Title.Replace("|", " ").Replace("/", "-").Replace("\","-").Replace(":","-").Replace("!", "-").Replace(";", "-").Replace(" ", "_").Replace("@","at").Replace(",", " ")            
                New-Object PSObject -Property @{            
                    safeFileName = $replacedPostTitle + ".simple.html"            
                    postFileName = $replacedPostTitle  + ".post.html"            
                    postDirectory = $replacedPostTitle             
                    postRssFileName = $replacedPostTitle  + ".xml"            
                    datePublishedFileName = try { ([DateTime]($post.DatePublished)).ToString("u").Replace(" ", "_").Replace(":", "-") + ".simple.html"} catch {}            
                }            
            }            
                                                            
                        
            # Get the command now so we can remove anything else from the pagecontent hashtable later            
            $rssItem = Get-Command New-RssItem | Select-Object -First 1             
            $moduleRssName = $moduleBlogTitle.Replace("|", " ").Replace("/", "-").Replace("\","-").Replace(":","-").Replace("!", "-").Replace(";", "-").Replace(" ", "_").Replace("@","at").Replace(",", "_")            
            $allPosts =             
                foreach ($postAndContent in $PipeworksManifest.Posts.GetEnumerator()) {            
                                
                    $pageName = $postAndContent.Key             
                    $pageContent = $postAndContent.Value            
                                    
                    $safePageName = $pageName.Replace("|", " ").Replace("/", "-").Replace("\","-").Replace(":","-").Replace("!", "-").Replace(";", "-").Replace(" ", "_").Replace("@","at").Replace(",", "_")            
                    if ($pageContent -like ".\*") {            
                        # Relative Path, try loading a post file            
                        $pagePath = Join-Path $moduleRoot $pageContent.Substring(2)            
                        if ($pagePath -notlike "*.htm*" -and (Test-Path $pagePath)) {            
                            try {            
                                $potentialPagecontent = [IO.File]::ReadAllText($pagePath)            
                                $potentialPagecontentAsScriptBlock = [ScriptBlock]::Create($potentialPageContent)            
                                $potentialPagecontentAsDataScriptBlock = [ScriptBlock]::Create("data { $potentialPagecontentAsScriptBlock }")            
                                $pageContent = & $potentialPagecontentAsDataScriptBlock             
                            } catch {            
                                $_ | Write-Error            
                            }            
                        } elseif (Test-Path $pagePath) {            
                            # Page is HTML.            
                            $pageContent = [IO.File]::ReadAllText($pagePath)            
                                        
                            # Try quickly to get the microdata from the HTML.            
                            $foundMicroData =             
                                Get-Web -Html $pageContent -ItemType http://schema.org/BlogPosting -ErrorAction SilentlyContinue |             
                                Select-Object -First 1             
                                        
                            if ($foundMicrodata) {            
                                $pageContent = @{            
                                    Title = $foundMicrodata.Name            
                                    Description = $foundMicrodata.ArticleText            
                                    DatePublished = $foundMicrodata.DatePublished            
                                    Category = $foundMicrodata.Keyword            
                                    Author = $foundMicrodata.author            
                                    Link = $foundMicrodata.url            
                                }            
                            }            
                                        
                        }            
                    }             
                                        
                    $feedContent =                                     
                        if ($pageContent -is [Hashtable]) {               
                            if (-not $pageContent.Description -and -not $pageContent.html) {                                    
                                continue            
                            }            
                                        
                            if ($pageContent.Html) {            
                                $pageContent.Description = $pageContent.html            
                            }                                                                             
                                        
                            if (-not $pageContent.Title) {            
                                $pageContent.Title = $pageName            
                            }                                                                                                
                                        
                            foreach ($key in @($pageContent.Keys)) {            
                                if ($rssItem.Parameters.Keys -notcontains $key) {            
                                    $pageContent.Remove($key)            
                                }            
                            }            
                                        
                            $fileNames = & $getPostFileNames $pageContent            
                            $pageContent.Link = $filenames.postFileName            
                            New-RssItem @pageContent             
                        } else {            
                            Write-Debug "$safePageName could not be processed"            
                            continue            
                        }                                                           
                                                
                    $safePageName = $fileNames.postFileName            
                    $xmlDescription = $pageContent.Description             
                                
                    if (-not $pageContent.Description) { continue }            
                                
                    $feedContent |             
                        Out-RssFeed -Title $pageName -Description $xmlDescription -Link "${safePageName}.Post.xml"|             
                        Set-Content "$outputDirectory\${safePageName}.Post.xml"                                                    
            
                    $pageWidgetContent = $ExecutionContext.SessionState.InvokeCommand.ExpandString($blogPostTemplate)            
                    $feedHtml = New-RssItem @pageContent -AsHtml            
                    # Create an article page            
                    New-WebPage -UseJQueryUI -Title $pageContent.Title -PageBody (            
                        New-Region -Container 'Headerbar' -Border '0px' -Style @{            
                            "margin-top"="1%"            
                            'margin-left' = $MarginPercentLeftString            
                            'margin-right' = $MarginPercentRightString            
                        } -Content "        
    <h1 class='blogTitle'><a href='$moduleBlogLink'>$moduleBlogTitle</a></h1>
    <h4 class='blogDescription'>$moduleBlogDescription</h4>"), (            
                        New-Region -Style @{            
                            'margin-left' = $MarginPercentLeftString            
                            'margin-right' = $MarginPercentRightString            
                            'margin-top' = '10px'               
                            'border' = '0px'             
                        } -AsWidget -ItemType http://schema.org/BlogPosting -Content $feedHtml              
                        ) |             
    Set-Content "$outputDirectory\${safePageName}" -PassThru |            
    Set-Content "$outputDirectory\$($safePageName.Replace('.post.html', '.html'))"            
                                                    
                    # Emit the page content, so the whole feed can be generated            
                    $feedContent            
                }            
                        
                        
            if ($allPosts) {             
                $moduleRss = $allPosts  |                                     
                    Out-RssFeed -Title $moduleBlogTitle -Description $module.Description -Link "\$($module.Name).xml" |            
                    Set-Content "$outputDirectory\$moduleRssName.xml" -PassThru |            
                    Set-Content "$outputDirectory\Rss.xml" -PassThru            
            } else {            
                $moduleRss = @()            
            }            
                            
            $categories = $moduleRss |             
                Select-Xml //item/category |             
                Group-Object { $_.Node.'#text'}                            
                            
            $postsByYear = $moduleRss |             
                Select-Xml //item/pubDate |             
                Group-Object { ([DateTime]$_.Node.'#text').Year }                            
                            
            $postsByYearAndMonth = $moduleRss |             
                Select-Xml //item/pubDate |                             
                Group-Object {             
                    ([DateTime]$_.Node.'#text').ToString("y")            
                }            
                            
            $allGroups = @($categories) + $postsByYear + $postsByYearAndMonth            
                         
            foreach ($groupPage in $allGroups) {            
                if (-not $groupPage) { continue }             
                $catLink = $groupPage.Name.Replace("|", " ").Replace("/", "-").Replace("\","-").Replace(":","-").Replace("!", "-").Replace(";", "-").Replace(" ", "_").Replace("@","at").Replace(",", "_") + ".posts.html"            
                $groupPage.Group |                                 
                    ForEach-Object {             
                        $_.Node.SelectSingleNode("..")            
                    } |             
                    Sort-Object -Descending { ([datetime]$_.pubdate).'#text' } |             
                    Select-Object title, creator, pubdate, link, category, @{            
                        Name='Description';            
                        Expression={            
                            $_.Description.InnerXml.Substring("<![CDATA[".Length).TrimEnd("]]>")            
                        }            
                    } |             
                    New-RssItem -AsHTML |            
                    New-Region -ItemType http://schema.org/BlogPosting -AsWidget -Style @{            
                        'margin-left' = $MarginPercentLeftString            
                        'margin-right' = $MarginPercentRightString            
                        'margin-top' = '10px'               
                        'border' = '0px'             
                    }|            
                    ForEach-Object -Begin {            
                        New-Region -Container 'Headerbar' -Border '0px' -Style @{            
                            "margin-top"="1%"            
                            'margin-left' = $MarginPercentLeftString            
                            'margin-right' = $MarginPercentRightString            
                        } -Content "        
    <h1 class='blogTitle'><a href='$moduleBlogLink'>$moduleBlogTitle</a></h1>
    <p class='blogDescription'>$moduleBlogDescription</p>
    <h2 class='blogCategoryHeader' style='text-align:right'>$($groupPage.Name)</h2>
    "                                    
                    } -Process {            
                        $_            
                    } |             
                    New-WebPage -Title "$moduleBlogTitle - $($groupPage.Name)" -Rss @{"Start-Scripting"= "$moduleRssName.xml"} |            
                    Set-Content "$outputDirectory/$catLink"            
                            
                                                
            }            
        }                    
                    
        #endregion HTML Based Blog            
                    
                    
        $embedUnpackItem = "`$unpackItem = {$unpackItem
        }"            
                    
        # This seems counter-intuitive, and so bears a little explanation.            
        # This makes schematics have a natural priority order according to how they were specified            
        # That is, if you have multiple schematics, you want the first item to be the most important            
        # (and it's default page to be the default page).  If it was processed first, this wouldn't happen.            
        # If this was sorted, also no.  So, it's flipped.            
                    
        if ($psboundParameters.useSchematic) {            
            $useSchematic = $useSchematic[-1..(0 -$useSchematic.Length)]            
        }            
                    
                        
        foreach ($schematic in $useSchematic) {            
            $moduleList = (@($realModule) + @($module.RequiredModules) + @(Get-Module Pipeworks))            
            $moduleList  =  $moduleList  | Select-Object -Unique            
            foreach ($moduleInfo in $moduleList  ) {            
                $thisModuleDir = $moduleInfo | Split-Path            
                $schematics = "$thisModuleDir\Schematics\$Schematic\" | Get-ChildItem -Filter "Use-*Schematic.ps1" -ErrorAction SilentlyContinue            
                foreach ($s in $schematics) {            
                    if (-not $s) { continue }             
                    if (-not $pipeworksManifest.$Schematic) {            
                        Write-Error "Missing $schematic schematic parameters for $($module.Name)"            
                        continue            
                    }            
                    $pagesToMerge = & {                                        
                        . $s.Fullname            
                        $schematicCmd =             
                            Get-Command -Verb Use -Noun *Schematic |             
                            Where-Object {$_.Name -ne 'Use-Schematic'} |             
                            Select-Object -First 1             
                                    
                        $schematicParameters = @{            
                            Parameter = $pipeworksManifest.$schematic            
                            Manifest = $PipeworksManifest             
                            DeploymentDirectory = $outputDirectory             
                            inputDirectory = $moduleRoot            
                        }            
                        if ($schematicCmd.Name) {            
                            & $schematicCmd @schematicParameters            
                            Remove-Item "function:\$($schematicCmd.Name)"            
                        }            
                    }            
                                
                    if ($pagesToMerge) {            
                        foreach ($kv in $pagesToMerge.GetEnumerator()) {            
                            $pipeworksManifest.pages[$kv.Key] = $kv.Value            
                        }                               
                    }            
                }                                
            }                            
        }            
                    
        if ($pipeworksManifest.Table) {            
            $RequiresPipeworks = $module.RequiredModules | Where-Object { $_.Name -eq 'Pipeworks'}                         
            if (-not $requiresPipeworks -and ($module.Name -ne 'Pipeworks')) {             
                Write-Error "Modules that use the Pipeworks Manifest table features must require Pipeworks in the module manifest.  Please add RequiredModules='Pipeworks' to the module manifest.'"            
                return            
            }            
                        
            if ($PipeworksManifest.Table.StorageAccountSetting) {            
                $storageAccount = $configSetting[$PipeworksManifest.Table.StorageAccountSetting]                            
            }            
                        
            if ($PipeworksManifest.Table.StorageKeySetting) {            
                $storageKey = $configSetting[$PipeworksManifest.Table.StorageKeySetting]                            
            }                                    
                                    
                        
                
                        
                                                                                             
        }            
            
                    
                    
        if ($hasPosts -and $ModuleRss) {            
            # Generate the main page, which is an expanded first item with popouts linking to other items            
            $moduleRss |             
                Select-Xml //item/pubDate |             
                Sort-Object -Descending { ([DateTime]$_.Node.'#text') } |             
                Select-Object -First 1 |             
                ForEach-Object {             
                        $_.Node.SelectSingleNode("..")            
                } |             
                Select-Object title, creator, pubdate, link, category, @{            
                    Name='Description';            
                    Expression={            
                        $_.Description.InnerXml.Substring("<![CDATA[".Length).TrimEnd("]]>")            
                    }            
                } |             
                New-RssItem -AsHTML |            
                New-Region -ItemType http://schema.org/BlogPosting -AsWidget -Style @{            
                    'margin-left' = $MarginPercentLeftString            
                    'margin-right' = $MarginPercentRightString            
                    'margin-top' = '10px'               
                    'border' = '0px'             
                }|            
                ForEach-Object -Begin {            
                    New-Region -Container 'Headerbar' -Border '0px' -Style @{            
                        "margin-top"="1%"            
                        'margin-left' = $MarginPercentLeftString            
                        'margin-right' = $MarginPercentRightString            
                    } -Content "        
<h1 class='blogTitle'><a href='$moduleBlogLink'>$moduleBlogTitle</a></h1>
<p class='blogDescription'>$moduleBlogDescription</p>
"                                    
                } -Process {            
                    $_            
                } |             
                New-WebPage -Title "$moduleBlogTitle" -Rss @{"$moduleBlogTitle"= "$moduleRssName.xml"} |            
                Set-Content "$outputDirectory/Blog.html"            
        }            
                    
        $usesDynamicPages = $false            
            
        if ($AllowDownload) {            
            # Generate the download page now, so the site can be baked and so that we don't waste time rending the page            
            if ($downloadUrl) {            
                $page = New-WebPage -Title "Download $($module.Name)" -RedirectTo "$downloadUrl"             
                $pipeworksManifest.Pages["Download.html"] = $page             
            } elseif ($allowDownload) {                              
            
                $modulezip = $module.name + '.' + $module.Version + '.zip'            
                $page = (New-object PSObject -Property @{RedirectTo=$modulezip;RedirectIn='0:0:0.50'}),(New-object PSObject -Property @{RedirectTo="./";RedirectIn='0:0:5'}) | New-WebPage             
                $pipeworksManifest.Pages["Download.html"] = $page             
            }            
        }            
            
                            
        #region Pages            
        #If the manifest declares additional web pages, create a page for each item            
        if ($PipeworksManifest.Pages -and             
            $PipeworksManifest.Pages.GetType() -eq [Hashtable] ) {            
                        
            $pageCounter = 0            
            foreach ($pageAndContent in $PipeworksManifest.Pages.GetEnumerator()) {            
                            
                $pageName = $pageAndContent.Key             
                $pageCounter++            
                $pagePercent = $pageCounter * 100 / $pipeworksManifest.Pages.Count            
                Write-Progress "Creating Pages" "$pageName" -PercentComplete $pagePercent             
                $safePageName = $pageName.Replace("|", " ").Replace("/", "-").Replace(":","-").Replace("!", "-").Replace(";", "-").Replace(" ", "_").Replace("@","at")            
                $pageContent = $pageAndContent.Value            
                $realPageContent =             
                    if ($pageContent -is [Hashtable]) {                                
                        if (-not $pageContent.Css -and $pipeworksManifest.Style) {            
                            $pageContent.Css = $pipeworksManifest.Style            
                        }            
                        if ($pageContent.PageContent) {            
                            $pageContent.PageContent = try { [ScriptBlock]::Create($pageContent.PageContent) } catch {}                                                                     
                        }            
                        if ($hasPosts) {            
                            # If there are posts, add a link to the feed to all pages            
                            $pageContent.Rss = @{            
                                "$($Module.Name) Blog" = "$($module.Name).xml"            
                            }            
                        }            
                                    
                        # Pass down the analytics ID to the page if one is not explicitly set            
                        if (-not $pageContent.AnalyticsId -and $analyticsId) {            
                            $pageContent.AnalyticsId = $analyticsId            
                        }            
                        New-WebPage @pageContent            
                    } elseif ($pageContent -like ".\*.pspg" -or $pageName -like "*.pspg" -or $pageName -like "*.pspage"){            
                        # .PSPages.  These are mixed syntax HTML and Powershell inlined in markup <| |>            
                        # Because they are loaded within the moudule, a PSPAge will contain $embedCommand, which imports the module            
                        if ($pageContent -notlike ".\*.pspg" -and $pageContent -notlike ".\*.pspage") {            
                            # the content isn't a filepath, so treat it as inline code            
                            $wholePageContent = "<| $embedCommand |>" + $pageContent                                       
                            ConvertFrom-InlinePowerShell -PowerShellAndHtml $wholePageContent -RunScriptMethod this.RunScript -CodeFile PowerShellPageBase.cs -Inherit PowerShellPage |             
                                Add-Member NoteProperty IsPsPage $true -PassThru            
                        } else {            
                            # The content is a path, treat it like one            
                            $pagePath = Join-Path $moduleRoot $pageContent.TrimStart(".\")            
                            if (Test-Path $pagePath) {            
                                $pageContent = [IO.File]::ReadAllText($pagePath)            
                                $wholePageContent = "<| $embedCommand |>" + $pageContent             
                                ConvertFrom-InlinePowerShell -PowerShellAndHtml $wholePageContent -CodeFile PowerShellPageBase.cs -Inherit PowerShellPage -RunScriptMethod this.RunScript  |             
                                    Add-Member NoteProperty IsPsPage $true -PassThru            
                            }                     
                        }            
                        $usesDynamicPages= $true            
                    } elseif ($pageName -like "*.*" -and $pageContent -as [Byte[]]) {            
                        # Path to item            
                        $itemPath = Join-Path $outputDirectory $pageName.TrimStart(".\")            
                        $parentPath = $itemPath | Split-Path            
                        if (-not (Test-Path "$parentPath")) {            
                            $null = New-Item -ItemType Directory -Path "$parentPath"            
                        }            
                        [IO.File]::WriteAllBytes("$itemPath", $pageContent)            
                    } elseif ($pageContent -like ".\*.htm*" -or $pagename -like "*.htm?"){            
                        # .HTML files            
                        $pagePath = Join-Path (Join-Path $moduleRoot "Pages") $pageName.TrimStart(".\")            
                        if (Test-Path $pagePath) {            
                            try {            
                                $pageItem =(Get-Item $pagePath)            
                                            
                                $potentialPagecontent = [IO.File]::ReadAllText($pageItem.FullName)                                            
                                # Include the page header information for each page            
                                $relativepath = $pageItem.Fullname -ireplace $moduleRoot.Replace(".", "\.").Replace("\","\\"),"" -ireplace "\\Pages\\", ""            
                                $depth = @($relativepath -split "\\").Count - 1            
                                $pageHeaderHtml = (& { $null = . New-WebPage -Depth $depth; $pageHeaderHtml })            
                                if (-not $allAboutFiles) {            
                                    $allAboutFiles = @{}            
                                    foreach ($cult in ([Globalization.CultureInfo]::GetCultures([Globalization.CultureTypes]::AllCultures))) {                            
                                        $allAboutFiles[$cult.Name] = @(Get-ChildItem -Filter *.help.txt -Path "$moduleRoot\$($cult.Name)" -ErrorAction SilentlyContinue)            
                                    }            
                                }            
                                $headStart = $potentialPagecontent.IndexOf("<head>", [StringComparison]::InvariantCultureIgnoreCase)            
                                $potentialPagecontent = $potentialPagecontent.Insert(($headStart + "<head>".Length), $pageHeaderHtml)            
                                            
                                            
                                if ($pageItem.Directory.Name -eq 'Templates' -or $pageItem.Directory.Name -eq 'Template') {            
                                    $regions = Get-WebTemplateEditableRegion -FilePath $pageItem.FullName            
                                                
                                                
                                                
                                    $moduleParts =             
                                            'docTypeText','Title','pageHeaderHtml','titleArea',            
                                            'descriptionArea', 'rssLink','socialArea','navBarHtml',            
                                            'confirmationArea','upperBannerSlot', 'topicHtml', 'defaultCommandSection',             
                                            'slideShowHtml', 'rest', 'bottomBannerSlot','orgArea', 'brandingSlot'            
            
                                    $commandParts = $topicParts =             
                                        'docTypeText','Title','pageHeaderHtml','titleArea',            
                                        'descriptionArea', 'rssLink','socialArea','navBarHtml',            
                                        'confirmationArea','upperBannerSlot', 'rest', 'bottomBannerSlot','orgArea', 'brandingSlot'            
            
                                                
                                    if ($pageItem.Name -like "Module*") {            
                                        $difference =             
                                            $regions.Region | Compare-Object $moduleParts            
                                    } elseif ($PageItem.Name) {            
                                        $difference =             
                                            $regions.Region | Compare-Object $commandParts            
            
            
                                    }            
            
                                    foreach ($rinf in $regions.MatchInfo)            
                                    {            
                                            $null =$rinf            
                                            $start = $potentialPagecontent.IndexOf($rinf.Value)            
                                            $end =             
                                                $potentialPagecontent.IndexOf("<!-- #EndEditable -->", $start, [StringComparison]::InvariantCultureIgnoreCase)            
            
                                            $part = $potentialPagecontent.Substring($start, $end-$start + "<!-- #EndEditable -->".Length)            
            
            
                                            $potentialPagecontent = $potentialPagecontent.Replace($part, '$' + $rinf.Groups[1])            
            
                                            $pagename = $pagename -iReplace "\.html", ".pswt" -iReplace "\.htm",".pswt"            
                                    }            
                                                
                                }            
            
                                # 9/16/2013 - Adding support for embedded topics and commands in HTML            
                                # If any HTML file contains a variable (i.e. $foo) that matches the name            
                                # of an about topic, walkthru, or command, then the item will be embedded in the HTML.            
                                # Topics and Walkthrus will be directly embedded            
                                # Commands will be embedded with Write-Ajax.            
                                # Unmatched items will be unchanged, but will warn the user            
                                            
                                $variableMatches = New-Object Collections.ArrayList            
                                $fn = $pageItem.Fullname            
                                $m = [Regex]::Matches($potentialPagecontent, "\`$([\w-]{1,})") |            
                                        Add-Member NoteProperty FileName $fn -Force -PassThru            
                                            
                                                    
                                $variablesUsed =             
                                    if ($m) {            
                                        foreach ($ma in $m) {            
                                            if (-not ($ma.Value -as [double])) {            
                                                $ma.Value            
                                                $null = $variableMatches.Add($ma)            
                                            }            
                            
                                        }            
                        
                                    }                    
                                                
                                $variablesUsed = $variablesUsed |             
                                    Select-Object -Unique |             
                                    Sort-Object -Descending            
            
            
            
                                $foundVariables = @()            
            
                                $topicsToReplace =             
                                    $allAboutFiles.Values |                
                                        where-object {            
                                            $_            
                                        } |            
                                        Where-Object {            
                                            $variablesUsed -like "?$($_.Name -ireplace '\.walkthru\.help\.txt', '' -ireplace '\.help\.txt', '')"            
                                        } |            
                                        ForEach-Object {            
                    
                                            foreach ($f in $_) {            
                                            $used = $($variablesUsed -like "?$($_.Name -ireplace '\.walkthru\.help\.txt', '' -ireplace '\.help\.txt', '')")            
                                                New-Object PSObject -Property @{            
                                                    TopicFile = $f            
                                                    UsedInFile = $variableMatches | Where-Object { $used -contains $_.Value   }  | Select-Object -ExpandProperty Filename             
                                                    Variable = $used            
                                                    Matches = $variableMatches | Where-Object { $used -contains $_.Value   }             
                                                }            
                                            }            
            
                                            $foundVariables += $used            
                                        }            
            
            
                                $moduleCommands = Get-Command -Module $Name -CommandType Alias, Function, Cmdlet            
            
                                $commandsUsed = foreach ($m in $moduleCommands) {            
                                    $m | Where-Object {            
                                        $variablesUsed -like "?$($_.Name -ireplace '\.walkthru\.help\.txt', '' -ireplace '\.help\.txt', '')"            
                                    } | ForEach-Object {            
                                        $used = $($variablesUsed -like "?$($_.Name -ireplace '\.walkthru\.help\.txt', '' -ireplace '\.help\.txt', '')")            
                                        New-Object PSObject -Property @{            
                                            Command = $m            
                                            UsedInFile = $variableMatches | Where-Object { $used -contains $_.Value   }  | Select-Object -ExpandProperty Filename             
                                            Variable = $used            
                                            Matches = $variableMatches | Where-Object { $used -contains $_.Value   }             
                                        }            
                                        $foundVariables+=$used            
                                    }            
                                }            
            
            
                                foreach ($cmd in $commandsUsed) {            
                                    foreach ($matchInf in $cmd.Matches) {            
            
                                        $relativepath = $matchInf.Filename -ireplace $moduleRoot.Replace(".", "\.").Replace("\","\\"),"" -ireplace "\\Pages\\", ""            
                                        $resolvedCommand = if ($cmd.Command.ResolvedCommand) {            
                                            $cmd.Command.ResolvedCommand            
                                        } else {            
                                            $cmd.Command            
                                        }            
                                        $depth = @($relativepath -split "\\").Count - 1            
                                        $cmdLink = "${RelativeDepth}${resolvedCommand}/?snug=true&ajax=true"            
                                        $fc = [IO.File]::ReadAllText($matchInf.FileName)            
                    
                                        $cmdIFrame = "$($resolvedCommand.Name.Replace('-',''))frame"            
                                        $cmdHtml = "<iframe style='width:100%;border:0' src='$cmdLink' id='$cmdIFrame' seamless=''></iframe>"            
                                        $cmdHtml =             
                                "
                                <div style='height:100%'>
                                
                                <div id='$($resolvedCommand.Name.Replace("-", ''))'>
                                </div>
                                $cmdHtml                                
                                </div>
                                <script>
                                    var buffer = 20; //scroll bar buffer
                                    var iframe = document.getElementById('$cmdIFrame');

                                    function pageY(elem) {
                                        return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
                                    }

                                    function resize$cmdIFrame() {
                                        var height = document.documentElement.clientHeight;
                                        height -= pageY(document.getElementById('$cmdIFrame'))+ buffer ;
                                        height = (height < 0) ? 0 : height;
                                        document.getElementById('$cmdIFrame').style.height = height + 'px';
                                    }

                                    // .onload doesn't work with IE8 and older.
                                    if (iframe.attachEvent) {
                                        iframe.attachEvent('onload', resize$cmdIFrame);
                                    } else {
                                        iframe.onload=resize$cmdIFrame;
                                    }

                                    if (window.addEventListener) {
                                        window.addEventListener('onresize', function() {
                                            resize$cmdIFrame();
                                        });
                
                                        window.addEventListener('onorientationchange', function() {
                                            resize$cmdIFrame();
                                        });   
                                    } else {
                                        if (window.attachEvent) {
                                            window.attachEvent('onresize', function(e) {                        
                                                resize$cmdIFrame();
                                            });
                                        }
                                    }
                                </script>
                                "            
                    
                                        $potentialPagecontent = [Regex]::Replace($potentialPagecontent, $matchInf.Value.Replace('$', '\$'), $cmdHtml)                                                    
                                    }            
                                }            
                                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                                    $false            
                                } else {            
                                    $true            
                                }            
                                foreach ($topic in $topicsToReplace) {            
                                    $topicHtml =             
                                        if ($topic.TopicFile -like "*.walkthru*") {            
                                            Write-WalkthruHTML -WalkThru (Get-Walkthru -File $topic.TopicFile)            
                                        } else {            
                                            $topicHelp = [IO.File]::ReadAllText($TOPIC.TopicFile.FullName)            
                                            ConvertFrom-Markdown -Markdown $topicHelp -ShowData:$ShowDataInTopic            
                                        }            
            
                                    $matchInf = $topic.Matches            
                                    foreach ($matchInf in $topic.Matches) {            
                                                    
                                        $potentialPagecontent = [Regex]::Replace($potentialPagecontent, $matchInf.Value.Replace('$', '\$'), $topicHtml)            
                                                    
                                    }            
                                }            
            
                                $missingvariables = $variablesUsed | Where-Object { $foundVariables -notcontains $_ }             
                                foreach ($missing in $missingvariables) {            
                                    Write-Warning "$($pagePath) references $missing, but there is no topic, walkthru, or command named $missing"            
                                }            
                                            
                                $pageContent = $potentialPagecontent             
                            } catch {            
                                $_ | Write-Error            
                            }            
                        }            
                    } elseif ($pageName -like ".\*.md" -or $pagename -like "*.md") {            
                        $pagePath = Join-Path (Join-Path $moduleRoot "Pages")  $pageName.TrimStart(".\")            
                        if (Test-Path $pagePath) {            
                            try {            
                                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                                    $false            
                                } else {            
                                    $true            
                                }            
                                $potentialPagecontent = [IO.File]::ReadAllText((Get-Item $pagePath).Fullname)                                            
                                $wholePageContent =  "
<| 
$embedCommand
ConvertFrom-Markdown -ShowData:`$$showDataInTopic -Markdown @`"
$potentialPagecontent
`"@ |
    New-Webpage

|>
"            
                                ConvertFrom-InlinePowerShell -PowerShellAndHtml $wholePageContent -CodeFile PowerShellPageBase.cs -Inherit PowerShellPage -RunScriptMethod this.RunScript  |             
                                    Add-Member NoteProperty IsPsPage $true -PassThru            
            
                                            
                            } catch {            
                                $_ | Write-Error            
                            }            
                        }            
                    } elseif ($pageName -like ".\*.psmd" -or $pagename -like "*.psmd") {            
                        $pagePath = Join-Path (Join-Path $moduleRoot "Pages") $pageName.TrimStart(".\")            
                        if (Test-Path $pagePath) {            
                            try {            
                                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                                    $false            
                                } else {            
                                    $true            
                                }            
                                $potentialPagecontent = [IO.File]::ReadAllText((Get-Item $pagePath).Fullname)                                            
                                $wholePageContent =  "
<| 
$embedCommand
ConvertFrom-Markdown -Splat -ScriptAsPowershell -ShowData:`$showDataInTopic -Markdown @`"
$potentialPagecontent
`"@ |
    New-Webpage
|>
"            
            
            
                            ConvertFrom-InlinePowerShell -PowerShellAndHtml $wholePageContent -CodeFile PowerShellPageBase.cs -Inherit PowerShellPage -RunScriptMethod this.RunScript  |             
                                Add-Member NoteProperty IsPsPage $true -PassThru            
                            } catch {            
                                $_ | Write-Error            
                            }            
                            $usesDynamicPages = $true            
                        }            
            
                    } else {            
                        $pageContentAsScriptBlock = try { [ScriptBlock]::Create($pageContent) } catch { }             
                        if ($pageContentAsScriptBlock) {            
                            & $pageContentAsScriptBlock            
                        } else {            
                            $pageContent            
                        }            
                    }            
                            
                          
                            
                if ($realPageContent.IsPsPage) {            
                    $safePageName = $safePageName.Replace(".pspage", "").Replace(".pspg", "").Replace(".md", "").Replace(".psmd", "")            
                    $parentPath = $safePageName | Split-Path            
                    if (-not (Test-Path "$outputDirectory\$parentPath")) {            
                        $null = New-Item -ItemType Directory -Path "$outputDirectory\$parentPath"            
                    }            
                    $realPageContent |             
                        Set-Content "$outputDirectory\${safepageName}.aspx"            
                    $usesDynamicPages = $true            
                } else {            
                    # Output the bytes            
                    $parentPath = $safePageName | Split-Path            
                    if (-not (Test-Path "$outputDirectory\$parentPath")) {            
                        $null = New-Item -ItemType Directory -Path "$outputDirectory\$parentPath"            
                    }            
                    if ($pageContent -as [Byte[]]) {            
                        [IO.File]::WriteAllBytes("$outputDirectory\$($pageName)", $pageContent)            
                    } else {            
                        [IO.File]::WriteAllText("$outputDirectory\$($pageName)", $pageContent)            
                    }            
                    <#                    
                    $safePageName = $safePageName.Replace(".html", "").Replace(".htm", "")
                    $parentPath = $safePageName | Split-Path
                    if (-not (Test-Path "$outputDirectory\$parentPath")) {
                        $null = New-Item -ItemType Directory -Path "$outputDirectory\$parentPath"
                    }
                    $realPageContent | 
                        Set-Content "$outputDirectory\${safepageName}.html"
                    #>            
                }            
            }                        
        }            
        #endregion Pages            
                    
                    
                           
        #region Command Handlers            
        $webCmds = @()            
        $downloadableCmds = @()            
        $cmdOutputDirs = @()            
        foreach ($command in $module.ExportedCommands.Values) {            
            # Generate individual handlers            
            $extraParams = if ($pipeworksManifest -and $pipeworksManifest.WebCommand.($Command.Name)) {                            
                @{} + $pipeworksManifest.WebCommand.($Command.Name)            
            } else {             
                @{            
                    ShowHelp = $true            
                }             
            }                         
                        
            if ($pipeworksManifest -and $pipeworksManifest.Style -and (-not $extraParams.Style)) {            
                $extraParams.Style = $pipeworksManifest.Style             
            }            
            if ($extraParams.Count -gt 1) {            
                # Very explicitly make sure it's there, and not explicitly false            
                if (-not $extra.RunOnline -or             
                    $extraParams.Contains("RunOnline") -and $extaParams.RunOnline -ne $false) {            
                    $extraParams.RunOnline = $true                                 
                }                            
            }             
                        
            if ($extaParams.PipeInto) {            
                $extaParams.RunInSandbox = $true            
            }            
                        
            if (-not $extraParams.AllowDownload) {            
                $extraParams.AllowDownload = $allowDownload            
            }            
                        
            if ($extraParams.RunOnline) {            
                # Commands that can be run online            
                $webCmds += $command.Name            
            }            
                        
            if ($extraParams.RequireAppKey -or $extraParams.RequireLogin -or $extraParams.IfLoggedAs -or $extraParams.ValidUserPartition) {            
                $extraParams.UserTable = $pipeworksManifest.Usertable.Name            
                $extraParams.UserPartition = $pipeworksManifest.Usertable.Partition            
                $extraParams.StorageAccountSetting = $pipeworksManifest.Usertable.StorageAccountSetting            
                $extraParams.StorageKeySetting = $pipeworksManifest.Usertable.StorageKeySetting             
            }            
                        
            if ($extraParams.AllowDownload) {            
                # Downloadable Commands            
                $downloadableCommands += $command.Name                            
            }            
                                    
                        
                        
            if ($psBoundParameters.OutputDirectory) {            
                $extraParams.OutputDirectory = Join-Path $psBoundParameters.OutputDirectory $command.Name            
                $cmdOutputDirs += "$(Join-Path $psBoundParameters.OutputDirectory $command.Name)"                            
            } else {            
                $extraParams.OutputDirectory = Join-Path $OutputDirectory $command.Name            
            }            
                        
            if ($MarginPercentLeftString -and (-not $extraParams.MarginPercentLeft)) {            
                $extraParams.MarginPercentLeft = $MarginPercentLeftString.TrimEnd("%")            
            }            
                        
            if ($MarginPercentRightString-and -not $extraParams.MarginPercentRight) {            
                $extraParams.MarginPercentRight = $MarginPercentRightString.TrimEnd("%")            
            }            
                        
            if ($IsolateRunspace) {            
                $extraParams.IsolateRunspace = $IsolateRunspace            
            }            
                        
            if ($psBoundParameters.StartOnCommand) {            
                # only create a full command service when the Module service starts on a command            
                #ConvertTo-CommandService -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId"            
            }            
                                    
            $cmdOutputDir = $extraParams.OutputDirectory.ToString()            
                        
        }            
                                                                         
        #endregion Command Handlers            
                    
        foreach ($cmdOutputDir in $cmdOutputDirs) {            
                        
        }            
            
        if (-not $CommandOrder) {            
            if ($pipeworksManifest.CommandOrder) {            
                $CommandOrder = $pipeworksManifest.CommandOrder            
            } else {            
                $CommandOrder = $module.ExportedCommmands.Keys | Sort-Object            
            }            
        }            
                    
            
            
            
        $useLoginHandlers =             
            foreach ($wc in $pipeworksManifest.WebCommand.Values) {            
                if ($wc.RequireLogin -or             
                    $wc.RequiresLogin -or             
                    $wc.IfLoggedInAS -or             
                    $wc.ValidUserTable -or             
                    $wc.RequireAppKey -or             
                    $wc.RequiresAppKey) {            
                    $true            
                    break            
                }            
            }            
            
            
                    
                    
            
            
        # This script is embedded in the module handler            
            $getModuleMetaData = {            
            
$startedGetModuleMetaDataAt = [DateTime]::Now            
            
#            
$moduleRoot = [IO.Path]::GetDirectoryName($module.Path)            
$psd1Path = $moduleRoot + '\' + $module.Name + '.psd1'            
            
$requestCulture =             
    if ($request -and $request["HTTP_ACCEPT_LANGUAGE"]) {            
        $request["HTTP_ACCEPT_LANGUAGE"]            
    } else {            
        "en-us"            
    }            
            
            
$namedTopics = @{}            
if (-not $customAnyHandler) {            
    $customAnyHandler = [IO.File]::Exists("$searchDirectory\AnyUrl.aspx")            
}            
            
$spacingDiv = "<div style='clear:both;margin-top:1.5%;margin-bottom:1.5%'></div>"            
            
if (-not $aboutFiles) {            
    if (-not $allAboutFiles) {            
        $allAboutFiles = @{}            
        foreach ($cult in ([Globalization.CultureInfo]::GetCultures([Globalization.CultureTypes]::AllCultures))) {                    
                    
            $allAboutFiles[$cult.Name] = @(Get-ChildItem -Filter *.help.txt -Path "$moduleRoot\$($cult.Name)" -ErrorAction SilentlyContinue)            
        }            
    }            
            
    if (-not $cachedAboutTopics) {            
        $cachedAboutTopics = @{}            
    }            
            
    # en-us and the current request culture get are used to create a list of help topics            
    $aboutFiles  =  @($AllaboutFiles["en-us"])            
            
    if ($requestCulture -and ($requestCulture -ine 'en-us')) {            
        $aboutFiles  +=  @($AllaboutFiles["$requestCulture"])            
    }            
            
            
            
            
    if (-not $walkThrus) {            
        $walkThrus = @{}            
    }            
    if (-not $aboutTopics) {            
        $aboutTopics = @()            
    }            
            
    if (-not $aboutTopicsByName) {            
        $aboutTopicsByName = @{}            
    }            
            
            
    $HiddenTopicsByName = @{}            
            
    $hiddenTopic = if ($pipeworksManifest.HiddenTopic) {            
        @($pipeworksManifest.HiddenTopic)            
    } elseif ($pipeworksManifest.HiddenTopics) {            
        @($pipeworksManifest.HiddenTopics)            
    }            
            
            
    $memberTopic = if ($pipeworksManifest.MemberTopic) {            
        @($pipeworksManifest.MemberTopic)            
    } elseif ($pipeworksManifest.MemberTopics) {            
        @($pipeworksManifest.MemberTopics)            
    }            
            
            
            
            
    foreach ($topic in $aboutFiles) {                   
        if (-not $topic) { continue }                              
        if (-not $topic.Name) { continue }                              
        if ($topic.fullname -ilike "*.walkthru.help.txt") {            
            $topicName = $topic.Name.Replace('_',' ') -iReplace '\.walkthru\.help\.txt',''            
            
            if (-not $walkThrus[$topicName]) {            
                $walkthruContent = Get-Walkthru -File $topic.Fullname                        
                            
                $walkThrus[$topicName] = $walkthruContent                                                 
            }                                    
        } else {            
            $topicName = $topic.Name.Replace(".help.txt","")            
            if (-not $aboutTopicsByName[$topicName.Replace("_", " ")]) {            
                $nat = New-Object PSObject -Property @{            
                    Name = $topicName.Replace("_", " ")            
                    SystemName = $topicName            
                    Topic = [IO.File]::ReadAllText($topic.Fullname)            
                    LastWriteTime = $topic.LastWriteTime            
                }             
                $aboutTopics += $nat            
                $aboutTopicsByName[$nat.Name] = $nat            
            } else {            
                $aboutTopics += $aboutTopicsByName[$nat.Name]            
            }            
                        
                        
                        
                             
                        
        }            
            
            
    }            
}            
            
$timeSpentGettingModuleMetaData = [DateTime]::now - $startedGetModuleMetaDataAt            
}            
            
        $moduleFeedHandler = {            
            if ($application -and $application["$($module.Name)_Feed"]) {            
                $response.ContentType = "text/xml"                            
                $response.Write("$($application["$($module.Name)_Feed"])")                    
                return            
            }            
                        
            $feedItems = @()            
            
            if ($aboutTopics) {            
                $feedItems +=             
                    $aboutTopics |            
                        Select-Object @{            
                            Name = 'Author'            
                            Expression = {            
                                if ($module.Author) {            
                                    $module.Author            
                                } else {            
                                    " "            
                                }                       
                            }            
                        }, @{            
                            Name = 'Title'            
                            Expression = { $_.Name }             
                        }, @{            
                            Name = 'Description'            
                            Expression = {            
                                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                                    $false            
                                } else {            
                                    $true            
                                }            
                                ConvertFrom-Markdown -Markdown "$($_.Topic) " -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
                            }            
                        }, @{            
                            Name = 'DatePublished'            
                            Expression = {            
                                $_.LastWriteTime            
                            }            
                        }, @{            
                            Name = 'Link'            
                            Expression = {            
                                if ($customAnyHandler) {                                
                                    "?About=" + $_.Name                                
                                } else {                                
                                    $_.Name + "/"                                
                                }            
                            }            
                        } | Where-Object {            
                            $_.Title -ne "About $Module"            
                        }            
            
            }            
            
            if ($walkThrus) {            
                $feedItems +=             
                    $walkThrus.Keys |            
                        Select-Object @{            
                            Name = 'Author'            
                            Expression = {            
                                if ($module.Author) {            
                                    $module.Author            
                                } else {            
                                    " "            
                                }                       
                            }            
                        }, @{            
                            Name = 'Title'            
                            Expression = { $_ }             
                        }, @{            
                            Name = 'Description'            
                            Expression = {            
                                Write-WalkthruHTML -WalkThru ($walkThrus[$_])             
                            }            
                        }, @{            
                            Name = 'DatePublished'            
                            Expression = {            
                                $walkThrus[$_] | Select-Object -ExpandProperty LastWriteTime -Unique            
                            }            
                        }, @{            
                            Name = 'Link'            
                            Expression = {            
                                if ($customAnyHandler) {                                
                                    "?Walkthru=" + $_            
                                } else {                                
                                    $_ + "/"                                
                                }            
                            }            
                        }            
            
            }            
                        
            
            
            $feedName = if ($pipeworksManifest.Blog.Name) {            
                $pipeworksManifest.Blog.Name            
            } else {            
                $module.Name            
            }            
            
            
            $feedDescription = if ($pipeworksManifest.Blog.Description) {            
                $pipeworksManifest.Blog.Description            
            } else {            
                $module.Description            
            }            
            
            $postFilters = @($pipeworksManifest.Blog.Posts) + @($pipeworksManifest.Blog.Post)            
            
            if ($postFilters) {            
                $feedItems =             
                    @(foreach ($fi in $feedItems) {            
                        $ItemIsOk = $false            
                        foreach ($po in $postFilters) {            
                            if ($fi.Name -like $po) {            
                                $ItemIsOk = $true            
                                break            
                            }            
                        }            
            
                        if ($ItemIsOk) {            
                            $fi              
                        }            
                    })            
            }            
            
            $feed = $feedItems |             
                Sort-Object { $_.DatePublished -as [DateTime] } -Descending |            
                New-RssItem -Description { "$($_.Description) " }|            
                Out-RssFeed -Title "$feedname " -Description "$feedDescription " -Link "/"            
                         
            
            $response.ContentType = "text/xml"            
            $strWrite = New-Object IO.StringWriter            
            ([xml]($feed)).Save($strWrite)            
            $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
            $application["$($module.Name)_Feed"] = "$resultToOutput"            
            $response.Write("$resultToOutput")                    
            
        }            
            
        $topicRssHandler = {            
                    
            
    if ($aboutTopics) {            
        $feed = $aboutTopics |             
            New-RssItem -Author {            
                if ($module.Author) {            
                    $module.Author            
                } else {            
                    " "            
                }            
            } -Title {$_.Name } -Description {             
                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                    $false            
                } else {            
                    $true            
                }            
                ConvertFrom-Markdown -Markdown $_.Topic -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
            } -DatePublished { $_.LastWriteTime } -Link {            
                if ($customAnyHandler) {                                
                    "?About=" + $_.Name                                
                } else {                                
                    $_.Name + "/"                                
                }            
            } |            
            Out-RssFeed -Title "$($module.Name) | Topics" -Description "$($module.Description) " -Link "/"            
            
        $response.ContentType = "text/xml"            
        $strWrite = New-Object IO.StringWriter            
        ([xml]($feed)).Save($strWrite)            
        $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
        $response.Write("$resultToOutput")                    
    }             
            
}            
            
        $walkThruRssHandler = {            
            
            
        $feed = $walkThrus.Keys |            
            Sort-Object {            
                $walkthrus[$_] | Select-Object -ExpandProperty LastWriteTime -Unique            
            } |            
            New-RssItem -Title {             
                $_            
            } -Author {            
                if ($module.Author) {            
                    $module.Author            
                } else {            
                    " "            
                }            
            } -Description {            
                Write-WalkthruHTML -WalkThru ($walkThrus[$_])             
            } -DatePublished {            
                $walkThrus[$_] | Select-Object -ExpandProperty LastWriteTime -Unique            
            } -Link {            
                if ($customAnyHandler) {                                
                    "?Walkthru=" + $_            
                } else {                                
                    $_ + "/"                                
                }            
            } |            
            Out-RssFeed -Title "$($module.Name) | Topics" -Description "$($module.Description) " -Link "/"            
            
        if ($feed) {            
            $response.ContentType = "text/xml"            
            $strWrite = New-Object IO.StringWriter            
            ([xml]($feed)).Save($strWrite)            
            $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
            $response.Write("$resultToOutput")                    
        }            
            
}            
                    
            
        #region About Topic Handler            
        $aboutHandler = {            
            
$theTopic = $aboutTopics |             
    Where-Object {             
    $_.SystemName -eq $request['about'].Trim() -or             
    $_.Name -eq $request['About'].Trim()            
}            
            
$topicMatch = if ($theTopic) {            
    $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
        $false            
    } else {            
        $true            
    }            
    ConvertFrom-Markdown -Markdown $theTopic.Topic -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
} else {            
    '<span style=''color:red''>Topic not found</span>'            
}            
                
                
    $page =(New-Region -LayerID "About$($module.Name)Header" -AsWidget -Style @{            
            'margin-left' = $MarginPercentLeftString            
            'margin-right' = $MarginPercentRightString            
        } -Content "
            <h1 itemprop='name' class='ui-widget-header'><a href='.'>$($module.Name)</a> | $($Request['about'].Replace('_', ' '))</h1>            
        "),(New-Region -Container "About$($module.Name)" -Style @{            
            'margin-left' = $MarginPercentLeftString            
            'margin-right' = $MarginPercentRightString            
        } -AsAccordian -HorizontalRuleUnderTitle -DefaultToFirst -Layer @{            
            $request['about'].Replace("_", " ") = "
            <div itemprop='ArticleText'>
            $topicMatch
            </div>
            "               
        }) |            
        New-WebPage -UseJQueryUI -Css $cssStyle -Title "$($module.Name) | About $($Request['about'])" -AnalyticsID "$analyticsId"            
    $response.contentType = 'text/html'            
    $response.Write("$page")            
        }            
        #endregion About Topic Handler            
            
        #region Show Groups            
                    
        #endregion Show Groups            
                                    
        #region Walkthru (Demo) Handler            
        $walkThruHandler = {            
$pipeworksManifestPath = Join-Path (Split-Path $module.Path) "$($module.Name).Pipeworks.psd1"            
$pipeworksManifest = if (Test-Path $pipeworksManifestPath) {            
    try {                                 
        & ([ScriptBlock]::Create(            
            "data -SupportedCommand Add-Member, New-WebPage, New-Region, Write-CSS, Write-Ajax, Out-Html, Write-Link { $(
                [ScriptBlock]::Create([IO.File]::ReadAllText($pipeworksManifestPath))                    
            )}"))                        
    } catch {            
        Write-Error "Could not read pipeworks manifest: ($_ | Out-String)"             
    }                                                            
} else { $null }             
                
                
$topicMatch =             
    if ($walkthrus.($request['walkthru'].Trim())) {            
        # Use splatting to tack on any extra parameters            
        $params = @{            
            Walkthru = $walkthrus.($request['walkthru'].Trim())            
            WalkThruName = $request['walkthru'].Trim()            
            StepByStep = $true            
        }                
            
        if ($pipeworksManifest.TrustedWalkthrus -contains $request['Walkthru'].Trim()) {            
            $params['RunDemo'] = $true            
        }            
        if ($pipeworksManifest.WebWalkthrus -contains $request['Walkthru'].Trim()) {            
            $params['OutputAsHtml'] = $true            
        }            
        Write-WalkthruHTML @params            
    } else {            
        '<span style=''color:red''>Topic not found</span>'            
    }            
        $page = (New-Region -LayerID "About$($module.Name)Header" -AsWidget -Style @{            
            'margin-left' = $MarginPercentLeftString            
            'margin-right' = $MarginPercentRightString            
        } -Content "
            <h1 itemprop='name' class='ui-widget-header'><a href='.'>$($module.Name)</a> | $($Request['walkthru'].Replace('_', ' '))</h1>            
        "),             
        (New-Region -LayerId WalkthruContainer -Style @{            
            'margin-left' = $MarginPercentLeftString            
            'margin-right' = $MarginPercentRightString            
        } -Content $topicMatch ) |            
        New-WebPage -UseJQueryUI -Css $cssStyle -Title "$($module.Name) | Walkthrus | $($Request['walkthru'].Replace('_', ' '))" -AnalyticsID '$analyticsId'             
$response.contentType = 'text/html'            
$response.Write("$page")            
            
        }            
        #endregion Walkthru (Demo) Handler            
                    
        #region Help Handler            
        $helpHandler = {            
            $RequestedCommand = $Request["GetHelp"]                           
                        
            $webCmds = @()            
            $downloadableCmds = @()            
            $cmdOutputDirs = @()            
                        
            $command = $module.ExportedCommands[$RequestedCommand]            
                        
            if (-not $command)  {            
                throw "$requestedCommand not found in module $module"            
            }            
                     
            $extraParams = if ($pipeworksManifest -and $pipeworksManifest.WebCommand.($Command.Name)) {                            
                @{} + $pipeworksManifest.WebCommand.($Command.Name)            
            } else { @{} }                            
                        
            $extraParams.ShowHelp=$true            
            
                        
            $linkUrl = "$FinalUrl".Substring(0, "$FinalUrl".LastIndexOf("/"))            
            $titleArea =             
                if ($PipeworksManifest -and $pipeworksManifest.Logo) {            
                    "<a href='$linkUrl' class='brand'><img src='$($pipeworksManifest.Logo)' alt='$($module)' style='border:0' /></a>"            
                } else {            
                    "<a href='$linkUrl' class='brand'>$($Module.Name)</a>"            
                }            
            
                        
            
            
                        
            
           if (-not $script:SocialArea) {            
                            
            
               $script:SocialArea = "
$(
    if (-not $antiSocial) {
        if ($pipeworksManifest -and ($pipeworksManifest.Facebook.AppId -or $pipeworksManifest.FacebookLike)) {
            
                        
            Write-Link "facebook:like"
                        
        }
        if ($pipeworksManifest -and ($pipeworksManifest.GoogleSiteVerification -or $pipeworksManifest.AddPlusOne)) {
            
                        
            Write-Link "google:plusone"
                        
        }
        if ($pipeworksManifest -and $pipeworksManifest.ShowTweet) {
            Write-Link "twitter:tweet"
                        
        } elseif ($pipeworksManifest -and ($pipeworksManifest.TwitterId)) {
            Write-Link "twitter:tweet"
                        
            
                        
            Write-Link "twitter:follow@$($pipeworksManifest.TwitterId.TrimStart('@'))"                        
        }
    }
)
               "            
            }            
            $socialArea = $script:SocialArea                    
                        
            $result =             
                Invoke-Webcommand -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1            
            
            if ($result) {            
                if ($Request.params["AsRss"] -or             
                    $Request.params["AsCsv"] -or            
                    $Request.params["AsXml"] -or            
                    $Request.Params["bare"]) {            
                    $response.Write($result)            
                } else {            
                    $outputPage = "<div style='float:left'>$($titleArea + $descriptionArea)</div>" + "<div style='float:right'>$socialArea</div>" + +($spacingDiv * 4) +$result |            
                        New-Region -Style @{            
                            "Margin-Left" = $marginPercentLeftString            
                            "Margin-Right" = $marginPercentLeftString            
                        }|            
                        New-WebPage -Title "$($module.Name) | $command" -UseJQueryUI             
                    $response.Write($outputPage)            
                }                            
            }            
                        
        }            
        #endregion Help Handler            
                    
        #region Command Handler            
        $commandHandler = {            
                        
                        
            $RequestedCommand = $Request["Command"]                                                               
                        
                        
            . $getCommandExtraInfo $RequestedCommand            
            
            $result = try {            
                Invoke-Webcommand -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1            
            } catch {            
                $_            
            }            
            $linkUrl = "$FinalUrl".Substring(0, "$FinalUrl".LastIndexOf("/"))            
            $titleArea =             
                if ($PipeworksManifest -and $pipeworksManifest.Logo) {            
                    "<a href='$linkUrl'><img src='$($pipeworksManifest.Logo)' alt='$($module)' style='border:0' /></a>"            
                } else {            
                    "<a href='$linkUrl'>" + $Module.Name + "</a>"            
                }            
                        
            $commandDescription  = ""                                    
            $commandHelp = Get-Help $command -ErrorAction SilentlyContinue | Select-Object -First 1             
            if ($commandHelp.Description) {            
                $commandDescription = $commandHelp.Description[0].text            
                $commandDescription = $commandDescription -replace "`n", ([Environment]::NewLine)             
            }            
            
            $descriptionArea = "
            $(ConvertFrom-Markdown -Markdown "$commandDescription ")            
            "            
            
            if ($result) {            
                if ($Request.params["AsRss"] -or             
                    $Request.params["AsCsv"] -or            
                    $Request.params["AsXml"] -or            
                    $Request.Params["bare"] -or             
                    $extraParams.ContentType -or            
                    $extraParams.PlainOutput) {            
                                        
                                        
                    if (-not ($extraParams.ContentType) -and                                    
                        $result -like "*<*>*" -and             
                        $result -like '*`$(*)*') {            
                        # If it's not HTML or XML, but contains tags, then render it in a page with JQueryUI            
                        $outputPage = $socialArea +  $spacingDiv + $descriptionArea + $spacingDiv + $result |            
                            New-WebPage -Title "$($module.Name) | $command"            
                        $response.Write($outputPage)            
                    } elseif ($extraParams.ContentType -eq 'text/html' -and            
                        $result -like "*$($command)_Input*" -and             
                        $result -notlike "*<html>*")            
                    {            
                        $outputPage = $socialArea +  $spacingDiv + $descriptionArea + $spacingDiv + $result |            
                            New-WebPage -Title "$($module.Name) | $command"            
                        $response.Write($outputPage)            
                    } else {            
                        $response.Write($result)            
            
                                    
                    }            
                                        
                } else {            
                    if (($result -is [Collections.IEnumerable]) -or ($result -isnot [string])) {            
                        $Result = $result | Out-HTML                                            
                    }            
                    if ($request["inline"]) {            
                        $response.Write($result)            
                    } elseif ($request["Snug"] -or $Request["Widget"]) {            
                        $outputPage = "<div style='clear:both;margin-top:1%'> </div>" + $result |            
                            New-Region -Style @{            
                                "Margin-Left" = "1%"            
                                "Margin-Right" = "1%"            
                            }|            
                            New-WebPage -Title "$($module.Name) | $command"            
                        $response.Write($outputPage)            
                    } else {            
                        $outputPage = $socialArea + $titleArea +  "<div style='clear:both;margin-top:1%'></div>" + $descriptionArea + $spacingDiv + $result |            
                        New-Region -Style @{            
                            "Margin-Left" = $marginPercentLeftString            
                            "Margin-Right" = $marginPercentLeftString            
                        }|            
                        New-WebPage -Title "$($module.Name) | $command"            
                        $response.Write($outputPage)            
                    }            
                                        
                }                            
            }            
                                    
                        
        }            
                            
        #endregion Command Handler            
        $validateUserTable = {            
            if (-not ($pipeworksManifest.UserTable.Name -and $pipeworksManifest.UserTable.StorageAccountSetting -and $pipeworksManifest.UserTable.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include these settings in order to manage users: UserTable.Name, UserTable.EmailAddress, UserTable.ExchangeServer, UserTable.ExchangePasswordSetting UserTable.StorageAccountSetting, and UserTable.StorageKeySetting'            
                return            
            }                        
        }            
                            
                    
                    
        #region Join Handler            
        $joinHandler = $validateUserTable.ToString()  + {            
            $DisplayForm = $false            
            $FormErrors = ""            
                      
                        
                      
                        
            if (-not $request["Join-$($module.Name)_EmailAddress"]) {            
                #$missingFields            
                $displayForm = $true            
            }            
                        
            $newUserData =@{}            
            $missingFields = @()            
            $paramBlock = @()            
            if ($session['ProfileEditMode'] -eq $true) {            
                $editMode = $true            
            }            
            $defaultValue = if ($editMode -and $session['User'].UserEmail) {            
                "|Default $($session['User'].UserEmail)"            
            } else {            
                ""            
            }            
                        
            if ($Request['ReferredBy']) {            
                $session['ReferredBy'] = $Request['ReferredBy']            
            }            
            $paramBlock += "
            #$defaultValue
            [Parameter(Mandatory=`$true,Position=0)]
            [string]
            `$EmailAddress
            "            
            if ($pipeworksManifest.UserTable.RequiredInfo) {            
                $Position = 1            
                foreach ($k in $pipeworksManifest.UserTable.RequiredInfo.Keys) {            
                    $newUserData[$k] = $request["Join-$($module.Name)_${k}"] -as $pipeworksManifest.UserTable.RequiredInfo[$k]            
                    $defaultValue = if ($session['User'].$k) {            
                        "|Default $($session['User'].$k)"            
                    } else {            
                        ""            
                    }            
                                
                    $paramBlock += "
            #$defaultValue
            [Parameter(Mandatory=`$true,Position=$position)]
            [$($pipeworksManifest.UserTable.RequiredInfo[$k].Fullname)]
            `$$k
            "            
                    $Position++            
                    if (-not $newUserData[$k]) {             
                        $missingFields += $k            
                    }            
                }            
            }            
                        
                        
            if ($pipeworksManifest.UserTable.OptionalInfo) {            
                foreach ($k in $pipeworksManifest.UserTable.OptionalInfo.Keys) {            
                    $newUserData[$k] = $request["Join-$($module.Name)_${k}"] -as $pipeworksManifest.UserTable.OptionalInfo[$k]            
                    $defaultValue = if ($session['User'].$k) {            
                        "|Default $($session['User'].$k)"            
                    } else {            
                        ""            
                    }            
                    $paramBlock += "
            #${defaultValue}
            [Parameter(Position=$position)]
            [$($pipeworksManifest.UserTable.OptionalInfo[$k].Fullname)]
            `$$k
            "            
                }            
            }            
                        
                        
            if ($pipeworksManifest.UserTable.TermsOfService) {            
                        
            }            
                        
            .([ScriptBlock]::Create(            
                "function Join-$($module.Name) {
                    <#
                    .Synopsis
                        Joins $($module.Name) or edits a profile
                    .Description
                           
                    #>
                    param(
                    $($paramBlock -join ",$([Environment]::NewLine)")
                    )
                }                
                "))            
                        
            $cmdInput = Get-WebInput -CommandMetaData (Get-Command "Join-$($module.Name)" -CommandType Function)            
            if ($cmdInput.Count -gt 0) {            
                $DisplayForm = $false            
            }            
                        
                        
            if ($missingFields) {            
                $email = $request["Join-$($module.Name)_EmailAddress"]            
                $emailFound = [ScriptBlock]::Create("`$_.UserEmail -eq '$email'")            
                $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting)            
                $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting)            
            
                $mailAlreadyExists =             
                    Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -StorageAccount $storageAccount -StorageKey $storageKey  -Where $emailFound            
            
                if (-not $mailAlreadyExists) {            
                    # Get required fields            
                    $DisplayForm = $true            
                } elseif ($editMode -and $session['User']) {            
                    # Get required fields            
                    $DisplayForm = $true            
                } else {            
                    # Reconfirm            
                    $DisplayForm = $false            
                }            
                            
            }            
            
                                
            $sendMailParams = @{            
                BodyAsHtml = $true            
                To = $request["Join-$($module.Name)_EmailAddress"]            
                            
            }            
                        
            $sendMailCommand = if ($pipeworksManifest.UserTable.SmtpServer -and $pipeworksManifest.UserTable.FromEmail -and $pipeworksManifest.UserTable.FromUser -and $pipeworksManifest.UserTable.EmailPasswordSetting) {            
                $($ExecutionContext.InvokeCommand.GetCommand("Send-MailMessage", "All"))            
                $un  = $pipeworksManifest.UserTable.FromUser            
                $pass = Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.EmailPasswordSetting            
                $pass = ConvertTo-SecureString $pass  -AsPlainText -Force             
                $cred =             
                    New-Object Management.Automation.PSCredential ".\$un", $pass             
                                    
                $sendMailParams += @{            
                    SmtpServer = $pipeworksManifest.UserTable.SmtpServer             
                    From = $pipeworksManifest.UserTable.FromEmail            
                    Credential = $cred            
                    UseSsl = $true            
                }            
            
            } else {            
                $($ExecutionContext.InvokeCommand.GetCommand("Send-Email", "All"))            
                $sendMailParams += @{            
                    UseWebConfiguration = $true            
                    AsJob = $true            
                }            
            }            
                        
                        
            if ($displayForm) {            
                $formErrors = if ($missingFields -and ($cmdInput.Count -ne 0)) {            
                    "Missing $missingFields"            
                } else {            
                            
                }                                            
                            
                $buttonText = if ($mailAlreadyExists -or $session['User']) {            
                    "Edit Profile"                                
                } else {            
                    "Join / Login"            
                }            
            
                            
                $response.Write("
                $FormErrors
                $(Request-CommandInput -ButtonText $buttonText -Action "${FinalUrl}?join=true" -CommandMetaData (Get-Command "Join-$($module.Name)" -CommandType Function))
                ")            
                            
            } else {            
                $session['UserEmail'] = $request["Join-$($module.Name)_EmailAddress"]            
                $session['UserData'] = $newUserData            
                $session['EditMode'] = $editMode            
                            
                            
                $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting)            
                $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting)            
            
                $email = $Session['UserEmail']            
                $editMode = $session['EditMode']            
                $session['EditMode'] = $null            
                $emailFound = [ScriptBlock]::Create("`$_.UserEmail -eq '$email'")            
            
                $userProfilePartition =            
                    if (-not $pipeworksManifest.UserTable.Partition) {            
                        "UserProfiles"            
                    } else {            
                        $pipeworksManifest.UserTable.Partition            
                    }            
            
                            
                $mailAlreadyExists =             
                    Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -StorageAccount $storageAccount -StorageKey $storageKey  -Where $emailFound |            
                    Where-Object {            
                        $_.PartitionKey -eq $userProfilePartition            
                    }            
                            
                            
                $newUserObject = New-Object PSObject -Property @{            
                    UserEmail = $Session['UserEmail']            
                    UserID = [GUID]::NewGuid()            
                    Confirmed = $false            
                    Created = Get-Date                            
                }            
                            
                            
                $ConfirmCode = [Guid]::NewGuid()            
                $newUserObject.pstypenames.clear()            
                $newUserObject.pstypenames.add("$($module.Name)_UserInfo")            
                            
                $extraPropCommonParameters = @{            
                    InputObject = $newUserObject            
                    MemberType = 'NoteProperty'            
                }            
                                    
                Add-Member @extraPropCommonParameters -Name ConfirmCode -Value "$confirmCode"            
                if ($session['UserData']) {            
                    foreach ($kvp in $session['UserData'].GetEnumerator()) {            
                        Add-Member @extraPropCommonParameters -Name $kvp.Key -Value $kvp.Value            
                    }            
                }            
                            
                $commonAzureParameters = @{            
                    TableName = $pipeworksManifest.UserTable.Name            
                    PartitionKey = $userProfilePartition            
                }            
                            
                            
                            
                if ($mailAlreadyExists) {            
                                
                                
                                
                    if ((-not $editMode) -or (-not $session['User'])) {            
                                
                        # Creating a brand new item via the email system.  Email the confirmation code out.            
                                
                                
                        $rootLocation= "$finalUrl".Substring(0, $finalUrl.LAstIndexOf("/"))            
                        $introMessage = if ($pipeworksManifest.UserTable.IntroMessage) {            
                            $pipeworksManifest.UserTable.IntroMessage + "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Confirm Email Address</a>"            
                        } else {            
                            "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Re-confirm Email Address to login</a>"            
                        }            
                                    
                        $sendMailParams += @{            
                            Subject= "Please re-confirm your email for $($module.Name)"            
                            Body = $introMessage            
                        }                                
                                    
                                    
                        & $sendMailcommand @sendMailParams             
                                    
                        "Account already exists.  A request to login has been sent to $($mailAlreadyExists.UserEmail)." |            
                            New-WebPage -Title "Email address is already registered, sending reconfirmation mail" -RedirectTo $rootLocation -RedirectIn "0:0:5"  |            
                            Out-HTML -WriteResponse                                                           #            
                                        
                        <# Send-Email -To $newUserObject.UserEmail -UseWebConfiguration - -Body $introMessage -BodyAsHtml -AsJob                
                        "Account already exists.  A request to login has been sent to $($mailAlreadyExists.UserEmail)." |
                            New-WebPage -Title "Email address is already registered, sending reconfirmation mail" -RedirectTo $rootLocation -RedirectIn "0:0:5"  |
                            Out-HTML -WriteResponse                                                           #>            
                                    
                        $mailAlreadyExists |            
                            Add-Member NoteProperty ConfirmCode "$confirmCode" -Force -PassThru |             
                            Update-AzureTable @commonAzureParameters -RowKey $mailAlreadyExists.RowKey -Value { $_}            
                    } else {            
                                    
                        # Reconfirmation of Changes.  If the user is logged in via facebook, then simply make the change.  Otherwise, make the changes pending.            
                        if (-not $pipeworksManifest.Facebook.AppId) {            
                                    
                            $introMessage =             
                            "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Please confirm changes to your $($module.Name) account</a>"                               
                                        
                            $introMessage += "<br/><br/>"            
                            $introMessage += New-Object PSObject -Property $session['UserData'] |            
                                Out-HTML            
                                     
                            $sendMailParams += @{            
                                Subject= "Please confirm changes to your $($module.Name) account"            
                                Body = $introMessage            
                            }               
                                        
                            & $sendMailcommand @sendMailParams            
                                        
                            "An email has been sent to $($mailAlreadyExists.UserEmail) to confirm the changes to your acccount" |            
                                New-WebPage -Title "Confirming Changes" -RedirectTo $rootLocation -RedirectIn "0:0:5" |            
                                Out-HTML -WriteResponse            
                                        
                            $mailAlreadyExists |            
                                Add-Member NoteProperty ConfirmCode "$confirmCode" -Force -PassThru |             
                                Update-AzureTable @commonAzureParameters -RowKey $mailAlreadyExists.RowKey -Value { $_}            
                            $changeToMake = @{} + $commonAzureParameters            
                                        
                            $changeToMake.PartitionKey = "${userProfilePartition}_PendingChanges"            
                                                            
                            # Create a row in the pending change table            
                            $newUserObject.psobject.properties.Remove('ConfirmCode')            
                            $newUserObject |            
                                Set-AzureTable @changeToMake -RowKey {[GUID]::NewGuid() }             
                        } else {            
                            # Make the profile change            
                            $newUserObject |            
                                Update-AzureTable @commonAzureParameters -RowKey $mailAlreadyExists.RowKey            
                        }            
                                    
                                        
                                        
                    }            
                                
                                
                } else {            
                                
                    if ($pipeworksManifest.UserTable.BlacklistParition) {            
                        $blackList =             
                            Search-AzureTable -TableName $pipeworks.UserTable.Name -Filter "PartitionKey eq '$($pipeworksManifest.UserTable.BlacklistParition)'"                                    
                                        
                        if ($blacklist) {            
                            foreach ($uInfo in $Blacklist) {            
                                if ($newUserObject.UserEmail -like "*$uInfo*") {            
                                    Write-Error "$($newUserObject.UserEmai) is blacklisted from $($module.Name)"            
                                    return            
                                }            
                            }            
                        }            
                    }            
                                
                    if ($pipeworksManifest.UserTable.WhitelistPartition) {            
                        $whiteList =             
                            Search-AzureTable -TableName $pipeworks.UserTable.Name -Filter "PartitionKey eq '$($pipeworksManifest.UserTable.WhitelistParition)'"                                    
                                        
                        if ($whiteList) {            
                            $inWhiteList = $false            
                            foreach ($uInfo in $whiteList) {            
                                if ($newUserObject.UserEmail -like "*$uInfo*") {            
                                    $inWhiteList = $true            
                                    break            
                                }            
                            }            
                            if (-not $inWhiteList) {            
                                Write-Error "$($newUserObject.UserEmail) is not on the whitelist for $($module.Name)"            
                            }            
                        }            
            
                    }            
                                
                    if ($pipeworksManifest.UserTable.InitialBalance) {            
                        $newUserObject |             
                            Add-Member NoteProperty Balance (0- ([Double]$pipeworksManifest.UserTable.InitialBalance))            
                    }            
                            
                    if ($session['RefferedBy']) {            
                        $newUserObject |            
                            Add-Member NoteProperty RefferedBy $session['RefferedBy'] -PassThru |            
                            Add-Member NoteProperty RefferalCreditApplied $false             
                    }            
                            
                    $newUserObject |            
                        Set-AzureTable @commonAzureParameters -RowKey $newUserObject.UserId            
                                    
                                    
                    $introMessage = if ($pipeworksManifest.UserTable.IntroMessage) {            
                        $pipeworksManifest.UserTable.IntroMessage + "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Confirm Email Address</a>"            
                    } else {            
                        "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Confirm Email Address</a>"            
                    }            
                                
                    $sendMailParams += @{            
                        Subject= "Please confirm your email for $($module.Name)"            
                        Body = $introMessage            
                    }            
                    & $sendMailcommand @sendMailParams            
                                                
                    if ($passThru) {            
                        $newUserObject            
                    }            
                                
                    $almostWelcomeScreen  = if ($pipeworksManifest.UserTable.ConfirmationMailSent) {            
                        $pipeworksManifest.UserTable.ConfirmationMailSent             
                    } else {            
                        "A confirmation mail has been sent to $($newUserObject.UserEmail)"            
                    }            
                                                
                    $html = New-Region -Content $almostWelcomeScreen -AsWidget -Style @{            
                        'margin-left' = $MarginPercentLeftString            
                        'margin-right' = $MarginPercentRightString            
                        'margin-top' = '10px'               
                        'border' = '0px'             
                    } |            
                    New-WebPage -Title "Welcome to $($module.Name) | Confirmation Mail Sent"             
                                
                    $response.Write($html)                                  
                                
                                
                }            
                            
            }            
                        
        }            
            
            
        if ($useLoginHandlers) {            
            $joinHandler = [ScriptBlock]::Create($joinHandler)            
        } else {            
            $joinHandler = {}            
        }            
        #endregion            
            
        $AddUserStat = $validateUserTable.ToString() + {             
            if (-not $session["User"]) {            
                throw "Must be logged in"            
                           
            }            
                                    
            
            
        }            
            
                    
                    
        $ShowApiKeyHandler = $validateUserTable.ToString() + {            
            if ($request.Cookies["$($module.Name)_ConfirmationCookie"]) {            
                $response.Write($request.Cookies["$($module.Name)_ConfirmationCookie"]["Key"])            
            }            
        }            
                    
        $logoutUserHandler = $validateUserTable.ToString()  + {                                    
            $secondaryApiKey = $session["$($module.Name)_ApiKey"]            
            $confirmCookie = New-Object Web.HttpCookie "$($module.Name)_ConfirmationCookie"            
            $confirmCookie["Key"] = "$secondaryApiKey"            
            $confirmCookie["CookiedIssuedOn"] = (Get-Date).ToString("r")            
            $confirmCookie.Expires = (Get-Date).AddDays(-365)                                
            $response.Cookies.Add($confirmCookie)            
            $session['User'] = $null                        
            $html = New-WebPage -Title "Logging Out" -RedirectTo "$finalUrl"            
            $response.Write($html)                                    
        }            
                    
        $loginUserHandler = $validateUserTable.ToString()  + {            
            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting)            
            $confirmCookie= $Request.Cookies["$($module.Name)_ConfirmationCookie"]            
                        
            if ($confirmCookie) {                        
                $matchApiInfo = [ScriptBLock]::Create("`$_.SecondaryApiKey -eq '$($confirmCookie.Values['Key'])'")                       
                $userFound =             
                    Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -StorageAccount $storageAccount -StorageKey $storageKey -Where $matchApiInfo             
                            
                if (-not $userFound) {            
                    $secondaryApiKey = $session["$($module.Name)_ApiKey"]            
                    $confirmCookie = New-Object Web.HttpCookie "$($module.Name)_ConfirmationCookie"            
                    $confirmCookie["Key"] = "$secondaryApiKey"            
                    $confirmCookie["CookiedIssuedOn"] = (Get-Date).ToString("r")            
                    $confirmCookie.Expires = (Get-Date).AddDays(-365)                                
                    $response.Cookies.Add($confirmCookie)            
                    $response.Flush()            
                                
                    $response.Write("User $($confirmCookie | Out-String) Not Found, ConfirmationCookie Set to Expire")                                                    
                    return            
                }                                                    
            
                $userIsConfirmed = $userFound |            
                    Where-Object {            
                        $_.Confirmed -ilike "*$true*"             
                    }            
                                
                $userIsConfirmedOnThisMachine = $userIsConfirmed |            
                    Where-Object {            
                        $_.ConfirmedOn -ilike "*$($Request['REMOTE_ADDR'] + $request['REMOTE_HOST'])*"            
                    }            
                                
                $sendMailParams = @{            
                    BodyAsHtml = $true            
                    To = $newUserObject.UserEmail            
                }            
                            
                $sendMailCommand = if ($pipeworksManifest.UserTable.SmtpServer -and             
                    $pipeworksManifest.UserTable.FromEmail -and             
                    $pipeworksManifest.UserTable.FromUser -and             
                    $pipeworksManifest.UserTable.EmailPasswordSetting) {            
                    $($ExecutionContext.InvokeCommand.GetCommand("Send-MailMessage", "All"))            
                    $un  = $pipeworksManifest.UserTable.FromUser            
                    $pass = Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.EmailPasswordSetting            
                    $pass = ConvertTo-SecureString $pass  -AsPlainText -Force             
                    $cred =             
                        New-Object Management.Automation.PSCredential ".\$un", $pass             
                    $sendMailParams += @{            
                        SmtpServer = $pipeworksManifest.UserTable.SmtpServer             
                        From = $pipeworksManifest.UserTable.FromEmail            
                        Credential = $cred            
                        UseSsl = $true            
                    }            
                                
                } else {            
                    $($ExecutionContext.InvokeCommand.GetCommand("Send-Email", "All"))            
                    $sendMailParams += @{            
                        UseWebConfiguration = $true            
                        AsJob = $true            
                    }            
                }            
                                    
                if (-not $userIsConfirmedOnThisMachine) {            
                    $confirmCode = [guid]::NewGuid()            
                    Add-Member -MemberType NoteProperty -InputObject $userIsConfirmed -Name ConfirmCode -Force -Value "$confirmCode"            
                                
                                
                    $introMessage = if ($pipeworksManifest.UserTable.IntroMessage) {            
                        $pipeworksManifest.UserTable.IntroMessage + "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Confirm Email Address</a>"            
                    } else {            
                        "<br/> <a href='${finalUrl}?confirmUser=$confirmCode'>Confirm Email Address</a>"            
                    }            
                                
                    $sendMailParams += @{            
                        Subject= "Welcome to $($module.Name)"            
                        Body = $introMessage            
                    }                                
                                
                                
                    & $sendMailcommand @sendMailParams            
            
                    # Send-Email -To $userIsConfirmed.UserEmail -UseWebConfiguration -Subject  -Body $introMessage -BodyAsHtml -AsJob            
                    $partitionKey = $userIsConfirmed.PartitionKey            
                    $rowKey = $userIsConfirmed.RowKey            
                    $tableName = $userIsConfirmed.TableName            
                    $userIsConfirmed.psobject.properties.Remove('PartitionKey')            
                    $userIsConfirmed.psobject.properties.Remove('RowKey')            
                    $userIsConfirmed.psobject.properties.Remove('TableName')                                
                    $userIsConfirmed |            
                        Update-AzureTable -TableName $tableName -RowKey $rowKey -PartitionKey $partitionKey -Value { $_}             
                                
                    $message = "User Not confirmed on this machine/ IPAddress.  A confirmation mail has been sent to $($userFound.UserEmail)"            
                                
                    $html = New-Region -Content $message -AsWidget -Style @{            
                        'margin-left' = $MarginPercentLeftString            
                        'margin-right' = $MarginPercentRightString            
                        'margin-top' = '10px'               
                        'border' = '0px'             
                    } |            
                    New-WebPage -Title "$($module.Name)| Login Error: Unrecognized Machine"                                
            
                                
                                
                    $response.Write("$html")            
                                
                                
                    return            
                } else {            
                    $session['User'] = $userIsConfirmedOnThisMachine            
                    $session['UserId'] = $userIsConfirmedOnThisMachine.UserId            
                    $welcomeBackMessage = "Welcome back " + $(            
                        if ($userIsConfirmedOnThisMachine.Name) {            
                            $userIsConfirmedOnThisMachine.Name            
                        } else {            
                            $userIsConfirmedOnThisMachine.UserEmail            
                        }            
                    )            
                                
                    $secondaryApiKey = "$($confirmCookie.Values['Key'])"                                
                                
                    $backToUrl = if ($session['BackToUrl']) {            
                        $session['BackToUrl']            
                        $session['BackToUrl'] = $null            
                    } else {            
                        $finalUrl.ToString().Substring(0,$finalUrl.ToString().LastIndexOf("/"))            
                    }            
                                
                    $html = New-Region -Content $welcomeBackMessage -AsWidget -Style @{            
                        'margin-left' = $MarginPercentLeftString            
                        'margin-right' = $MarginPercentRightString            
                        'margin-top' = '10px'               
                        'border' = '0px'             
                    } |            
                    New-WebPage -Title "Welcome to $($module.Name)" -RedirectTo $backToUrl -RedirectIn "0:0:0.125"            
                    $response.Write("$html")            
                                
                                
               
                                
                    $partitionKey = $userIsConfirmedOnThisMachine.PartitionKey            
                    $rowKey = $userIsConfirmedOnThisMachine.RowKey            
                    $tableName = $userIsConfirmedOnThisMachine.TableName            
                    $userIsConfirmedOnThisMachine.psobject.properties.Remove('PartitionKey')            
                    $userIsConfirmedOnThisMachine.psobject.properties.Remove('RowKey')            
                    $userIsConfirmedOnThisMachine.psobject.properties.Remove('TableName')                                
                    $userIsConfirmedOnThisMachine | Add-Member -MemberType NoteProperty -Name LastLogon -Force -Value (Get-Date)            
                    $userIsConfirmedOnThisMachine | Add-Member -MemberType NoteProperty -Name LastLogonFrom -Force -Value "$($Request['REMOTE_ADDR'] + $request['REMOTE_HOST'])"            
                    $userIsConfirmedOnThisMachine |            
                        Update-AzureTable -TableName $tableName -RowKey $rowKey -PartitionKey $partitionKey -Value { $_}             
                                    
                    $session['User'] = $userIsConfirmedOnThisMachine            
                }            
                            
                            
                            
            } else {            
                        
                $html = New-WebPage -Title "User Information Not Found - Redirecting to Signup Page" -RedirectTo "${finalUrl}?join=true"            
                $response.Write($html)            
                return            
            }            
            
        }            
                    
                    
        $confirmUserHandler = $validateUserTable.ToString()  + {            
                        
            $confirmationCode = [Web.HttpUtility]::UrlDecode($request['confirmUser']).TrimEnd(" ").TrimEnd("#").TrimEnd(">").TrimEnd("<")            
                        
            $session['ProfileEditMode'] = $false                        
                        
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting)            
            $confirmCodeFilter =             
                [ScriptBLock]::Create("`$_.ConfirmCode -eq '$confirmationCode'")            
            $confirmationCodeFound =             
                Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -StorageAccount $storageAccount -StorageKey $storageKey -Where $confirmCodeFilter            
                        
            if (-not $confirmationCodeFound) {            
                Write-Error "Confirmation Code Not Found"            
                return            
            }            
                                    
            $confirmedOn = ($confirmationCodeFound.ConfirmedOn + "," +            
                ($Request['REMOTE_ADDR'] + $request['REMOTE_HOST'])) -split "," -ne "" | Select-Object -Unique            
                        
            $confirmSalts = @($confirmationCodeFound.ConfirmSalt -split "\|")            
                        
            $confirmationCodeFound |             
                Add-Member NoteProperty Confirmed $true -Force            
            $confirmationCodeFound |            
                Add-Member NoteProperty ConfirmedOn ($confirmedOn -join ',') -Force            
                            
                        
            # When we confirm the item, we set two cookies.  One keeps the Secondary API key, and the other a confirmation salt.  Both are HTTP only            
            $ThisConfirmationSalt = [GUID]::NewGuid()            
            $confirmSalts += $ThisConfirmationSalt             
            $confirmationCodeFound |                            
                Add-Member NoteProperty ConfirmedOn ($confirmedOn -join ',') -Force            
<#            $confirmationCodeFound |                
                Add-Member NoteProperty ConfirmSalt ($confirmSalts -join '|') -Force
#>                        
            if (-not $confirmationCodeFound.PrimaryApiKey) {             
                $primaryApiKey  =[guid]::NewGuid()            
                $secondaryApiKey = [guid]::NewGuid()            
                $confirmationCodeFound |            
                    Add-Member NoteProperty PrimaryApiKey "$primaryApiKey" -PassThru -ErrorAction SilentlyContinue |            
                    Add-Member NoteProperty SecondaryApiKey "$secondaryApiKey" -ErrorAction SilentlyContinue              
            } else {            
                $primaryApiKey = $confirmationCodeFound.PrimaryApiKey            
                $secondaryApiKey = $confirmationCodeFound.SecondaryApiKey            
                $sessionApiKey = [Convert]::ToBase64String(([Guid]$secondaryApiKey).ToByteArray())            
                $session["$($module.Name)_ApiKey"] = $sessionApiKey            
            }            
                        
            $confirmCookie = New-Object Web.HttpCookie "$($module.Name)_ConfirmationCookie"            
            $confirmCookie["Key"] = "$secondaryApiKey"            
            $confirmCookie["CookiedIssuedOn"] = (Get-Date).ToString("r")            
            $confirmCookie["ConfirmationSalt"] = $ThisConfirmationSalt            
            $confirmCookie["Email"] = $confirmationCodeFound.UserEmail            
            $confirmCookie.Expires = (Get-Date).AddDays(365)            
            $response.Cookies.Add($confirmCookie)            
                        
                            
            $partitionKey = $confirmationCodeFound.PartitionKey            
            $rowKey = $confirmationCodeFound.RowKey            
            $tableName = $confirmationCodeFound.TableName            
            $confirmCount =$confirmationCodeFound.ConfirmCount -as [int]             
            $confirmCount++            
            $confirmationCodeFound | Add-Member NoteProperty ConfirmCount $ConfirmCount -Force            
            $confirmationCodeFound.psobject.properties.Remove('PartitionKey')            
            $confirmationCodeFound.psobject.properties.Remove('RowKey')            
            $confirmationCodeFound.psobject.properties.Remove('TableName')            
            $confirmationCodeFound.psobject.properties.Remove('ConfirmCode')            
                        
                        
            # At this point they are actually confirmed            
            $confirmationCodeFound |             
                Update-AzureTable -TableName $pipeworksManifest.UserTable.Name  -RowKey $rowKey -PartitionKey $partitionKey -Value { $_}             
                            
            if ($confirmationCodeFound.ConfirmCount -eq 1 ) {            
                $ConfirmMessage = @"
$($pipeworksManifest.UserTable.WelcomeEmailMessage)
<BR/>
Thanks for confirming,<br/>
<br/>
Your API key is: $secondaryApiKey <br/>
<br/>

Whenever you need to use a software service in $($module.Name), use this API key.

(It's also being emailed to you)
"@            
                                                        
                $html = New-Region -Content $confirmMessage -AsWidget -Style @{            
                    'margin-left' = $MarginPercentLeftString            
                    'margin-right' = $MarginPercentRightString            
                    'margin-top' = '10px'               
                    'border' = '0px'             
                } |            
                New-WebPage -Title "Welcome to $($module.Name)" -RedirectTo "${finalUrl}?login=true" -RedirectIn "0:0:5"            
                $session['User']  = Get-AzureTable -TableName $pipeworksManifest.UserTable.Name  -RowKey $rowKey -PartitionKey $partitionKey            
                $response.Write("$html")            
                            
                            
                $sendMailParams = @{            
                    BodyAsHtml = $true            
                    To = $newUserObject.UserEmail            
                }            
                            
                $sendMailCommand = if ($pipeworksManifest.UserTable.SmtpServer -and             
                    $pipeworksManifest.UserTable.FromEmail -and             
                    $pipeworksManifest.UserTable.FromUser -and             
                    $pipeworksManifest.UserTable.EmailPasswordSetting) {            
                    $($ExecutionContext.InvokeCommand.GetCommand("Send-MailMessage", "All"))            
                    $un  = $pipeworksManifest.UserTable.FromUser            
                    $pass = Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.EmailPasswordSetting            
                    $pass = ConvertTo-SecureString $pass  -AsPlainText -Force             
                    $cred =             
                        New-Object Management.Automation.PSCredential ".\$un", $pass             
                    $sendMailParams += @{            
                        SmtpServer = $pipeworksManifest.UserTable.SmtpServer             
                        From = $pipeworksManifest.UserTable.FromEmail            
                        Credential = $cred            
                        UseSsl = $true            
                    }            
                                
            
                } else {            
                    $($ExecutionContext.InvokeCommand.GetCommand("Send-Email", "All"))            
                    $sendMailParams += @{            
                        UseWebConfiguration = $true            
                        AsJob = $true            
                    }            
                }            
                            
                            
                $sendMailParams += @{            
                    Subject= "Welcome to $($module.Name)"            
                    Body = @"
$($pipeworksManifest.UserTable.WelcomeEmailMessage)
<BR/>
Thanks for confirming,<br/>
<br/>
Your API key is: $secondaryApiKey <br/>
<br/>
"@                                
                }            
                            
                & $sendMailcommand @sendMailParams             
                               
                # Send-Email -UseWebConfiguration -AsJob -To $confirmationCodeFound.UserEmail -BodyAsHtml            
                            
            } else {              
                # Check to see if this is confirming an update, and make the changes            
                $emailFilter = [ScriptBlock]::Create("`$_.UserEmail -eq '$($confirmationCodeFound.UserEmail)'")            
                $emailEditsByTime = Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -Where $emailFilter  |             
                    Sort-Object { [DateTime]$_.Timestamp }             
                            
                $userProfilePartition =            
                    if (-not $pipeworksManifest.UserTable.Partition) {            
                        "UserProfiles"            
                    } else {            
                        $pipeworksManifest.UserTable.Partition            
                    }            
                            
                $original  = $emailEditsByTime|            
                    Where-Object { $_.PartitionKey -eq $userProfilePartition } |            
                    Select-Object -First 1             
                                
                $update =  $emailEditsByTime|            
                    Where-Object { $_.PartitionKey -ne $userProfilePartition } |            
                    Select-Object -Last 1             
                            
                                                                
                if ($original -and $update) {            
                    $changeProperties = @($pipeworksManifest.UserTable.RequiredInfo.Keys) + @($pipeworksManifest.UserTable.OptionalInfo.Keys)            
                    $toChange = $update | Select-Object -First 1 | Select-Object $changeProperties             
                                
                    foreach ($prop in $toChange.psobject.properties) {            
                        $original | Add-Member NoteProperty $prop.Name $prop.Value -Force            
                    }            
            
                                
                    $original |             
                        Update-AzureTable -TableName $pipeworksManifest.UserTable.name -PartitionKey $userProfilePartition -RowKey $original.UserId -Value { $_}            
                                    
                    $userInfo  =            
                        Get-AzureTable -TableName $pipeworksManifest.UserTable.name -PartitionKey $userProfilePartition -RowKey $original.UserId            
                    $session['User']  = $userInfo            
                                
                    $update |            
                        Remove-AzureTable -Confirm:$false            
                                
                    $ConfirmMessage = @"
<BR/>
Thanks for confirming.  The following changes have been made to your account:<br/>

$($toChange | Out-HTML)
"@            
                            
                            
                } else {            
                    $ConfirmMessage = @"
$($pipeworksManifest.UserTable.WelcomeBackMessage)
<BR/>
Thanks for re-confirming, and welcome back<br/>
"@            
                }            
                            
                            
                            
                $html = New-Region -Content $confirmMessage -AsWidget -Style @{            
                    'margin-left' = $MarginPercentLeftString            
                    'margin-right' = $MarginPercentRightString            
                    'margin-top' = '10px'               
                    'border' = '0px'             
                } |            
                New-WebPage -Title "Welcome back to $($module.Name)" -RedirectTo "${finalUrl}?login=true"            
                $response.Write("$html")            
            }            
        }            
                    
                    
        $TextHandler = {            
            # Handle text input for all commands in WebCommand            
                        
                        
                                
        }            
                    
        $MeHandler = {            
            $confirmPersonHtml = . Confirm-Person -WebsiteUrl $finalUrl            
            if ($session -and $session["User"]) {            
                $profilePage = $session["User"] |             
                    Out-HTML |             
                    New-WebPage            
                $response.Write($profilePage)            
            } else {            
                throw "Not Logged In"            
            }            
        }            
            
        if (-not $useLoginHandlers) {            
            $MeHandler = {}            
        }            
                    
        $settleHandler = $validateUserTable.ToString() + {            
            if (-not ($session -and $session["User"])) {            
                throw "Not Logged in"            
            }            
                        
                        New-WebPage -RedirectTo "?Purchase=true&ItemName=Settle Account Balance&ItemPrice=$($session["User"].Balance)" |            
                Out-html -writeresponse            
        }            
            
            
        $buywithCodeHandler = $validateUserTable.ToString() + {            
                        
            if (-not $pipeworksManifest.PaymentProcessing.BuyCodeHandler) {            
                return            
            }            
            
            if (-not $pipeworksManifest.PaymentProcessing.BuyCodePartition) {            
                return            
            }            
            
            if (-not ($request -and $request["PotentialBuyCode"])) {            
                return            
            }            
            
            $storageAccount = Get-SecureSetting $pipeworksManifest.UserTable.StorageAccountSetting -ValueOnly            
            $storageKey = Get-SecureSetting $pipeworksManifest.UserTable.StorageKeySetting -ValueOnly            
            $buyCodeFound = Get-AzureTable -StorageAccount $storageAccount -StorageKey $storageAccount -PartitionKey $pipeworksManifest.PaymentProcessing.BuyCodePartition -RowKey $($request["PotentialBuyCode"])            
            if ($buyCodeFound) {            
                if (($buyCode.NumberOfUses -as [int]) -ge 0) {            
            
                } else {            
                    "Buy code not found" |             
                    New-WebPage -Title "Buy code not found" |            
                        Out-html -writeresponse            
                }            
            } else {            
                "Buy code not found" |             
                New-WebPage -Title "Buy code not found" |            
                    Out-html -writeresponse            
            }            
            <#
            
                
            } else {             
                
                
            }
            #>            
        }            
                    
            
                    
        $addCartHandler = {            
            if (-not ($request -and $request["ItemId"] -and $request["ItemName"] -and $Request["ItemPrice"])) {            
                throw "Must provide an ItemID and ItemName and ItemPrice"                
            }            
            $cartCookie = $request.Cookies["$($module.Name)_CartCookie"]            
            if (-not $cartCookie) {            
                $CartCookie = New-Object Web.HttpCookie "$($module.Name)_CartCookie"                        
            }            
            $CartCookie["Item_" + $request["ItemID"]]= $request["ItemName"] + "|" + $request["ItemPrice"]            
            $CartCookie["LastUpdatedOn"] = (Get-Date).ToString("r")            
            $CartCookie.Expires = (Get-Date).AddMinutes(60)                                
            $response.Cookies.Add($CartCookie )                        
            $response.Write("<p style='display:none'>")            
            $response.Flush()            
            return            
        }            
            
        $showCartHandler = {            
            $cartCookie = $request.Cookies["$($module.Name)_CartCookie"]            
            if (-not $cartCookie) {            
                $CartCookie = New-Object Web.HttpCookie "$($module.Name)_CartCookie"                        
            }            
                        
                        
            $cartCookie.Values.GetEnumerator()  |            
                Where-Object {            
                    $_ -like "Item_*"            
                } |            
                Foreach-Object -Begin {            
                    $items = @()            
                                
                } {            
                    $itemId = $_.Replace("Item_", "")            
                    $itemName, $itemPrice = $cartCookie.Values[$_] -split "\|"                   
                                
                    if (-not ($itemPrice -as [Double])) {            
                        if ($itemPrice.Substring(1) -as [Double]) {            
                            $itemPrice = $itemPrice.Substring(1)            
                        }            
                    }                         
                    $items+= New-Object PSObject |            
                        Add-Member NoteProperty Name $itemName -passthru |             
                        Add-Member NoteProperty Price ($itemPrice -as [Double]) -passthru             
                } -End {            
                    $subtotal = $items |             
                        Measure-Object -Sum Price |             
                        Select-Object -ExpandProperty Sum            
                    ($items | Out-HTML ) +             
                        "<HR/>" +             
                        ("<div style='float:right;text-align:right'><b>Subtotal:</b><br/><br/><span style='margin:5px'>$Subtotal</span></div><div style='clear:both'></div>")            
                }|            
                Out-HTML -WriteResponse            
            
            
            if ($session -and $session["User"]) {            
                        
            } else {            
                function Request-ContactInfo            
                {            
                    <#
                    .Synopsis
                    
                    .Description
                        Please let us know how to get in touch with you in case there's a problem with your order
                    .Example

                    #>            
                    param(            
                    # Your Name            
                    [string]            
                    $Name,            
            
                    # Your email            
                    [string]            
                    $Email,            
            
            
                    # Your Phone number            
                    [string]            
                    $PhoneNumber            
                    )            
                }            
            
                Request-CommandInput -CommandMetaData (Get-Command Request-Contactinfo) -ButtonText "Checkout" -Action "${finalUrl}?Checkout=true" | Out-HTML -WriteResponse            
                            
            }            
                        
            return            
        }            
            
            
        $checkoutCartHandler = {            
                        
            if ($pipeworksManifest.Checkout.To -and            
                $pipeworksManifest.Checkout.SmtpServer -and             
                $pipeworksManifest.Checkout.SmtpUserSetting -and             
                $pipeworksManifest.Checkout.SmtpPasswordSetting) {            
                # Email based cart, send the order along            
            
                $emailContent = $cartCookie.Values.GetEnumerator()  |            
                    Where-Object {            
                        $_ -like "Item_*"            
                    } |            
                    Foreach-Object -Begin {            
                        $items = @()            
                                
                    } {            
                        $itemId = $_.Replace("Item_", "")            
                        $itemName, $itemPrice = $cartCookie.Values[$_] -split "\|"                   
                                
                        if (-not ($itemPrice -as [Double])) {            
                            if ($itemPrice.Substring(1) -as [Double]) {            
                                $itemPrice = $itemPrice.Substring(1)            
                            }            
                        }                         
                        $items+= New-Object PSObject |            
                            Add-Member NoteProperty Name $itemName -passthru |             
                            Add-Member NoteProperty Price ($itemPrice -as [Double]) -passthru             
                    } -End {            
                        $subtotal = $items |             
                            Measure-Object -Sum Price |             
                            Select-Object -ExpandProperty Sum            
                        ($items | Out-HTML ) +             
                            "<HR/>" +             
                            ("<div style='float:right;text-align:right'><b>Subtotal:</b><br/><br/><span style='margin:5px'>$Subtotal</span></div><div style='clear:both'></div>")            
                    }            
            
            
                $emailAddress = Get-SecureSetting -Name $pipeworksManifest.Checkout.SmtpUserSetting            
                $emailPassword = Get-SecureSetting -Name $pipeworksManifest.Checkout.SmtpPasswordSetting             
            
                $emailCred = New-Object Management.Automation.PSCredential ".\$emailAddress", (ConvertTo-SecureString -AsPlainText -Force $emailPassword)            
            
            
                $to = $pipeworksManifest.Checkout.To -split "\|"            
                Send-MailMessage -SmtpServer $pipeworksManifest.Checkout.SmtpServer -From $emailAddress -UseSsl -BodyAsHtml -Body $emailContent -Subject "Order From $from" -To $to -Credential $emailCred             
            }            
        }            
            
            
        $AddPurchaseHandler = $validateUserTable.ToString() + {                                    
            if ($request["Rent"]) {            
                $isRental = $true            
                $billingFrequency = $request["BillingFrequency"]            
            } else {            
                $isRental = $false            
                $billingFrequency = ""            
            }            
            if (-not ($session -and $session["User"])) {            
                throw "Not Logged in"            
            }            
                        
            if (-not ($Request -and $request["ItemName"])) {            
                throw "Must Provide an ItemName"            
            }            
                        
            if (-not ($Request -and $request["ItemPrice"])) {            
                throw "Must Provide an ItemPrice"            
            }            
                        
            $currency = "USD"            
            if ($request -and $request["Currency"]) {            
                $currency  = $reqeust["Currency"]            
            }            
                        
            if (-not ($Request -and $request["ItemPrice"])) {            
                throw "Must Provide an ItemPrice"            
            }            
            
            $PostPaymentParameter,$postPaymentCommand = $null            
                        
            if ($session["PostPaymentCommand"]) {            
                            
                $postPaymentCommand= $session["PostPaymentCommand"]            
                if ($session["PostPaymentParameter"]) {            
                    try {            
                        $PostPaymentParameter= $session["PostPaymentParameter"]            
                    } catch {            
                    }            
            
                }            
                            
            }            
                        
                                    
            $userPart = if ($pipeworksManifest.UserTable.Partition) {            
                $pipeworksManifest.UserTable.Partition            
            } else {            
                "Users"            
            }            
                        
            $purchaseHistory = $userPart + "_Purchases"            
                        
            $purchaseId = [GUID]::NewGuid()            
                        
                        
            $purchase = New-Object PSObject            
            $purchase.pstypenames.clear()            
            $purchase.pstypenames.add('http://shouldbeonschema.org/ReceiptItem')            
                        
                        
            $purchase  = $purchase |            
                Add-Member NoteProperty PurchaseId $purchaseId -PassThru |            
                Add-Member NoteProperty ItemName $request["ItemName"] -PassThru |            
                Add-Member NoteProperty ItemPrice $request["ItemPrice"] -PassThru |            
                Add-Member NoteProperty Currency $request["Currency"] -PassThru |            
                Add-Member NoteProperty OrderTime $request["OrderTime"] -PassThru |            
                Add-Member NoteProperty UserID $session["User"].UserID -PassThru            
            
            if ($postPaymentCommand) {            
                $purchase = $purchase |            
                    Add-Member NoteProperty PostPaymentCommand $postPaymentCommand -PassThru            
            }            
            
            if ($PostPaymentParameter) {            
                $purchase  = $purchase |            
                    Add-Member NoteProperty PostPaymentParameter $PostPaymentParameter -PassThru            
            }            
                        
            $azureStorageAccount = Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting            
            $azureStorageKey= Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting            
            
            $purchase |             
                Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -PartitionKey $purchaseHistory -RowKey $purchaseId -StorageAccount $azureStorageAccount  -StorageKey $azureStorageKey            
                        
            $payLinks = ""            
            $payLinks +=             
                if ($pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -and             
                    $pipeworksManifest.PaymentProcessing.AmazonAccessKey) {            
                    Write-Link -ItemName $request["ItemName"] -Currency $currency -ItemPrice $request["ItemPrice"] -AmazonPaymentsAccountId $pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -AmazonAccessKey $pipeworksManifest.PaymentProcessing.AmazonAccessKey            
                }            
                            
                        
            $payLinks +=             
                if ($pipeworksManifest.PaymentProcessing.PaypalEmail) {            
                    Write-Link -ItemName $request["ItemName"] -Currency $currency -ItemPrice $request["ItemPrice"] -PaypalEmail $pipeworksManifest.PaymentProcessing.PaypalEmail -PaypalIPN "${FinalUrl}?-PaypalIPN" -PaypalCustom $purchaseId -Subscribe:$isRental            
                }            
            
            
                            
            $paypage = $payLinks |             
                New-WebPage -Title "Buy $($Request["ItemName"]) for $($Request["ItemPrice"])"              
                            
            $paypage|            
                Out-html -writeresponse            
            
            if ($PipeworksManifest.Mail.SmtpServer -and            
                $pipeworksManifest.Mail.SmtpUserSetting -and            
                $pipeworksManifest.Mail.SmtpPasswordSetting -and            
                $pipeworksManifest.Mail.From) {            
                $smtpServer = $pipeworksManifest.Mail.SmtpServer            
                $smtpUser = Get-WebConfigurationSetting -Setting $pipeworksManifest.Mail.SmtpUserSetting            
                $smtpPassword =  Get-WebConfigurationSetting -Setting $pipeworksManifest.Mail.SmtpPasswordSetting            
            
                $smtpCred = New-Object Management.Automation.PSCredential ".\$smtpUser",            
                    (ConvertTo-SecureString -String $smtpPassword -AsPlainText -Force)            
            
                Send-MailMessage -UseSsl -SmtpServer $smtpServer -Subject $Request["ItemName"] -Body $payPage -BodyAsHtml -Credential $smtpCred             
            }            
                        
        }            
                    
                    
                    
        $payPalIpnHandler =  $validateUserTable.ToString() + {            
                        
            $error.Clear()            
            
            $userPart =             
                if ($pipeworksManifest.UserTable.Partition) {            
                    $pipeworksManifest.UserTable.Partition            
                } else {            
                    "Users"            
                }            
                        
            $purchaseHistory = $userPart + "_Purchases"                                    
            $req = [Net.HttpWebRequest]::Create("https://www.paypal.com/cgi-bin/webscr")             
            # //Set values for the request back            
            $req.Method = "POST";            
            $req.ContentType = "application/x-www-form-urlencoded"            
                        
            $strRequest = $request.Form.ToString() +             
                "&cmd=_notify-validate";            
            $req.ContentLength = $strRequest.Length;            
             
            $parsed = [Web.HttpUtility]::ParseQueryString($strRequest)            
            
            $streamOut = New-Object IO.StreamWriter $req.GetRequestStream()            
            $streamOut.Write($strRequest);            
            $streamOut.Close();            
            $streamIn = New-Object IO.StreamReader($req.GetResponse().GetResponseStream());            
            $strResponse = $streamIn.ReadToEnd();            
            $streamIn.Close();            
             
            $azureStorageAccount = Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageAccountSetting            
            $azureStorageKey= Get-WebConfigurationSetting -Setting $pipeworksManifest.UserTable.StorageKeySetting            
                        
                        
            $custom = $Request["Custom"]            
            $ipnResponse = $strResponse            
            
            $ipn =             
                New-Object PSObject -Property @{            
                    Custom = "$custom"            
                    Request = $strRequest             
                    IPNResponse = $ipnResponse            
                    UserPart = $purchaseHistory             
                }             
            $ipn |            
                Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -RowKey { [GUID]::NewGuid() } -PartitionKey "PaypalIPN" -StorageAccount $azureStorageAccount -StorageKey $azureStorageKey            
                            
            
            if ($ipnResponse -eq "VERIFIED")            
            {            
            <#    //check the payment_status is Completed
                //check that txn_id has not been previously processed
                //check that receiver_email is your Primary PayPal email
                //check that payment_amount/payment_currency are correct
                //process payment
            #>                            
                            
                            
                            
                $filterString = "PartitionKey eq '$purchaseHistory' and RowKey eq '$($ipn.Custom)'"             
                $transactionExists = Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -Filter $filterString            
                            
                if ($transactionExists) {            
                    # Alter the user balance            
                                
                    if ($transactionExists.Processed -like "True*") {            
                        # already processed, skip            
                        New-Object PSObject -Property @{            
                            Custom = "$custom"            
                            SkippingProcessedTransaction=$true                                    
                                        
                        } |            
                            Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -RowKey { [GUID]::NewGuid() } -PartitionKey "PaypalIPN"            
            
                        return            
                    }            
            
                    $result = " "             
                    if ($request["Payment_Status"] -ne "Completed") {            
                        New-Object PSObject -Property @{            
                            Custom = $custom                                    
                            TransactionIncomplete = $request["Payment_Status"]            
                        } |            
                            Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -RowKey { [GUID]::NewGuid() } -PartitionKey "PaypalIPN"            
                    } else {            
                        $userInfo =            
                            Search-AzureTable -TableName $pipeworksManifest.UserTable.Name -Filter "PartitionKey eq '$userPart' and RowKey eq '$($transactionExists.UserID)'"            
                                    
                        $balance = $userInfo.Balance -as [Double]                                
                        $balance -= $request["payment_gross"] -as [Double]            
                        $userInfo |            
                            Add-Member NoteProperty Balance $balance -Force -PassThru |             
                            Update-AzureTable -TableName $pipeworksManifest.UserTable.Name -Value { $_ }             
                                    
                        $session["User"] = $userInfo            
            
                        if ($transactionExists.postPaymentCommand) {            
                            $postPaymentCommand = Get-Command -Module $module.Name -Name "$($transactionExists.postPaymentCommand)".Trim()            
                            $PostPaymentParameter = if ($transactionExists.postPaymentParameter) {            
                                invoke-expression "data { $($transactionExists.postPaymentParameter) }"            
                            } else {            
                                @{}            
                            }            
            
                            $extra = if ($pipeworksManifest.WebCommand."$($transactionExists.postPaymentCommand)".Trim()) {            
                                $pipeworksManifest.WebCommand."$($transactionExists.postPaymentCommand)".Trim()            
                            } else {            
                                @{}            
                            }            
            
                            if ($extra.RunWithoutInput) {            
                                $null = $extra.Remove("RunWithoutInput")                                            
                            }            
            
                            if ($extra.ParameterDefaultValue) {            
                                try {            
                                    $postPaymentParameter += $extra.ParameterDefaultValue            
                                } catch {            
                                }            
                                $null = $extra.Remove("ParameterDefaultValue")                                            
                            }            
            
            
                            if ($extra.RequireAppKey -or             
                                $extra.RequireLogin -or             
                                $extra.IfLoggedAs -or             
                                $extra.ValidUserPartition -or             
                                $extra.Cost -or             
                                $extra.CostFactor) {            
            
                                $extra.UserTable = $pipeworksManifest.Usertable.Name            
                                $extra.UserPartition = $pipeworksManifest.Usertable.Partition            
                                $extra.StorageAccountSetting = $pipeworksManifest.Usertable.StorageAccountSetting            
                                $extra.StorageKeySetting = $pipeworksManifest.Usertable.StorageKeySetting             
            
                            }            
            
                                        
                            $result = Invoke-WebCommand @extra -RunWithoutInput -PaymentProcessed -Command $postPaymentCommand -ParameterDefaultValue $PostPaymentParameter -AsEmail $userInfo.UserEmail -PlainOutput 2>&1             
                                        
                        }            
            
                        $transactionExists |            
                            Add-Member NoteProperty Processed $true -Force -PassThru |            
                            Add-Member NoteProperty CommandResult ($result | Out-Html) -force -passthru |             
                            Add-Member NoteProperty PayPalIpnID $request['Transacation_Subject'] -Force -PassThru |            
                            Update-AzureTable -TableName $pipeworksManifest.UserTable.Name -Value { $_ }             
            
            
                        $smtpServer = $pipeworksManifest.UserTable.SmtpServer            
                        if ($smtpServer) {            
            
                        }                    
                    }            
                                
                                
                                
                                
                } else {            
                    New-Object PSObject -Property @{            
                        Custom = $custom            
                        Errors = "$($error | Select-Object -First 1 | Out-String)"            
                        TransactionNotFound = $true            
                        Filter = $filterString             
                    } |            
                        Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -RowKey { [GUID]::NewGuid() } -PartitionKey "PaypalIPN"            
                }            
            } elseif ($strResponse -eq "INVALID") {            
                # //log for manual investigation            
                $strResponse            
            } else {            
                # //log response/ipn data for manual investigation            
                            
            }            
        }            
                    
                    
        $facebookConfirmUser = {            
                        
                        
            if (-not ($pipeworksManifest.Facebook.AppId -or $pipeworksManifest.Facebook.AppIdSetting)) {            
                throw 'The Pipeworks manifest must include a facebook section with an AppId or AppIdSetting'            
                return            
            }            
                        
                        
                        
            $fbAppId = $pipeworksManifest.Facebook.AppId            
                        
            if (-not $fbAppId) {            
                $fbAppId= Get-WebConfigurationSetting -Setting $pipeworksManifest.Facebook.AppIdSetting            
            }            
                        
            if (-not $fbAppId) {            
                throw "No Facebook AppID found"            
                return            
            }            
                        
                        
            if ($request.Params["accesstoken"]) {            
                $accessToken = $request.Params["accesstoken"]            
                . Confirm-Person -FacebookAccessToken $accessToken -FacebookAppId $fbAppId -WebsiteUrl $finalUrl            
            } elseif ($request.Params["code"]) {            
                $code = $request.Params["code"]            
            
                $fbSecret = Get-WebConfigurationSetting -Setting $pipeworksManifest.Facebook.AppSecretSetting            
            
                $result =Get-Web -url "https://graph.facebook.com/oauth/access_token?client_id=$fbAppId&redirect_uri=$([Web.HttpUtility]::UrlEncode("${finalUrl}?FacebookConfirmed=true"))&client_secret=$fbsecret&code=$code"            
            
                $token = [web.httputility]::ParseQueryString($result)["access_token"]                            
            
                . Confirm-Person -FacebookAccessToken $Token -FacebookAppId $fbAppId -WebsiteUrl $finalUrl            
            }            
            
                        
                        
                        
            if ($request.Params["ReturnTo"]) {            
                $returnUrl = [Web.HttpUtility]::UrlDecode($request.Params["ReturnTo"])            
                New-WebPage -AnalyticsId "" -title "Welcome to $($module.Name)" -RedirectTo $returnUrl |            
                    Out-HTML -WriteResponse            
            } elseif ($Request.Params["ThenRun"]) {             
                . $getCommandExtraInfo $Request.Params["ThenRun"]            
            
                $result =             
                    Invoke-Webcommand -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1            
            } else {            
                New-WebPage -AnalyticsId "" -title "Welcome to $($module.Name)" -RedirectTo "/" |            
                    Out-HTML -WriteResponse            
            }                                     
        }            
                    
                    
        $liveIdConfirmUserHandler = {            
            if ($request.Params["accesstoken"]) {            
                $accessToken = $request.Params["accesstoken"]            
                . Confirm-Person -liveIDAccessToken $accessToken -WebsiteUrl $finalUrl            
            } elseif ($request.Params["code"]) {            
                $code = $request.Params["code"]            
            
                $appId = $pipeworksManifest.LiveConnect.ClientId                            
                $appSecret = Get-SecureSetting -Name $pipeworksManifest.LiveConnect.ClientSecretSetting -ValueOnly            
            
                $redirectUri = if ($session["LiveIDRedirectURL"]) {            
                    $session["LiveIDRedirectURL"]            
                } elseif ($pipeworksManifest.LiveConnect.RedirectUrl) {            
                    $pipeworksManifest.LiveConnect.RedirectUrl            
                } else {            
                    $finalUrl            
                }            
            
                            
                $result =Get-Web -url "https://login.live.com/oauth20_token.srf" -RequestBody "client_id=$([Web.HttpUtility]::UrlEncode($appId))&redirect_uri=$([Web.HttpUtility]::UrlEncode($redirectUri))&client_secret=$([Web.HttpUtility]::UrlEncode($appSecret.Trim()))&code=$([Web.HttpUtility]::UrlEncode($code.Trim()))&grant_type=authorization_code" -UseWebRequest -Method POST -AsJson            
            
                            
                $token = $result.access_token            
                if (-not $Token) {            
                    New-Object PSObject -Property @{            
                        Code = $code            
                        Error = ($Error |Out-String)            
                        AppId = $appId            
                        Result = $result            
                        RedirectUrl = $redirectUri            
                    } | Out-HTML -WriteResponse            
                } else {            
                    if ($response.Cookies) {            
                        $confirmCookie = New-Object Web.HttpCookie ("LiveConnectCode_For_$($pipeworksManifest.LiveConnect.ClientID)", $code)            
                        $confirmCookie.Expires = (Get-Date).AddMinutes(15)                                
                        $response.Cookies.Add($confirmCookie)                                
                    }            
                    . Confirm-Person -LiveIDAccessToken $token -WebsiteUrl $finalUrl             
                }            
            }            
            
            
            if ($session["User"]) {            
                if ($request.Params["ReturnTo"]) {            
                    $returnUrl = [Web.HttpUtility]::UrlDecode($request.Params["ReturnTo"])            
                    New-WebPage -AnalyticsId "" -title "Welcome to $($module.Name)" -RedirectTo $returnUrl |            
                        Out-HTML -WriteResponse            
                } elseif ($Request.Params["ThenRun"]) {             
                    . $getCommandExtraInfo $Request.Params["ThenRun"]            
            
                    $result =             
                        Invoke-Webcommand -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1            
            
                    if ($result) {            
                        $result |            
                            New-WebPage            
                    }            
                } else {            
                    New-WebPage -AnalyticsId "" -title "Welcome to $($module.Name)" -RedirectTo "/" |            
                        Out-HTML -WriteResponse            
                }            
            }            
            
                        
        }                         
                    
                    
        #region Facebook Login Chunk            
        $facebookLoginDisplay = {            
            if (-not ($pipeworksManifest.Facebook.AppId -or $pipeworksManifest.Facebook.AppIdSetting)) {            
                throw 'The Pipeworks manifest must include a facebook section with an AppId or AppIdSetting'            
                return            
            }            
                        
                        
                        
            $fbAppId = $pipeworksManifest.Facebook.AppId            
                        
            if (-not $fbAppId) {            
                $fbAppId= Get-WebConfigurationSetting -Setting $pipeworksManifest.Facebook.AppIdSetting            
            }            
                        
            if (-not $fbAppId) {            
                throw "No Facebook AppID found"            
                return            
            }            
                        
            #if (-not $pipew            
            $scope = if ($pipeworksManifest -and $pipeworksManifest.Facebook.Scope) {            
                @($pipeworksManifest.Facebook.Scope) + "email" |             
                    Select-Object -Unique            
            } else {            
                "email"            
            }            
                        
                        
            $response.Write(("$(Write-Link -ToFacebookLogin -FacebookAppId $fbAppId -FacebookLoginScope $scope |
    New-WebPage -Title "Login with Facebook")"))            
                        
                                   
        }                    
        #endregion            
                    
        #region MailHandler            
        $mailHandler = {            
            $to = $request["To"]            
            $from = $Request["From"]            
            $replyTo = $request["Replyto"]            
            $body = $Request["Body"]            
            $subject= $Request["Subject"]            
            $useSsl = -not $pipeworksManifest.Mail.DoNotUseSsl            
            $smtpServer = $pipeworksManifest.Mail.SmtpServer            
            $smtpUser = Get-WebConfigurationSetting -Setting $pipeworksManifest.Mail.SmtpUserSetting            
            $smtpPassword =  Get-WebConfigurationSetting -Setting $pipeworksManifest.Mail.SmtpPasswordSetting            
                        
            if (-not $pipeworksManifest.Mail.CanSendTo) {            
                throw "Must add a CanSendTo list to the mail section"             
                            
            }            
                        
            $canSend = $false            
            foreach ($couldSendTo in $pipeworksManifest.Mail.CanSendTo) {            
                if ($to -like $couldSendto) {            
                    $canSend = $true            
                }            
                            
            }            
                        
            if (-not $canSend) {            
                throw "Cannot send mail to $to"            
            }            
                        
            $smtpCred = New-Object Management.Automation.PSCredential ".\$smtpUser",            
                (ConvertTo-SecureString -String $smtpPassword -AsPlainText -Force)            
                            
            $emailParams = @{            
                From=$from            
                To=$To            
                Body=$body+"
----
Reply To:$replyTo 
"                             
                                         
                Subject=$subject            
                UseSsl=$useSsl            
                SmtpServer=$smtpServer            
                Credential=$smtpCred                        
            }            
            Send-MailMessage @emailParams            
                        
                        
            $redirectto = $Request["RedirectTo"]            
            if ($redirectTo){            
                New-WebPage -RedirectTo $redirectTo | Out-HTML -WriteResponse            
            }            
        }            
        #endregion MailHandler            
                    
        $tableItemProcess = {            
            $BeginTableItem = {            
                $itemsToShow = @()            
            }            
            $endTableItem = {            
                $itemsToShow | Out-HTML -WriteResponse            
            }             
                        
            $ProcessEachTableItem = {            
                # If there's a content type, set the response's content type to match            
                            
                if ($_.RequireSessionHandShake -and             
                    -not $session[$_.RequireSessionHandShake]) {            
                    throw "Required Session Handshake is not present $($_.RequireSessionHandShake)"            
                    return            
                }            
                            
                if ($_.ExpirationDate -and (            
                    [DateTime]::Now -gt $_.ExpirationDate)) {            
                    throw "Content is Expired"            
                    return            
                }            
                            
                # Unpack any properties on the item without spaces (or try)            
                . $unpackItem            
                            
                if ($Request['LinkOnly']) {            
                    $item = Write-Link -Caption Name -Url $item.Url            
                }            
                if ($_.ContentType) {            
                    $response.ContentType = $_.ContentType            
                }            
                if ($_.Bytes) {                                
                    $response.BufferOutput = $true            
                    $response.BinaryWrite([Convert]::FromBase64String($_.Bytes))            
                    $response.Flush()                                    
                } elseif ($_.Xml) {            
                    $strWrite = New-Object IO.StringWriter            
                    ([xml]($_.Xml)).Save($strWrite)            
                    $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
                    if (-not $cmdOptions.ContentType) {            
                        $response.ContentType ="text/xml"            
                    }            
                    $response.Write("$resultToOutput")                
                } elseif ($_.Html) {                                
                    $itemsToShow += $_.Html            
                } else {            
                    $itemsToShow += $_                                
                }                                                            
                            
                if ($_.TimesViewed) {            
                    $timesViewed = [int]$_.TimesViewed + 1            
                    $putItBack = $_            
                    $rowKey = $_.psobject.properties['RowKey']            
                    $_.psobject.properties.Remove('RowKey')            
                    $partitionKey = $_.psobject.properties['PartitionKey']                                
                    $_.psobject.properties.Remove('PartitionKey')            
                    $tableName= $_.psobject.properties['TableName']            
                    $_.psobject.properties.Remove('TableName')            
                    $putItBack | Add-Member NoteProperty TimesViewed $timesViewed -Force            
                    $putItBack | Update-AzureTable -TableName $tableName -PartitionKey $partitionKey -RowKey $rowKey            
                }            
            }            
        }            
                    
                    
        #region SearchHandler            
        $SearchHandler = $embedUnpackItem + $tableItemProcess.ToString() + {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)            
                        
            $lastSearchTime = $application["KeywordSearchTime_$($request['Search'])"]            
            $lastResults = $application["SearchResults_$($request['Search'])"]            
                        
            # If the PipeworksManifest is going to index table data, then load this up rather than query            
            if ($pipeworksManifest.Table.IndexBy) {            
                if (-not $pipeworksManifest.Table.SqlAzureConnectionSetting) {            
                    Write-Error "Modules that index tables must also declare a SqlAzureConnectionString within the table"            
                    return            
                }            
                                        
                $connectionString = Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.SqlAzureConnectionSetting            
                $sqlConnection = New-Object Data.SqlClient.SqlConnection "$connectionString"            
                $sqlConnection.Open()            
                            
                $matchSql = @(foreach ($indexTerm in $pipeworksManifest.Table.IndexBy) {            
                    "$indexTerm like '%$($request['search'].Replace("'","''"))%'"             
                }) -join ' or '             
                                                            
                $searchSql = "select id from $($pipeworksManifest.Table.Name) where $matchSql"            
                            
                            
                $sqlAdapter= new-object "Data.SqlClient.SqlDataAdapter" ($searchSql, $sqlConnection)            
                $sqlAdapter.SelectCommand.CommandTimeout = 0            
                $dataSet = New-Object Data.DataSet             
                $null = $sqlAdapter.Fill($dataSet)            
                $allIds = @($dataSet.Tables | Select-Object -ExpandProperty Rows | Select-Object -ExpandProperty Id)            
                foreach ($id in $allIds) {            
                    if (-not $id) {             
                        continue             
                    }             
                    $part,$row = $id -split ":"            
                                
                    Get-AzureTable -TableName $pipeworksManifest.Table.Name -Row $row.Trim() -Partition $part.Trim() -StorageAccount $storageAccount -StorageKey $storageKey|             
                        ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
                }            
                            
                        
            } else {            
                Search-AzureTable -TableName $pipeworksManifest.Table.Name -Select Name, Description, Keyword, PartitionKey, RowKey -StorageAccount $storageAccount -StorageKey $storageKey |            
                ForEach-Object $UnpackItem |            
                Where-Object {                                
                    ($_.Name -ilike "*$($request['Search'])*") -or            
                    ($_.Description -ilike "*$($request['Search'])*") -or            
                    ($_.Keyword -ilike "*$($request['Search'])*") -or            
                    ($_.Keywords -ilike "*$($request['Search'])*")                                                  
                } |            
                            
                Get-AzureTable -TableName $pipeworksManifest.Table.Name |             
                    ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
                            
            }            
                        
            if (-not $lastResults) {                                  
                if (-not $application['TableIndex'] -or (-not $pipeworksManifest.Table.IndexBy)) {            
                    # If theres' not an index, or the manifest does not build one, search the table            
                    $application['TableIndex'] =             
                        Search-AzureTable -TableName $pipeworksManifest.Table.Name -Select Name, Description, Keyword, PartitionKey, RowKey -StorageAccount $storageAccount -StorageKey $storageKey            
                }            
                                                                            
            } else {            
                $lastResults |             
                    ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
            }            
        }            
        #endregion            
                    
        #region NameHandler            
        $nameHandler = $tableItemProcess.ToString() + $embedUnpackItem + {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)            
            $nameMatch  =([ScriptBLock]::Create("`$_.Name -eq '$($request['name'])'"))            
            Search-AzureTable -Where $nameMatch -TableName $pipeworksManifest.Table.Name -StorageAccount $storageAccount -StorageKey $storageKey |             
                ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
        }            
        #endregion            
                    
                           
        #region LatestHandler            
        $latestHandler = $tableItemProcess.ToString() + $embedUnpackItem +  {            
            $PartitionKey = $request['Latest']            
        } + $refreshLatest + {            
            $latest |                             
                ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
        }             
        #endregion LatestHandler            
                    
        #region RssHandler            
        $rssHandler = $embedUnpackItem + {            
            $PartitionKey = $request['Rss']            
        } + $refreshLatest.ToString() + {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)                        
            $finalSite = $finalUrl.ToString().Substring(0,$finalUrl.ToString().LastIndexOf("/"))            
            
            $blogName =             
                if ($pipeworksManifest.Blog.Name) {            
                    $pipeworksManifest.Blog.Name            
                } else {            
                    $module.Name            
                }            
                            
            $blogDescription =             
                if ($pipeworksManifest.Blog.Description) {            
                    $pipeworksManifest.Blog.Description            
                } else {            
                    $module.Description            
                }            
                            
            $syncTime = [Datetime]::Now - [Timespan]"0:20:0"            
            if (-not ($session["RssFeed$($blogName)LastSyncTime"] -ge $syncTime)) {            
                $session["RssFeed$($blogName)"] = $null            
            }            
                       
            
            if (-not $session["RssFeed$($blogName)"]) {            
                        
                $feedlength = if ($pipeworksManifest.Blog.FeedLength -as [int]) {            
                    $pipeworksManifest.Blog.FeedLength -as [int]            
                } else {            
                    25            
                }            
                            
                if ($feedLength -eq -1 ) { $feedLength = [int]::Max }             
                            
                $getDateScript = {            
                    if ($_.DatePublished) {            
                        [DateTime]$_.DatePublished            
                    } elseif ($_.TimeCreated) {            
                        [DateTime]$_.TimeCreated            
                    } elseif ($_.TimeGenerated) {            
                        [DateTime]$_.TimeGenerated            
                    } elseif ($_.Timestamp) {            
                        [DateTime]$_.Timestamp            
                    } else {            
                        Get-Date            
                    }            
                }            
                            
                $rssFeed =             
                    Search-AzureTable -TableName $pipeworksManifest.Table.Name -Filter "PartitionKey eq '$PartitionKey'" -Select Timestamp, DatePublished, PartitionKey, RowKey -StorageAccount $storageAccount -StorageKey $storageKey |            
                    Sort-Object $getDateScript -Descending  |            
                    Select-Object -First $feedlength |             
                    Get-AzureTable -TableName $pipeworksManifest.Table.Name |            
                    ForEach-Object $UnpackItem |            
                    New-RssItem -Title  {            
                        if ($_.Name) {                                
                            $_.Name            
                        } else {            
                            ' '            
                        }            
                    } -DatePublished $getDateScript -Author {             
                        if ($_.Author) { $_.Author} else { ' '  }             
                    } -Url {            
                        if ($_.Url) {            
                            $_.Url            
                        } else {            
                            "$($finalSite.TrimEnd('/') + '/')?post=$($_.Name)"            
                        }            
                    } |                             
                    Out-RssFeed -Title $blogName -Description $blogDescription -ErrorAction SilentlyContinue -Link $finalSite                             
                $session["RssFeed$($blogName)"] = $rssFeed            
                $session["RssFeed$($blogName)LastSyncTime"]  = Get-Date            
            } else {            
                $rssFeed = $session["RssFeed$($blogName)"]            
            }            
                        
            $response.ContentType = 'text/xml'            
            $response.Write($rssFeed)            
        }            
        #endregion RssHandler            
                    
        #region TypeHandler            
        $typeHandler = $tableItemProcess.ToString() + $embedUnpackItem +{            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)            
            $nameMatch  =([ScriptBLock]::Create("`$_.psTypeName -eq '$($request['Type'])'"))            
            Search-AzureTable -Where $nameMatch -TableName $pipeworksManifest.Table.Name -StorageAccount $storageAccount -StorageKey $storageKey |             
                ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
        }            
        #endregion TypeHandler            
                            
                    
            
            
        #region IdHandler            
        $idHandler = $tableItemProcess.ToString() + $embedUnpackItem + {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
                        
            $partition, $row = $request['id'] -split ':'                   
                                         
            <#$rowMatch= [ScriptBLock]::Create("`$_.RowKey -eq '$row'")
            $partitionMatch = [ScriptBLock]::Create("`$_.PartitionKey -eq '$partition'")
            #>            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)            
            Search-AzureTable -TableName $pipeworksManifest.Table.Name -StorageAccount $storageAccount -StorageKey $storageKey -Filter "RowKey eq '$row' and PartitionKey eq '$partition'" |            
                ForEach-Object -Begin $BeginTableItem -Process $ProcessEachTableItem -End $EndTableItem            
                        
                         
                        
        }            
        #endregion            
            
                            
        #region PrivacyPolicyHandler            
            
        $privacyPolicyHandler = {            
$siteUrl = $finalUrl.ToString().Substring(0, $finalUrl.LastIndexOf("/")) + "/"            
$OrgInfo = if ($module.CompanyName) {            
    $module.CompanyName            
} elseif ($pipeworksManifest.Organization.Name) {            
    $pipeworksManifest.Organization.Name            
} else {            
    " THE COMPANY"            
}            
            
$policy = if ($pipeworksManifest.PrivacyPolicy) {            
    $pipeworksManifest.PrivacyPolicy                
} else {            
            
@"
<!-- START PRIVACY POLICY CODE -->
<div style="font-family:arial">
  <strong>What information do we collect?</strong>
  <br />
  <br />
We ( $OrgInfo ) collect information from you when you register on our site ( $siteUrl ) or place an order.  <br /><br />
When ordering or registering on our site, as appropriate, you may be asked to enter your: name, e-mail address or phone number. You may, however, visit our site anonymously.<br /><br />
Google, as a third party vendor, uses cookies to serve ads on your site.
Google's use of the DART cookie enables it to serve ads to your users based on their visit to your sites and other sites on the Internet.
Users may opt out of the use of the DART cookie by visiting the Google ad and content network privacy policy..<br /><br /><strong>What do we use your information for?</strong><br /><br />
Any of the information we collect from you may be used in one of the following ways: <br /><br />
<br/>
 To personalize your experience<br />
(your information helps us to better respond to your individual needs)<br /><br />
<br/>
To improve our website<br />
(we continually strive to improve our website offerings based on the information and feedback we receive from you)<br /><br />
<br/>
To improve customer service<br />
(your information helps us to more effectively respond to your customer service requests and support needs)<br /><br />
<br/>
To process transactions<br /><blockquote>Your information, whether public or private, will not be sold, exchanged, transferred, or given to any other company for any reason whatsoever, without your consent, other than for the express purpose of delivering the purchased product or service requested.</blockquote><br />
<br/>To send periodic emails<br /><blockquote>The email address you provide for order processing, may be used to send you information and updates pertaining to your order, in addition to receiving occasional company news, updates, related product or service information, etc.</blockquote><br /><br /><strong>How do we protect your information?</strong><br /><br />
We offer the use of a secure server. All supplied sensitive/credit information is transmitted via Secure Socket Layer (SSL) technology and then encrypted into our Payment gateway providers database only to be accessible by those authorized with special access rights to such systems, and are required to?keep the information confidential.<br /><br />
After a transaction, your private information (credit cards, social security numbers, financials, etc.) will not be stored on our servers.<br /><br /><strong>Do we use cookies?</strong><br /><br />
Yes (Cookies are small files that a site or its service provider transfers to your computers hard drive through your Web browser (if you allow) that enables the sites or service providers systems to recognize your browser and capture and remember certain information<br /><br />
 We use cookies to help us remember and process the items in your shopping cart, understand and save your preferences for future visits and keep track of advertisements and .<br /><br /><strong>Do we disclose any information to outside parties?</strong><br /><br />
We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our website, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.<br /><br /><strong>Third party links</strong><br /><br />
 Occasionally, at our discretion, we may include or offer third party products or services on our website. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.<br /><br /><strong>California Online Privacy Protection Act Compliance</strong><br /><br />
Because we value your privacy we have taken the necessary precautions to be in compliance with the California Online Privacy Protection Act. We therefore will not distribute your personal information to outside parties without your consent.<br /><br /><strong>Online Privacy Policy Only</strong><br /><br />
This online privacy policy applies only to information collected through our website and not to information collected offline.<br /><br /><strong>Your Consent</strong><br /><br />
By using our site, you consent to our web site privacy policy.<br /><br /><strong>Changes to our Privacy Policy</strong><br /><br />
If we decide to change our privacy policy, we will post those changes on this page.


Hope this Helps,

$OrgInfo
"@                    
}            
            
            $response.Write("$policy")                
            return            
        }            
        #endregion            
            
        #region Anything Handler            
        $anythingHandler = $tableItemProcess.ToString() + $embedUnpackItem + {                    
            $anythingHandlerStartedAt = [DateTime]::Now            
                        
            # Determine the Relative Path, Full URL, and Depth            
                                    
            # First, parse and chunk the full path, so we can see what to do with it            
                                      
                                            
            
            
            # Create a Social Row (Facebook Likes, Google +1, Twitter)            
            if (-not $script:SocialArea) {            
                            
            
               $script:SocialArea = "
$(
    if (-not $antiSocial) {
        if ($pipeworksManifest -and ($pipeworksManifest.Facebook.AppId -or $pipeworksManifest.FacebookLike)) {
            
                        
            Write-Link "facebook:like"
                        
        }
        if ($pipeworksManifest -and ($pipeworksManifest.GoogleSiteVerification -or $pipeworksManifest.AddPlusOne)) {
            
                        
            Write-Link "google:plusone"
                        
        }
        if ($pipeworksManifest -and $pipeworksManifest.ShowTweet) {
            Write-Link "twitter:tweet"
                        
        } elseif ($pipeworksManifest -and ($pipeworksManifest.TwitterId)) {
            Write-Link "twitter:tweet"
                        
            
                        
            Write-Link "twitter:follow@$($pipeworksManifest.TwitterId.TrimStart('@'))"                        
        }
    }
)
               "            
            }            
            
            $socialArea = $script:SocialArea            
                        
                                 
                        
            $relativeUrlParts = @($relativeUrl.Split("/", [StringSplitOptions]"RemoveEmptyEntries"))            
            $linkUrl = "$FinalUrl".Substring(0, "$FinalUrl".LastIndexOf("/"))            
            $titleArea =             
                if ($PipeworksManifest -and $pipeworksManifest.Logo) {            
                    "<a href='$linkUrl'><img src='$($pipeworksManifest.Logo)' alt='$($module)' style='border:0' /></a>"            
                } else {            
                    "<a href='$linkUrl'>" + $Module.Name + "</a>"            
                }                         
            
            
            
            $rest = ""            
            
            
            
            # If there was more than ne additional part of the URL, it could be:            
            # - A Command            
            # - A Help Topic            
            # - A Walkthru            
            # - A Schema            
            # - The user's profile            
            if ($relativeUrlParts.Count -ge 1) {            
                # If it's a command, invoke the command            
                $found = $false            
            
                $plainOutput = $false            
                $part = $RelativeUrlParts[0]            
                if ($module.ExportedFunctions.$part -or             
                    $module.ExportedAliases.$part -or             
                    $module.ExportedCmdlets.$part -or (            
                    (-not $pipeworksManifest.IgnoreBuiltInCommand) -and             
                    $ExecutionContext.SessionState.InvokeCommand.GetCommand("$part", "Alias,Function,Cmdlet")            
                    )) {            
                                
                    $found = $true            
                    if ($module.ExportedAliases.$part) {            
                        $command = $module.ExportedAliases.$part            
                    } elseif ($module.ExportedFunctions.$part) {            
                        $command = $module.ExportedFunctions.$part            
                    } elseif ($module.ExportedCmdlets.$part) {            
                        $command = $module.ExportedCmdlets.$part            
                    } elseif (-not $pipeworksManifest.IgnoreBuiltInCommand) {            
                        $command = @($ExecutionContext.SessionState.InvokeCommand.GetCommand("$part", "Alias,Function,Cmdlet"))[0]            
                    }            
            
                    # The display name of the command.  By default, the alias or the command            
                    $displayedCommand = "$command"            
                                
                    if ($command.ResolvedCommand) {            
                        $command = $command.ResolvedCommand            
                    }            
            
            
                    #$titleArea = $displayedCommand            
                                
                    if ($command) {            
                        $found = $true            
                    }            
                    $commandDescription  = ""                             
                                
                                
                    # Cache the command help for performance            
                    $commandHelp =             
                        if (-not $script:CachedCommandHelp) {            
                            $script:CachedCommandHelp = @{}            
                            $script:CachedCommandHelp.$command = @(Get-Help $command -ErrorAction SilentlyContinue)[0]            
                            $script:CachedCommandHelp.$command            
                        } else {            
                            if (-not $script:CachedCommandHelp.$command) {            
                                $script:CachedCommandHelp.$command = @(Get-Help $command -ErrorAction SilentlyContinue)[0]            
                            }            
                            $script:CachedCommandHelp.$command            
                        }            
                                
                    if ($commandHelp.Description) {            
                        $commandDescription = $commandHelp.Description[0].text            
                        $commandDescription = $commandDescription -replace "`n", ([Environment]::NewLine)             
                    }            
            
                    $Friendlyname = if ($pipeworksManifest.WebCommand.($command.Name).FriendlyName) {            
                        $pipeworksManifest.WebCommand.($command.Name).FriendlyName            
                    } else {            
                        $Command.Name            
                    }            
                                
                    # Set the title variable, in the hopes that the templates will pick up on it later            
                    $title = $Friendlyname            
            
                    if (-not $script:CachedCommandDescription) {            
                        $script:CachedCommandDescription = @{}            
                    }            
                    if (-not $script:CachedCommandDescription.$Command) {            
                        $script:CachedCommandDescription.$Command = "                    
<div style='font-size:1.11em;margin-top:1%;margin-left:3%;vertical-align:middle'>
    $Friendlyname
    <div style='font-size:.66em;margin-top:1%;margin-left:3%;vertical-align:middle'>                        
        $(ConvertFrom-Markdown -Markdown "$commandDescription ")
    </div>
</div>"            
            
                    }            
                    $descriptionArea = $script:CachedCommandDescription.$Command            
                    $extraParams = if ($pipeworksManifest -and $pipeworksManifest.WebCommand.($Command.Name)) {                            
                        @{} + $pipeworksManifest.WebCommand.($Command.Name)            
                    } elseif ($pipeworksManifest -and $pipeworksManifest.WebAlias.($Command.Name) -and            
                        $pipeworksManifest.WebCommand.($pipeworksManifest.WebAlias.($Command.Name).Command)) {             
                            
                        $webAlias = $pipeworksManifest.WebAlias.($Command.Name)            
                        $paramBase = $pipeworksManifest.WebCommand.($pipeworksManifest.WebAlias.($Command.Name).Command)            
                        foreach ($kv in $webAlias.GetEnumerator()) {            
                            if (-not $kv) { continue }            
                            if ($kv.Key -eq 'Command') { continue }            
                            $paramBase[$kv.Key] = $kv.Value            
                        }            
            
                        @{} + $paramBase            
                    } else {             
                        # It's not a command we "trust", so display help            
                        @{            
                            ShowHelp = $true            
                        }             
                    }                         
                                
                    if ($pipeworksManifest -and $pipeworksManifest.Style -and (-not $extraParams.Style)) {            
                        $extraParams.Style = $pipeworksManifest.Style             
                    }            
            
            
                    # Change the display name of the command has a friendly name            
                    if ($extraParams.FriendlyName) {            
                        $displayedCommand = $extraParams.FriendlyName            
                    }            
            
            
                    if ($extraParams.Count -gt 1) {            
                        # Very explicitly make sure it's there, and not explicitly false            
                        if (-not $extra.RunOnline -or             
                            $extraParams.Contains("RunOnline") -and $extaParams.RunOnline -ne $false) {            
                            $extraParams.RunOnline = $true                                 
                        }                            
                    }             
                                
                    if ($extaParams.PipeInto) {            
                        $extaParams.RunInSandbox = $true            
                    }            
                                
                    if (-not $extraParams.AllowDownload) {            
                        $extraParams.AllowDownload = $allowDownload            
                    }            
                                
                    if ($extraParams.RunOnline) {            
                        # Commands that can be run online            
                        $webCmds += $command.Name            
                    }            
                                
                    if ($extraParams.RequireAppKey -or             
                        $extraParams.RequireLogin -or             
                        $extraParams.IfLoggedAs -or             
                        $extraParams.ValidUserPartition -or             
                        $extraParams.Cost -or             
                        $extraParams.CostFactor) {            
            
                        $extraParams.UserTable = $pipeworksManifest.UserTable.Name            
                        $extraParams.UserPartition = $pipeworksManifest.UserTable.Partition            
                        $extraParams.StorageAccountSetting = $pipeworksManifest.Usertable.StorageAccountSetting            
                        $extraParams.StorageKeySetting = $pipeworksManifest.Usertable.StorageKeySetting             
            
                    }            
                                
                    if ($extraParams.AllowDownload) {            
                        # Downloadable Commands            
                        $downloadableCommands += $command.Name                            
                    }            
                                            
                                                                                            
                    if ($MarginPercentLeftString -and (-not $extraParams.MarginPercentLeft)) {            
                        $extraParams.MarginPercentLeft = $MarginPercentLeftString.TrimEnd("%")            
                    }            
                                
                    if ($MarginPercentRightString-and -not $extraParams.MarginPercentRight) {            
                        $extraParams.MarginPercentRight = $MarginPercentRightString.TrimEnd("%")            
                    }            
                                                        
                    
                    if ($relativeUrlParts.Count -gt 1 ) {            
                        $commandMetaData = $command -as [Management.Automation.CommandMetadata]            
                                    
                        $hideParameter = if ($extraParams.HideParameter) {            
                            @($extraParams.HideParameter )            
                        } else {            
                            @()            
                        }            
            
                                    
                                    
                        $allowedParameter  = $CommandMetaData.Parameters.Keys             
                        
                        # Remove the denied parameters            
                        $allParameters = foreach ($param in $allowedParameter) {            
                            if ($hideParameter -notcontains $param) {            
                                $param            
                            }            
                        }            
                        
                        $order =             
                             @($allParameters|             
                                Select-Object @{            
                                    Name = "Name"            
                                    Expression = { $_ }            
                                },@{            
                                    Name= "NaturalPosition"            
                                    Expression = {             
                                        $p = @($commandMetaData.Parameters[$_].ParameterSets.Values)[0].Position            
                                        if ($p -ge 0) {            
                                            $p            
                                        } else { 1gb }                                                          
                                    }            
                                } |            
                                Where-Object {                                               
                                    $_.NaturalPosition -ne 1gb                                                 
                                } |            
                                Sort-Object NaturalPosition|             
                                Select-Object -ExpandProperty Name)            
                        $cmdPart, $orderedParams = @($relativeUrlParts |            
                            Where-Object {            
                                -not "$_".Contains("?")            
                            })            
                                    
                        if (-not $extraParams.ParameterDefaultValue) {            
                             $extraParams.ParameterDefaultValue = @{}            
                        }            
            
            
            
                        # If there were ordered parameters, we can supply them via the URL (i.e. Measure-Sum/1/2/3/4/)            
            
                        if ($orderedParams) {            
                            $orderedParams = @($orderedParams)            
                            $lastParameter = $null            
                            for ($n =0 ;$n -lt $orderedParams.Count;$n++) {                                                                            
            
                                $ParameterValue = [Web.HttpUtility]::UrlDecode($orderedParams[$n])            
                                            
                                if ($n -ge $order.Count) {            
                                    $acceptsRemainingArguments = $command.Parameters.$($order[$order.Count -1]).Attributes |             
                                        Where-Object {$_.ValueFromRemainingArguments }             
                                    if ($acceptsRemainingArguments) {            
                                        if ($command.Parameters.$($order[$order.Count -1]).ParameterType.IsSubclassOf([Array])) {            
                                            $extraParams.ParameterDefaultValue.($order[$order.Count -1]) = @($extraParams.ParameterDefaultValue.($order[$order.Count -1])) + $parameterValue            
                                        } elseif ($command.Parameters.$($order[$order.Count -1]).ParameterType -is [ScriptBlock]) {            
                                            $extraParams.ParameterDefaultValue.($order[$order.Count -1]) = [ScriptBlock]::Create(($extraParams.ParameterDefaultValue.($order[$order.Count -1])).ToString() + $parameterValue)            
                                        } else {            
                                            $extraParams.ParameterDefaultValue.($order[$order.Count -1]) += $ParameterValue            
                                        }                                                    
                                    }            
                                    #$command.Parameter.$($order[$n])            
                                } else {            
                                    $extraParams.ParameterDefaultValue.($order[$n]) = $ParameterValue            
                                                
                                    if ($command.Parameters.($order[$n]).ParameterType -eq             
                                        [ScriptBlock]) {            
                                        $extraParams.ParameterDefaultValue.($order[$n]) =            
                                            [ScriptBlock]::Create($extraParams.ParameterDefaultValue.($order[$n]))            
                                    }            
                                }            
            
                                if ($extraParams.ParameterDefaultValue.Count) {            
                                    $extraParams.RunWithoutInput = $true            
                                }                                            
                            }            
                        }            
                    }            
                                
            
                    if ($extraParams.DefaultParameter -and $extraParams.ParameterDefaultValue) {            
                        # Reconcile aliases            
            
            
                        $combinedTable = @{}            
                        foreach ($kv in $extraParams.ParameterDefaultValue.GetEnumerator()) {            
                            $combinedTable[$kv.Key] = $kv.Value            
                        }            
                        foreach ($kv in $extraParams.DefaultParameter.GetEnumerator()) {            
                            $combinedTable[$kv.Key] = $kv.Value                                        
                        }            
            
                        $null = $extraParams.Remove('DefaultParameter')            
                        $extraParams['ParameterDefaultValue'] = $combinedTable            
                    }            
                                                    
            
            
                    $StartedInvokeWebCommand = [DateTime]::now            
                    # Run the command.            
                    $rest = $result =             
                        try {            
                            Invoke-Webcommand -Command $command @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1            
                        } catch {            
                            $_                    
                        }            
                    $TimeSpentInInvokeWebCommand = [DateTime]::now - $StartedGeneratingCoreContent                                
                                                    
                    if ($result) {            
                                    
                        if ($result -is [Management.Automation.ErrorRecord]) {            
                            $result = "$($result | Out-String -Width 10kb)"            
                        } elseif ($result -is [Exception]) {            
                            $result = "$($result | Out-String -Width 10kb)"            
                        }            
            
                        $ifTemplateFound = @{}            
                        if ($pipeworksManifest.TemplateFiles.$Command) {            
                            $ifTemplateFound.Template = $command            
                        } elseif ($pipeworksManifest.CommandTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.CommandTemplate            
                        } elseif ($pipeworksManifest.DefaultTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
                        } elseif ($pipeworksManifest.Template) {            
                            $ifTemplateFound.Template =$pipeworksManifest.Template            
                        }            
                                    
                        if ($Request.params["AsRss"] -or             
                            $Request.params["AsCsv"] -or            
                            $Request.params["AsXml"] -or            
                            $Request.Params["bare"] -or             
                            $extraParams.ContentType -or            
                            $extraParams.PlainOutput) {            
                                        
                                            
            
            
                                $realOrder = @()            
                                $navBarData = @{}            
                                $navBarOrder = @{}            
                                $navBarUrls = @{}            
                                $cmdTabs = @{}            
                                $cmdUrls = @{}            
            
                                        
                            if (((-not $extraParams.ContentType)) -or (            
                                $extraParams.ContentType -notlike "text*" -and             
                                $result -is [string]            
                                ) -or (            
                                $extraParams.ContentType -eq "text/html" -and             
                                $result -like "*class=?$($command)*"            
                                ) -or (            
                                $result -is [string] -and            
                                $result -like "*class=?$($command)*"            
                                )) {            
                                            
                                # If it's not HTML or XML, but contains tags            
                                $rest = $result            
                                if ($request["inline"]) {            
                                    $response.Write($result)            
                                } elseif ($request["Snug"] -or $request["Widget"]) {            
                                    $outputPage = "<div style='clear:both;margin-top:1%'> </div>" + $result |            
                                        New-Region -Style @{            
                                            "margin-left" = "3%"            
                                            "margin-right" = "3%"            
                                        }|            
                                        New-WebPage -Title "$($module.Name) | $displayedCommand"            
                                    $response.Write($outputPage)            
                                } else {            
                                            
                                if (-not $script:CachedNavBar.($module.Name)) {            
                                    if (-not $script:CachedNavBar) {            
                                        $script:CachedNavBar = @{}                                                    
                                    }            
                                                
                                    . $getGroups -NavBarOnly                  
            
                                    $navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {            
                
                
    New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
} elseif ($navBarData) {            
    New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
} else {            
    ""            
}            
            
                                    if ($cancacheGroups) {            
                                        $script:CachedNavBar.($module.Name) = $navBarHtml            
                                    }            
                                                                              
                                } else {            
                                    $navBarHtml = $script:CachedNavBar.($module.Name)             
                                }            
            
            
                                            
            
                                . $getBanners            
            
            
            
                                            
"
<div style='float:right;position:absolute;zindex:30;right:15px;top:15px;'>
$socialArea
</div>
<div style='float:left'>
<h1 style='float:left'>$titleArea</h1>
<h2 style='text-align:right;float:left;margin-top:75px;margin-left:50px'>
$descriptionArea 
</h2>
$navBarHtml
</div>
$spacingDiv
$spacingDiv
$spacingDiv
<div style='clear:both;margin-top:1%'>$upperBannerSlot</div>
$rest 
<div style='clear:both;margin-top:1%'>$bottomBannerSlot</div>
<div style='float:right;margin-top:15%'>$brandingSlot</div>
" |             
                            New-Region -Style @{            
                                "Margin-Left" = $marginPercentLeftString            
                                "Margin-Right" = $marginPercentLeftString            
                            } |            
                            New-WebPage -Title "$($module.Name) | $displayedCommand" @ifTemplateFound |            
                            Out-HTML -WriteResponse            
                                return            
                                            
                            }            
                            } else {            
                                $plainOutput = $true            
                                if ($result -and $extraParams.ContentType ) {            
                                    if ((            
                                        $result -is [string] -and            
                                        $result -like "*class=?$($command)*"            
                                        )-or (            
                                        $extraParams.ContentType -ne "text/html" -and             
                                        $result -like "*class=?$($command)*"            
                                        ) -or (            
                                        $extraParams.ContentType -notlike "text*" -and             
                                        $result -is [string]            
                                        )) {            
                                        if (-not $script:CachedNavBar.($module.Name)) {            
                                            if (-not $script:CachedNavBar) {            
                                                $script:CachedNavBar = @{}                                                    
                                            }            
            
                                            . $getGroups -NavBarOnly                  
            
                                            $navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {            
                
                
            New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
        } elseif ($navBarData) {            
            New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
        } else {            
            ""            
        }            
            
                                            if ($cancacheGroups) {            
                                                $script:CachedNavBar.($module.Name) = $navBarHtml            
                                            }            
                                                                              
                                        } else {            
                                            $navBarHtml = $script:CachedNavBar.($module.Name)             
                                        }            
            
                                        . $getBanners            
            
            
                                        $navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {            
                
                
                                            New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
                                        } elseif ($navBarData) {            
                                            New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
                                        } else {            
                                            ""            
                                        }              
            
                                        New-WebPage -Title "$($module.Name) | $displayedCommand" @ifTemplateFound |            
                                        Out-HTML -WriteResponse            
                                    } else {            
                                        $response.ContentType=  $extraParams.ContentType            
                                        if ($global:ContentDisposition) {            
                                            $null = $response.Headers.Add('content-disposition', $global:ContentDisposition.ToString())            
                                            $global:ContentDisposition = $null            
                                        }            
                                        $response.Write("$result")            
                                    }            
                                } elseif ($result) {            
                                    $response.Write($result)            
                                }            
                            }            
                                        
                        }             
                        else {            
                            if (($result -is [Collections.IEnumerable]) -and ($result -isnot [string])) {            
                                $Result = $result | Out-HTML                                            
                            }            
            
                            $rest = $result            
            
                            if ($request["inline"]) {            
                                $response.Write($result)            
                            } elseif ($request["Snug"] -or $Request["Widget"]) {            
                                $outputPage = "<div style='clear:both;margin-top:1%'> </div>" + $result |            
                                    New-Region -Style @{            
                                        "margin-left" = "3%"            
                                        "margin-right" = "3%"            
                                    }|            
                                    New-WebPage -Title "$($module.Name) | $displayedCommand"            
                                $response.Write($outputPage)            
                            } else {            
            
                                            
                                $rest = $result            
                                            
                                            
                                $realOrder = @()            
                                $navBarData = @{}            
                                $navBarOrder = @{}            
                                $navBarUrls = @{}            
                                $cmdTabs = @{}            
                                $cmdUrls = @{}            
            
                                if (-not $script:CachedNavBar.($module.Name)) {            
                                    if (-not $script:CachedNavBar) {            
                                        $script:CachedNavBar = @{}                                                    
                                    }            
            
                                    . $getGroups -NavBarOnly                  
            
                                    $navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {            
                
                
    New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
} elseif ($navBarData) {            
    New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
} else {            
    ""            
}            
            
                                    if ($cancacheGroups) {            
                                        $script:CachedNavBar.($module.Name) = $navBarHtml            
                                    }            
                                                                              
                                } else {            
                                    $navBarHtml = $script:CachedNavBar.($module.Name)             
                                }            
            
                                . $getBanners            
            
                                            
" " |            
                            New-Region -Style @{            
                                "Margin-Left" = $marginPercentLeftString            
                                "Margin-Right" = $marginPercentLeftString            
                            } |            
                            New-WebPage -Title "$($module.Name) | $displayedCommand" @ifTemplateFound |            
                            Out-HTML -WriteResponse            
                            return            
                            }            
                                        
                        }                            
                    }                                
                } elseif (($relativeUrlParts[0].EndsWith("-?")) -or             
                    ($relativeUrlParts[1] -eq '-?')) {            
                    $CommandNameGuess = $RelativeUrlParts[0].TrimEnd("?").TrimEnd("-")            
                                
                                
                    $command = $module.ExportedCommands[$commandNameGuess]            
                    if ($command) {            
                        $extraParams = if ($pipeworksManifest -and $pipeworksManifest.WebCommand.($Command.Name)) {                            
                            @{} + $pipeworksManifest.WebCommand.($Command.Name)            
                        } else { @{} }                         
                        $extraParams.ShowHelp = $true            
                        $result =Invoke-WebCommand -Command $command @extraParams -ServiceUrl $finalUrl 2>&1            
            
                    }            
            
                                
                    if ($result) {            
                                    
                        $result |            
                            New-Region -Style @{            
                                "Margin-Left" = $marginPercentLeftString            
                                "Margin-Right" = $marginPercentLeftString            
                            }|            
                            New-WebPage -Title "$($module.Name) | $displayedCommand" @ifTemplateFound |            
                            Out-HTML -WriteResponse             
                                    
                    }            
                    return            
                }            
                            
                            
                            
                            
                $potentialTopicName = $relativeUrlParts[0].Replace("+"," ").Replace("_", " ").Replace("%20"," ")            
                $potentialTopicName =  [Regex]::Replace($potentialTopicName ,             
                        "\b(\w)",             
                        { param($a) $a.Value.ToUpper() })                                                             
                # If it's a topic, display the topic            
                $theTopic = foreach ($top in $aboutTopics) {            
                    if ($top.Name -eq $potentialTopicName) {            
                        $top            
                    }            
                }            
            
                            
                                
            
                if ($theTopic) {            
                    $found = $true            
            
            
                    if (-not $script:CachedTopics) {            
                        $script:CachedTopics  = @{}            
                    }            
            
            
                    $descriptionArea = "$potentialTopicName"            
                    $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                        $false            
                    } else {            
                        $true            
                    }            
            
                    if (-not $script:CachedTopics["${Module}_${potentialTopicName}"]) {            
                        $script:CachedTopics["${Module}_${potentialTopicName}"] = ConvertFrom-Markdown -Markdown $theTopic.Topic -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
                    }            
            
                    $rest = $script:CachedTopics["${Module}_${potentialTopicName}"]            
                    #$rest = ConvertFrom-Markdown -Markdown $theTopic.Topic -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
                    if ($request["Snug"] -or $request["widget"]) {            
                        $response.Write("$rest")            
                    }            
                    $topicTemplateName = $potentialTopicName.Replace(" ", "_")            
                                
                }             
                            
                $theWalkthru = if ($walkthrus) {            
                    $walkthrus.GetEnumerator() |             
                        Where-Object {             
                            $_.Key -eq $potentialTopicName             
                        }            
                }             
            
                if ($theWalkthru) {            
                    $found = $true            
                    $descriptionArea = "$potentialTopicName"            
            
                    $params = @{}            
                    if ($pipeworksManifest.TrustedWalkthrus -contains $theWalkThru.Key) {            
                        $params['RunDemo'] = $true            
                    }            
                    if ($pipeworksManifest.WebWalkthrus -contains $theWalkThru.Key) {            
                        $params['OutputAsHtml'] = $true            
                    }            
            
                    if (-not $script:CachedTopics["${Module}_${potentialTopicName}"]) {            
                        $script:CachedTopics["${Module}_${potentialTopicName}"] = Write-WalkthruHTML -WalkthruName $theWalkthru.Key -WalkThru $theWalkthru.Value -StepByStep @params            
                    }            
            
                    $rest = $script:CachedTopics["${Module}_${potentialTopicName}"]            
                                
                    if ($request["inline"]) {            
                        $response.Write("$rest")            
                    } elseif ($request["Snug"] -or $Request["widget"]) {            
                        $response.Write("$rest")            
                    }            
            
                    $topicTemplateName = $potentialTopicName.Replace(" ", "_")            
                                
                }            
                            
                            
                            
                                           
                            
            
            
                if ($found -and $rest -and -not ($plainOutput) -and (-not $Request["Snug"]) -and (-not $request["widget"]) -and (-not $request["inline"])) {            
            
            
$ifTemplateFound = @{}            
if ($pipeworksManifest.TemplateFiles.$topicTemplateName) {            
    $ifTemplateFound.Template =$topicTemplateName            
} elseif ($pipeworksManifest.TopicTemplate) {            
    $ifTemplateFound.Template =$pipeworksManifest.TopicTemplate            
} elseif ($pipeworksManifest.DefaultTemplate) {            
    $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
} elseif ($pipeworksManifest.Template) {            
    $ifTemplateFound.Template =$pipeworksManifest.Template            
}            
            
if ($request["inline"]) {            
    $response.Write($rest)            
} elseif ($request["Snug"]) {            
$socialArea + "<div style='clear:both;margin-top:1%'></div>" + ($spacingDiv * 4) + $rest |            
                        New-Region -Style @{            
                            "Margin-Left" = $marginPercentLeftString            
                            "Margin-Right" = $marginPercentLeftString            
                        }|            
                        New-WebPage -Title "$($module.Name) | $potentialTopicName" |            
                        Out-HTML -WriteResponse             
            
} else {            
            
            
            
                        $realOrder = @()            
                        $navBarData = @{}            
                        $navBarOrder = @{}            
                        $navBarUrls = @{}            
                        $cmdTabs = @{}            
                        $cmdUrls = @{}            
            
                        if (-not $script:CachedNavBar.($module.Name)) {            
                            if (-not $script:CachedNavBar) {            
                                $script:CachedNavBar = @{}                                                    
                            }            
            
                            . $getGroups -NavBarOnly                  
            
                            $navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {            
                
                
New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
} elseif ($navBarData) {            
New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
} else {            
""            
}            
            
                            if ($cancacheGroups) {            
                                $script:CachedNavBar.($module.Name) = $navBarHtml            
                            }            
                                                                              
                        } else {            
                            $navBarHtml = $script:CachedNavBar.($module.Name)             
                        }            
            
                        . $getBanners            
            
$navBarHtml = if ($navBarData -and $PipeworksManifest.UseBootstrap) {                
    New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
} elseif ($navBarData) {            
    New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
} else {            
    ""            
}            
            
            
            
    if ($ifTemplateFound.Template -and $ifTemplateFound.Template.Trim()) {            
        $content = "
<div style='float:right;position:absolute;zindex:30;right:15px;top:15px;'>
$socialArea
</div>
<div style='float:left'>
<h1 style='float:left'>$titleArea</h1>
<h2 style='text-align:right;float:left;margin-top:75px;margin-left:50px'>
$descriptionArea 
</h2>
</div>
" + ($spacingDiv * 3) +                
    "<div style='clear:both;margin-top:1%'>$upperBannerSlot</div>" +            
    $rest +            
    "<div style='clear:both;margin-top:1%'>$bottomBannerSlot</div>" +            
    "<div style='float:right;margin-top:15%'>$brandingSlot</div>" |            
                            New-Region -Style @{            
                                "Margin-Left" = $marginPercentLeftString            
                                "Margin-Right" = $marginPercentLeftString            
                            }            
            
    } else {            
        $content = ""            
    }            
             
    "$content " |            
        New-WebPage -Title "$($module.Name) | $potentialTopicName" @ifTemplateFound |            
        Out-HTML -WriteResponse                                                                            
    }            
                }             
                            
                            
                            
            
            
            
            
            
            
                if (-not $found) {            
                    $thePage = $module |             
                        Split-Path |             
                        Get-ChildItem -Filter "Pages" -ErrorAction SilentlyContinue |             
                        Get-ChildItem -ErrorAction SilentlyContinue |             
                        Where-Object { '.html', '.htm', '.ps1', '.pspage' -contains $_.Extension }|            
                        Where-Object {            
                            $pageNAme = $_.Name.Substring(0, $_.Name.Length - $_.Extension.Length)            
                            ($pageName -eq $potentialTopicName)             
                        }            
            
                    if ($thePage)  {            
                        $found = $true            
                    }            
            
                    if ($thePage.Extension -eq '.html' -or $thePage.Extension -eq '.htm') {            
                        $response.Write([IO.File]::ReadAllText($thePage.FullName))            
                                    
                    } elseif ($thePage.Extension -eq '.ps1') {            
                        $responseContent = . $module $thePage.FullName            
                        $response.Write("$responseContent")            
                    }            
                }            
            
                # If there's not a topic, walkthru, command, or page            
                # See if there's a schema.            
            
                if ($pipeworksManifest.Schema -or $pipeworksManifest.Schemas) {            
                                
                    $schemaList = if ($pipeworksManifest.Schema) {            
                        Import-PSData -Hashtable $pipeworksManifest.Schema            
                    } else {            
                        Import-PSData -Hashtable $pipeworksManifest.Schemas            
                    }            
            
            
                                
                    $matchingSchema = $schemaList.$potentialTopicName            
            
                                
            
                    if ($matchingSchema) {            
                        $ifTemplateFound = @{}            
                                
                        if ($pipeworksManifest.TemplateFiles.$matchingSchema) {            
                            $ifTemplateFound.Template =$matchingSchema            
                        } if ($pipeworksManifest.TopicTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.TopicTemplate            
                        } elseif ($pipeworksManifest.DefaultTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
                        } elseif ($pipeworksManifest.Template) {            
                            $ifTemplateFound.Template =$pipeworksManifest.Template            
                        }            
            
                                
            
                        $rest = $content = $matchingSchema | Out-HTML            
             
                        "$content " |            
                            New-WebPage -Title "$($module.Name) | $potentialTopicName" @ifTemplateFound |            
                            Out-HTML -WriteResponse                                                                            
                                    
            
                        $found = $true            
                    }            
                }            
            
            
                if ($potentialTopicName -eq 'Awards' -or $potentialTopicName -eq 'Award') {            
                    $awardsList = if ($pipeworksManifest.Award) {            
                        Import-PSData -Hashtable $pipeworksManifest.Award            
                    } elseif ($pipeworksManifest.Awards) {            
                        Import-PSData -Hashtable $pipeworksManifest.Awards            
                    } else {            
                        $null            
                    }            
            
                    $ifTemplateFound = @{}            
                                
                    if ($pipeworksManifest.TemplateFiles.Awards) {            
                        $ifTemplateFound.Template ='Awards'            
                    } elseif ($pipeworksManifest.TemplateFiles.Award) {            
                        $ifTemplateFound.Template ='Award'            
                    } elseif ($pipeworksManifest.TopicTemplate) {            
                        $ifTemplateFound.Template =$pipeworksManifest.TopicTemplate            
                    } elseif ($pipeworksManifest.DefaultTemplate) {            
                        $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
                    } elseif ($pipeworksManifest.Template) {            
                        $ifTemplateFound.Template =$pipeworksManifest.Template            
                    }            
            
                    if ($awardsList) {            
                        $rest = ($awardsList.psobject.properties |            
                            Sort-Object Name |            
                            ForEach-Object {             
                                $_.Value | Out-HTML             
                            }) -join "<hr style='clear:both' />"                                        
            
                        "$rest" |            
                            New-WebPage -Title "$($module.Name) | $potentialTopicName" @ifTemplateFound |            
                            Out-HTML -WriteResponse                                                                            
            
                        $found = $true            
                    }            
                }            
            
                if ($potentialTopicName -eq 'Schemas' -or $potentialTopicName -eq 'Schema') {            
                    if ($pipeworksManifest.Schema -or $pipeworksManifest.Schemas) {            
                                
                        $schemaList = if ($pipeworksManifest.Schema) {            
                            Import-PSData -Hashtable $pipeworksManifest.Schema            
                        } elseif ($pipeworksManifest.Schemas) {            
                            Import-PSData -Hashtable $pipeworksManifest.Schemas            
                        } else {            
                            $null            
                        }            
            
                        $ifTemplateFound = @{}            
                                
                        if ($pipeworksManifest.TemplateFiles.Schemas) {            
                            $ifTemplateFound.Template ='Schemas'            
                        } elseif ($pipeworksManifest.TemplateFiles.Schema) {            
                            $ifTemplateFound.Template ='Schema'            
                        } elseif ($pipeworksManifest.TopicTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.TopicTemplate            
                        } elseif ($pipeworksManifest.DefaultTemplate) {            
                            $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
                        } elseif ($pipeworksManifest.Template) {            
                            $ifTemplateFound.Template =$pipeworksManifest.Template            
                        }            
            
                        if ($schemaList) {            
                            $rest = ($schemaList.psobject.properties |            
                                Sort-Object Name |            
                                ForEach-Object {             
                                    $_.Value | Out-HTML             
                                }) -join "<hr style='clear:both' />"                                        
            
                            "$rest" |            
                                New-WebPage -Title "$($module.Name) | $potentialTopicName" @ifTemplateFound |            
                                Out-HTML -WriteResponse                                                                            
            
                            $found = $true            
                        }            
                    }            
                }            
            
                if ($potentialTopicName -eq 'Profile' -or $potentialTopicName -eq 'Me') {            
                    $ifTemplateFound = @{}            
                                
                    if ($pipeworksManifest.TemplateFiles.Profile) {            
                        $ifTemplateFound.Template ='Profile'            
                    } elseif ($pipeworksManifest.TemplateFiles.Me) {            
                        $ifTemplateFound.Template ='Me'            
                    } if ($pipeworksManifest.TopicTemplate) {            
                        $ifTemplateFound.Template =$pipeworksManifest.TopicTemplate            
                    } elseif ($pipeworksManifest.DefaultTemplate) {            
                        $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
                    } elseif ($pipeworksManifest.Template) {            
                        $ifTemplateFound.Template =$pipeworksManifest.Template            
                    }            
            
                                        
                    $userName = ""            
                    $rest = if ($session -and $session["User"]) {            
                        $session["User"] | Out-HTML            
                        $userName = $session["User"].Name            
                    } else {            
                        $confirmed = Confirm-Person -WebsiteUrl $finalUrl            
                        if ($session -and $session["User"]) {            
                            $session["User"] | Out-HTML            
                        } else {            
                            $confirmed            
                        }            
                                    
                    }            
                                
                    if ($request["inline"]) {            
                        $response.Write($rest)            
                    } elseif ($request["Snug"]) {            
                    "<div style='clear:both;margin-top:1%'> </div>" + $rest |            
                            New-Region -Style @{            
                                "Margin-Left" = "1%"            
                                "Margin-Right" = "1%"            
                            }|            
                            New-WebPage -Title "$($module.Name) | $($Session["User"].Name)" |            
                            Out-HTML -WriteResponse            
                    } else {            
                        "$rest" |            
                        New-WebPage -Title "$($module.Name) | $userName" @ifTemplateFound |            
                        Out-HTML -WriteResponse                                                                            
                    }            
                                
            
                    $found = $true            
                }            
            
            
                if (-not $found) {            
                    $response.StatusCode = 404            
                    try {            
                        $response.TrySkipIisCustomErrors  = $true            
                    } catch {            
                    }            
                    $response.Write("Not Found")            
                    return            
                }            
                            
            } else {            
                        
            }            
                    
            $timeSpentInAnythingHandler = [DateTime]::Now - $anythingHandlerStartedAt                    
        }                                            
        #endregion Anything Handler            
                    
        #region ObjectHandler            
        $objectHandler = {            
            if (-not ($pipeworksManifest.Table -and $pipeworksManifest.Table.StorageAccountSetting -and $pipeworksManifest.Table.StorageKeySetting)) {            
                throw 'The Pipeworks manifest must include three settings in order to retrieve items from table storage: Table, TableStorageAccountSetting, and TableStorageKeySetting'            
                return            
            }            
                        
            $partition, $row = $request['Object'] -split ':'                   
                                         
            $rowMatch= [ScriptBLock]::Create("`$_.RowKey -eq '$row'")            
            $partitionMatch = [ScriptBLock]::Create("`$_.PartitionKey -eq '$partition'")            
            $storageAccount = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageAccountSetting)            
            $storageKey = (Get-WebConfigurationSetting -Setting $pipeworksManifest.Table.StorageKeySetting)            
            Show-WebObject -Table $pipeworksManifest.Table.Name -Row $row -Part $partition |            
                New-Region -Style @{            
                    'margin-left' = '7.5%'            
                    'margin-right' = '7.5%'            
                    'margin-top' = '2%'                            
                } -layerid objectHolder |            
                New-WebPage -Title $row |            
                Out-HTML -WriteResponse            
                        
                         
                        
        }            
        #endregion ObjectHandler            
            
        # The Import Handler            
        $importHandler = {            
            
            
            
$returnedScript = {            
            
}.ToString() + @"
    `$moduleName = '$($module.Name)'
    if (Get-Module `$moduleName) { 
        Write-Warning '$($module.Name) Already Exists'
        return
    }
    `$xhttp = New-Object -ComObject Microsoft.XmlHttp
    `$xhttp.open('GET', '${finalUrl}?-GetManifest', 1)
    `$xhttp.Send()
    do {
        Write-Progress "Downloading Manifest" '${finalUrl}?-GetManifest'    
    } while (`$xHttp.ReadyState -ne 4)

    `$manifest = `$xHttp.ResponseText
    if (-not `$toDirectory) {    
        `$targetModuleDirectory =Join-Path `$home '\Documents\WindowsPowerShell\Modules\$($module.Name)'
    } else {
        `$targetModuleDirectory = `$toDirectory
    }

Write-Progress "Downloading Commands" "${finalUrl}?-GetManifest"
"@ + {            
            
            
            
$importScript = $manifest |             
        Select-Xml //AllCommands |             
        ForEach-Object {            
            $_.Node.Command             
        } |            
        ForEach-Object -Begin {            
            $stringBuilder = New-Object Text.StringBuilder            
        } {                    
            $cmdName = $_.Name            
            Write-Progress "Downloading Metadata" "$cmdName"            
            $xhttp.open('GET', "$($_.Url.Trim('/'))/?-GetMetaData", 1)            
            $xhttp.Send()            
            do {            
                Write-Progress "Downloading Metadata" "$cmdName"                
            } while ($xHttp.ReadyState -ne 4)            
            
            $commandMetaData = $xHttp.responseText            
            $cxml = $commandMetaData -as [xml]            
            if ($cxml.CommandManifest.AllowDownload -eq 'true') {            
                # Download it            
                $xhttp.open('GET', "$($_.Url.TrimEnd('/'))/?-Download", 1)            
                $xhttp.Send()            
                do {            
                    Write-Progress "Downloading" "$cmdName"                
                } while ($xHttp.ReadyState -ne 4 )            
            
                try {            
                    $sb = $xHttp.responseText            
                    $null = ([ScriptBlock]::Create($sb))            
                    $null = $stringBuilder.Append("$sb
")            
                } catch {            
                    Write-Debug $xHttp.ResponseText            
                    $_ | Write-Error            
              
                }             
            } elseif ($cxml.CommandManifest.RunOnline -eq 'true') {            
                # Download the proxy            
                $xhttp.open('GET', "$($_.Url.TrimEnd('/'))/?-DownloadProxy", 1)            
                $xhttp.Send()            
                do {            
                    Write-Debug "Downloading" "$cmdName"                
                } while ($xHttp.ReadyState -ne 4)            
                            
                $sb = $xHttp.responseText            
                . ([ScriptBlock]::Create($sb))            
                if ($?) {              
                    $null = $stringBuilder.Append("$sb
")            
}            
            }            
                                 
        } -End {            
            [ScriptBLock]::Create($stringBuilder)            
        }            
            
New-Module -ScriptBlock $importScript -Name $moduleName            
            
}            
$response.ContentType = 'text/plain'            
$response.Write("$returnedScript")            
$response.Flush()            
}            
                    
        # The Self-Install Handler            
        $installMeHandler = {            
                    
$returnedScript = {            
            
param([string]$toDirectory)            
    $webClient = New-Object Net.WebClient             
                
}.ToString() + @"
    Write-Progress "Downloading Manifest" '${finalUrl}?-GetManifest'
    `$manifest = `$webClient.DownloadString('${finalUrl}?-GetManifest')
    if (-not `$toDirectory) {    
        `$targetModuleDirectory =Join-Path `$home '\Documents\WindowsPowerShell\Modules\$($module.Name)'
    } else {
        `$targetModuleDirectory = `$toDirectory
    }
"@ + {            
            
Write-Progress "Downloading Commands" '${finalUrl}?-GetManifest'            
if ((Test-Path $targetModuleDirectory) -and (-not $toDirectory)) {            
    Write-Warning "$targetModuleDirectory Exists, Creating ${targetModuleDirectory}Proxy"                
    $targetModuleDirectory = "${targetModuleDirectory}Proxy"            
}             
            
$null = New-Item -ItemType Directory -Path $targetModuleDirectory            
            
$directoryName = Split-Path $targetModuleDirectory -Leaf            
            
$xmlMan = $manifest -as [xml]            
$moduleVersion = $xmlMan.ModuleManifest.Version -as [Version]            
if (-not $moduleVersion) {             
    $moduleVersion = "0.0"            
}            
            
$guidLine = if ($xmlMan.ModuleManifest.Guid) {            
    "Guid = '$($xmlMan.ModuleManifest.Guid)'"            
} else { ""}             
            
$companyLine = if ($xmlMan.ModuleManifest.Company) {            
    "CompanyName = '$($xmlMan.ModuleManifest.Company)'"            
} else { ""}             
            
            
$authorLine = if ($xmlMan.ModuleManifest.Author) {            
    "Author = '$($xmlMan.ModuleManifest.Author)'"            
} else { ""}             
            
$CopyrightLine = if ($xmlMan.ModuleManifest.Copyright) {            
    "Copyright = '$($xmlMan.ModuleManifest.Copyright)'"            
} else { ""}             
            
            
$descriptionLine= if ($xmlMan.ModuleManifest.Description) {            
    "Description = @'
$($xmlMan.ModuleManifest.Description)
'@"            
} else { ""}             
            
            
            
$psd1 = @"
@{
    ModuleVersion = '$($moduleVersion)'
    
    ModuleToProcess = '${directoryName}.psm1'
    
    $descriptionLine
    
    $guidLine
    
    $companyLine 
    
    $authorLine
    
    $CopyrightLine
    
    PrivateData = @{
        Url = '$($xmlMan.ModuleManifest.Url)'
        XmlManifest = @'
$(
$strWrite = New-Object IO.StringWriter
$xmlMan.Save($strWrite)
$strWrite 
)
'@        
    }   
}
"@            
            
                    
            
$psm1 = $manifest |             
    Select-Xml //AllCommands |             
    ForEach-Object {            
        $_.Node.Command             
    } |            
    ForEach-Object -Begin {            
        $psm1 = ""            
    } {                    
        $targetPath = Join-Path $targetModuleDirectory "$($_.Name).ps1"            
        Write-Progress "Downloading $($_.Name)" "From $($_.Url) to $targetPath"            
        $commandMetaData = $webClient.DownloadString("$($_.Url.Trim('/'))/?-GetMetaData")            
        $cxml = $commandMetaData -as [xml]            
        if ($cxml.CommandManifest.AllowDownload -eq 'true') {            
            # Download it            
            $webClient.DownloadString("$($_.Url.Trim('/'))/?-AllowDownload") |             
                Set-Content $targetPath            
        } elseif ($cxml.CommandManifest.RunOnline -eq 'true') {            
            # Download the proxy            
            $webClient.DownloadString("$($_.Url.Trim('/'))/?-DownloadProxy") |             
                Set-Content $targetPath            
                        
        } else {            
            # Download the stub            
            $webClient.DownloadString("$($_.Url.Trim('/'))/?-Stub") |             
                Set-Content $targetPath            
        }            
                    
        $psm1 += '. $psScriptRoot\' + $_.Name + '.ps1' + ([Environment]::NewLine)             
    } -End {            
        $psm1             
    }            
                
    $psm1 |             
        Set-Content "$targetModuleDirectory\$directoryName.psm1"             
                    
    $psd1 |             
        Set-Content "$targetModuleDirectory\$directoryName.psd1"            
            
}            
            
            
            
$response.ContentType = 'text/plain'            
$response.Write("$returnedScript")            
$response.Flush()            
}            
        # all Commands page            
        $allCommandsPage = {            
            
            
$commandUrlList=  Get-Command | Where-Object { $_.Module.Name -eq $module.Name } | Sort-Object | Select-Object -ExpandProperty Name | Write-Link -List            
$order = @()            
$layerTitle = "$($module.Name) | All Commands"             
$order += $layerTitle            
$layers = @{            
    $layerTitle = '<div style=''margin-left:15px''>' + $commandUrlList+ '</div>'            
}            
            
# Group by Verb            
Get-Command | Where-Object { $_.Module.Name -eq $module.Name }  |             
    Group-Object {$_.Name.Substring(0,$_.Name.IndexOf("-")) } |            
    ForEach-Object {            
        $order += $_.Name            
        $layers[$_.Name] = '<div style=''margin-left:15px''>'  + ($_.Group | Select-Object -ExpandProperty Name | Write-Link) + '</div>'            
    }            
            
$region =             
    New-Region -AutoSwitch '0:0:15' -HorizontalRuleUnderTitle -DefaultToFirst -Order $order -Container 'CommandList' -Layer $layers            
$page = New-WebPage -Css $cssStyle -Title $layerTitle -AnalyticsID '$analyticsId' -PageBody $region            
$response.ContentType = 'text/html'            
$response.Write("     $page                ")                    
            
        }             
                    
        # -GetCommand list            
        $getCommandList = {            
$baseUrl = $request.URL            
    $commandUrlList = foreach ($cmd in $moduleCommands) {            
        $cmd.Name            
    }            
    $commandUrlList = $commandUrlList | Sort-Object            
    $response.ContentType = 'text/plain'            
    $commandList = ($commandUrlList -join ([Environment]::NewLine))            
    $response.Write([string]"
$commandList
")            
                    
        }            
            
        $newRobotsTxt = {            
    param($RemoteCommandUrl)            
"User-Agent: *
Crawl-Delay: 5
Host: $RemoteCommandUrl       
"            
        }            
            
        $NewSiteMap = {            
    param($RemoteCommandUrl)            
            
$aboutFiles  =  @(Get-ChildItem -Filter *.help.txt -Path "$moduleRoot\en-us" -ErrorAction SilentlyContinue)            
            
if ($requestCulture -and ($requestCulture -ine 'en-us')) {            
    $aboutFiles  +=  @(Get-ChildItem -Filter *.help.txt -Path "$moduleRoot\$requestCulture" -ErrorAction SilentlyContinue)            
}            
            
            
$walkThrus = @{}            
$aboutTopics = @()            
$namedTopics = @{}            
            
$aboutTopicsByName  = @{}            
            
            
if ($aboutFiles) {            
    foreach ($topic in $aboutFiles) {                    
        if ($topic.fullname -like "*.walkthru.help.txt") {            
            $topicName = $topic.Name.Replace('_',' ').Replace('.walkthru.help.txt','')            
            $walkthruContent = Get-Walkthru -File $topic.Fullname                        
            $walkThruName = $topicName                         
            $walkThrus[$walkThruName] = $walkthruContent                                                 
        } else {            
            $topicName = $topic.Name.Replace(".help.txt","")            
            $nat = New-Object PSObject -Property @{            
            
                    Name = $topicName.Replace("_", " ")            
                    SystemName = $topicName            
                    Topic = [IO.File]::readalltext($topic.Fullname)            
                    LastWriteTime = $topic.LastWriteTime            
                }            
            $aboutTopics += $nat            
            $aboutTopicsByName[$nat.Name] = $nat            
                             
        }            
    }            
}            
            
$blogChunk = if ($pipeworksManifest.Blog -and $pipeworksManifest.Blog.Link -and $pipeworksManifest.Blog.Name) {            
    $blogLink = if ($pipeworksManifest.Blog.Link -like "http*" -and $pipeworksManifest.Blog.Name -and $pipeworksManifest.Blog.Description) {            
        # Absolute link to module base,            
        $pipeworksManifest.Blog.Link.TrimEnd("/") + "/Module.ashx?rss=$($pipeworksManifest.Blog.Name)"            
    } else {            
        $pipeworksManifest.Blog.Link            
    }            
    "<url>        
        <loc>$([Security.Securityelement]::Escape($BlogLink))</loc>        
    </url>"            
} else {            
    ""            
}            
$aboutChunk = ""            
$aboutChunk = foreach ($topic in $aboutTopics) {            
    if (-not $topic) { continue }            
    $isInGroup = $false            
            
    if (($pipeworksManifest.TopicGroup |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq ($Topic.Name) }            
            }) -or            
        ($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq ($Topic.Name) }            
            })) {            
            
        $isInGroup = $true            
    }            
            
    "<url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($topic.Name)/</loc>
        <changefreq>weekly</changefreq>
        $(if ($isInGroup) {
            "<priority>0.8</priority>"
        })
    </url>"            
}            
            
$walkthruChunk = ""            
$walkthruChunk = foreach ($walkthruName in ($walkthrus.Keys | Sort-Object)) {            
    $isInGroup = $false            
    if (($pipeworksManifest.TopicGroup |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $walkthruName }            
            }) -or            
            ($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $walkthruName }            
            })) {            
            
        $isInGroup = $true            
    }            
            
            
    "<url>
        
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($walkthruName)/</loc>
        <changefreq>weekly</changefreq>
        $(if ($isInGroup) {
            "<priority>0.8</priority>"
        })
    </url>"            
}            
            
$CommandChunk = ""            
$CommandChunk = foreach ($cmd in ($pipeworksManifest.WebCommand.Keys | Sort-Object)) {            
    if ($pipeworksManifest.WebCommand[$Cmd].Hidden -or            
        $pipeworksManifest.WebCommand[$Cmd].IfLoggedInAs -or            
        $pipeworksManifest.WebCommand[$Cmd].ValidUserPartition -or             
        $pipeworksManifest.WebCommand[$Cmd].RequireLogin -or             
        $pipeworksManifest.WebCommand[$Cmd].RequireAppKey) {            
        continue            
    }            
            
    $aliased = Get-Command -Module $module -CommandType Alias | Where-Object { $_.ResolvedCommand.Name -eq $cmd }             
    $isInGroup = $false            
    if (($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $cmd }            
            })) {            
            
        $isInGroup = $true            
    }            
    if ($aliased) {            
        foreach ($a in $aliased) {            
            "
    <url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($a.Name)/</loc>        
        $(if ($isInGroup) {
            "<priority>1</priority>"
        } else {
            "<priority>0.7</priority>"
        })
    </url>
        "            
        }            
    }            
    "<url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($cmd)/</loc>        
        $(if ($isInGroup) {
            "<priority>0.9</priority>"
        } else {
            "<priority>0.6</priority>"
        })
    </url>"            
}            
            
$siteMapXml = [xml]"<urlset xmlns=`"http://www.sitemaps.org/schemas/sitemap/0.9`">
    <url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/</loc>
        <priority>1.0</priority>
    </url>
    $aboutChunk
    $WalkThruChunk
    $CommandChunk 
</urlset>"            
            
return $siteMapXml                    
        }            
            
            
        $getSiteMapHandler = {            
if ($application -and $application["SitemapFor_$($module.Name)"]) {            
    $manifestXml = $application["SitemapFor_$($module.Name)"]            
    $strWrite = New-Object IO.StringWriter            
    $manifestXml.Save($strWrite)            
    $response.ContentType = 'text/xml'            
    $response.Write("$strWrite")            
    return            
}                    
            
            
            
$blogChunk = if ($pipeworksManifest.Blog -and $pipeworksManifest.Blog.Link -and $pipeworksManifest.Blog.Name) {            
    $blogLink = if ($pipeworksManifest.Blog.Link -like "http*" -and $pipeworksManifest.Blog.Name -and $pipeworksManifest.Blog.Description) {            
        # Absolute link to module base,            
        $pipeworksManifest.Blog.Link.TrimEnd("/") + "/Module.ashx?rss=$($pipeworksManifest.Blog.Name)"            
    } else {            
        $pipeworksManifest.Blog.Link            
    }            
    "<url>        
        <loc>$([Security.Securityelement]::Escape($BlogLink))</loc>        
    </url>"            
} else {            
    ""            
}            
$aboutChunk = ""            
$aboutChunk = foreach ($topic in $aboutTopics) {            
    if (-not $topic) { continue }            
    $isInGroup = $false            
            
    if (($pipeworksManifest.TopicGroup |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq ($Topic.Name) }            
            }) -or            
            ($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq ($Topic.Name) }            
            })) {            
            
        $isInGroup = $true            
    }            
            
    "<url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($topic.Name)</loc>
        <changefreq>weekly</changefreq>
        $(if ($isInGroup) {
            "<priority>0.8</priority>"
        })
    </url>"            
}            
            
$walkthruChunk = ""            
$walkthruChunk = foreach ($walkthruName in ($walkthrus.Keys | Sort-Object)) {            
    $isInGroup = $false            
    if (($pipeworksManifest.TopicGroup |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $walkthruName }            
            }) -or            
            ($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $walkthruName }            
            })) {            
            
        $isInGroup = $true            
    }            
            
            
    "<url>
        
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($walkthruName)</loc>
        <changefreq>weekly</changefreq>
        $(if ($isInGroup) {
            "<priority>0.8</priority>"
        })
    </url>"            
}            
            
$CommandChunk = ""            
$CommandChunk = foreach ($cmd in ($pipeworksManifest.WebCommand.Keys | Sort-Object)) {            
    if ($pipeworksManifest.WebCommand[$Cmd].Hidden -or            
        $pipeworksManifest.WebCommand[$Cmd].IfLoggedInAs -or            
        $pipeworksManifest.WebCommand[$Cmd].ValidUserPartition -or             
        $pipeworksManifest.WebCommand[$Cmd].RequireLogin -or             
        $pipeworksManifest.WebCommand[$Cmd].RequireAppKey) {            
        continue            
    }            
            
    $aliased = Get-Command -Module $module -CommandType Alias | Where-Object { $_.ResolvedCommand.Name -eq $cmd }             
    $isInGroup = $false            
    if (($pipeworksManifest.Group |             
            Where-Object { $_.Values |             
                Where-Object { $_ -eq $cmd }            
            })) {            
            
        $isInGroup = $true            
    }            
    if ($aliased) {            
        foreach ($a in $aliased) {            
            "
    <url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($a.Name)</loc>        
        $(if ($isInGroup) {
            "<priority>1</priority>"
        } else {
            "<priority>0.7</priority>"
        })
    </url>
        "            
        }            
    }            
    "<url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/$($cmd)</loc>        
        $(if ($isInGroup) {
            "<priority>0.9</priority>"
        } else {
            "<priority>0.6</priority>"
        })
    </url>"            
}            
            
$siteMapXml = [xml]"<urlset xmlns=`"http://www.sitemaps.org/schemas/sitemap/0.9`">
    <url>
        <loc>$($remoteCommandUrl.TrimEnd('/'))/</loc>
        <priority>1.0</priority>
    </url>
    $aboutChunk
    $WalkThruChunk
    $CommandChunk 
</urlset>"            
            
            
            
$application["SitemapFor_$($module.Name)"] = $siteMapXml;            
$strWrite = New-Object IO.StringWriter            
$siteMapXml.Save($strWrite)            
$response.ContentType = 'text/xml'            
$response.Write("$strWrite")            
            
            
            
            
            
        }            
            
            
                            
        $getManifestXmlHandler = {            
            
if ($application -and $application["ManifestXmlFor_$($module.Name)"]) {            
    $manifestXml = $application["ManifestXmlFor_$($module.Name)"]            
    $strWrite = New-Object IO.StringWriter            
    $manifestXml.Save($strWrite)            
    $response.ContentType = 'text/xml'            
    $response.Write("$strWrite")            
    return            
}            
            
            
            
# The Manifest XML is used to help interact with a module from a remote service.            
# It contains module metadata and discovery information that will be used by most clients.            
$commandGroupChunk = ""            
$commandGroupChunk = foreach ($commandGroup in $pipeworksmanifest.Group) {            
    if (-not $commandGroup) { continue }             
    if ($commandGroup -isnot [Hashtable]) { continue }             
            
    foreach ($kv in $commandGroup.GetEnumerator()) {            
        $groupItems = $null            
        $groupItems= foreach ($cmd in $kv.Value) {            
            if ($pipeworksManifest.WebCommand.$cmd) {            
                "<Command>$cmd</Command>"            
            }            
                        
        }            
            
        if ($groupItems) {            
            "<CommandGroup>
                <Name>
                    $($kv.Key)
                </Name>
                $groupItems
            </CommandGroup>"            
        }            
                    
    }            
            
                
        $cmdGroups            
                
}            
if ($commandGroupChunk) {            
    $commandGroupChunk = "<CommandGroups>
$commandGroupChunk
</CommandGroups>"            
            
}            
            
$topicGroupChunk = ""            
$topicGroupChunk  = foreach ($topicGroup in $pipeworksmanifest.Group) {            
    if (-not $topicGroup) { continue }             
    if ($topicGroup -isnot [Hashtable]) { continue }             
                
    foreach ($kv in $topicGroup.GetEnumerator()) {            
        $groupItems= foreach ($cmd in $kv.Value) {                   
            if (-not (Get-Command -Module $module -Name $Cmd -ErrorAction SilentlyContinue)) {                 
                "<Topic>$cmd</Topic>"            
            }                        
        }            
        if ($groupItems) {            
            "<TopicGroup>
                <Name>
                    $($kv.Key)
                </Name>
            $groupItems
            </TopicGroup>"            
        }            
    }            
            
}            
            
if ($topicGroupChunk  ) {            
    $topicGroupChunk  = "<TopicGroups>
$topicGroupChunk  
</TopicGroups>"            
            
}            
            
            
$blogChunk = if ($pipeworksManifest.Blog -and $pipeworksManifest.Blog.Link -and $pipeworksManifest.Blog.Name) {            
    $blogLink = if ($pipeworksManifest.Blog.Link -like "http*" -and $pipeworksManifest.Blog.Name -and $pipeworksManifest.Blog.Description) {            
        # Absolute link to module base,            
        $pipeworksManifest.Blog.Link.TrimEnd("/") + "/Module.ashx?rss=$($pipeworksManifest.Blog.Name)"            
    } else {            
        $pipeworksManifest.Blog.Link            
    }            
    "<Blog>
        <Name>$([Security.Securityelement]::Escape($pipeworksManifest.Blog.Name))</Name>
        <Feed>$([Security.Securityelement]::Escape($BlogLink))</Feed>        
    </Blog>"            
} else {            
    ""            
}            
$ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
        $false            
    } else {            
        $true            
    }            
$aboutChunk = foreach ($topic in $aboutTopics) {            
    if (-not $topic) { continue }            
            
    "<Topic>
        <Name>
$([Security.Securityelement]::Escape($topic.Name))
        </Name>
        <Content>
$([Security.Securityelement]::Escape((

ConvertFrom-Markdown -Markdown $topic.Topic -ScriptAsPowerShell -ShowData:$ShowDataInTopic
)))
        </Content>
    </Topic>"            
}            
            
            
$styleChunk = if ($pipeworksmanifest.Style) {            
    $styleXml = "<Style>"            
    if ($pipeworksmanifest.Style.Body."font-family") {            
        $fonts = foreach ($fontName in ($pipeworksmanifest.Style.Body."font-family" -split ",")) {            
            "<Font>$([Security.SecurityElement]::Escape($FontName))</Font>"            
        }            
        $styleXml += "<Fonts>$Fonts</Fonts>"            
    }            
    if ($pipeworksmanifest.Style.Body.color) {             
        $styleXml += "<Foreground>$([Security.SecurityElement]::Escape($pipeworksmanifest.Style.Body.color))</Foreground>"            
    }            
    if ($pipeworksmanifest.Style.Body.'background-color') {             
        $styleXml += "<Background>$([Security.SecurityElement]::Escape($pipeworksmanifest.Style.Body.'background-color'))</Background>"            
    }            
    $styleXml += "</Style>"            
    $styleXml             
} else {            
    ""            
}            
            
$walkthruChunk = foreach ($walkthruName in ($walkthrus.Keys | Sort-Object)) {            
    $steps = foreach ($step in $walkthrus[$walkthruName]) {            
        $videoChunk = if ($step.videoFile) {            
            "<Video>$($step.videoFile)</Video>"            
        } else {            
            ""            
        }            
        "<Step>
            <Explanation>
$([Security.SecurityElement]::Escape($step.Explanation))
            </Explanation>
            <Script>

$(
if ($Step.Script -ne '$null') {
    [Security.SecurityElement]::Escape((Write-ScriptHTML -Text $step.Script))
})
            </Script>                        
            $videoChunk
        </Step>"            
    }            
    "<Walkthru>
        <Name>$([Security.SecurityElement]::Escape($WalkthruName))</Name>
        $steps
    </Walkthru>"            
}            
            
            
if ($aboutChunk -or $walkthruChunk) {            
    $aboutChunk = "
<About>
$aboutChunk
$WalkthruChunk
</About>
"            
}            
            
            
            
            
# This handler creates a Manifest XML.            
$psd1Content = (Get-Content $psd1Path -ReadCount 0 -ErrorAction SilentlyContinue)            
$psd1Content = $psd1Content -join ([Environment]::NewLine)            
$manifestObject=  New-Object PSObject (& ([ScriptBlock]::Create(            
     $psd1Content            
)))            
$protocol = ($request['Server_Protocol'] -split '/')[0]            
$serverName= $request['Server_Name']            
$shortPath = Split-Path $request['PATH_INFO']            
            
$remoteCommandUrl= $Protocol + '://' + $ServerName.Replace('\', '/').TrimEnd('/') + '/' + $shortPath.Replace('\','/').TrimStart('/')            
$remoteCommandUrl = ($finalUrl -replace 'Module\.ashx', "" -replace 'Default.ashx', "").TrimEnd("/")            
            
            
$pipeworksManifestPath = Join-Path (Split-Path $module.Path) "$($module.Name).Pipeworks.psd1"            
$pipeworksManifest = if (Test-Path $pipeworksManifestPath) {            
    try {                                 
        & ([ScriptBlock]::Create(            
            "data -SupportedCommand Add-Member, New-WebPage, New-Region, Write-CSS, Write-Ajax, Out-Html, Write-Link { $(
                [ScriptBlock]::Create([IO.File]::ReadAllText($pipeworksManifestPath))                    
            )}"))                        
    } catch {            
        Write-Error "Could not read pipeworks manifest: ($_ | Out-String)"             
    }                                                            
} else { $null }             
            
$allCommandChunks = New-Object Text.StringBuilder            
$cmdsInModule = Get-Command | Where-Object { $_.Module.Name -eq $module.Name }            
foreach ($cmd in  $cmdsInModule) {            
    $help = Get-Help $cmd.Name            
    if ($help.Synopsis) {            
        $description = $help.Synopsis            
        $null = $allCommandChunks.Append("<Command Name='$($cmd.Name)' Url='$($remoteCommandUrl.TrimEnd('/') + '/' + $cmd.Name + '/')'>$([Security.SecurityElement]::Escape($description))</Command>")                
    } else {            
        $null  = $allCommandChunks.Append("<Command Name='$($cmd.Name)' Url='$($remoteCommandUrl.TrimEnd('/') + '/' + $cmd.Name + '/')'/>")            
    }                
}            
$allCommandChunks = "$allCommandChunks"            
            
$defaultCommmandChunk  = if ($pipeworksManifest.DefaultCommand) {            
    $defaultParams =  if ($pipeworksManifest.DefaultCommand.Parameter) {            
        foreach ($kv in ($pipeworksManifest.DefaultCommand.Parameter | Sort-Object Key)) {            
        "        
        <Parameter>
            <Name>$([Security.SecurityElement]::Escape($kv.Key))</Name>
            <Value>$([Security.SecurityElement]::Escape($kv.Value))</Value>
        </Parameter>
        "            
        }            
                    
    } else {            
        ""            
    }            
   "<DefaultCommand>
        <Name>$($pipeworksManifest.DefaultCommand.Name)</Name>
        $defaultParams
   </DefaultCommand>"            
} else {            
    ""            
}            
            
if ($pipeworksManifest.WebCommand) {            
    $webCommandsChunk = "<WebCommand>"                
    $webcommandOrder = if ($pipeworksManifest.CommandOrder) {            
        $pipeworksManifest.CommandOrder            
    } else {            
        $pipeworksManifest.WebCommand.Keys | Sort-Object            
    }            
            
            
    foreach ($wc in $webcommandOrder) {            
        $LoginRequired=             
            $pipeworksManifest.WebCommand.$($wc).RequireLogin -or            
            $pipeworksManifest.WebCommand.$($wc).RequiresLogin -or            
            $pipeworksManifest.WebCommand.$($wc).RequireAppKey -or             
            $pipeworksManifest.WebCommand.$($wc).RequiresAppKey -or             
            $pipeworksManifest.WebCommand.$($wc).IfLoggedInAs -or            
            $pipeworksManifest.WebCommand.$($wc).ValidUserPartition            
                    
            
        $LoginRequiredChunk =             
            if ($loginRequired) {            
                " RequireLogin='true'"            
            } else {            
                ""            
            }            
            
        $isHiddenChunk =             
            if ($pipeworksManifest.WebCommand.$($wc).IfLoggedInAs -or            
                $pipeworksManifest.WebCommand.$($wc).ValidUserPartition -or            
                $pipeworksManifest.WebCommand.$($wc).Hidden)             
            {            
                " Hidden='true'"            
            } else {            
                " "            
            }            
            
        $cmdFriendlyName = if ($pipeworksManifest.WebCommand.$wc.FriendlyName) {            
            $pipeworksManifest.WebCommand.$wc.FriendlyName            
        } else {            
            $wc            
        }            
            
        $runWithoutInputChunk = if ($pipeworksManifest.WebCommand.$($wc).RunWithoutInput) {            
            " RunWithoutInput='true'"            
        } else {            
            ""            
        }            
            
        $selectivelyVisibleChunk = if ($pipeworksManifest.WebCommand.$($wc).IfLoggedInAs -or             
            $pipeworksManifest.WebCommand.$($wc).ValidUserPartition) {            
            " SelectivelyVisible='true'"            
        } else {            
            ""            
        }            
            
            
            
        $redirectToChunk = if ($pipeworksManifest.WebCommand.$($wc).RedirectTo) {            
            " RedirectTo='$([web.httputility]::HtmlAttributeEncode($pipeworksManifest.WebCommand.$($wc).RedirectTo))'"            
        } else {            
            ""            
        }            
            
        $redirectInChunk = if ($pipeworksManifest.WebCommand.$($wc).RedirectIn) {            
            " RedirectIn='$([web.httputility]::HtmlAttributeEncode($pipeworksManifest.WebCommand.$($wc).RedirectIn))'"            
        } elseif ($pipeworksManifest.WebCommand.$($wc).RedirectTo) {            
            " RedirectIn='$([web.httputility]::HtmlAttributeEncode("00:00:00.25"))'"            
        } else {            
            ""            
        }            
            
        $help = Get-Help $wc            
        if ($help.Synopsis) {            
            $description = $help.Synopsis            
            $webCommandsChunk += "<Command Name='$([Security.SecurityElement]::Escape($cmdFriendlyName))' RealName='$wc' ${LoginRequiredChunk}${isHiddenChunk}${runWithoutInputChunk}${selectivelyVisibleChunk} Url='$($remoteCommandUrl.TrimEnd('/') + '/' + $wc + '/')' $redirectToChunk $redirectInChunk>$([Security.SecurityElement]::Escape($description))</Command>"                
        } else {            
            $webCommandsChunk += "<Command Name='$([Security.SecurityElement]::Escape($cmdFriendlyName))' RealName='$wc' ${LoginRequiredChunk}${isHiddenChunk}${runWithoutInputChunk}${selectivelyVisibleChunk} Url='$($remoteCommandUrl.TrimEnd('/') + '/' + $wc + '/')' $redirectToChunk $redirectInChunk />"            
        }               
    }            
    $webCommandsChunk += "</WebCommand>"            
}            
            
if ($pipeworksManifest.ModuleUrl) {            
    $remoteCommandUrl = $pipeworksManifest.ModuleUrl            
}            
            
            
            
            
$moduleUrl = if ($request['Url'] -like "*.ashx*" -and $request['Url'] -notlike "*Default.ashx*") {            
    $u = $request['Url'].ToString()            
    $u = $u.Substring($u.LastIndexOf('/'))            
    $remoteCommandUrl + $u            
} elseif ($request['Url'] -like "*.ashx*" -and$moduleUrl -like "*Default.ashx") {            
                
    $remoteCommandUrl.Substring(0,$remoteCommandUrl.Length - "Default.ashx".Length - 1)            
} else {            
    $remoteCommandUrl + "/"            
}            
            
            
            
$zipDownloadUrl  = if ($allowDownload) {            
                
    "<DirectDownload>$($moduleUrl.Substring(0,$moduleUrl.LastIndexOf("/")) + '/' + $module.Name + '.' + $module.Version + '.zip')</DirectDownload>"            
} else {            
    ""            
}            
            
            
            
            
$facebookChunk =             
if ($pipeworksManifest.Facebook.AppId) {            
    $scopeString =             
        if ($pipeworksManifest.Facebook.Scope) {            
            $pipeworksManifest.Facebook.Scope -join ", "            
        } else {            
            "email, user_birthday"            
        }            
    "<Facebook>
        <AppId>$($pipeworksManifest.Facebook.AppId)</AppId>
        <Scope>$scopeString</Scope>
    </Facebook>"            
} else {            
    ""            
}            
            
            
$LogoChunk = if ($pipeworksManifest.Logo) {            
    "<Logo>$([Security.SecurityElement]::Escape($pipeworksManifest.Logo))</Logo>"            
} else {            
    ""            
}            
            
$pubCenterChunk =if ($pipeworksManifest.PubCenter) {            
    $pubCenterId = if ($pipeworksmanifest.PubCenter.ApplicationId) {            
        $pipeworksmanifest.PubCenter.ApplicationId            
    } elseif ($pipeworksmanifest.PubCenter.Id) {            
        $pipeworksmanifest.PubCenter.Id            
    }            
    if (-not $pubCenterId) {            
        ""            
    } else {            
        "
<PubCenter>
    <ApplicationID>$($pubCenterId)</ApplicationID>
    <TopAdUnit>$($pipeworksmanifest.PubCenter.TopAdUnit)</TopAdUnit>
    <BottomAdUnit>$($pipeworksmanifest.PubCenter.BottomAdUnit)</BottomAdUnit>    
</PubCenter>"            
    }            
            
} else {            
    ""            
}            
            
            
$adSenseChunk = if ($pipeworksManifest.AdSense) {            
    $theAdSenseId =  if ($pipeworksmanifest.AdSense.AdSenseId) {            
        $pipeworksmanifest.AdSense.AdSenseId            
    } elseif ($pipeworksmanifest.AdSense.Id) {            
        $pipeworksmanifest.AdSense.Id            
    }            
            
"<AdSense>
    <ApplicationID>$($TheAdSenseId)</ApplicationID>
    <TopSlot>$($pipeworksmanifest.AdSense.TopSlot)</TopSlot>
    <BottomSlot>$($pipeworksmanifest.AdSense.BottomAdSlot)</BottomSlot>
</AdSense>
"            
} else {            
    ""            
}            
            
            
            
$commandTriggerChunk = if ($pipeworksmanifest.CommandTrigger) {            
    $sortedTriggers = $pipeworksmanifest.CommandTrigger.GetEnumerator() | Sort-Object Key            
               
    $commandTriggerXml = foreach ($trigger in $sortedTriggers) {            
        "
        <CommandTrigger>
            <Trigger>$([Security.SecurityElement]::Escape($Trigger.Key))</Trigger>
            <Command>$([Security.SecurityElement]::Escape($Trigger.Value))</Command>
        </CommandTrigger>"                    
    }            
    "<CommandTriggers>
    $($commandTriggerXml)
    </CommandTriggers>"            
} else {            
    ""            
}            
            
            
$manifestXml = [xml]"<ModuleManifest>
    <Name>$($module.Name)</Name>
    <Url>$($moduleUrl)</Url>
    <Version>$($module.Version)</Version>
    <Description>$([Security.SecurityElement]::Escape($module.Description))</Description>
    $LogoChunk
    $styleChunk
    <Company>$($manifestObject.CompanyName)</Company>
    <Author>$($manifestObject.Author)</Author>
    <Copyright>$($manifestObject.Copyright)</Copyright>    
    <Guid>$($manifestObject.Guid)</Guid> 
    $zipDownloadUrl   
    
    $facebookChunk 
    $blogChunk
    $aboutChunk
    $topicGroupChunk
    $defaultCommmandChunk  
    <AllCommands>
        $allCommandChunks
    </AllCommands>
    
    $webCommandsChunk
    
    $commandGroupChunk 
    $commandTriggerChunk
    $pubCenterChunk
    $AdSenseChunk
</ModuleManifest>"            
            
$application["ManifestXmlFor_$($module.Name)"] = $manifestXml;            
$strWrite = New-Object IO.StringWriter            
$manifestXml.Save($strWrite)            
$response.ContentType = 'text/xml'            
$response.Write("$strWrite")            
        }            
                           
                           
        $mailHandlers =  if ($pipeworksManifest.Mail) {            
@"
elseif (`$request['SendMail']) {
    $($mailHandler.ToString().Replace('"','""'))
}
"@                    
        } else {            
""            
        }            
            
        $checkoutHandlers =             
@"
elseif (`$request['AddItemToCart']) {
    $($addCartHandler.ToString().Replace('"','""'))
} elseif (`$request['ShowCart']) {
    $($ShowCartHandler.ToString().Replace('"','""'))
} elseif (`$request['Checkout']) {
    $($checkoutCartHandler.ToString().Replace('"','""'))    
}
"@            
                    
        $TableHandlers = if ($pipeworksManifest.Table) { @"
elseif (`$request['id']) {
    $($idHandler.ToString().Replace('"','""'))
} elseif (`$request['object']) {
    $($objectHandler.ToString().Replace('"','""'))
} elseif (`$request['Name']) {
    $($nameHandler.ToString().Replace('"','""'))
} elseif (`$request['Latest']) {
    $($latestHandler.ToString().Replace('"','""'))
} elseif (`$request['Rss']) {
    $($RssHandler.ToString().Replace('"','""'))
} elseif (`$request['Type']) {
    $($typeHandler.ToString().Replace('"','""'))
} elseif (`$request['Search']) {
    $($searchHandler.ToString().Replace('"','""'))
} 
"@.TrimEnd()            
} else {            
    ""            
}            
                    
    $userTableHandlers = if ($pipeworksManifest.UserTable) {            
@" 
elseif (`$request['Join']) {
    `$session['ProfileEditMode'] = `$true    
    $($JoinHandler.ToString().Replace('"','""'))
} elseif (`$request['EditProfile']) {
    `$editMode = `$true
    $($JoinHandler.ToString().Replace('"','""'))
} elseif (`$request['ConfirmUser']) {
    $($ConfirmUserHandler.ToString().Replace('"','""'))
} elseif (`$request['Login']) {
    $($LoginUserHandler.ToString().Replace('"','""'))
} elseif (`$request['Logout']) {
    $($LogoutUserHandler.ToString().Replace('"','""'))
} elseif (`$request['ShowApiKey']) {
    $($ShowApiKeyHandler.ToString().Replace('"','""'))
} elseif (`$request['FacebookConfirmed']) {
    $($facebookConfirmUser.ToString().Replace('"','""'))
} elseif (`$request['LiveIDConfirmed']) {
    $($liveIdConfirmUserHandler.ToString().Replace('"','""'))
} elseif (`$request['FacebookLogin']) {
    $($facebookLoginDisplay.ToString().Replace('"','""'))
} elseif (`$request['Purchase'] -or `$request['Rent']) {
    $($addPurchaseHandler.ToString().Replace('"','""'))
} elseif (`$request['Settle']) {
    $($settleHandler.ToString().Replace('"','""'))
}
"@                    
        } else {            
            ""            
        }            
                    
                    
        #region GetExtraCommandInfo            
        $getCommandExtraInfo = {            
            param([string]$RequestedCommand)             
            
            $command =             
                if ($module.ExportedAliases[$RequestedCommand]) {            
                    $module.ExportedAliases[$RequestedCommand]            
                } elseif ($module.ExportedFunctions[$requestedCommand]) {            
                    $module.ExportedFunctions[$RequestedCommand]            
                } elseif ($module.ExportedCmdlets[$requestedCommand]) {            
                    $module.ExportedCmdlets[$RequestedCommand]            
                }            
                        
            if ($command.ResolvedCommand) {            
                $command = $command.Resolvedcommand            
            }            
                        
            if (-not $command)  {            
                throw "$requestedCommand not found in module $module"            
            }            
                        
                        
            # Generate individual handlers            
            $extraParams = if ($pipeworksManifest -and $pipeworksManifest.WebCommand.($Command.Name)) {                            
                $pipeworksManifest.WebCommand.($Command.Name)            
            } elseif ($pipeworksManifest -and $pipeworksManifest.WebAlias.($Command.Name) -and            
                $pipeworksManifest.WebCommand.($pipeworksManifest.WebAlias.($Command.Name).Command)) {             
                            
                $webAlias = $pipeworksManifest.WebAlias.($Command.Name)            
                $paramBase = $pipeworksManifest.WebCommand.($pipeworksManifest.WebAlias.($Command.Name).Command)            
                foreach ($kv in $webAlias.GetEnumerator()) {            
                    if (-not $kv) { continue }            
                    if ($kv.Key -eq 'Command') { continue }            
                    $paramBase[$kv.Key] = $kv.Value            
                }            
            
                $paramBase            
            } else { @{            
                    ShowHelp=$true            
            
            } }                         
                        
            if ($pipeworksManifest -and $pipeworksManifest.Style -and (-not $extraParams.Style)) {            
                $extraParams.Style = $pipeworksManifest.Style             
            }            
            if ($extraParams.Count -gt 1) {            
                # Very explicitly make sure it's there, and not explicitly false            
                if (-not $extra.RunOnline -or             
                    $extraParams.Contains("RunOnline") -and $extaParams.RunOnline -ne $false) {            
                    $extraParams.RunOnline = $true                                 
                }                            
            }             
                        
            if ($extaParams.PipeInto) {            
                $extaParams.RunInSandbox = $true            
            }            
                        
            if (-not $extraParams.AllowDownload) {            
                $extraParams.AllowDownload = $allowDownload            
            }            
                        
                            
                        
            if ($extraParams.RequireAppKey -or             
                $extraParams.RequireLogin -or             
                $extraParams.IfLoggedAs -or             
                $extraParams.ValidUserPartition -or             
                $extraParams.Cost -or             
                $extraParams.CostFactor) {            
            
                $extraParams.UserTable = $pipeworksManifest.Usertable.Name            
                $extraParams.UserPartition = $pipeworksManifest.Usertable.Partition            
                $extraParams.StorageAccountSetting = $pipeworksManifest.Usertable.StorageAccountSetting            
                $extraParams.StorageKeySetting = $pipeworksManifest.Usertable.StorageKeySetting             
            
            }            
                        
            if ($extraParams.AllowDownload) {            
                # Downloadable Commands            
                $downloadableCommands += $command.Name                            
            }            
                                    
                        
                        
                        
                        
            if ($MarginPercentLeftString -and (-not $extraParams.MarginPercentLeft)) {            
                $extraParams.MarginPercentLeft = $MarginPercentLeftString.TrimEnd("%")            
            }            
                        
            if ($MarginPercentRightString-and -not $extraParams.MarginPercentRight) {            
                $extraParams.MarginPercentRight = $MarginPercentRightString.TrimEnd("%")            
            }            
        }                    
            
            
        $getCommandTab = {            
            param($cmd, [switch]$NavBarOnly)            
            
            
            $CanCacheTab = $false            
            # If the command is Marked Hidden, then it will not be displayed on a web interface.            
            
            if ($pipeworksManifest.WebCommand.$cmd.Hidden) {            
                return            
            }            
            
            
            $realCmd = $cmd            
            
            
            if ($pipeworksManifest.WebAlias.$Cmd) {            
                $realCmd = $pipeworksManifest.WebAlias.$cmd.Command            
            }            
            
            if (-not $realCmd) { return }            
            
            
            if (-not $script:CachedResolvedCommand.($module.Name).$realCmd) {            
                if (-not $script:CachedResolvedCommand) {            
                    $script:CachedResolvedCommand = @{}            
                }            
                if (-not $script:CachedResolvedCommand.($module.Name)) {            
                    $script:CachedResolvedCommand.($module.Name) = @{}            
                }            
                $script:CachedResolvedCommand.($module.Name).$realCmd = Get-Command $realcmd -ErrorAction SilentlyContinue            
            }            
                        
            $resolvedCommand = $script:CachedResolvedCommand.($module.Name).$realCmd            
            if (-not $resolvedCommand) { return }                    
                        
            $cmdUrl = "${cmd}/?-widget"            
            $hideParameter =@($pipeworksManifest.WebCommand.$realcmd.HideParameter)            
            $cmdOptions = $pipeworksManifest.WebCommand.$realcmd            
            
            
            if ($pipeworksManifest.WebAlias.$cmd) {            
                foreach ($kv in ($pipeworksManifest.WebAlias.$cmd).GetEnumerator()) {            
                    if (-not $kv) {            
                        continue            
                    }            
                    if ($kv.Key -eq 'Command') { continue }             
                    $cmdOptions[$kv.Key] = $kv.Value            
                }            
            }            
            
            
            
            
                        
            $cmdFriendlyName = if ($pipeworksManifest.WebCommand.$realcmd.FriendlyName) {            
                $pipeworksManifest.WebCommand.$realcmd.FriendlyName            
            } else {            
                $realCmd            
            }               
            $cmdIsVisible = $true            
            if ($pipeworksManifest.WebCommand.$realcmd.IfLoggedInAs -or $pipeworksManifest.WebCommand.$realcmd.ValidUserPartition) {            
                $confirmParams = @{            
                    IfLoggedInAs = $pipeworksManifest.WebCommand.$realcmd.IfLoggedInAs            
                    ValidUserPartition = $pipeworksManifest.WebCommand.$realcmd.ValidUserPartition            
                    CheckId = $true            
                    WebsiteUrl = $finalUrl            
                }            
                $cmdIsVisible = . Confirm-Person @confirmParams            
            }            
            if ($cmdIsVisible) {            
                            
                $commandDescription  = ""                                    
                $command = $cmd             
                if (-not $script:CachedCommandHelp.($module).$command) {            
                    if (-not $script:CachedCommandHelp) {            
                        $script:CachedCommandHelp = @{}            
                    }            
                    if (-not $script:CachedCommandHelp.($module)) {            
                        $script:CachedCommandHelp.($module) = @{}            
                    }            
                    $commandHelp = Get-Help $command -ErrorAction SilentlyContinue | Select-Object -First 1                 
                    $script:CachedCommandHelp.($module).$command = $commandHelp            
                } else {            
                    $commandHelp = $script:CachedCommandHelp.($module).$command             
                }            
                            
                if ($commandHelp.Description) {            
                    $commandDescription = $commandHelp.Description[0].text                                
                }            
            
                if (-not $script:CachedCommandMarkdown.$command) {            
                    if (-not $script:CachedCommandMarkdown) {            
                         $script:CachedCommandMarkdown = @{}            
                    }            
                    $script:CachedCommandMarkdown.$command = ConvertFrom-markdown -markdown "$commandDescription "            
                }            
                            
                $commandaction =             
                    if ($customAnyHandler) {            
                        "?Command=$realcmd"            
                    } else {            
                        "${RelativeDepth}$realcmd/"            
                    }            
            
            "
<div>
$($script:CachedCommandMarkdown.$command)

</div>

<div id='${cmd}_container' style='padding:20px'>
$(
if ($cmdOptions.RequireLogin -and (-not $session['User'])) {    
    $confirmHtml = . Confirm-Person -WebsiteUrl $finalUrl
    # Localize Content Here
    'You have to log in'  + $confirmHtml   
    $CanCacheTab = $false
    return
} 

if ($NavBarOnly) {
    
    return " " 
}
if ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $realCmd) {
    $CanCacheTab = $false
    if ($cmdOptions.RunWithoutInput ) {
        $extraParams = @{} + $cmdOptions
        if ($pipeworksManifest -and $pipeworksManifest.Style -and (-not $extraParams.Style)) {
            $extraParams.Style = $pipeworksManifest.Style 
        }
        if ($extraParams.Count -gt 1) {
            # Very explicitly make sure it's there, and not explicitly false
            if (-not $extra.RunOnline -or 
                $extraParams.Contains("RunOnline") -and $extaParams.RunOnline -ne $false) {
                $extraParams.RunOnline = $true                     
            }                
        } 
            
        if ($extaParams.PipeInto) {
            $extaParams.RunInSandbox = $true
        }
            
        if (-not $extraParams.AllowDownload) {
            $extraParams.AllowDownload = $allowDownload
        }
            
        if ($extraParams.RunOnline) {
            # Commands that can be run online
            $webCmds += $command.Name
        }
            
        if ($extraParams.RequireAppKey -or $extraParams.RequireLogin -or $extraParams.IfLoggedAs -or $extraParams.ValidUserPartition) {
            $extraParams.UserTable = $pipeworksManifest.Usertable.Name
            $extraParams.UserPartition = $pipeworksManifest.Usertable.Partition
            $extraParams.StorageAccountSetting = $pipeworksManifest.Usertable.StorageAccountSetting
            $extraParams.StorageKeySetting = $pipeworksManifest.Usertable.StorageKeySetting 
        }
    
    
        Invoke-Webcommand -Command $resolvedCommand @extraParams -AnalyticsId "$AnalyticsId" -AdSlot "$AdSlot" -AdSenseID "$AdSenseId" -ServiceUrl $finalUrl 2>&1
    
    } else {
        $useAjax = 
            if ($pipeworksManifest.NoAjax -or $cmdOptions.ContentType -or $cmdOptions.RedirectTo -or $cmdOptions.PlainOutput) {
                if ($request -and $request["Ajax"]) {
                    $true
                } else {
                    $false
                }
            } else {
                $true
            }

        Request-CommandInput -Action "$commandaction" -CommandMetaData (Get-Command $realcmd -Module "$($module.Name)") -DenyParameter $hideParameter -Ajax:$useAjax  -ButtonText $cmdFriendlyName    
    }
} elseif ($pipeworksManifest.Link -eq '*' -or $pipeworksManifest.Link -eq $realCmd) {
    $cmdLinks["$cmdFriendlyName"] = $commandaction
    return " "
} else {
    $cmdUrls["$cmdFriendlyName/?inline=true"] = $commandaction
    return " " 
}
)            
</div>"             
            }              
                        
                                    
                        
        }            
            
        $getGroups = {            
            param([switch]$NavBarOnly)            
                    
            
        $getGroupsStartedAt = [DateTime]::Now            
        $CanCacheGroups = $true            
        $realOrder = @()            
        if ($pipeworksManifest.Group -or $pipeworksManifest.Groups) {            
            $groups = New-Object Collections.ArrayList            
            
            $groupInfo = if ($pipeworksManifest.Group) {            
                $pipeworksManifest.Group            
            } else {            
                $pipeworksManifest.Groups            
            }            
            
            foreach ($grp in $groupInfo ) {            
                if (-not $grp) { continue }             
                if ($grp -isnot [hashtable]) { continue }             
                $GroupIsVisible =  $false            
                $CanCacheGroup = $true            
                foreach ($key in ($grp.Keys | Sort-Object)) {            
                    $innerLayers = @{}            
                    $innerRestUrls = @{}            
                    $innerLinks = @{}            
                    $navBarData[$key] = @{}                                
                    $values = @($grp[$key])            
                    $innerOrder = New-Object Collections.ArrayList            
                    $expandedLayers = @()            
                    foreach ($cmd in $values) {            
                        $top = $cmd                           
                        $cmdFriendlyName = $cmd            
                        $t = ""                                         
                        $tab =             
                                        
                                            
                                if ($walkthrus[$top]) {                                                           
                                    $cmdFriendlyName = $top            
                                    $namedtopics[$top] = $top            
            
                                    # If it's inlined, get the walkthru HTML, otherwise, just get the link            
                                    if ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $top) {            
                                        if (-not $NavBarOnly) {            
                                            $CanCacheGroup = $false            
                                            $params = @{}            
                                            if ($pipeworksManifest.TrustedWalkthrus -contains $top) {            
                                                $params['RunDemo'] = $true            
                                            }            
                                            if ($pipeworksManifest.WebWalkthrus -contains $top) {            
                                                $params['OutputAsHtml'] = $true            
                                            }            
                                            if (-not $script:CachedWalkthrus) {            
                                                $script:CachedWalkthrus = @{}            
                                            }            
                                            if (-not $script:CachedWalkthrus["${module}_${top}"]) {            
                                                $script:CachedWalkthrus["${module}_${top}"] = Write-WalkthruHTML -StepByStep -WalkthruName $top -WalkThru $walkthrus[$top] @params            
                                            }                                                
            
                                            $script:CachedWalkthrus["${module}_${top}"]            
                                                    
                                            if ($pipeworksManifest.Inline -ne '*') {            
                                                $expandedLayers += $top            
                                            }            
                                        } else {            
                                            " "             
                                        }            
                                    } elseif ($pipeworksManifest.Link -eq '*' -or $pipeworksManifest.Link -eq $top) {            
                                        " "             
                                        $innerLinks[$cmdFriendlyName] = "${RelativeDepth}${cmd}"            
                                    } else {            
                                        " "             
                                        $innerRestUrls[$cmdFriendlyName] = "${RelativeDepth}${cmd}/?inline=true"            
                                    }            
            
                                } elseif ($aboutTopicsByName[$top])  {            
                                    $cmdFriendlyName= $top            
                                    $namedtopics[$top] = $top            
                                    $topicMatch = $aboutTopicsByName[$top]            
                                    if ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $top) {            
                                        if (-not $NavBarOnly) {                
                                            $CanCacheGroup = $false                                            
                                            if (-not $script:CachedTopics) {            
                                                $script:CachedTopics = @{}            
                                            }            
                                                
                                            if (-not $script:CachedTopics["${module}_${top}"]) {            
                                                $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                                                        $false            
                                                    } else {            
                                                        $true            
                                                    }            
            
                                                $script:CachedTopics["${module}_${top}"] = ConvertFrom-Markdown -Markdown "$($topicMatch.Topic) " -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
                                            }                
                                            $script:CachedTopics["${module}_${top}"]            
                                                        
                                            if ($pipeworksManifest.Inline -ne '*') {            
                                                $expandedLayers += $top            
                                            }            
                                                        
                                        } else {            
                                            " "             
                                        }                
                                    } elseif ($pipeworksManifest.Link -eq '*' -or $pipeworksManifest.Link -eq $top) {            
                                        " "             
                                        $innerLinks[$cmdFriendlyName] = "${RelativeDepth}${cmd}"            
                                    } else {            
                                        " "            
                                        $innerRestUrls[$cmdFriendlyName] = "${RelativeDepth}${cmd}/?snug=true"            
                                    }            
                                } else {            
                                    if ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $cmd) {            
                                        $CanCacheGroup = $false            
                                        . $getCommandTab $cmd -navbarOnly:$NavBarOnly            
                                        if ($cmdFriendlyName -and $pipeworksManifest.Inline -ne '*') {            
                                            $expandedLayers += $cmdFriendlyName            
                                        }            
                                    } elseif ($pipeworksManifest.Link -eq '*' -or $pipeworksManifest.Link -eq $cmd) {            
                                        . $getCommandTab $cmd -navbarOnly            
                                        if (-not $cancacheTab) {            
                                            $CanCacheGroup = $false            
                                        }            
                                        $innerLinks[$cmdFriendlyName] = "${RelativeDepth}${cmd}"            
                                    } else {            
                                        . $getCommandTab $cmd -navbarOnly            
                                        if (-not $cancacheTab) {            
                                            $CanCacheGroup = $false            
                                        }            
                                        $innerRestUrls[$cmdFriendlyName] = "${RelativeDepth}${cmd}/?inline=true"            
                                    }                                            
                                }            
                                        
                                    
                        if ($tab) {            
                                        
                            $innerLayers[$cmdFriendlyName] = $tab                   
                            $null = $innerOrder.Add($cmdFriendlyName)            
            
            
                            $navBarData[$key][$cmdFriendlyName] = "${relativeDepth}${cmd}".Replace(" ", "_").TrimEnd("/") + "/"            
                                        
                            $GroupIsVisible = $true            
                        }            
                                    
                    }            
                                
                    $regionLayoutParams =             
                        if ($pipeworksManifest.InnerRegion -is [Hashtable]) {            
                            $pipeworksManifest.InnerRegion            
                        } else {                                                                    
                            @{            
                                AsNewspaper = $true            
                                ExpandNewspaperColumn = $expandedLayers            
                                NewspaperColumn = 1            
                                NewspaperHeadingSize = 3                                            
                            }            
            
                        }            
            
                    if ($GroupIsVisible) {            
                        $cmdTabs[$key] = New-Region @regionLayoutParams  -LayerID $Key -Layer $innerLayers -Order $innerOrder -LayerUrl $innerRestUrls -LayerLink $innerLinks            
                        $navBarOrder[$key] = $innerOrder                                    
                                
                    $null = $groups.Add($key)            
                    }            
                    if (-not $CanCacheGroup) {            
                        $CanCacheGroups = $false            
                    }                                               
                }            
                            
            }            
            $realOrder += $groups            
            # Filter out anything displayed elsewhere            
            $screencasts = @(            
                foreach ($_ in $screencasts) {            
                    if ($_.Caption -and -not $namedtopics[$_.Caption]) {            
                        $_            
                    }            
                })             
            $onlineWalkthrus = @(            
                foreach ($_ in $onlineWalkthrus) {            
                    if ($_.Caption -and -not $namedtopics[$_.Caption]) {            
                        $_            
                    }            
                })            
            $codeWalkThrus = @(            
                foreach ($_ in $codeWalkThrus) {            
                    if ($_.Caption -and -not $namedtopics[$_.Caption]) {            
                        $_            
                    }            
                })            
            
            $tutorialItems = @(            
                foreach ($_ in $tutorialItems) {            
                    if ($_.Caption -and -not $namedtopics[$_.Caption]) {            
                        $_            
                    }            
                })                                    
        } else {             
            $commandOrder = if ($pipeworksManifest.CommandOrder) {            
                $pipeworksManifest.CommandOrder            
            } else {            
                $pipeworksManifest.WebCommand.Keys | Sort-Object            
            }            
            
                    
                        
            
            $expandedLayers = @()            
            foreach ($cmd in $commandOrder) {                        
                        
                $tab = . $getCommandTab $cmd            
                if (-not $cancacheTab) {            
                    $CanCacheGroups = $false            
                }            
                if ($tab) {            
                    . ([ScriptBlock]::create("
`${Global:$($cmdFriendlyName)} = `$tab
`${Global:$($cmd)} = `$tab
"))            
            
                    $cmdTabs[$cmdFriendlyName] = $tab             
            
                    if ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $cmd) {            
                        if ($pipeworksManifest.Inline -ne '*') {            
                            $expandedLayers += $cmdFriendlyName            
                        }            
                    } elseif ($pipeworksManifest.Link -eq '*' -or $pipeworksaManifest.Link -eq $cmd) {            
                        $cmdLinks[$cmdFriendlyName] = "${RelativeDepth}${cmd}/"            
                    } else {            
                        $cmdUrls[$cmdFriendlyName] = "${RelativeDepth}${cmd}/?inline=true"            
                    }            
                                
                    $realOrder += $cmdFriendlyName            
            
                    $navBarData[$cmdFriendlyName] = "${RelativeDepth}${cmd}".Replace(" ", "_").TrimEnd("/") + "/"            
                    $navBarUrls[$cmdFriendlyName] = "${RelativeDepth}${cmd}".Replace(" ", "_").TrimEnd("/") + "/"            
                                
                }            
                            
                    
            }            
                        
            
                        
        }            
            $timespentIngetGroups = [DateTime]::Now - $getGroupsStartedAt            
        }                            
        #endregion            
            
            
        $getBanners = {            
$bottomBannerSlot =             
    if ($pipeworksManifest.AdSense -and $PipeworksManifest.AdSense.BottomAdSlot) {            
                
        if ($PipeworksManifest.AdSense.BottomAdSlot -like "*/*") {            
            $slotAdSenseId = $pipeworksManifest.AdSense.BottomAdSlot.Split("/")[0]            
            $slotAdSlot =  $pipeworksManifest.AdSense.BottomAdSlot.Split("/")[1]            
        } elseif ($pipeworksManifest.AdSense.Id) {            
            $slotAdSenseId = $pipeworksManifest.AdSense.Id            
            $slotAdSlot = $PipeworksManifest.AdSense.BottomAdSlot            
        }            
                    
        "<p style='text-align:center'>
        <script type='text/javascript'>
        <!--
        google_ad_client = 'ca-pub-$($slotAdSenseId)';
        /* AdSense Banner */
        google_ad_slot = '$($slotAdSlot)';
        google_ad_width = 728;
        google_ad_height = 90;
        //-->
        </script>
        <script type='text/javascript'
        src='http://pagead2.googlesyndication.com/pagead/show_ads.js'>
        </script>
        </p>"                
    } else {            
        ""            
    }            
            
            
$upperBannerSlot =             
    if ($pipeworksManifest.AdSense -and $PipeworksManifest.AdSense.TopAdSlot) {            
        if ($PipeworksManifest.AdSense.TopAdSlot -like "*/*") {            
            $slotAdSenseId = $pipeworksManifest.AdSense.TopAdSlot.Split("/")[0]            
            $slotAdSlot =  $pipeworksManifest.AdSense.TopAdSlot.Split("/")[1]            
        } elseif ($pipeworksManifest.AdSense.Id) {            
            $slotAdSenseId = $pipeworksManifest.AdSense.Id            
            $slotAdSlot = $PipeworksManifest.AdSense.TopAdSlot             
        }            
        "<p style='text-align:center'>
<script type='text/javascript'>
<!--
google_ad_client = 'ca-pub-$($slotAdSenseId)';
/* AdSense Banner */
google_ad_slot = '$($slotAdSlot)';
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type='text/javascript'
src='http://pagead2.googlesyndication.com/pagead/show_ads.js'>
</script>
</p>"              
                
                
} else {            
    ""            
}            
            
            
$brandingSlot =             
if ($script:CachedBrandingSlot) {            
    $script:CachedBrandingSlot            
} else {            
    if ($pipeworksManifest.Branding) {            
        if ($pipeworksManifest.Branding) {            
            $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
                $false            
            } else {            
                $true            
            }            
            
            ConvertFrom-Markdown $pipeworksManifest.Branding -ShowData:$ShowDataInTopic            
                                  
        } else {            
            ""            
        }            
    } elseif ($ModuleMaker -eq 'Start-Automating') {            
@"
<div style='font-size:.75em;text-align:right'>
Provided By 
<a href='http://start-automating.com'>
<img src='http://StartAutomating.com/Assets/StartAutomating_100_Transparent.png' align='middle' style='width:60px;height:60px;border:0' />
</a>

</div>

<div style='font-size:.75em;text-align:right'>
Powered With
<a href='http://powershellpipeworks.com'>
<img src='http://powershellpipeworks.com/assets/powershellpipeworks_150.png' align='middle' style='width:60px;height:60px;border:0' />
</a>

</div>
"@            
    } else {            
@"
<div style='font-size:.75em;text-align:right'>
Powered With
<a href='http://powershellpipeworks.com'>
<img src='http://powershellpipeworks.com/assets/powershellpipeworks_150.png' align='middle' style='width:60px;height:60px;border:0' />
</a>

</div>
"@                    
            
                
    }            
            
}            
            
$script:CachedBrandingSlot = $brandingSlot            
            
}                
        $coreModuleHandler = {            
            
$coreHandlerStartedAt = [DateTime]::Now            
            
# Here is where the default module experience happens.            
            
            
<#

# This consists of declaring several variables that can be used within templates

    $TitleArea - 
        An area containing the title of the module the module logo
    $descriptionArea -
        An area containing the description of the module or the current command        
    $socialArea
        An area containing social media, login links, and company contact info
#>            
            
            
            
            
<#
$TitleArea - 
        An area containing the title of the module the module logo
#>             
$linkUrl = if ("$finalUrl") {            
    "$FinalUrl".Substring(0, "$FinalUrl".LastIndexOf("/"))            
} else {            
    "./"            
}            
            
$titleArea =             
    if ($PipeworksManifest -and $pipeworksManifest.Logo) {            
        "<a href='$linkUrl' class='brand'><img src='$($pipeworksManifest.Logo)' alt='$($module.Name)' style='border:0' /></a>"            
    } else {            
        "<a href='$linkUrl' class='brand'>$($Module.Name)</a>"            
    }            
            
$socialArea = ''            
            
            
$descriptionArea = $module.Description.Replace("`n", "<br/>")            
            
            
$cmdTabs = @{}            
$navBarData = @{}            
$navBarUrls = @{}            
$navBarOrder = @{}            
if ($AllowDownload) {            
    if ($pipeworksManifest.Technet.Url -or $pipeworksManifest.Win8.PublishedUrl -or $PipeworksManifest.Github.Url) {            
        $downloads = @{            
            "Download Latest"  = "Download.html"                        
        }            
            
                    
            
            
        if ($PipeworksManifest.Technet.Url) {            
            $downloads+= @{                        
                "Download From Technet"  = "$($pipeworksManifest.Technet.Url)"                        
            }            
        }            
            
        if ($PipeworksManifest.Win8.PublishedUrl) {            
            $downloads+= @{                        
                "Download Windows App"  = "$($PipeworksManifest.Win8.PublishedUrl)"                        
            }            
        }            
            
        if ($PipeworksManifest.Github.Url) {            
            $downloads+= @{                        
                "Download From Github"  = "$($PipeworksManifest.Github.Url)"                        
            }            
        }            
        $navBarData["Download"] = $downloads                    
    } else {            
        $navBarData["Download"] = ""                
        $navBarUrls["Download"] = "Download.html"            
    }            
                
}            
if ($pipeworksManifest.Win.PublishedUrl -and -not $allowDownload) {            
            
}            
$cmdUrls = @{}            
$cmdLinks = @{}            
            
            
            
$telephoneArea = ""            
$addressArea = ""            
$emailArea = ""            
$orgArea = ""            
$orgItems = @()            
$OrgInfoSlot = if ($pipeworksManifest.Organization) {            
                
    if ($pipeworksManifest.Organization.Telephone) {            
        $telephoneArea = ($pipeworksManifest.Organization.Telephone -join ' | ') + "<BR/>"                    
        $orgItems += $telephoneArea             
    }            
    if ($pipeworksManifest.Organization.Address) {            
        $addressArea = $pipeworksManifest.Organization.Address -split ([Environment]::NewLine) -join '<br/>'            
        $orgItems += $addressArea             
    }            
            
    if ($pipeworksManifest.Organization.Email) {            
        $emailArea = (            
        "<a href='mailto:$($pipeworksManifest.Organization.Email)'>$($pipeworksManifest.Organization.Email)</a>"  + "<BR/>"            
        )                    
        $orgItems += $emailArea            
    }            
    $orgArea = $orgItems -ne '' -join '<br/>'            
    # $socialArea +=  $orgText            
            
} else {            
    ""            
}            
            
$loginRequired = $false            
if ($PipeworksManifest.WebCommand) {            
    foreach ($_ in $PipeworksManifest.WebCommand.Values) {            
        if ($_.RequireLogin -or $_.RequireAppKey -or $_.IfLoggedInAs -or $_.ValidUserPartition) {            
            $loginRequired = $true            
            break            
        }            
    }            
}            
            
            
if (-not $script:SocialArea) {            
                            
            
               $script:SocialArea = "
$(
    if (-not $antiSocial) {
        if ($pipeworksManifest -and ($pipeworksManifest.Facebook.AppId -or $pipeworksManifest.FacebookLike)) {
            
                        
            Write-Link "facebook:like"
                        
        }
        if ($pipeworksManifest -and ($pipeworksManifest.GoogleSiteVerification -or $pipeworksManifest.AddPlusOne)) {
            
                        
            Write-Link "google:plusone"
                        
        }
        if ($pipeworksManifest -and $pipeworksManifest.ShowTweet) {
            Write-Link "twitter:tweet"
                        
        } elseif ($pipeworksManifest -and ($pipeworksManifest.TwitterId)) {
            Write-Link "twitter:tweet"
                        
            
                        
            Write-Link "twitter:follow@$($pipeworksManifest.TwitterId.TrimStart('@'))"                        
        }
    }
)
               "            
            }            
            
$socialArea = $script:SocialArea            
            
            
$confirmationArea = ""            
if ($loginRequired) {            
    $confirmationArea  = . Confirm-Person -WebsiteUrl $finalUrl                            
}            
            
$topicHtml  = ""            
            
$subtopics = @{            
    LayerId = 'MoreInfo'            
    Layer = @{}            
}            
            
$webPageRss = @{}            
            
$ShowBuiltInBlog = $true            
            
if ($PipeworksManifest.Blog -and $PipeworksManifest.Blog.Name) {                
    $blogLink = if ($pipeworksManifest.Blog.Link -like "http*" -and $pipeworksManifest.Blog.Name -and $pipeworksManifest.Blog.Description) {            
        # Absolute link to module base,            
        $pipeworksManifest.Blog.Link.TrimEnd("/") + "/Module.ashx?rss=$($pipeworksManifest.Blog.Name)"            
    } elseif ($pipeworksManifest.Blog.Link) {            
        $pipeworksManifest.Blog.Link            
    } else {            
        "Module.ashx?Rss=true"            
        $ShowBuiltInBlog  = $false            
    }            
    $webPageRss += @{            
        $PipeworksManifest.Blog.Name=$blogLink             
    }            
}             
            
            
$topicsByName = @{}            
            
            
if ($aboutTopics) {            
    $coreAboutTopic = $null            
    $otherAboutTopics =             
        @(foreach ($_ in $aboutTopics) {            
            if (-not $_) {continue }             
            if ($_.Name -ne "About $($Module.Name)") {            
                $_            
            } else {            
                $coreAboutTopic = $_                            
            }            
        })            
                    
                
    if ($coreAboutTopic) {            
        $coreAboutTopic = @($coreAboutTopic)[0]            
        $ShowDataInTopic = if ($pipeworksManifest.HideDataInTopic) {            
            $false            
        } else {            
            $true            
        }            
            
        if (-not $script:CachedCoreTopic.($module.Name)) {            
            if (-not $script:CachedCoreTopic) {            
                $script:CachedCoreTopic = @{}            
            }            
            $script:CachedCoreTopic.($module.Name) = ConvertFrom-Markdown -Markdown "$($coreAboutTopic.Topic) "  -ScriptAsPowerShell -ShowData:$ShowDataInTopic                        
        }            
        $topicHtml = $script:CachedCoreTopic.($module.Name) # ConvertFrom-Markdown -Markdown "$($coreAboutTopic.Topic) "  -ScriptAsPowerShell -ShowData:$ShowDataInTopic            
    }                     
                
    if ($otherAboutTopics -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {                           
        $aboutItems = @()            
        $tutorialItems = @()            
                    
        foreach ($oat in $otherAboutTopics) {            
                        
            $tutorialItems +=             
                if ($customAnyHandler) {            
                    New-Object PSObject -Property @{            
                        Caption = $oat.Name            
                        Url = "?About=" + $oat.Name            
                    }            
                } else {            
                    New-Object PSObject -Property @{            
                        Caption = $oat.Name            
                        Url = $oat.Name + "/"            
                    }            
                }            
                            
                        
                        
        }                            
                    
        if ($ShowBuiltInBlog) {            
            $webPageRss["$($module)"] = "${RelativeDepth}Module.ashx?rss=true"                    
        }            
        if ($tutorialLayer.Count) {            
                        
        }             
        if ($aboutLayer.Count) {            
                    
        }                
    }            
                
}            
            
            
                
if ($walkthrus -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {            
    $screenCasts = @()            
    $onlineWalkthrus = @()            
    $codeWalkThrus = @()            
                
    foreach ($walkthruName in $walkThrus.Keys) {            
        if ($walkThruName -like "*Video*" -or             
            $walkThruName -like "*Screencasts*") {            
            $screenCasts +=            
                if ($customAnyHandler) {            
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName.Replace('.walkthru.help.txt', '').Replace('_', ' ')            
                        Url = "?Walkthru=" + $walkThruName.Replace('.walkthru.help.txt', '').Replace('_', ' ')            
                    }            
                } else {            
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName.Replace('.walkthru.help.txt', '').Replace('_', ' ')            
                        Url = $walkThruName.Replace('.walkthru.help.txt', '').Replace('_', ' ') + "/"            
                    }            
                }            
                            
        } elseif ($pipeworksManifest.TrustedWalkthrus -contains $walkThruName) {            
            $onlineWalkThrus +=             
                if ($customAnyHandler) {             
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName            
                        Url = "?Walkthru=" + $walkThruName            
                    }            
                } else {            
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName            
                        Url = $walkThruName + "/"            
                    }            
                }            
        } else {            
            $codeWalkThrus +=             
                if ($customAnyHandler) {             
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName            
                        Url = "?Walkthru=" + $walkThruName            
                    }            
                } else {            
                    New-Object PSObject -Property @{            
                        Caption = $walkThruName            
                        Url = $walkThruName + "/"            
                    }            
                }            
        }            
                    
                    
    }            
            
}                    
            
                
            
                    
if ($request -and $request["Snug"]) {            
    $MarginPercentLeftString = $MarginPercentRightString = "1%"            
}            
            
               
            
            
#region Services Tab            
            
    $StartedGeneratingCoreContent = [DateTime]::Now            
                
                
    if (-not $canCacheGroups) {            
        . $getGroups             
    }                
                
            
                
            
                
    $videosOrder = @()            
    $screenCastSection = if ($screenCasts -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {            
        $navBarData["Videos"] = @{}            
        $subTopics.Layer."Videos"  = @"
<p class='ModuleWalkthruExplanation'>
        
Watch these videos to get started:

$($ScreenCasts |
    Sort-Object Caption | 
    ForEach-Object {
        $navBarData["Videos"][$($_.Caption)] = "$RelativeDepth$($_.Url)".Replace(' ', '%')
        $videosOrder  += $_.Caption
        $_
    } |
    Write-Link -AsList)
</p>
"@            
            
        $navBarOrder["Videos"] = $videosOrder            
    } else {            
        ""            
    }            
            
    $demoOrder = @()            
                
    $onlineWalkthruSection = if ($onlineWalkthrus -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {            
                    
        $navBarData["Demos"] = @{}            
        $subTopics.Layer."Demos" = @"
<p class='ModuleWalkthruExplanation'>
        
See each step, and see each step's results.

$($OnlineWalkthrus|
    Sort-Object Caption|
    ForEach-Object {
        $navBarData["Demos"][$_.Caption] = "$RelativeDepth$($_.Url)".Replace(' ', '%')
        $demoOrder += $_.Caption
        $_
    } |
    Write-Link -AsList )
</p>
"@            
    $navBarOrder["Demos"] = $demoOrder            
    } else {            
        ""            
    }            
            
            
                
    $walkthruOrder = @()            
    $codeWalkthruSection = if ($codeWalkThrus -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {            
        $navBarData["Walkthrus"] = @{}            
        $subTopics.Layer."Walkthrus" = @"
<p class='ModuleWalkthruExplanation'>
        
See the code step by step.

$($CodeWalkthrus |  
    Sort-Object Caption|
    ForEach-Object {
        $navBarData["Walkthrus"][$_.Caption] = "$RelativeDepth$($_.Url)".Replace(' ', '%')
        $walkthruOrder += $_.Caption
        $_
    } |
    Write-Link -AsList)
</p>
"@            
        $navBarOrder["Walkthrus"] = $walkthruOrder             
    } else {            
        ""            
    }             
                
    if ($aboutItems -or $tutorialItems -and -not ($pipeworksManifest.HideUngrouped -or $pipeworksManifest.HideUngroupedTopics)) {            
        $MoreAboutModule = @()            
        $navBarData["More About $Module"] = @{}            
        $subTopics.Layer."More About $Module" = @"
<p class='ModuleWalkthruExplanation'>
        


$($aboutItems + $tutorialItems |  
    Sort-Object Caption |
    ForEach-Object {
        
        $navBarData["More About $Module"]["$($_.Caption)"] = "$RelativeDepth$($_.Url)".Replace(' ', '%')
        $MoreAboutModule += $_.Caption
        $_
    } | 
    Write-Link -AsList)
</p>

"@                            
        $navBarOrder["More About $Module"] =$MoreAboutModule            
    }            
                
    $learnMore = if ($subtopics.Layer.Count) {            
        foreach ($layerName in "More About $module", "Videos", "Walkthrus", "Demos") {            
            if( $subtopics.Layer.$layerName) {            
                $realOrder += $layerName            
                if (-not $cmdTabs) {            
                    $cmdTabs = @{}            
                }            
                $cmdTabs[$layerName] = $subtopics.Layer.$layerName            
            
                            
            }            
        }             
                    
                    
                    
                    
                    
        ""            
    } else {            
        ""            
    }            
                
            
            
                
    if ($AllowDownload) {            
                    
            
            
        if ($pipeworksManifest.Technet.Url -or $PipeworksManifest.Win8.PublishedURL -or $PipeworksManifest.Github.Url) {            
                        
            $downloads = @{            
                "Download Latest"  = "Download.html"            
            }            
            $downloadLayers = @{            
                "Download Latest" =  " "            
            }            
            
            if ($PipeworksManifest.Technet.Url) {            
                $downloads += @{            
                    "Download From Technet"  = $PipeworksManifest.Technet.Url            
                }            
                $downloadLayers += @{            
                    "Download From Technet" =  " "            
                }            
            }            
            
            if ($PipeworksManifest.Win8.PublishedURL) {            
                $downloads +=@{            
                    "Download Windows App"  = $PipeworksManifest.Win8.PublishedURL            
                }            
                $downloadLayers += @{            
                    "Download Windows App" =  " "            
                }            
            }            
            
            if ($PipeworksManifest.Github.Url) {            
                $downloads +=@{            
                    "Download From GitHub"  = $PipeworksManifest.Github.Url            
                }            
                $downloadLayers += @{            
                    "Download From GitHub" =  " "            
                }            
            }            
                        
            $layerName = "Download"            
            $regionLayoutParams =             
                if ($pipeworksManifest.InnerRegion -is [Hashtable]) {            
                    $pipeworksManifest.InnerRegion            
                } else {                                        
                    @{            
                        AsNewspaper = $true            
                        ExpandNewspaperColumn = ""            
                        NewspaperColumn = 1            
                        NewspaperHeadingSize = 3            
                        NewspaperHeadingAlignment = 'center'            
            
                    }            
            
                }            
            
            $cmdTabs[$layerName] = New-Region -LayerID 'DownloadLayer' -layerLink $downloads -Layer $downloadLayers @regionLayoutParams            
                               
            $realOrder += "Download"            
                        
        } else {            
            $layerName = "Download"            
            $realOrder += "Download"            
            $cmdTabs[$layerName] = " "            
                        
            $cmdLinks += @{Download="Download.html"}            
                        
        }                                           
    }            
            
            
    if ($pipeworksManifest.Win8.PublishedUrl) {            
        if (-not $allowDownload) {            
            $cmdLinks += @{"Download Windows App"=$pipeworksManifest.Win8.PublishedUrl}            
            $layerName = "Download Windows App"            
            $realOrder += "Download Windows App"            
            $cmdTabs[$layerName] = " "            
        }            
                    
    }            
                
    $regionLayoutParams = if ($pipeworksManifest.MainRegion -is [hashtable]) {            
        $pipeworksManifest.MainRegion            
    } else {            
        if ($pipeworksManifest.Group) {            
            @{            
                AsNewspaper=$true            
                #UnderlineNewspaperHeadline = $true            
                UseButtonForNewspaperHeadline = $true            
            }            
        } else {            
            @{            
                AsNewspaper=$true            
                NewspaperColumn = 1            
                ExpandNewspaperColumn = $expandedLayers            
                UseButtonForNewspaperHeadline = $true            
                NewspaperHeadingSize = 3            
                NewspaperHeadingAlignment = "center"            
            }            
        }            
                            
    }            
            
    $rest = if ($canCacheGroups) {            
        if (-not $script:CachedGroupHTML.($module.Name)) {            
            if (-not $script:CachedGroupHTML) {            
                $script:CachedGroupHTML = @{}            
            }            
            $script:CachedGroupHTML.($module.Name)= New-Region -LayerID Items -Layer $cmdTabs -order $realOrder @regionLayoutParams -LayerUrl $cmdUrls -layerLink $cmdLinks            
            
            $script:CachedGroupHTML.($module.Name)            
        } else {            
            $script:CachedGroupHTML.($module.Name)            
        }            
    } else {            
        New-Region -LayerID Items -Layer $cmdTabs -order $realOrder @regionLayoutParams -LayerUrl $cmdUrls -layerLink $cmdLinks            
    }            
    $TimeSpentGeneratingCoreContent = [DateTime]::now - $StartedGeneratingCoreContent            
    #endregion Services Tab            
                
            
            
            
. $getBanners            
$ifTemplateFound = @{}            
            
$rssLink =             
if ($webPageRss.Count -ge 1 -and $otherAboutTopics.Count -and $pipeworksManifest.Blog) {            
    $rsslinks = foreach ($rss in $webPageRss.GetEnumerator()) {            
        if (-not $rss) { continue }            
        "<a href='$($rss.Value)'><img src='/rss.png' style='border:0;' alt='$([Web.HttpUtility]::HtmlAttributeEncode($rss.Key))' /></a>"            
    }            
    $rsslinks -join ("<br/>")            
} else {            
    " "             
}            
            
if ($pipeworksManifest.TemplateFiles.($module.Name)) {            
    $ifTemplateFound.Template =($module.Name)            
} elseif ($pipeworksManifest.ModuleTemplate) {            
    $ifTemplateFound.Template =$pipeworksManifest.ModuleTemplate            
} elseif ($pipeworksManifest.DefaultTemplate) {            
    $ifTemplateFound.Template =$pipeworksManifest.DefaultTemplate            
} elseif ($pipeworksManifest.Template) {            
    $ifTemplateFound.Template =$pipeworksManifest.Template            
}            
            
            
            
if (-not $ModuleTemplateExists) {            
    $ModuleTemplateExists = "Template", "Templates" | Get-ChildItem -ErrorAction SilentlyContinue -Filter "$($ifTemplateFound.Template).pswt" | Select-Object -First 1            
    # If the template won't make use of automatically generated sections, then don't generate them.            
    $makeNavBar = $true            
    $makeSlideShow = $true            
    $showDefaultCommand = $true            
            
    if ($global:ModuleTemplateExists) {            
        $templateText = [IO.File]::ReadAllText($global:ModuleTemplateExists.FullName)            
            
        $makeNavBar = [Regex]::Match($templateText, '\$navBarHtml')            
        $makeSlideShow = [Regex]::Match($templateText, '\$slideShowHtml')            
        $showDefaultCommand = [Regex]::Match($templateText, '\$defaultCommandSection')            
    }            
}            
            
            
            
            
            
if ($makeNavBar) {            
    $navBarHtml =             
        if ($navBarData -and $PipeworksManifest.UseBootstrap) {                
            New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder            
        } elseif ($navBarData) {            
            New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder               
        } else {            
            ""            
        }            
}            
            
if ($makeSlideShow) {            
            
    $slideShowHtml = ""            
    if ($pipeworksManifest.Slideshow) {            
        $slidesInShow  = @{}            
        $slideShowNaturalOrder = @()                
        $slideCount = 0            
            $slideList =             
                if ($pipeworksManifest.SlideShow.Slide) {            
                    $pipeworksManifest.SlideShow.Slide            
                } elseif ($pipeworksManifest.SlideShow.Slides){            
                    $pipeworksManifest.SlideShow.Slides            
                } else {            
                    $null            
                }            
            
            
            
            foreach ($slide in $slideList) {            
                if (-not $slide) { continue }            
                if ($slide -is [Hashtable]) {            
                    foreach ($k in  ($slide.Keys | Sort-Object)) {            
                        $slideName  = $k            
                        $slideShowNaturalOrder += $k            
                        $slidesInShow[$k] = $slide[$k]            
                    }            
                } elseif ($slide -as [string]) {            
                    $slideName = "Slide" + $slideCount            
                    $slideCount++            
                    $slidesInShow[$slideName] = "<img src='$($slide)' style='border:0;max-width:75%' />"            
                    $slideShowNaturalOrder += $slideName            
                }            
            }            
            
        if ($pipeworksManifest.Slideshow.Order) {            
            $slideShowOrder  = $pipeworksManifest.Slideshow.Order            
        } else {            
            $slideShowOrder  = $slideShowNaturalOrder            
        }            
            
        $slideShowParams = @{}            
            
        if ($PipeworksManifest.UseBootstrap) {            
            $slideShowParams["AsCarousel"] = $true            
            $slideShowParams["HideSlideNameButton"] = $true            
        } else {            
            $slideShowParams["AsSlideShow"] = $true            
            $slideShowParams["UseDotInsteadOfName"] = $true            
        }            
        $slideShowHtml = New-Region -LayerID MainSlideshow -Layer $slidesInShow -Order $slideShowOrder @slideShowParams            
                
    }            
}            
            
if ($showDefaultCommand) {            
$defaultCommandSection  = if ($pipeworksManifest.DefaultCommand) {            
    $defaultCmd = @($ExecutionContext.InvokeCommand.GetCommand($pipeworksManifest.DefaultCommand.Name, "All"))[0]            
                
    $defaultCmdParameter = if ($pipeworksManifest.DefaultCommand.Parameter) {            
        $pipeworksManifest.DefaultCommand.Parameter            
    } else {            
        @{}            
    }            
                
    $cmdOutput = & $defaultcmd @defaultCmdParameter            
                
    if ($pipeworksManifest.DefaultCommand.GroupBy) {            
        $defaulItem  =""            
        $CmdOutputGrouped = $cmdOutput |             
            Group-Object $pipeworksManifest.DefaultCommand.GroupBy |            
            Foreach-Object -Begin {            
                $groupedLayers = @{}            
                $asStyle = if ($pipeworksManifest.DefaultCommand.DisplayAs) {            
                    "As$($pipeworksManifest.DefaultCommand.DisplayAs)"            
                } else {            
                    "AsSlideshow"            
                }            
            } {            
                if (-not $defaulItem ) {            
                    $defaultItem = $_.Name            
                }             
                            
                $groupedLayers[$_.Name] = $_.Group | Out-HTML            
            } -End {            
                $asStyleParam = @{            
                    $AsStyle = $true            
                }            
                New-Region  -Default $defaultItem -Layer $groupedLayers -LayerID DefaultcommandSection @asStyleParam             
            }            
        $cmdOutputGrouped            
    } else {            
        $cmdOutput | Out-Html            
    }            
} else {            
    ""            
}            
}            
            
$pageHtml = if (-not $ifTemplateFound.Template) {            
"
<div style='float:right;position:absolute;zindex:30;right:15px;top:15px;'>
$socialArea
</div>
<div style='float:left'>
<h1 style='float:left'>$titleArea</h1>
<h2 style='text-align:right;float:left;margin-top:75px'>
$descriptionArea 
</h2>
$(if ($navBarData -and $PipeworksManifest.UseBootstrap) {    
    New-Region -LayerID "MainNavBar" -Layer $navBarData -AsNavbar -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -LayerInnerOrder $navBarOrder
} elseif ($navBarData) {
    New-Region -LayerId "MainMenu" -AsMenu -Style @{"float"="right"} -Order $realOrder -LayerUrl $navBarUrls -Layer $navBarData -LayerInnerOrder $navBarOrder   
} else {
    ''
})
</div>
" + ($spacingDiv * 3) +            
    "<div style='margin-top:1%'>$topicHtml</div>" +               
    "<div style='clear:both;margin-top:1%'>$upperBannerSlot</div>" +            
    "<div style='clear:both;margin-top:1%'>$defaultCommandSection</div>" +                
    $rest +            
    "<div style='clear:both;margin-top:1%'>$bottomBannerSlot</div>" +            
    "<div style='float:right;margin-top:15%'>$brandingSlot</div>" |            
                
    New-Region -Style @{            
        "Margin-Left" = $MarginPercentLeftString            
        "Margin-Right" = $MarginPercentRightString            
    }             
} else {            
    " "            
}            
    if (-not $BakingPage) {            
        $pageHtml |            
            New-WebPage -NoCache -Title $module.Name -Description $module.Description -Rss $webPageRss @ifTemplateFound |            
        Out-HTML -WriteResponse             
                    
    } else {            
        $pageHtml |            
            New-WebPage -NoCache -Title $module.Name -Description $module.Description -Rss $webPageRss @ifTemplateFound            
    }            
                
$timeSpentInCoreHandler = [DateTime]::Now - $coreHandlerStartedAt             
}            
            
        $antiSocial = if ($pipeworksManifest.AntiSocial) {            
            $true             
        } else {            
            $false            
        }            
            
        $getVisibleGroups = {            
            if (-not ($session -and $session["User"]) -and $request["LiveIdAccessToken"]) {            
                $accessToken = $request["LiveIdaccesstoken"]            
                . Confirm-Person -liveIDAccessToken $accessToken -WebsiteUrl $finalUrl            
            }            
            #if (-not ($session -and $session["User"])) { return }            
            
                        
            if ($pipeworksManifest.Group) {            
                $groupVisibilityXml = "<VisibleGroups>"            
                foreach ($g in $pipeworksManifest.Group) {            
                                
                                
                                
                                
                    foreach ($i in $g.GetEnumerator()) {            
                        $groupIsVisible = $false             
                        $groupXml = "<Group Name='$([security.securityElement]::Escape($i.Key))'>"                
                        foreach ($v in $i.Value) {            
                            if ($pipeworksManifest.WebCommand.$v) {            
                                if ($pipeworksManifest.WebCommand.$v.IfLoggedInAs -or $pipeworksManifestPath.WebCommand.$v.ValidUserPartition) {            
                                    $ok = Confirm-person -websiteUrl $finalUrl -IfLoggedInAs $pipeworksManifest.WebCommand.IfLoggedInAs -ValidUserPartition $pipeworksManifest.WebCommand.ValidUserPartition -CheckId            
                                    if ($ok) {            
                                        $groupIsVisible = $true            
                                        $groupXml += "<Item>$($v)</Item>"            
                                    }            
                                } else {            
                                    $groupIsVisible = $true            
                                    $groupXml += "<Item>$($v)</Item>"            
                                }            
                                            
                                # It's a command            
                            } else {            
                                # It's a topic            
                                $groupXml += "<Item>$($v)</Item>"            
                                $groupIsVisible = $true             
                            }            
                        }            
                                        
                        if ($groupIsVisible) {            
                            $groupXml += "</Group>"            
                            $groupVisibilityXml += $groupXml            
                        }            
                    }            
            
                                
                }            
            }            
            
            if ($groupVisibilityXml) {            
                if ($session -and $session["User"]) {            
                    $groupVisibilityXml+="<LoggedIn/>"            
                } else {            
                }            
                $groupVisibilityXml += "</VisibleGroups>"            
                $response.ContentType = "text/xml"            
                $strWrite = New-Object IO.StringWriter            
                ([xml]($groupVisibilityXml)).Save($strWrite)            
                $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
                $response.Write("$ResultToOutput")            
                            
            }            
            return            
        }            
            
        <#$moduleInit = @"
$embedCommand
$getModuleMetaData
`$getCommandExtraInfo = { $($getCommandExtraInfo.ToString())
}
`$getCommandTab = { $($getCommandTab.ToString())
}
`$getGroups = { $($getGroups.ToString())
}

`$getBanners ={ $($getBanners.ToString())
} 
`$cssStyle = $((Write-PowerShellHashtable $Style))
`$HalfMarginPercentLeftString = '$(($MarginPercentLeftString.Replace('%', '') -as [double])/2)%'
`$HalfMarginPercentRightString = '$(($MarginPercentRightString.Replace('%', '') -as [double])/2)%'

`$MarginPercentLeftString = '$MarginPercentLeftString'.Trim()
`$MarginPercentRightString  = '$MarginPercentRightString'.Trim()

`$DownloadUrl = '$DownloadUrl'
`$analyticsId = '$analyticsId'

`$allowDownload = $(if ($allowDownload) { '$true'} else {'$false'}) 
`$antiSocial= $(if ($antiSocial) { '$true'} else {'$false'}) 
`$highlightedModuleCommands = '$($CommandOrder -join "','")'

$($resolveFinalUrl.ToString())

"@#>            
            
            
        $moduleHandler = @"
WebCommandSequence.InvokeScript(@"
if (-not `$global:ExecutionPolicyChanged) {
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force 
    `$global:ExecutionPolicyChanged = `$true
    `$getCommandExtraInfo = { $($getCommandExtraInfo.ToString().Replace('"', '""'))
}
`$getCommandTab = { $($getCommandTab.ToString().Replace('"', '""'))
}
`$getGroups = { $($getGroups.ToString().Replace('"', '""'))
}

`$getBanners ={ $($getBanners.ToString().Replace('"', '""'))
} 
`$cssStyle = $((Write-PowerShellHashtable $Style).Replace('"','""'))
`$HalfMarginPercentLeftString = '$(($MarginPercentLeftString.Replace('%', '') -as [double])/2)%'
`$HalfMarginPercentRightString = '$(($MarginPercentRightString.Replace('%', '') -as [double])/2)%'

`$MarginPercentLeftString = '$MarginPercentLeftString'.Trim()
`$MarginPercentRightString  = '$MarginPercentRightString'.Trim()

`$DownloadUrl = '$DownloadUrl'
`$analyticsId = '$analyticsId'

`$allowDownload = $(if ($allowDownload) { '$true'} else {'$false'}) 
`$antiSocial= $(if ($antiSocial) { '$true'} else {'$false'}) 
`$highlightedModuleCommands = '$($CommandOrder -join "','")'


}


$($embedCommand.ToString().Replace('"','""'))
$($getModuleMetaData.ToString().Replace('"', '""'))


$($resolveFinalUrl.ToString().Replace('"', '""'))

`if (`$request['about']) {
    $($aboutHandler.ToString().Replace('"','""'))
} elseif (`$request['VisibleGroup']) {
    $($getVisibleGroups.ToString().Replace('"','""'))
} elseif (`$request['ShowPrivacyPolicy']) {
    $($privacyPolicyHandler.ToString().Replace('"','""').Replace('THE COMPANY', $module.CompanyName))
} elseif  (`$request['walkthru']){
    $($walkthruHandler.ToString().Replace('"','""'))
} elseif (`$request.QueryString.ToString() -ieq '-TopicRSS' -or `$request['TopicRSS']) {
    $($topicRssHandler.ToString().Replace('"','""')) 
} elseif (`$request.QueryString.ToString() -ieq '-WalkthruRSS' -or `$request['WalkthruRSS']) {
    $($walkthruRssHandler.ToString().Replace('"','""')) 
} elseif (`$request.QueryString.ToString() -ieq '-ModuleRSS' -or `$request['ModuleRss'] -or `$request['Rss']) {
    $($moduleFeedHandler.ToString().Replace('"','""')) 
} elseif (`$Request['GetHelp']) {
    $($helpHandler.ToString().Replace('"','""'))
} elseif (`$Request['Command']) {
    $($commandHandler.ToString().Replace('"','""'))
} elseif (`$request['AnythingGoes']) {
    $($anythingHandler.ToString().Replace('"','""'))
} $tableHandlers $checkoutHandlers $userTableHandlers $mailHandlers  elseif  (`$request.QueryString.ToString() -eq '-Download') {
    `$page = New-WebPage -Css `$cssStyle -Title ""`$(`$module.Name) | Download"" -AnalyticsID '$analyticsId' -RedirectTo '?-DownloadNow'
    `$response.Write(`$page )
} elseif (`$request.QueryString.ToString() -eq '-Me' -or `$request['ShowMe']) {
    $($meHandler.ToString().Replace('"', '""'))
} elseif (`$request.QueryString.ToString() -eq '-DownloadProxyModule') {
    $($installMeHandler.ToString().Replace('"', '""'))
} elseif (`$request.QueryString.Tostring() -eq '-GetPSD1' -or `$request['PSD1']) {
    `$baseUrl = `$request.URL
    `$response.ContentType = 'text/plain'  
    `$response.Write([string]""
`$((Get-Content `$psd1Path -ErrorAction SilentlyContinue) -join ([Environment]::NewLine))
"")

} elseif (`$request.QueryString.Tostring() -eq '-GetManifest' -or `$request['GetManifest']) {
    $($getManifestXmlHandler.ToString().Replace('"','""'))
} elseif (`$request.QueryString.Tostring() -eq '-Sitemap' -or `$request['GetSitemap']) {
    $($getSitemapHandler.ToString().Replace('"','""'))
} elseif (`$request.QueryString.Tostring() -eq '-Css' -or `$request.QueryString.Tostring() -eq '-Style') {
    if (`$pipeworksManifest -and `$pipeworksManifest.Style) {
        `$outcss = Write-CSS -NoStyleTag -Css `$pipeworksManifest.Style
        `$response.ContentType = 'text/css'
        `$response.Write([string]`$outCss)      
    } else {
        `$response.ContentType = 'text/plain'
        `$response.Write([string]'')      
    }
} elseif  (`$request.QueryString.ToString() -eq '-DownloadNow' -or `$request['DownloadNow']) {         
    if (`$downloadUrl) {
        `$page = New-WebPage -Title ""Download `$(`$module.Name)"" -RedirectTo ""`$downloadUrl""
        `$response.Write([string]`$page)
    } elseif (`$allowDownload) {                  

        `$modulezip = `$module.name + '.' + `$module.Version + '.zip'
         `$page = (New-object PSObject -Property @{RedirectTo=`$modulezip;RedirectIn='0:0:0.50'}),(New-object PSObject -Property @{RedirectTo=""/"";RedirectIn='0:0:7'}) | New-WebPage
        `$response.Write([string]`$page)
        `$response.Flush()                
    }
} elseif (`$request.QueryString.Tostring() -eq '-PaypalIPN' -or `$request['PayPalIPN']) {
    $($payPalIpnHandler.ToString().Replace('"','""'))
} else {
`

"@ + $coreModuleHandler.ToString().Replace('"', '""') + @"

$(if ('continue', 'inquire' -contains $DebugPreference) {
@"
if (`$request['Timings'] -or `$request.Headers['Timings']) {
    `$timings = Get-Variable timeSpent* | 
        Foreach-Object -Process {
            ""`$(`$_.Name)-`$(`$_.Value)""
        }
    `$response.Headers.Add(""Timings"", ""`$Timings"")
}
"@
})

}
", context, null, false, $((-not $IsolateRunspace).ToString().ToLower()));
"@            
                    
        $moduleAshxInsteadOfDefault = $psBoundParameters.StartOnCommand -or $psBoundParameters.AsBlog            
        $AcceptAnyUrl= $true            
        if ($pipeworksManifest.AcceptanyUrl) {            
            $AcceptAnyUrl= $true            
        }             
            
        if ($pipeworksManifest.DomainSchematics -and -not $PipeworksManifest.Stealth) {            
            $firstdomain  = $pipeworksManifest.DomainSchematics.GetEnumerator() | Sort-Object Key | Select-Object -First 1 -ExpandProperty Key            
            $firstdomain  = $firstdomain  -split "\|" | ForEach-Object { $_.Trim() } | Select-Object -First 1            
            
            $x = & $NewSiteMap "http://$firstdomain"            
            $x.Save("$outputDirectory\sitemap.xml")            
            
            
            $x = & $NewRobotsTxt "http://$firstdomain"            
            [IO.File]::WriteAllText("$outputDirectory\robots.txt", $x)            
            
            
        }            
                    
                    
        $importsPipeworks =             
            $module.Name -eq 'Pipeworks' -or            
            $module.RequiredModules -like "Pipeworks"            
            
        if (-not $importsPipeworks) {            
            Write-Progress "Determining Included Commands" " "             
            $commandTokens=             
                Get-Variable -Name *handler | Where-Object {$_.Value -is [ScriptBlock] } |            
                    ForEach-Object {            
                        [Management.Automation.PSParser]::Tokenize($_.Value, [ref]$null)                                
                    }            
            
                    
            $loadedCommands = @{}            
            $loadCommandQueue = New-Object Collections.Queue            
            $commandsUsedInHandler = @($commandTokens + $tokensInPages |            
                Where-Object {            
                    $_.Type -eq 'Command'            
                } |             
                Select-Object -ExpandProperty Content -Unique |            
                Get-Command -Type Function -ErrorAction SilentlyContinue |            
                ForEach-Object {            
                    $loadedCommands[$_.Name] = $_            
                    $null = $loadCommandQueue.Enqueue($_)            
                })            
            
            $loadedCommandCount = $loadedCommands.Count            
            
            
            do {            
                if ($loadCommandQueue.Count -eq 0) {             
                    break             
                }             
                $loadedCmd = $loadCommandQueue.Dequeue()            
                        
                        
                $commandTokens=             
                    [Management.Automation.PSParser]::Tokenize($loadedCmd.Definition, [ref]$null)                                
                                
            
                @($commandTokens |            
                Where-Object {            
                    $_.Type -eq 'Command'            
                } |             
                Select-Object -ExpandProperty Content -Unique |            
                Get-Command -Type Function -ErrorAction SilentlyContinue |            
                ForEach-Object {            
                    if (-not ($loadedCommands[$_.Name]) -and -not ($loadCommandQueue -like "$($_.Name)")) {            
                        $loadedCommands[$_.Name] = $_            
                        $null = $loadCommandQueue.Enqueue($_)            
                    }            
                })            
            } while ($loadCommandQueue.Count)            
            
                    
            
            $commandsUsedInHandler = @('Write-Link', 'Write-CSS', 'Get-Walkthru', 'Get-Person', 'ConvertFrom-Markdown', 'Get-Hash', 'Out-HTML', 'New-Region', 'New-WebPage', 'Write-Ajax') +             
                @($loadedCommands.Values | Where-Object { $_.Module.Name -eq 'Pipeworks' }  | Select-Object -ExpandProperty Name )            
                    
            $commandsUsedInHandler = ($commandsUsedInHandler | Select-Object -Unique)            
        }            
            
        #region CommonPageCodeBehind            
        if ($usesDynamicPages) {            
            $embedSection = ""            
            if (-not $ImportsPipeworks) {                                            
                $commandsUsedInHandler = $commandsUsedInHandler | Select-Object -Unique            
            } else {            
            
                $commandsUsedInHandler = 'Out-HTML'            
            }            
            $embedSection += foreach ($func in (Get-Command -Name $commandsUsedInHandler -CommandType Function)) {            
            
@"
        string compressed$($func.Name.Replace('-', ''))Defintion = "$(Compress-Data -String $func.Definition.ToString())";
        byte[] binaryDataFor$($func.Name.Replace('-', '')) = System.Convert.FromBase64String(compressed$($func.Name.Replace('-', ''))Defintion);
        System.IO.MemoryStream memoryStreamFor$($func.Name.Replace('-', '')) = new System.IO.MemoryStream(); 
        memoryStreamFor$($func.Name.Replace('-', '')).Write(binaryDataFor$($func.Name.Replace('-', '')), 0, binaryDataFor$($func.Name.Replace('-', '')).Length);
        memoryStreamFor$($func.Name.Replace('-', '')).Seek(0, 0);
        System.IO.Compression.GZipStream decompressorFor$($func.Name.Replace('-', '')) = 
            new System.IO.Compression.GZipStream(memoryStreamFor$($func.Name.Replace('-', '')), System.IO.Compression.CompressionMode.Decompress);
        System.IO.StreamReader readerFor$($func.Name.Replace('-', '')) = new System.IO.StreamReader(decompressorFor$($func.Name.Replace('-', '')));
        string decompressedDefinitionFor$($func.Name.Replace('-', '')) = readerFor$($func.Name.Replace('-', '')).ReadToEnd();
        SessionStateFunctionEntry $($func.Name.Replace('-',''))Command = new SessionStateFunctionEntry(
            "$($func.Name)", decompressedDefinitionFor$($func.Name.Replace('-', ''))
        );
        iss.Commands.Add($($func.Name.Replace('-',''))Command);
"@            
            }            
            
                        
            
            $codeBehind = @"
using System;
using System.Web.UI;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections;
using System.Collections.ObjectModel;
public partial class PowerShellPage : Page {
    public InitialSessionState InitializeRunspace() {
        InitialSessionState iss = InitialSessionState.CreateDefault();
        $embedSection
        string[] commandsToRemove = new String[] { "$($functionBlacklist -join '","')"};
        foreach (string cmdName in commandsToRemove) {
            iss.Commands.Remove(cmdName, null);
        }
        return iss;
    }
    public void RunScript(string script) {
        bool shareRunspace = $((-not $IsolateRunspace).ToString().ToLower());
        UInt16 poolSize = $PoolSize;
        PowerShell powerShellCommand = PowerShell.Create();
        bool justLoaded = false;
        PSInvocationSettings invokeNoHistory = new PSInvocationSettings();
        invokeNoHistory.AddToHistory = false;
        Collection<PSObject> results;
        if (shareRunspace) {
            if (Application["RunspacePool"] == null) {                        
                justLoaded = true;
                
                RunspacePool rsPool = RunspaceFactory.CreateRunspacePool(InitializeRunspace());
                rsPool.SetMaxRunspaces($PoolSize);
                
                rsPool.ApartmentState = System.Threading.ApartmentState.STA;            
                rsPool.ThreadOptions = PSThreadOptions.ReuseThread;
                rsPool.Open();                                
                powerShellCommand.RunspacePool = rsPool;
                Application.Add("RunspacePool",rsPool);
                
                // Initialize the pool
                Collection<IAsyncResult> resultCollection = new Collection<IAsyncResult>();
                for (int i =0; i < $poolSize; i++) {
                    PowerShell execPolicySet = PowerShell.Create().
                        AddScript(@"
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force 
", false);
                    execPolicySet.RunspacePool = rsPool;
                    resultCollection.Add(execPolicySet.BeginInvoke());
                }
                
                foreach (IAsyncResult lastResult in resultCollection) {
                    if (lastResult != null) {
                        lastResult.AsyncWaitHandle.WaitOne();
                    }
                }
                
                powerShellCommand.Commands.Clear();
            }
            
            
                        
            
            powerShellCommand.RunspacePool = Application["RunspacePool"] as RunspacePool;
            
            
            
            string newScript = @"param(`$Request, `$Response, `$Server, `$session, `$Cache, `$Context, `$Application, `$JustLoaded, `$IsSharedRunspace, [Parameter(ValueFromRemainingArguments=`$true)]`$args)
            if (`$request -and `$request.Params -and `$request.Params['PATH_TRANSLATED']) {
                Split-Path `$request.Params['PATH_TRANSLATED'] |
                    Set-Location
            }
            
            " + script;            
            powerShellCommand.AddScript(newScript, false);
                       
            
            powerShellCommand.AddParameter("Request", Request);
            powerShellCommand.AddParameter("Response", Response);
            powerShellCommand.AddParameter("Session", Session);
            powerShellCommand.AddParameter("Server", Server);
            powerShellCommand.AddParameter("Cache", Cache);
            powerShellCommand.AddParameter("Context", Context);
            powerShellCommand.AddParameter("Application", Application);
            powerShellCommand.AddParameter("JustLoaded", justLoaded);
            powerShellCommand.AddParameter("IsSharedRunspace", true);
            results = powerShellCommand.Invoke();        
        
        } else {
            Runspace runspace;
            if (Session["UserRunspace"] == null) {
                
                Runspace rs = RunspaceFactory.CreateRunspace(InitializeRunspace());
                rs.ApartmentState = System.Threading.ApartmentState.STA;            
                rs.ThreadOptions = PSThreadOptions.ReuseThread;
                rs.Open();
                powerShellCommand.Runspace = rs;
                powerShellCommand.
                    AddCommand("Set-ExecutionPolicy", false).
                    AddParameter("Scope", "Process").
                    AddParameter("ExecutionPolicy", "Bypass").
                    AddParameter("Force", true).
                    Invoke(null, invokeNoHistory);
                powerShellCommand.Commands.Clear();

                Session.Add("UserRunspace",rs);
                justLoaded = true;
            }

            runspace = Session["UserRunspace"] as Runspace;

            if (Application["Runspaces"] == null) {
                Application["Runspaces"] = new Hashtable();
            }
            if (Application["RunspaceAccessTimes"] == null) {
                Application["RunspaceAccessTimes"] = new Hashtable();
            }
            if (Application["RunspaceAccessCount"] == null) {
                Application["RunspaceAccessCount"] = new Hashtable();
            }

            Hashtable runspaceTable = Application["Runspaces"] as Hashtable;
            Hashtable runspaceAccesses = Application["RunspaceAccessTimes"] as Hashtable;
            Hashtable runspaceAccessCounter = Application["RunspaceAccessCount"] as Hashtable;
            
            
            if (! runspaceTable.Contains(runspace.InstanceId.ToString())) {
                runspaceTable[runspace.InstanceId.ToString()] = runspace;
            }

            if (! runspaceAccessCounter.Contains(runspace.InstanceId.ToString())) {
                runspaceAccessCounter[runspace.InstanceId.ToString()] = 0;
            }
            runspaceAccessCounter[runspace.InstanceId.ToString()] = ((int)runspaceAccessCounter[runspace.InstanceId.ToString()]) + 1;
            runspaceAccesses[runspace.InstanceId.ToString()] = DateTime.Now;


            runspace.SessionStateProxy.SetVariable("Request", Request);
            runspace.SessionStateProxy.SetVariable("Response", Response);
            runspace.SessionStateProxy.SetVariable("Session", Session);
            runspace.SessionStateProxy.SetVariable("Server", Server);
            runspace.SessionStateProxy.SetVariable("Cache", Cache);
            runspace.SessionStateProxy.SetVariable("Context", Context);
            runspace.SessionStateProxy.SetVariable("Application", Application);
            runspace.SessionStateProxy.SetVariable("JustLoaded", justLoaded);
            runspace.SessionStateProxy.SetVariable("IsSharedRunspace", false);
            powerShellCommand.Runspace = runspace;


        
            powerShellCommand.AddScript(@"
`$timeout = (Get-Date).AddMinutes(-20)
`$oneTimeTimeout = (Get-Date).AddMinutes(-1)
foreach (`$key in @(`$application['Runspaces'].Keys)) {
    if ('Closed', 'Broken' -contains `$application['Runspaces'][`$key].RunspaceStateInfo.State) {
        `$application['Runspaces'][`$key].Dispose()
        `$application['Runspaces'].Remove(`$key)
        continue
    }
    
    if (`$application['RunspaceAccessTimes'][`$key] -lt `$Timeout) {
        
        `$application['Runspaces'][`$key].CloseAsync()
        continue
    }    
}
            ").Invoke(null, invokeNoHistory);
            powerShellCommand.Commands.Clear();        

            powerShellCommand.AddCommand("Split-Path", false).AddParameter("Path", Request.ServerVariables["PATH_TRANSLATED"]).AddCommand("Set-Location").Invoke(null, invokeNoHistory);
            powerShellCommand.Commands.Clear();        

            results = powerShellCommand.AddScript(script, false).Invoke();        

        }
            
        
        foreach (Object obj in results) {
            if (obj != null) {
                if (obj is IEnumerable) {
                    if (obj is String) {
                        Response.Write(obj);
                    } else {
                        IEnumerable enumerableObj = (obj as IEnumerable);
                        foreach (Object innerObject in enumerableObj) {
                            if (innerObject != null) {
                                Response.Write(innerObject);
                            }
                        }
                    }
                    
                } else {
                    Response.Write(obj);
                }
                    
            }
        }
        
        foreach (ErrorRecord err in powerShellCommand.Streams.Error) {
            Response.Write("<span class='ErrorStyle' style='color:red'>" + err + "<br/>" + err.InvocationInfo.PositionMessage + "</span>");
        }

        powerShellCommand.Dispose();
    
    }
}
"@ |             
            Set-Content "$outputDirectory\PowerShellPageBase.cs"            
        }            
        #endregion CommonPageCodeBehind            
            
        #region Module Output            
            
        if ($pipeworksManifest.PoolSize -as [uint32]) {            
            $poolSize = $pipeworksManifest.PoolSize            
        }            
            
        $newDefaultExtensions  = Get-ChildItem $outputDirectory -Filter default.* | Select-Object -ExpandProperty Extension            
        $handlerText = & $writeSimpleHandler -PoolSize:$PoolSize -sharerunspace:(-not $isolateRunspace) -csharp $moduleHandler -ImportsPipeworks:$importsPipeworks -EmbeddedCommand $commandsUsedInHandler            
        $defaultFile = if ($newDefaultExtensions -contains '.aspx') {            
                        
            $moduleAshxInsteadOfDefault = $true            
                         
                        
            [IO.File]::WriteAllText("$outputDirectory\Module.ashx", $handlerText)            
        } elseif ($newDefaultExtensions -contains '.html') {             
            "default.html"            
                        
        } elseif ($newDefaultExtensions -contains '.ashx') {            
            "default.ashx"                        
        } else {            
                    
            if ($AcceptAnyUrl) {            
                $null            
            } else {            
                "default.ashx"            
            }                        
        }            
                    
        if ($moduleAshxInsteadOfDefault) {            
            if ($psBoundParameters.AsBlog) {            
                Copy-Item "$outputDirectory\Blog.html" "$outputDirectory\Default.htm"            
            }            
            [IO.File]::WriteAllText("$outputDirectory\Module.ashx", $handlerText)            
        } else {            
            [IO.File]::WriteAllText("$outputDirectory\Module.ashx", $handlerText)            
            $defaultFile = "Module.ashx"            
            #[IO.File]::WriteAllText("$outputDirectory\Default.ashx", $handlerText)            
        }            
                            
        #endregion Module Output            
            
            
            
        #region Module Nesting            
            
            
                    
        # In some cases, one might want to publish multiple modules to different sublocations at the same time.            
                    
        # A good example would be having a main site, a blog, and an online store.            
                    
        # In order to nest, make a Pipeworks Manifest section called "Nest", "Nested", or "NestedModules".            
        # This section will be a hashtable,            
        # The key will be the subdirectory where the nested module will be placed.            
        # The value will contain the module placed in the subdirectory.            
        # It can optionally be followed by a : and a comma-separated list of schematics.            
        # It can also start with a : and contain the schematics that will be published.            
        # If this occurs, the current module will be published to the subdirectory, using the specified schematics.            
            
        # For example:            
        # @{Blog='Start-Scripting:Blog'} # nest the module Start-Scripting to the subdirectory blog.            
            
        $nestedModules = @($pipeworksManifest.Nest) + $pipeworksManifest.Nested + $pipeworksManifestPath.NestedModule + $pipeworksManifest.NestedModules            
        $nestedModules = @($nestedModules -ne $null )            
        foreach ($nested in $nestedModules) {            
            if ($nested -isnot [Hashtable]) { continue }            
            
            foreach ($ni in $nested.GetEnumerator()) {            
                $nestedOutputDirectory = Join-Path $OutputDirectory $ni.Key            
                $nestedModule = if ($ni.Value -like ":*") {            
                    $realModule.Name            
                } else {            
                    @($ni.Value -split ":")[0]            
                }            
            
            
                $nestedSchematic = if ($ni.Value -notlike "*:*") {            
                    @("Default")            
                } else {            
                    @(@($ni.Value -split ":")[1] -split "," -ne '')            
            
                }            
            
            
                $nestedSchematic = @(foreach ($ns in $nestedSchematic) {            
                    $ns.Trim()            
                })            
            
                ConvertTo-ModuleService -OutputDirectory $nestedOutputDirectory -Name $nestedModule -UseSchematic $nestedSchematic -Force -IsNested            
            }            
        }            
            
                    
        # 11/2/2013            
            
        #endregion Module Nesting            
                    
        #region Configuration Settings            
        $configSettingsChunk = ''            
                            
        if ($ConfigSetting.Count) {            
             $configSettingsChunk = "<appSettings>" + (@(foreach ($kv in $configSetting.GetEnumerator()) {"
        <add key='$($kv.Key)' value='$($kv.Value)'/>"                            
             }) -join ('')) + "</appSettings>"            
        }            
                    
        $acceptAnyUrl = $true                      
                    
        if ($pipeworksManifest.MaximumRequestLength) {            
            $maximumRequestLength = $pipeworksManifest.MaximumRequestLength            
        }            
            
        $realMax = [Math]::Ceiling(($maximumRequestLength  / 1kb))            
            
                    
        if ($pipeworksManifest.ExecutionTimeout -as [timespan]) {            
            $ExecutionTimeout = $pipeworksManifest.ExecutionTimeout -as [timespan]            
        }                     
            
        $cacheControl = "
    <staticContent>
      <clientCache cacheControlMode='UseMaxAge' cacheControlMaxAge='$($CacheStaticContentFor)' />
    </staticContent>
        "            
                    
        $runTimeChunk  ="
<httpRuntime 
executionTimeout='$($executionTimeout.TotalSeconds -as [uint32])' 
maxRequestLength='$realMax' 
useFullyQualifiedRedirectUrl='false'
appRequestQueueLimit='100'
enableVersionHeader='false' />"                                      
            
        $childDirectories = Get-ChildItem -Path $OutputDirectory |             
            Where-Object { $_.PSIsContainer }             
                    
        $excludeChildDirectories = foreach ($child in $childDirectories) {             
            @"
            <add input="{URL}" pattern="^$($child.Name)/" negate="true" />
            <add input="{URL}" pattern="^$($child.Name)$" negate="true" />    
"@            
        }            
        $rewriteUrlChunk = "<rewrite>
            <rules>
                <rule name='RewriteAll_For$($psBoundParameters.Name + $(if ($psBoundParameters.UseSchematic) { "_$($psBoundParameters.UseSchematic)" }))'>
                    <match url='.*' />
                    <conditions logicalGrouping='MatchAll'>
                        <add input='{REQUEST_FILENAME}' matchType='IsDirectory' negate='true' />
                        $excludeChildDirectories
                        <add input='{URL}' pattern='^.*\.(ashx|axd|css|gif|png|ico|jpg|jpeg|js|flv|f4v|zip|xlsx|docx|mp3|mp4|xml|html|htm|aspx|php|pdf)$' negate='true' />
                        
                    </conditions>

                    <action type='Rewrite' url='AnyUrl.aspx' />
                </rule>
            </rules>
        </rewrite>"            
                   
        if (-not $AcceptAnyUrl) {            
            
            $rewriteUrlChunk = ""            
        } else {            
            if (-not (Test-Path "$outputDirectory\AnyUrl.aspx")) {            
                $rewriteUrlChunk = $rewriteUrlChunk.Replace("AnyUrl.aspx", "Module.ashx?AnythingGoes=true")            
            }            
        }            
        # $rewriteUrlChunk= ""            
            
        $defaultFound = (            
            (Join-Path (Split-Path $OutputDirectory) "web.config") |             
                Get-Content -path  { $_ } -ErrorAction SilentlyContinue |             
                Select-String defaultDocument            
            ) -as [bool]            
            
                    
        if ($Isnested) {            
            $defaultFound = $true            
        }            
        $defaultDocumentChunk = if ((-not ($defaultFile))) {            
@"    
    <system.webServer>
        $(if (-not $defaultFound) { @"
<defaultDocument>
            <files>
                <add value="default.ashx" />
            </files>
        </defaultDocument>
"@})
        $rewriteUrlChunk
        $cacheControl
    </system.webServer>
        
"@                    
        }  else {            
@"
    <system.webServer>
        $(if (-not $defaultFound) { @"
        <defaultDocument>
            <files>
                <add value="${defaultFile}" />
            </files>
        </defaultDocument>
"@})
        $rewriteUrlChunk
        $cacheControl
    </system.webServer>
"@            
        }            
                    
                
    $null = $null            
    $customErrorPages = @($pipeworksManifest.Pages.Keys) -like "???.*"            
            
    $AlwaysGenerateErrorPages = @{            
        "400" = "Bad Request"            
        "401" = "Sorry, no admittance"            
        "403" = "Sorry, no admittance"            
        "404" = "This is not the web page you were looking for"            
        "408" = "That took too long"            
        "450" = "Sorry, kid.  Mom and Dad don't want you visiting this page"            
        "451" = "Lawyers have informed us that we can't show this page"            
    }            
            
    $customErrorsSection = "        "            
    $customErrorsSection +=             
        foreach ($cep in $customErrorPages) {            
            $cepNumber = "$cep".Substring(0, 3) -as [uint32]            
            if (-not $cepNumber) { continue}            
            if ($AlwaysGenerateErrorPages.$cepNumber) {            
                $null =$AlwaysGenerateErrorPages.Remove($cepNumber)            
            }            
        "<error statusCode='$cepNumber' redirect='~$Cep' />
"                                     
        }            
            
    $customErrorsSection += foreach ($k in $AlwaysGenerateErrorPages.Keys) {            
$titleArea =             
    if ($PipeworksManifest -and $pipeworksManifest.Logo) {            
        "<a href='$linkUrl' class='brand'><img src='$($pipeworksManifest.Logo)' alt='$($module)' style='border:0' /></a>"            
    } else {            
        "<a href='$linkUrl' class='brand'>$($Module.Name)</a>"            
    }            
            
"
<div style='width:100%;height:100%'>
    <div style='width:50%;margin-left:auto;margin-right:auto;text-align:center'>
        $titleArea
    </div>

    <br style='line-height:500%' />
    <h1 style='width:75%;margin-left:auto;margin-right:auto;text-align:center'>
        $($AlwaysGenerateErrorPages[$k])
    </h1>
</div>
" |            
New-WebPage -Title $AlwaysGenerateErrorPages[$k] |            
Set-Content "$OutputDirectory\$k.html"            
                    
                    
        "<error statusCode='$k' redirect='~$($k).html' />
"                   
    }            
            
            
            
                                       
                
$webConfig = @"
<configuration>
    $ConfigSettingsChunk
    $defaultDocumentChunk 
    $net4Compat
    <system.web>
        <customErrors mode="On">
            $customErrorsSection
        </customErrors>
        $runTimeChunk 
    </system.web>
    
</configuration>
"@            
            
    $webConfig |            
        Set-Content "$outputDirectory\web.config"            
                    
    # If there's a user DB, make sure that it exists            
    if ($pipeworksManifest.UserDB.Name -and $pipeworksManifest.UserDB.ConnectionSetting) {            
        $tableExists = Get-SQLTable -TableName $pipeworksManifest.UserDB.Name -ConnectionStringOrSetting $pipeworksManifest.UserDB.ConnectionSetting             
            
        if (-not $tableExists) {            
            Add-SqlTable -RowKey "UserId" -TableName $pipeworksManifest.UserDB.Name -Column UserEmail -ConnectionStringOrSetting $pipeworksManifest.UserDB.ConnectionSetting -ErrorVariable CreateTableIssues            
            
            if ($createTableIssues) {            
                Write-Warning "The User table did not exist in SQL, and count not be created"            
            }            
        }            
    }            
            
            
            
    # If nothing on the page requires a login, "bake" the finished page.  This will only work if the output directory is beneath the WWWRoot of the local server.            
            
            
    $anyCommandRequiresLogin = $pipeworksManifest.WebCommand.Values |             
        Where-Object { $_.RequiresLogin -or $_.RequireLogin -or $_.ValidUserTable -or $_.IfLoggedInAs }             
    $anyCommandRunsWithoutInput = if ($pipeworksManifest.WebCommand) {            
        $pipeworksManifest.WebCommand.GetEnumerator() |             
            Where-Object {             
                $_.Value.RunWithoutInput -and -not $_.Value.Hidden -and ($pipeworksManifest.Inline -eq '*' -or $pipeworksManifest.Inline -eq $_.Key)            
            }             
    } else {            
        $null            
    }            
    $thereIsADefaultCommand = $pipeworksManifest.DefaultCommand            
    $noServices = $PipeworksManifest.WebCommand -as [bool]            
            
            
            
    $shouldBakePages = $true            
            
    if ($anyCommandRequiresLogin -or $anyCommandRunsWithoutInput -or $thereIsADefaultCommand) {            
        $shouldBakePages = $false            
    }            
            
    if (($newDefaultExtensions -like '.aspx') -and (-not $pipeworksManifest.BakePage)) {            
        $shouldBakePages = $false            
    }            
            
    if ($newDefaultExtensions -like ".htm*") {            
                    
        $shouldBakePages = $false            
    }            
                    
            
    if ($shouldBakePages) {            
        if ($newDefaultExtensions -like '.aspx') {            
            
        }            
            
        Write-Progress "Baking Module Page" " "             
            
        #$cssStyle = $((Write-PowerShellHashtable $Style))            
        $HalfMarginPercentLeftString = "$(($MarginPercentLeftString.Replace('%', '') -as [double])/2)%"            
        $HalfMarginPercentRightString = "$(($MarginPercentRightString.Replace('%', '') -as [double])/2)%"            
            
        $MarginPercentLeftString = $MarginPercentLeftString.Trim()            
        $MarginPercentRightString  = $MarginPercentRightString.Trim()            
            
        $DownloadUrl = '$DownloadUrl'            
        $analyticsId = '$analyticsId'            
            
        $modulemaker = $module.CompanyName            
                    
            
        $bakingPage = $true            
        $null = . ([ScriptBlock]::Create($embedCommand))            
        $null = . ([ScriptBlock]::Create($initModuleDefaults))            
        $null = . ([ScriptBlock]::Create($getModuleMetaData))            
        $pipeworksManifest = @{} + $Global:pipeworksManifest            
                    
        $bakedDefault = . $coreModuleHandler            
        $global:PipeworksManifest = $null            
        $bakingPage = $false            
        #$bakedDefault = Get-Web -Url "http://localhost/$realModule/" -UseWebRequest -Timeout 01:00:00            
        if ($bakedDefault) {            
            [IO.File]::WriteAllText("$outputDirectory/Default.htm", $bakedDefault)            
            
            $defaultDocumentChunk = @"    
    <system.webServer>       
        $rewriteUrlChunk
        $cacheControl
    </system.webServer>
        
"@                    
                    
            $webConfig = @"
<configuration>
    $ConfigSettingsChunk
    $defaultDocumentChunk 
    $net4Compat
    <system.web>
        <customErrors mode="On">
            $customErrorsSection
        </customErrors>
        $runTimeChunk 
    </system.web>
</configuration>
"@            
            
            $webConfig |            
                Set-Content "$outputDirectory\web.config"            
            
        }            
    }            
                
                    
    if ($AsIntranetSite) {            
        Import-Module WebAdministration -Global -Force            
        $allSites = Get-Website            
                    
        $AlreadyExists = $allSites |            
            Where-Object {$_.Name -eq "$Name" }             
                        
        if (-not $alreadyExists) {            
            $targetPort = $Port            
            $portIsOccupied  = $null            
            do {            
                if (-not $targetPort) {            
                    $targetPort = 80            
                } else {            
                    $oldTargetPort = $targetPort            
                    if ($portIsOccupied) {            
                        $targetPort = Get-Random -Maximum 64kb            
                        Write-Warning "Port $oldTargetPort occupied, trying Port $targetPort"            
                    }            
                }            
            
                $portIsOccupied = Get-Website |             
                    Where-Object {             
                        $_.Bindings.Collection |             
                            Where-Object {             
                                $_-like "*:$targetPort*"             
                            }              
                        }                                
            }            
            while ($portIsOccupied)             
                       
            $w = New-Website -Name "$Name" -Port $targetPort -PhysicalPath $outputDirectory -Force             
                        
                        
            $AlreadyExists = Get-Website |            
                Where-Object {$_.Name -eq "$Name" }             
            
                        
        }            
            
        if ($Realm) {            
            Set-WebConfigurationProperty -filter /system.webServer/security/authentication/anonymousAuthentication -name enabled -value false -PSPath IIS:\ -Location $Name            
            Set-WebConfigurationProperty -filter /system.webServer/security/authentication/windowsAuthentication -name enabled -value true -PSPath IIS:\ -Location $Name            
        } else {            
            Set-WebConfigurationProperty -filter /system.webServer/security/authentication/anonymousAuthentication -name enabled -value false -PSPath IIS:\ -Location $Name            
            Set-WebConfigurationProperty -filter /system.webServer/security/authentication/windowsAuthentication -name enabled -value true -PSPath IIS:\ -Location $Name            
            
        }            
            
                
        if ($appPoolCredential) {            
            $appPool = Get-Item "IIS:\AppPools\${name}AppPool" -ErrorAction SilentlyContinue             
            if (-not $appPool) {            
                $pool = New-WebAppPool -Name "${name}AppPool" -Force            
                $appPool = Get-Item "IIS:\AppPools\${name}AppPool" -ErrorAction SilentlyContinue             
                       
            }            
            $appPool.processModel.userName = $appPoolCredential.username            
            $appPool.processModel.password = $appPoolCredential.GetNetworkCredential().password            
            $appPool.processModel.identityType = 3            
            $appPool | Set-Item            
            $AlreadyExists = Get-Website |            
                Where-Object {$_.Name -eq "$Name" }             
            
            $siteInf = Get-ChildItem             
            
            Set-ItemPRoperty iis:\sites\$name -Name ApplicationPool -Value "${name}AppPool" -Force            
        }                    
    }            
#region Global.asax Session Cleanup            
@'
<%@ Assembly Name="System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<script language="C#" runat="server">
public void Session_OnEnd()
{
    System.Management.Automation.Runspaces.Runspace rs = Session["User_Runspace"] as System.Management.Automation.Runspaces.Runspace;
    if (rs != null)
    {
        rs.Close();
        rs.Dispose();
    }
    System.GC.Collect();
}
</script>
'@ |         Set-Content "$outputDirectory\Global.asax"             
            
                
#endregion            
            
        }            
        Pop-Location                   
            
        if ($IISReset) {            
            iisreset /noforce | ForEach-Object { Write-Progress "Resetting IIS" "$_ " }             
        }            
            
            
        if ($Show) {            
                        
            if ($port) {            
                Start-Process -FilePath "http://localhost:$Port/"            
            } else {            
                Start-Process -FilePath "http://localhost/$Module/"            
            }            
        }            
            
            
        if ($do) {            
            if (-not $do.DnsSafeHost) {            
                if ($port) {            
                    Start-Process -FilePath "http://localhost:$Port/$("$Do".TrimStart('/'))"            
                } else {            
                    Start-Process -FilePath "http://localhost/$Module/$("$Do".TrimStart('/'))"            
                }            
            } else {            
                Start-Process -FilePath "$Do"            
            }                        
        }            
            
        #endregion Configuration Settings            
    }            
            
}