Invoke-WebCommand
Invokes the commands within a Pipeworks web service

function Invoke-WebCommand {             
            
    <#
    .Synopsis
        Invokes the commands within a web service
    .Description
        Invokes the commands within a Pipeworks web service
    .Example
        # Invoke-WebCommand is the Pipeworks function runs commands in a web service.  It's automatically called in many places, but can be used on the command line to emulate and debug running on the web.
    .Link
        ConvertTo-ModuleService
    #>            
    [OutputType([PSObject])]            
    param(            
    # The command that is being executed            
    [Parameter(Mandatory=$true,            
        ValueFromPipeline=$true,            
        ValueFromPipelineByPropertyName=$true)]            
    [Management.Automation.CommandInfo]            
    $Command,            
                
    # A friendly name for the service            
    [Parameter(Position=1)]            
    [string]            
    $FriendlyName,                    
            
    # The order of the displayed parameters            
    [Parameter(Position=2)]            
    [string[]]$ParameterOrder,            
                        
                
    # If set, allows the command to be run without any parameters.  This is especially useful for Get- commands.            
    [switch]$RunWithoutInput,            
                
    # If set, these parameters will be hidden from a command handler's input and output parameters.            
    # They will still be visible in help.            
    [Parameter(Position=3)]            
    [Alias('DenyParameter')]            
    [string[]]$HideParameter,                    
                
    # The ID to use for Google Analytics tracking            
    [string]            
    $AnalyticsId,            
                
    # The AdSenseID used to monetize the command with Google AdSense            
    [string]            
    $AdSenseID,            
                
    # The AdSlotId used to monetize the command with Google AdSense            
    [string]            
    $AdSlot,            
                
    # If set, allows the command to be downloaded            
    [Switch]$AllowDownload,            
                   
            
    # If set, the command will be enabled as a web service.  This parameter is implied by almost every other parameter (except -ShowHelp, which contravenes it), and is primarily present for backwards-compatibility.            
    [Switch]            
    $RunOnline,            
            
    # If set, the payment has been processed by the server.  This is used internally to finalize actions after payments.            
    [switch]            
    $PaymentProcessed,            
                
    # If SessionThrottle is set, the request handler will wait for at least the -SessionThrottle before            
    # allowing the user to re-run the command.  This can be useful in mitigating Denial of Service attacks            
    # as well as providing an avenue to upsell (i.e. a free user can run a command once a minute, where as a premium user can run requests without the throttle)            
    [Timespan]            
    $SessionThrottle = "0:0:0",                
                    
    # If set, escapes the output from the command, so it can be embedded into a webpage            
    [switch]$EscapeOutput,            
                
    # The CSS Style section to use for the page            
    [Hashtable]$Style,            
                    
    # If set, will output the results of the command without encasing it in a container            
    [Switch]$PlainOutput,            
                
    # If set, will output the results of the command with a particular content type            
    [string]$ContentType,            
                
    # Sets the method used for the web form.  By default, POST is used, but Get is required if the command outputs binary data (like image streams)            
    [ValidateSet('POST', 'GET')]            
    [string]$Method = "POST",            
                
    # If set, will not add sharing links to the page            
    [Switch]$AntiSocial,            
                
    # The Module Service URL.            
    # If this is not set, this will automatically be the url to the command directory.            
    [Uri]$ServiceUrl,            
                
    # The Web Front End for a command, declared in HTML.  Setting a Web Front End will override the default front end with any web page.            
    [String]$WebFrontEnd,            
                
    # The Mobile Web Front End for a command, declared in HTML.  Setting a Mobile Web Front End will override the default front end with any web page.            
    [String]$MobileWebFrontEnd,            
                      
    # A table of parameters that will get their value from a cookie            
    [Hashtable]$CookieParameter = @{},            
                
    # If set, will save the output in a cookie.            
    [string]$SaveInCookie,            
            
    # A table of parameter URL aliases.  These allow URLs to the sevice to become shorter.            
    [Hashtable]$ParameterAlias= @{},            
             
    # Default values for the parameters            
    [Alias('DefaultParameter')]            
    [Hashtable]$ParameterDefaultValue = @{},            
                
    # Parameters that are taken from the web.config settings            
    [Alias('SettingParameter')]            
    [Hashtable]$ParameterFromSetting= @{},            
                
                
    # Parameters that are taken from the user settings            
    [Alias('UserParameter')]            
    [Hashtable]$ParameterFromUser= @{},            
                
    # Any additional commands that the command can be piped into.            
    # In the Sandbox service, these commands will be allowed as well            
    [string[]]$PipeInto,            
                
    # If set, will allow the command to be run in a sandbox            
    [Switch]$RunInSandBox,            
                
    # The margin on either side of the module content.  Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercent = 7.5,            
                
    # The margin on the left side of the module content. Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercentLeft = 7.5,            
                
    # The margin on the left side of the module content. Defaults to 7.5%.            
    [ValidateRange(0,100)]            
    [Double]            
    $MarginPercentRight = 7.5,            
                
    # If set, will only allow logged-in users to run the command            
    [Alias('RequiresLogin', 'RequiredLogin', 'LoginRequired')]            
    [Switch]            
    $RequireLogin,            
                
    # If set, will require an app key to run the command.  Logged in users will automatically use their app key            
    [Alias('RequiresAppKey', 'RequiredAppKey', 'AppKeyRequired')]            
    [Switch]            
    $RequireAppKey,            
                
    # If set, will track uses of an appkey.            
    [string]            
    $UserTable,            
                
    # The partition in a usertable containing data            
    [string]            
    $UserPartition,            
                
    # If set, will track parameters the user supplied for a command, and when they ran it.            
    [switch]            
    $KeepUserHistory,            
                
    # If set, will keep a history of command input and output            
    [switch]            
    $KeepHistory,            
                
    # If set, will keep results in the UseTrackingTable            
    [switch]            
    $KeepResult,            
                
    # If set, will track uses of the command.            
    [string]            
    $UseTrackingTable,            
                
    # If set, will track unique properties of the output, such as the number of times an item with a particular ID is output.            
    [string[]]            
    $TrackProperty,            
                
    # If set, will track unique parameters in the input, such as the number of times an input value is used            
    [string[]]            
    $TrackParameter,                    
                    
    # The name of the web.config setting containing the storage account name.  Required for tracking.            
    [string]            
    $StorageAccountSetting = 'AzureStorageAccountName',            
                
    # The name of the web.config setting containing the storage account key. Required for tracking.            
    [string]            
    $StorageKeySetting = 'AzureStorageAccountKey',            
                
    # Allows the command to be run only if the user is logged as one of the values.            
    #            
    #            
    # Values can be email addresses or userids.  With email addresses, wildcards (i.e. *@microsoft.com) will be supported.            
    [string[]]            
    $IfLoggedInAs,            
                
    # Validates that users are allowed to run the command by checking objects with a Condition property found in ValidUserPartition            
    [string]            
    $ValidUserPartition,            
                
                
    # Any config settings            
    [Hashtable]$ConfigSetting,            
                
    # A table of costs per run by locale            
    [Hashtable]            
    $CostPerRun,            
            
            
    # If set, makes the person pay before the command is actually executed            
    [Alias('BuyNow')]            
    [Switch]            
    $PayNow,            
            
    # If set, makes the person subscribe before the command is actually executed            
                
    [Switch]            
    $SubscribeNow,            
            
    # The currency used for the transaction.  By default, US Dollars.  Additional currencies are treated as additional purchasing options            
    [string[]]$Currency = "USD",                
            
    # The frequency for the subscription.  By default, every month.  Additional billing frequencies are used to create additional subscription options.            
    [ValidateSet("Daily", "Weekly", "Monthly", "Yearly")]                
    [string[]]            
    $BillingFrequency = 'Monthly',            
            
            
            
    # If set, prompts for confirmation before a command will be run            
    [Switch]            
    $PromptForConfirmation,            
            
    # A custom confirmation message.  If provided, -PromptForConfirmation is assumed.            
    [string]            
    $ConfirmationMessage,            
            
                
    # A location to redirect to when the command is complete.            
    [Uri]            
    $RedirectTo,                    
                
    # The amount of time to wait before redirecting (by default, no time)            
    [Timespan]            
    $RedirectIn,            
                
    # The cost to run the command. Providing more than one cost is used to create additional subscription options.            
    [Double[]]            
    $Cost,            
                
    # A cost factor table            
    [Hashtable]            
    $CostFactor= @{},            
                
                
    # If set, will show the help for a command, but will not run it            
    [Switch]            
    $ShowHelp,            
            
    # If provided, will use this PSOBject for the command help.            
    [PSObject]            
    $HelpObject,            
            
    # If set, will hide the related items in command help.            
    [Switch]            
    [Alias('HideRelatedItems')]            
    $HideRelatedItem,            
            
    # The string shown to a person when the command does not throw an error but has not output            
    [Alias('NoOp')]            
    [String]            
    $NoOutputMessage,            
            
                
    # The properties from the output to display            
    [String[]]            
    $OutputProperty,            
            
    # Will link selected items to items from a command            
    [Hashtable]            
    $LinkTo,            
            
            
    # If set, the command will be hidden from web front ends, but can still be directly invoked.            
    [Switch]            
    $Hidden,            
            
    # If provided, the output will be rendered with a given type name.            
    # Changing this will allow you to override the look and feel of any object.            
    [string]            
    $AsTypename,            
            
    # If provided, will lookup the user by email and will run commands as them.            
    # This is used for montezation, and should only be used directly very carefully.            
    [string]            
    $AsEmail,            
            
    # If provided, will lookup the user by email and will run commands as them.            
    # This is used for montezation, and should only be used directly very carefully.            
    [string]            
    $AsUserId,            
            
    # If provided, will not use ajax while running the command            
    [Switch]            
    $NoAjax,            
            
    # If provided, will use window.external.notify to provide a notification message when complete.            
    [string]            
    $Notify,            
                
    # If set, default values and other information the pipeworks manifest will be ignored.  This allows you to execute commands with parameters that would not be available to a web user.            
    [Switch]            
    $IgnoreManifest            
    )            
                
            
    begin {            
        if (-not $global:session) {            
            $global:Session = @{}            
        }            
        if (-not $global:Application) {            
            $global:Application= @{}            
        }                    
                    
            
        $ComputeTotalCost = {            
            $totalCost = 0            
            $listOfCosts= @()            
            $listOfFrequencies= @()            
            $listOfCurrencies = @()            
                        
            for ($i = 0;  $i -lt $cmdOptions.Cost.Count; $i++) {            
            
                $listOfCosts+= $cmdOptions.Cost[$i]                                
                                                                       
            }            
            
            
                        
                            
            if ($cmdOptions.CostFactor) {            
                $factoredCost = 0            
                            
                foreach ($kv in $cmdOptions.CostFactor.getEnumerator()) {                                    
                    $parameterValue = $mergedParameters["$($kv.Value.Parameter)"]            
                    if ($kv.Value.CostMap) {            
                                    
                        if ($kv.Value.CostMap[$parameterValue]) {            
                            $factoredCost += $kv.Value.CostMap[$parameterValue]            
                        } elseif ($kv.Value.CostMap[$parameterValue -as [int]]) {            
                            $factoredCost += $kv.Value.CostMap[$parameterValue -as [int]]            
                        }                     
                                    
                    } elseif ($kv.Value.CostPerItem) {            
                                    
                        $factoredCost += $kv.Value.CostPerItem * $parameterValue            
                    }            
                                        
                }            
                             
                $listOfCosts += $factoredCost            
            }            
                                    
            $confirmLink = "$fullUrl"            
            
            if ($confirmLink.Contains("?")) {            
                $confirmLink += "&"            
            } else {            
                $confirmLink = $confirmLink.TrimEnd("/") + "/?"            
            }            
            
            $costString = "$" + $totalCost                         
        }            
            
            
        $getProxyCommand = {            
                        
if (-not $script:CachedProxies) {            
    $script:CachedProxies = @{}            
}            
            
if ($script:CachedProxies["$command"]) {            
    $proxyCommandText  = $script:CachedProxies["$command"]            
}            
            
$proxyCommandMetaData = [Management.Automation.CommandMetaData]$command            
# then strip off hidden parameters            
foreach ($p in $hideParameter){            
    $null = $proxyCommandMetaData.Parameters.Remove($p)                
}            
            
$paramBlock = [Management.Automation.ProxyCommand]::GetParamBlock($proxyCommandMetaData)            
    $remoteCommandUrl= $serviceUrl.ToString() + "?command=$command"            
                
            
$handleResponseScript  =             
"
    if (`$getWebCommandLink) { return `$str }
    `$xmlResult = `$str -as [xml]

    if (`$xmlResult) {
        Write-Verbose 'Response is XML'
        if (`$str -like '*<Object*') {
            Write-Verbose 'Response is Object Xml'
            Write-Verbose `$str
            `$str | 
                Select-Xml //Object |
                ForEach-Object {
                    `$_.Node
                } | 
                ForEach-Object {
                    if (`$_.Type -like 'System.*' -and `$_.'#text') {
                        `$_.'#text'
                    } elseif (`$_.Property) {
                        `$_ | 
                            Select-Object -ExpandProperty Property | 
                            ForEach-Object -Begin {
                                `$outObject = @{}
                            } {
                                `$name = `$_.Name
                                `$value = `$_.'#Text'
                                `$outObject[`$name] = `$value
                            } -End {
                                New-Object PSObject -Property `$outObject
                            }
                    }
                }
        } else { 
            Write-Verbose 'Response is Normal Xml'
            `$strWrite = New-Object IO.StringWriter
            `$xmlResult.Save(`$strWrite)
            `$strOut = `"`$strWrite`"
            `$strOut.Substring(`$strOut.IndexOf([environment]::NewLine) + 2)
        }
    } elseif (`$str -and 
        (`$str -notlike '*://*' -or
        (`$str.ToCharArray()[1..100] | ? { `$_ -eq ' '} ))) {
        Write-Verbose 'Response is Text with spaces'
        `$str.ResponseText
    } elseif (`$xmlHttp.ResponseBody) {
        Write-Verbose 'Response is Data'
        `$r
    } elseif (`$xmlHttp.ResponseText) {
        Write-Verbose 'Response is Text'
        `$str
    } else {
        Write-Verbose 'Unknown Response'
    }
"                    
            
$script:CachedProxies["$command"] =             
$proxyCommandText = "
function $($command.Name) {
    $([Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($proxyCommandMetaData))
    param(
    $paramBlock,
    [Timespan]`$WebCommandTimeout = '0:0:45',
    $(if ($CmdOptions.RequireAppKey -or $cmdOptions.RequireLogin -or $cmdOptions.IfLoggedInAs -or $cmdOptions.ValidUserPartition) {
    "
    # An API Key    
    [string]`$AppKey,
    
    
    # An API Key    
    [string]`$AppKeySetting,    
    "
    })
    [switch]`$GetWebCommandLink
    )
    begin {
        
        Add-Type -AssemblyName System.Web
        `$xmlHttp = New-Object -ComObject Microsoft.XmlHttp 
        `$remoteCommandUrl = '$RemoteCommandUrl'
        `$wc = New-Object Net.Webclient        
    }
    process {        
        if (`$psBoundParameters.AppKey) {
            `$script:CachedAppKey = `$appKey
        } elseif (`$psBoundParameters.AppKeySetting) {
            `$script:CachedAppKey = Get-SecureSetting `$psBoundParameters.AppKeySetting -ValueOnly
        }

        if (`$script:CachedAppKey) {
            `$appKey = `$script:CachedAppKey
        } else {
            `$appKey = ''
        }

        `$result = `$null
        `$nvc = New-Object Collections.Specialized.NameValueCollection
        `$urlParts = foreach (`$param in `$psBoundParameters.Keys) {
            if ('WebCommandTimeout', 'GetWebCommandLink', 'AppKey', 'AppKeySetting' -contains `$param) { continue }            
            `$null = `$nvc.Add(`"$($command.Name)_`$param`", `"`$(`$psBoundParameters[`$param])`")
            `"$($command.Name)_`$param=`$([Web.HttpUtility]::UrlEncode(`$psBoundParameters[`$param]))`" 
        }
        `$urlParts = `$urlParts -join '&' 
        if (`$remoteCommandUrl.Contains('?')) {
            `$fullUrl = `$RemoteCommandUrl + '&' + `$urlParts
        } else {
            `$fullUrl = `$RemoteCommandUrl + '?' + `$urlParts
        }
        
        if (`$GetWebCommandLink) {
            `$fullUrl += '&-GetLink=true'
            `$null = `$nvc.Add('GetLink', 'true')
        } else {
            $(if (-not $cmdOptions.PlainOutput) { "`$fullUrl += '&AsXml=true'" })             
            `$null = `$nvc.Add('AsXml', 'true')
        }

        if (`$AppKey) {
            if (`$fullUrl.Contains('?')) {
                `$fullUrl += '&AppKey=' + `$appKey
            } else {
                `$fullUrl += '?AppKey=' + `$appKey
            }
        }
        
        
        `$sendTime  = Get-Date
        Write-Verbose `"`$fullUrl - Sent `$sendTime`"        
        `$r = `$wc.UploadValues(`"`$remoteCommandUrl`", `"POST`", `$nvc)                    
        if (-not `$?) {
            return
        }
        `$str = [Text.Encoding]::UTF8.GetString(`$r)
        
        Write-Verbose `"`$fullUrl - Response Received `$(Get-Date)`"        
        $handleResponseScript            
        
       
                
        
    }
    
}
"            
            
}            
    }            
                
    process {            
        $commandWasRun = $false            
            
        $inputWasRequested = $false            
            
        $commandError = $null            
            
        if (-not $ServiceUrl) {            
            $ServiceUrl = "/"            
        }            
            
#        if (-not $request -and $Response) {            
#            Write-Error "Must be run within a web site"            
#            return            
#        }            
                    
                    
        $cmdmd = $Command -as [Management.Automation.CommandMetaData]            
        $cmdOptions = @{} + $psBoundParameters              
            
                     
            
        if (-not $FriendlyName) {            
            $FriendlyName = $Command.Name            
        }            
                    
        $manifestIsTemporary = $false            
        if (-not $pipeworksManifest) {            
            if ($Command.Module) {            
                $global:pipeworksManifest = Get-PipeworksManifest  -ModuleName $Command.Module            
                if (-not ($request -and $response)) {            
                    $manifestIsTemporary = $true            
                }            
            }            
        }            
        if (-not $IgnoreManifest) {            
            if ($pipeworksManifest.WebCommand.($Command.Name)) {            
                foreach ($kv in $pipeworksManifest.WebCommand.($command.Name).GetEnumerator()) {            
                    $cmdOptions[$kv.Key] = $kv.Value            
                    Set-Variable -Name $kv.Key -Value $kv.Value            
                }            
            }            
        }            
                    
            
        $RequestParameterNames = @{}            
        foreach ($k in @($request.Params.Keys)) {            
            if (-not $k) { continue }            
            $RequestParameterNames[$k] = $request[$k]            
        }            
            
                    
        if ($storageAccountSetting) {            
            $storageAccount = Get-SecureSetting -Name $storageAccountSetting -ValueOnly            
        }            
                    
        if ($storageKeySetting) {            
            $storageKey = Get-SecureSetting -Name $storageKeySetting -ValueOnly            
        }            
                    
                                           
        $cmdHasErrors = $null            
            
        if ($AsEmail -or $AsUserId) {            
            $userExists = $null            
            
            if ($pipeworksManifest.UserDB) {            
                $TheUserDB = @{} + $pipeworksManifest.UserDB            
                if ($AsEmail) {            
                    $userExists = Select-SQL -FromTable $pipeworksManifest.UserDB.Name -ConnectionStringOrSetting $pipeworksManifest.UserDB.ConnectionSetting -Where "UserEmail = '$($AsEmail)'"            
                } elseif ($AsUserId) {            
                    $userExists = Select-SQL -FromTable $pipeworksManifest.UserDB.Name -ConnectionStringOrSetting $pipeworksManifest.UserDB.ConnectionSetting -Where "UserID = '$($AsUserId)'"            
                }            
            
                $null = $TheUserDB.Remove("Name")                        
                            
            
            } elseif ($pipeworksManifest.UserTable) {            
                $TheUserTable = @{} + $pipeworksManifest.UserTable            
                if (-not $cmdOptions.UserTable) {            
                    $cmdOptions.UserTable = $TheUserTable.Name                        
                    $UserTable = $TheUserTable.Name            
                }            
            
                if (-not $cmdOptions.UserPartition) {            
                    $cmdOptions.UserPartition  = $TheUserTable.Partition            
                    $UserPartition = $TheUserTable.Partition            
                }            
            
            
                if (-not $cmdOptions.StorageAccountSetting) {            
                            
                    $storageAccountSetting = $cmdOptions.StorageAccountSetting = $TheUserTable.StorageAccountSetting            
                    $storageAccount = Get-SecureSetting -Name $storageAccountSetting -ValueOnly            
            
                }            
            
                if (-not $cmdOptions.StorageKeySetting) {            
                            
                    $storageKeySetting= $cmdOptions.StorageKeySetting = $TheUserTable.StorageKeySetting            
                    $storageKey= Get-SecureSetting -Name $storageKeySetting -ValueOnly            
            
                }            
            
            
                $TheUserTable.Remove("Name")                        
                $TheUserTable.UserTable = $pipeworksManifest.UserTable.Name            
                            
            
                if ($AsEmail) {            
                    $userExists = Search-AzureTable -TableName $cmdOptions.UserTable -Filter "PartitionKey eq '$($cmdOptions.UserPartition)' and UserEmail eq '$($AsEmail)'" -StorageAccount $storageAccount -StorageKey $storageKey            
                } elseif ($AsUserId) {            
                    $userExists = Search-AzureTable -TableName $cmdOptions.UserTable -Filter "PartitionKey eq '$($cmdOptions.UserPartition)' and RowKey eq '$($AsUserId)'" -StorageAccount $storageAccount -StorageKey $storageKey            
                }            
            }            
            
                        
            
            if (-not $userExists) {            
                if ($AsEmail) {            
                    $userExists = New-Object PSObject -Property @{            
                        UserEmail = $AsEmail            
                    }            
                } elseif ($AsUserId) {            
                    $userdomain = if ($pipeworksManifest.DomainSchematics) {            
                        @($pipeworksManifest.DomainSchematics.Keys)[0]            
                    } else {            
                        "unknown.com"            
                    }            
                    $userExists = New-Object PSObject -Property @{            
                        UserEmail = "$asUserId@$userdomain"            
                    }            
                }            
            }             
            
            if ($AsEmail) {            
                if ($pipeworksManifest.UserDB) {            
                        New-Object PSObject -Property $TheUserDB |            
                            Confirm-Person -WebsiteUrl $serviceUrl -Email $userExists.UserEmail -PersonObject $userExists              
                } else {            
                    $confirmedUserAccount =             
                        New-Object PSObject -Property $TheUserTable |            
                            Confirm-Person -WebsiteUrl $serviceUrl -Email $userExists.UserEmail -PersonObject $userExists -StorageAccountSetting $StorageAccountSetting -StorageKeySetting $StorageKeySetting                        
            
                }            
            } elseif ($AsUserId -and $userExists) {            
                $confirmedUserAccount = $userExists            
                            
            }            
            
            
            if ($confirmedUserAccount) {            
                $session["User"] = $confirmedUserAccount             
            }            
            
        }            
            
                    
            
        if ($session -and (-not $session['User'])) {            
            if ($cmdOptions.IfLoggedInAs -or $cmdOptions.RequireLogin -or $cmdOptions.ValidUserPartition) {            
                            
                $confirmHtml = . Confirm-Person -WebsiteUrl $ServiceUrl             
                if (-not $session['User']) {            
                    '<span style="margin-top:3%;margin-bottom:3%" class=''ui-state-error''>You have to log in</span><br/>'  + $confirmHtml               
                    return            
                }             
            
                            
            }                        
        }            
            
        if ($cmdOptions.IfLoggedInAs -or $cmdOptions.ValidUserPartition) {            
            $ok = Confirm-Person -CheckId -WebsiteUrl $ServiceUrl -IfLoggedInAs $cmdOptions.IfLoggedInAs -ValidUserPartition $cmdOptions.ValidUserPartition            
            if (-not $ok) { return }             
            
        }            
        <#
        $okIf = @()
        # ValidateUserTable preceeds IfLoggedInAs, and $ok is set first.
        # this way, logins in tables work as well as specific whitelists                                        
        if ($cmdOptions.ValidUserPartition) {
            $okUserList = 
                Search-AzureTable -TableName $UserTable -Filter "PartitionKey eq '$($cmdOptions.ValidUserPartition)' and IfLoggedInAs ne ''" -Select IfLoggedInAs -StorageAccount $storageAccount -StorageKey $storageKey   -ExcludeTableInfo
            $okUserIf = $okUserList | 
                Select-Object -ExpandProperty IfLoggedInAs
            
            $okIf += $okUserIf    
        }
        
        if ($cmdOptions.IfLoggedInAs) {
            $okIf += $cmdOptions.IfLoggedInAs                    
        }
        
        if ($okIf) {
            $ok = $false
            $global:notOkReason = ""
            foreach ($if in $okIf) {
                if ($If -eq '*') {
                    if ($session['User']) {
                        $ok= $true
                        break
                    }
                    $global:notOkReason = "Not Logged In"
                } 
                if ($if -like "*@*") {
                    # Email
                    if ($session["User"].UserEmail -like $if)  {
                        $ok = $true
                        break
                    }
                } elseif ($if -like "*:*") {
                    $ifParts = $if -split ':'
                    if ($ifParts[0] -ieq 'memberOf') {
                        if ($session['User'].MemberOf -and $session['User'].MemberOf -like "*$($ifParts[1])*") {
                            $ok = $true
                            break
                        }
                        $global:notOkReason = "Not Member Of $($ifParts[1])"
                    } elseif ($ifParts[0] -ieq 'notMemberOf') {
                        if ($session['User'].MemberOf -and $session['User'].MemberOf -notlike "*$($ifParts[1])*") {
                            $ok = $true
                            break
                        }
                        $global:notOkReason = "Member Of $($ifParts[1])"
                    } elseif ($ifParts[0] -ieq 'awarded') {
                        if ($session['User'].Awards -and $session['User'].Awards -like "*$($ifParts[1])*") {
                            $ok = $true
                            break
                        }
                    } elseif ($ifParts[0] -ieq 'notAwarded') {
                        if ($session['User'].Awards -and $session['User'].Awards -notlike "*$($ifParts[1])*") {
                            $ok = $true
                            break
                        }
                    } elseif ($ifParts[0] -ieq 'interactionCount') {
                        $interactionCountOperations = if ($ifParts[1] -like "*>=*") {
                            if ($session['User'].InteractionCount) {
                                $interactionCountData = ConvertFrom-StringData -StringData "$($session['User'].InteractionCount)".Replace(':', '=') -ErrorAction SilentlyContinue
                                $equation = $ifParts[1] -split "\>="

                                if (($interactionCountData[$equation[0].Trim()] -as [double]) -ge ($equation[1] -as [double])) {
                                    $ok=$true
                                    break
                                }
                            } 
                                
                                
                        } elseif ($ifParts[1] -like "*>*") {
                            if ($session['User'].InteractionCount) {
                                $interactionCountData = ConvertFrom-StringData -StringData "$($session['User'].InteractionCount)".Replace(':', '=') -ErrorAction SilentlyContinue
                                $equation = $ifParts[1] -split "\>"

                                if (($interactionCountData[$equation[0].Trim()] -as [double]) -gt ($equation[1] -as [double])) {
                                    $ok=$true
                                    break
                                }
                            } 
                                
                                
                        } if ($ifParts[1] -like "*<=*") {
                            if ($session['User'].InteractionCount) {
                                $interactionCountData = ConvertFrom-StringData -StringData "$($session['User'].InteractionCount)".Replace(':', '=') -ErrorAction SilentlyContinue
                                $equation = $ifParts[1] -split "\<="

                                if (($interactionCountData[$equation[0].Trim()] -as [double]) -le ($equation[1] -as [double])) {
                                    $ok=$true
                                    break
                                }
                            }                                                                 
                        } elseif ($ifParts[1] -like "*<*") {
                            if ($session['User'].InteractionCount) {
                                $interactionCountData = ConvertFrom-StringData -StringData "$($session['User'].InteractionCount)".Replace(':', '=') -ErrorAction SilentlyContinue
                                $equation = $ifParts[1] -split "\<"

                                if (($interactionCountData[$equation[0].Trim()] -as [double]) -lt ($equation[1] -as [double])) {
                                    $ok=$true
                                    break
                                }
                            }
                        }
                    }
                } else {
                    if ($session["User"].UserId -eq $if) {
                        $ok = $true
                        break
                    }
                    $global:notOkReason = "Not Correct UserID"
                }
            }
            
            if (-not $ok) {  return } 
        }
        #>            
                    
        $depth = 0            
        $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))            
            if ($relativeUrl -like "*/*") {            
                $depth = @($relativeUrl -split "/" -ne "").Count - 1                                
                if ($fullOriginalUrl.EndsWith("/")) {             
                    $depth++            
                }                                                    
            } else {            
                $depth  = 0            
            }            
            #endregion Determine the Relative Path, Full URL, and Depth            
            $fullUrl = $fullOriginalUrl            
                        
        }            
                    
        $fullUrl = $fullUrl -ireplace "\?widget=true", "" -ireplace "\?inline=true"            
        $global:FullUrl = $fullUrl            
                    
                    
        $depthChunk = "../"  * $depth            
                    
        $commandParameters = Get-WebInput -ParameterAlias $cmdOptions.ParameterAlias -CommandMetaData $command -DenyParameter $HideParameter -ErrorAction SilentlyContinue -ErrorVariable ValidationErrors                             
                    
        # Prefer supplied parameters to default values, but remove one or the other or the commands will not run            
        $defaultValues = $cmdOptions.parameterDefaultValue            
        $cmdParamNames = $commandParameters.Keys             
        foreach ($k in @($defaultValues.Keys)) {            
            if (-not $k) { continue}             
            if ($cmdParamNames -contains $k -and $commandParameters[$k]) {            
                $null = $defaultValues.Remove($k)            
            }            
        }            
        if (-not $defaultValues) {            
            $defaultValues = @{}            
        }            
            
            
        if (-not $commandParameters ) {            
            $commandParameters = @{}            
        }            
            
        $parametersFromCookies = @{}            
        if ($cmdOptions.CookieParameter) {                    
            foreach ($parameterCookieInfo in $cmdOptions.CookieParameter.GetEnumerator()) {            
                if ($command.Parameters[$parameterCookieInfo.Key]) {                
                    $cookie = $request.Cookies[$parameterCookieInfo.Value]            
                    if ($cookie) {            
                        $parametersFromCookies[$parameterCookieInfo.Key] = $cookie            
                    }                        
                }            
            }            
                        
            
            foreach ($k in @($parametersFromCookies.Keys))            
            {            
                if ($cmdParamNames -contains $k -and $commandParameters[$k]) {            
                    $null = $parametersFromCookies.Remove($k)            
                }            
            }            
        }            
            
            
        $parametersFromSettings = @{}            
        if ($cmdOptions.ParameterFromSetting) {            
            foreach ($parameterSettingInfo in $cmdOptions.parameterFromSetting.GetEnumerator()) {            
                if ($command.Parameters[$parameterSettingInfo.Key]) {                
                    $webConfsetting = Get-SecureSetting -Name $parameterSettingInfo.Value -ValueOnly            
                    if ($webConfsetting ) {            
                        $parametersFromSettings[$parameterSettingInfo.Key] = $webConfsetting            
                    }                        
                }            
            }            
            
            foreach ($k in @($parametersFromSettings.Keys))            
            {            
                if ($cmdParamNames -contains $k -and $commandParameters[$k]) {            
                    $null = $parametersFromSettings.Remove($k)            
                }            
            }            
        }            
            
            
        $parametersFromUser = @{}            
        if ($cmdOptions.ParametersFromUser) {            
            foreach ($parameterUserInfo in $cmdOptions.parametersFromUser.GetEnumerator()) {            
                if ($command.Parameters[$parameterUserInfo.Key]) {                
                    $userSetting = if ($session -and $session['User'].($parameterUserInfo.Key)) {            
                        $session['User'].($parameterUserInfo.Key)            
                    }  else {            
                        $null            
                    }            
                    if ($userSetting ) {            
                        $parametersFromUser[$parameterUserInfo.Key] = $userSetting             
                    }                        
                }            
            }            
            
            foreach ($k in @($parametersFromUser.Keys))            
            {            
                if ($cmdParamNames -contains $k -and $commandParameters[$k]) {            
                    $null = $parametersFromUser.Remove($k)            
                }            
            }            
            
                    
        }            
                    
            
        $nonDefaultParameters = @{} + $commandParameters + $parametersFromCookies + $parametersFromSettings + $parametersFromUser            
        $mergedParameters = @{} + $commandParameters + $defaultValues + $parametersFromCookies + $parametersFromSettings + $parametersFromUser            
                           
        if (-not $script:CachedHelp) {            
            $script:CachedHelp = @{}            
        }            
            
        if (-not $script:CachedHelp["$Command"]) {                                    
            $script:CachedHelp["$Command"] = Get-Help -Name "$Command"            
        }            
            
            
        $help = $helpObj = $script:CachedHelp["$Command"]            
                    
            
        if (-not $psBoundParameters.HelpObject) {            
            $HelpObject = $helpObj            
        }            
                    
                    
            
        if ($RequestParameterNames.'Download') {            
            # If the module can be downloaded, let the command be downloaded.  Otherwise, download the proxy            
            if ($cmdOptions.AllowDownload) {            
$proxyCommandText = "function $($Command.Name) { 
$($Command.Definition)
}
" } elseif (-not $ShowHelp) {            
    $proxyCommandText = . $getProxyCommand            
} else {            
    $proxyCommandText = " "             
}            
            
            
            
            
if ($Request.Params["AsHtml"]) {            
$webPage = Write-ScriptHtml ([ScriptBlock]::create($proxyCommandText))             
$webPage            
} else {            
    #$proxyCommandText            
    $response.ContentType = "text/plain"            
    $response.Write($proxyCommandText)            
    $response.Flush()            
}            
            
return            
        } elseif ($ShowHelp -or             
            ($Request -and $Request["GetHelp"]) -or            
            $FullUrl.EndsWith("-?")){            
            # The Help Handler            
                        
            if ($HelpObject) {            
                $commandTitleArea = "<h2>
                    $($HelpObject.Details.Name)
                    $(if (($AllowDownload -or $pipeworksManifest.AllowDownload) -and $Command.ScriptBlock.File) {
                        "<span style='font-size:.33em'><a href='?Download=true&AsHtml=true'>(View Source)</a></span>"
                    } else {
                        ''
                    })
                    </h2>"            
            } else {            
                $commandTitleArea = "<h2>
                    $command
                    $(if (($AllowDownload -or $pipeworksManifest.AllowDownload) -and $Command.ScriptBlock.File) {
                        "<span style='font-size:.33em'><a href='?Download=true&AsHtml=true'>(View Source)</a></span>"
                    } else {
                        ''
                    })
                </h2>"            
            }            
            
            
                        
                        
                        
                        
            $helpObj = $HelpObject            
                        
            if (-not $script:CachedHelpContent) {            
                $script:CachedHelpContent = @{}            
            }            
            
            if (-not $script:CachedHelpContent."$Command") {            
                $script:CachedHelpContent."$command" = if ($HelpObj.Synopsis) {            
                    $description = @($helpObj.Description)[0].Text            
                    "<h3>$($helpObj.Synopsis)</h3>" +             
                        (ConvertFrom-Markdown -Markdown "$description " ) + "<BR/>"            
            
                                
                                
            
                                
                    $navLinks = @(@($helpObj.relatedLinks)[0].NavigationLink)            
                    $examples = @(@($helpObj.examples)[0].Example)            
                    $parameters = @(@($helpObj.parameters)[0].Parameter)            
                                
                    $seeAlso = foreach ($nav in $navLinks) {            
                        if ($nav.LinkText) {            
                            # Link to topic or command            
                            $isCommand  =             
                                if ($command.ScriptBlock.Module.ExportedFunctions.($nav.LinkText) -or $command.ScriptBlock.Module.ExportedCmdlets.($nav.LinkText)) {            
                                    $command.ScriptBlock.Module.ExportedCommands[$nav.LinkText]            
                                } else {            
                                    $false            
                                }            
                                        
                            if ($isCommand) {            
                                Write-Link -Style @{            
                                    "font-size"="small";            
                                    "text-align" = "center"            
                                    "padding" = "5px"            
                                    width="66%"            
                                } -Url "$($depthChunk)$($nav.LinkText)/" -Caption $nav.Linktext -CssClass btn            
                            } elseif ($nav.LinkText -like "*_*") {            
                                Write-Link -Style @{            
                                    "font-size"="small";            
                                    "text-align" = "center"            
                                    "padding" = "5px"            
                                    width="66%"            
                                } -Url "$($depthChunk)$($nav.LinkText.Replace('_', ' '))" -Caption $nav.LInktext.Replace("_"," ") -CssClass btn            
                            }            
                        } elseif ($nav.Uri) {            
                            # External link            
            
            
            
                            Write-Link -Style @{            
                                    "font-size"="small";            
                                    "text-align" = "center"            
                                    "padding" = "5px"            
                                    "margin-top" = "3%"            
                                    width="66%"            
                            } -Url $nav.Uri -Caption $nav.Uri -CssClass btn            
                         }            
                    }            
                                
                    $examples = foreach ($ex in $examples) {            
                        if ($ex) {            
                            $s = $ex | Out-String            
                            $s = $s.Substring($s.IndexOf("C:\PS>") + 6)            
                                        
                            # One line trimmed example, use remarks            
                            if ($s.Trim().Length -ge 63 -and $s.Trim().Length -lt 64) {            
                                $remarks = $s.Remarks | ForEach-Object {$_.Text }             
                                $s = $remarks            
                            }            
            
                            $sAsScriptBlock = try {             
                                [ScriptBlock]::Create($s)            
                            } catch {            
                                            
                            }            
                                        
                            if ($sAsScriptBlock) {            
                                Write-ScriptHTML -Text $sAsScriptBlock            
                            } else {            
                                $s            
                            }            
                        }            
                    }            
                                
                                
                    $parameterLayer = @{}            
                    foreach ($param in $parameterS) {            
                        if (-not $param) {            
                            continue            
                        }            
                        if ($HideParameter -contains $param.Name) {            
                            continue            
                        }            
                        $parameterLayer[$param.Name]  =            
                            ConvertFrom-Markdown -Markdown "$(@($param.Description)[0].Text) " -ScriptAsPowerShell            
                    }            
                                
                                
                    $helpTabs = @{}            
                                
                    if ($examples) {            
                        $exLayer = @{}            
                        $c = 0            
                        foreach ($ex in $examples) {            
                            $c++            
                            $exLayer["Example $c"] = $ex                
                        }                                  
            
                        $helpTabs.Examples=              
                            New-Region -Style @{            
                                "Font-size" = "small"            
                            } -AsNewspaper -NewspaperColumn 1 -ExpandNewspaperColumn $exLayer.Keys -layer $exLayer -layerId "$($command)_Example_Content"            
            
                                    
                    }            
                                
                    if ($seeAlso -and (-not $HideRelatedItem)) {            
                                    
                        $helpTabs."Related Links" = "<p style='text-align:center'>" + ($seeAlso -join "<BR style='line-height:250%' />") + "</p>"            
                    }                                
                                
                    if ($parameterLayer) {            
            
                        $helpTabs.Parameters =             
                            New-Region -Style @{            
                                "Font-size" = "small"            
                            } -AsNewspaper -ExpandNewspaperColumn $parameterLayer.Keys -LayerId "$($Command)_Parameters" -layer $parameterLayer -NewspaperColumn 1             
            
                    }            
                                
            
                    $order = if ($helpTabs."Related Links") {            
                        'Related Links', 'Parameters', 'Examples'            
                    } else {            
                        'Examples', 'Parameters'            
                    }            
                                
            
            
                    New-Region -LayerID "$($command)_HelpContent" -Style @{            
                        "Font-size" = "Medium"            
                    } -AsNewspaper $helpTabs -Order $order -NewspaperColumn .6, .4, 1 -NewspaperHeadingSize 2            
                                
                } else {            
                    # Syntax only help, just display a pre            
                    "<pre>$($helpObj)</pre>"            
                }            
            }            
                        
            $helpContent = $script:CachedHelpContent."$command"            
                            
                        
                        
                        
                        
            ($commandTitleArea, ($helpContent -join '<br style="clear:both" />')|             
                New-Region -Style @{                                
                }) -join ([Environment]::NewLine)            
                            
                            
            return            
        } elseif ($Request -and $Request["Platform"]) {            
            $platform = $request["Platform"]            
            
            $allHiddenParameters =@() + $HideParameter            
                        
            if ($ParameterDefaultValue) {            
                $allHiddenParameters += $ParameterDefaultValue.Keys            
            }            
            
            $inputForPlatform = Request-CommandInput -Platform $platform -CommandMetaData $cmdMd -DenyParameter $allHiddenParameters            
            
            if ($platform -ne 'Web' -and ($inputForPlatform -as [xml])) {            
                $strWrite = New-Object IO.StringWriter            
                ([xml]$inputForPlatform).Save($strWrite)            
                $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
                if (-not $cmdOptions.ContentType) {            
                    $response.ContentType ="text/xml"            
                }            
                $response.Write("$resultToOutput")                
            
                            
            } else {            
                if ($platform -ne 'Web') {            
                    $Response.ContentType = 'text/plain'            
                } else {            
                    $inputForPlatform = $inputForPlatform |             
                        New-WebPage -UseJQueryUI            
                }            
                $Response.Write($inputForPlatform)            
            }            
            
        } elseif ($request -and $Request["Body"] -and            
            $Request["From"] -and            
            $Request["To"] -and            
            $Request["SmsSid"] -and            
            $Request["AccountSid"]) {            
                        
                        
            # Text handler            
            # The command is being texted.  If the command contains parameters that match, use them, otherwise, pass the whole            
            # body as an embedded script in data language mode.            
            $cmdParams = @{} + $commandParameters            
                        
            if ($cmdOptions.ShowHelp) {            
                # Text Back the Description            
                            
                $helpObj= (Get-Help $cmdMd.Name)            
                $description  = if ($helpObj.Description) {            
                    $helpObj.Description[0].text.Replace('"',"'").Replace('<', '<').Replace('>', '>').Replace('$', '`$')            
                } else {            
                    ""            
                }            
                            
                $response.contentType = 'text/xml'            
                            
                            
                $response.Write("<?xml version='1.0' encoding='UTF-8'?>
        <Response>
            <Sms>$($cmdMd.name): $([Security.SecurityElement]::Escape($Description))</Sms>
        </Response>        ")             
                $response.Flush()            
                            
                            
                return                              
            }            
                        
            #region Conditionally move any parameters found into the cmdparams            
            if ($command.Parameters.From -and $request['From']) {            
                $cmdParams["From"] = $request['From']            
            }            
                        
            if ($command.Parameters.To -and $request['To']) {            
                $cmdParams["To"] = $request['To']            
            }            
                           
                        
            if ($command.Parameters.Body -and $request['Body']) {            
                $cmdParams["Body"] = $request['Body']            
            }            
                        
            if ($command.Parameters.AccountSid -and $request['AccountSid']) {            
                $cmdParams["Accountsid"] = $request['Accountsid']            
            }            
                        
            if ($command.Parameters.SmsSid -and $request['SmsSid']) {            
                $cmdParams["SmsSid"] = $request['SmsSid']            
            }            
                        
            if ($command.Parameters.FromCity -and $request['FromCity']) {            
                $cmdParams["FromCity"] = $request['FromCity']            
            }            
                        
            if ($command.Parameters.FromState -and $request['FromState']) {            
                $cmdParams["FromState"] = $request['FromState']            
            }            
                        
            if ($command.Parameters.FromZip -and $request['FromZip']) {            
                $cmdParams["FromZip"] = $request['FromZip']            
            }            
                        
            if ($command.Parameters.FromCountry -and $request['FromCountry']) {            
                $cmdParams["FromCountry"] = $request['FromCountry']            
            }            
                        
                        
            if ($command.Parameters.ToCity -and $request['ToCity']) {            
                $cmdParams["ToCity"] = $request['ToCity']            
            }            
                        
            if ($command.Parameters.ToState -and $request['ToState']) {            
                $cmdParams["ToState"] = $request['ToState']            
            }            
                        
            if ($command.Parameters.ToZip -and $request['ToZip']) {            
                $cmdParams["ToZip"] = $request['ToZip']            
            }            
                        
            if ($command.Parameters.ToCountry -and $request['ToCountry']) {            
                $cmdParams["ToCountry"] = $request['ToCountry']            
            }              
            
            $allowedParameter  = @($cmdMd.Parameters.Keys )            
            if (-not $AllowedParameter) {            
                $allowedParameter  = $cmdMd.Parameters.Keys             
            }            
               
            # If a parameter set was provided, filter out parameters from other parameter sets            
            if ($parameterSet) {                    
                $allParameters = $allowedParameter |            
                    Where-Object {            
                        $cmdMd.Parameters[$_].Attributes |             
                            Where-Object { $_.ParameterSetName -eq $parameterSet }            
                    }            
            }            
                    
            if ($parameterSet) {                    
                $allParameters = $allParameters |            
                    Where-Object {            
                        $cmdMd.Parameters[$_].Attributes |             
                            Where-Object { $_.ParameterSetName -eq $parameterSet }            
                    }            
            }            
                             
            $allParameters = foreach ($param in $allowedParameter) {            
                if ($HideParameter -notcontains $param) {            
                    $param            
                }            
            }            
                    
            # Order parameters if they are not explicitly ordered            
            if (-not $order) {            
                $order =             
                     @($allParameters |                                     
                        Select-Object @{            
                            Name = "Name"            
                            Expression = { $_ }            
                        },@{            
                            Name= "NaturalPosition"            
                            Expression = {             
                                $p = @($cmdMd.Parameters[$_].ParameterSets.Values)[0].Position            
                                if ($p -ge 0) {            
                                    $p            
                                } else { 1gb }                                                          
                            }            
                        } |                                     
                        Sort-Object NaturalPosition|             
                        Select-Object -ExpandProperty Name)            
            }            
                        
            
                      
            if (-not $cmdParams.Body) {            
                $body =             
                    if ($request -and $request.Params -and $request.Params['Body']) {            
                        $request.Params['Body']            
                    } else {            
                        ""            
                    }            
                                
            
                # The body should strip off the command specifier, so that the input could be easily redirected from a module            
                $possibleCmdNames =             
                    @(Get-Alias -Definition "$($cmdMd.Name)" -ErrorAction SilentlyContinue) + "$($cmdMd.Name)"            
                            
                foreach ($pcn in $possibleCmdNames) {            
                    if ($body -like "$pcn*") {            
                        $body = $body.Susbstring("$pcn".Length).TrimStart(":").TrimStart("-")            
                    }            
                }            
            
                $body = $body.Replace(",", '`,').Replace("(", '`(').Replace(")",'`)').Replace(";", '`;')            
                            
                            
                            
                $dataScriptBlock = [ScriptBlock]::create("
$($cmdMd.Name) @cmdParams $body 
                ")            
                            
                            
                            
                $dataScriptBlock = [ScriptBlock]::Create("data -SupportedCommand $($cmdMd.Name) { $dataScriptBlock } ")                    
                try {            
                    $error.clear()            
                    $outputData = & $dataScriptBlock                           
            
                } catch {            
                    $errorRecord = $_            
                                
                               
                }            
                            
            } else {            
                $error.clear()            
                try {            
                    $outputData = & $command @mergedParameters 2>&1                 
                } catch {            
                    $errorRecord = $_            
                                
                }            
            }            
            
            
                        
                        
            if ($outputData -is [string]) {            
                $response.contentType = 'text/xml'            
                $response.Write("<?xml version='1.0' encoding='UTF-8'?>
        <Response>
            <Sms>$([Security.SecurityElement]::Escape($OutputData))</Sms>
        </Response>")            
            } elseif ($outputData -is [Management.Automation.ErrorRecord]) {            
                $msg = $OutputData.Message            
                $msg = if ($msg.Length -gt 160) {            
                    $msg.Substring(0, 159)            
                } else {            
                    $msg            
                }            
                $response.contentType = 'text/xml'            
                $response.Write("<?xml version='1.0' encoding='UTF-8'?>
        <Response>
            <Sms>$([Security.SecurityElement]::Escape($msg))</Sms>
        </Response>")            
            } elseif ($ErrorRecord) {            
                $msg = "$errorRecord"            
                $msg = if ($msg.Length -gt 160) {            
                    $msg.Substring(0, 159)            
                } else {            
                    $msg            
                }            
                $response.contentType = 'text/xml'            
                $response.Write("<?xml version='1.0' encoding='UTF-8'?>
        <Response>
            <Sms>$([Security.SecurityElement]::Escape($msg))</Sms>
        </Response>")            
            } else {            
                $outputText = ""                    
                            
                # Loop thru each object and concatenate properties            
                foreach ($outputItem in $outputData) {            
                    foreach ($kv in $outputItem.psObject.properties) {            
                        if (-not $kv) { continue }             
                        $outputText += "$($kv.Name):$($kv.Value)$([Environment]::NewLine)"            
                    }            
                }            
            
                if ($outputText) {            
                    $response.contentType = 'text/xml'            
                    $response.Write("<?xml version='1.0' encoding='UTF-8'?>
            <Response>
                <Sms>$($outputText)</Sms>
            </Response>")            
                            
                }            
                                    
            }                                                                                        
            return                              
                        
                             
        } elseif ($Request -and $Request["CallSid"] -and            
            $Request["From"] -and            
            $Request["To"] -and            
            $Request["AccountSid"]            
        ) {             
            # Phone handler            
            
            $callSid = $request["CallSid"]            
            
            $cmdParams = @{} + $commandParameters            
            
            if ($parameterDefaultValue) {            
                foreach ($d in $ParameterDefaultValue.Keys) {            
                    if (! $cmdParams.ContainsKey($D)) {            
                        $cmdParams[$d] = $ParameterDefaultValue[$d]            
                    }            
                }                            
            }            
                        
            
            
            
            if ($command.Parameters.From -and $request['From']) {            
                $cmdParams["From"] = $request['From']            
            }            
                        
            if ($command.Parameters.To -and $request['To']) {            
                $cmdParams["To"] = $request['To']            
            }            
                           
            
            if ($command.Parameters.AccountSid -and $request['AccountSid']) {            
                $cmdParams["Accountsid"] = $request['Accountsid']            
            }            
                        
            if ($command.Parameters.CallSid -and $request['CallSid']) {            
                $cmdParams["CallSid"] = $request['CallSid']            
            }            
                        
            if ($command.Parameters.FromCity -and $request['FromCity']) {            
                $cmdParams["FromCity"] = $request['FromCity']            
            }            
                        
            if ($command.Parameters.FromState -and $request['FromState']) {            
                $cmdParams["FromState"] = $request['FromState']            
            }            
                        
            if ($command.Parameters.FromZip -and $request['FromZip']) {            
                $cmdParams["FromZip"] = $request['FromZip']            
            }            
                        
            if ($command.Parameters.FromCountry -and $request['FromCountry']) {            
                $cmdParams["FromCountry"] = $request['FromCountry']            
            }            
                        
                        
            if ($command.Parameters.ToCity -and $request['ToCity']) {            
                $cmdParams["ToCity"] = $request['ToCity']            
            }            
                        
            if ($command.Parameters.ToState -and $request['ToState']) {            
                $cmdParams["ToState"] = $request['ToState']            
            }            
                        
            if ($command.Parameters.ToZip -and $request['ToZip']) {            
                $cmdParams["ToZip"] = $request['ToZip']            
            }            
                        
            if ($command.Parameters.ToCountry -and $request['ToCountry']) {            
                $cmdParams["ToCountry"] = $request['ToCountry']            
            }            
            
            $allowedParameter  = @($cmdMd.Parameters.Keys )            
            if (-not $AllowedParameter) {            
                $allowedParameter  = $cmdMd.Parameters.Keys             
            }            
               
            # If a parameter set was provided, filter out parameters from other parameter sets            
            if ($parameterSet) {                    
                $allParameters = $allowedParameter |            
                    Where-Object {            
                        $cmdMd.Parameters[$_].Attributes |             
                            Where-Object { $_.ParameterSetName -eq $parameterSet }            
                    }            
            }            
                    
                        
            $allParameters = foreach ($param in $allowedParameter) {            
                if ($HideParameter -notcontains $param -and (! $CmdParams.ContainsKey($param))) {            
                    $param            
                }            
            }            
                        
                        
                        
            
                        
                    
            # Order parameters if they are not explicitly ordered            
            $order =             
                    @($allParameters |                                     
                    Select-Object @{            
                        Name = "Name"            
                        Expression = { $_ }            
                    },@{            
                        Name= "NaturalPosition"            
                        Expression = {             
                            $p = @($cmdMd.Parameters[$_].ParameterSets.Values)[0].Position            
                            if ($p -ge 0) {            
                                $p            
                            } else { 1gb }                                                          
                        }            
                    } |            
                    Where-Object { $_.NaturalPosition -ne 1gb -and (! $CmdParams.ContainsKey($_.Name))} |             
                    Sort-Object NaturalPosition|             
                    Select-Object -ExpandProperty Name)            
                 
                        
            
            $parameterNumber =             
                if ($request["ParameterNumber"]) {            
                    $request["ParameterNumber"] -as [Int32]            
                } else {            
                    0            
                }            
                            
                        
            # In phone calls, the system needs to keep track of the state of each individual call.            
            # This is done using a cookie keyed off of the CallSid            
            $callSid = $request["CallSid"]            
            $parameterValues = @()            
            
            for ($pN = 0; $pn -lt $parameterNumber; $pn++) {            
                if ($request["P$Pn"]) {            
                    # A parameter value exists!            
                    $parameterValues+= $request["P$pn"]            
                                    
                                
                }            
            }            
            
                        
                        
                        
            $helpObj= ($command | Get-Help)                        
                        
            $responseXml = "<Response>"            
                                         
            if ($parameterNumber -lt $order.Count) {            
                $parameterInfo = $order[$parameterNumber]            
                $parameterInfo = $command.Parameters[$parameterInfo]             
            } else {            
                $parameterInfo  = $null            
            }                                                
                        
            $parameter = $parameterInfo.Name            
            $parameterType = $parameterInfo.ParameterType            
            $validateSet =             
                foreach ($attribute in $parameterInfo.Attributes) {            
                    if ($attribute.TypeId -eq [Management.Automation.ValidateSetAttribute]) {            
                        $attribute            
                        break            
                    }            
                }            
                            
            $parameterHelp  =             
                foreach ($p in $helpObj.Parameters.Parameter) {            
                    if ($p.Name -eq $parameter) {            
                        $p.Description | Select-Object -ExpandProperty Text            
                    }            
                }                            
                        
                            
            $parameterVisibleHelp = $parameterHelp -split ("[`n`r]") |? { $_ -notlike "|*" }             
                        
            $pipeworksDirectives  = @{}            
            foreach ($line in $parameterHelp -split ("[`n`r]")) {            
                if ($line -like "|*") {            
                    $directiveEnd= $line.IndexofAny(": `n`r".ToCharArray())            
                    if ($directiveEnd -ne -1) {            
                        $name, $rest = $line.Substring(1, $directiveEnd -1).Trim(), $line.Substring($directiveEnd +1).Trim()            
                        $pipeworksDirectives.$Name = $rest            
                    } else {            
                        $name = $line.Substring(1).Trim()            
                        $pipeworksDirectives.$Name = $true            
                    }            
                                
                                
                }            
            }                            
            
            
            if ($request.Cookies["CallStatusFor_${CallSid}"]) {            
                $callStatusCookie = $request.Cookies["CallStatusFor_${CallSid}"]            
            } else {            
                $callStatusCookie = New-Object Web.HttpCookie "CallStatusFor_${CallSid}"            
            }            
                        
            
            
                        
                        
            if ($pipeworksDirectives.Options -or $validateSet -or ($parameterType -and $parameterType.IsSubClassOf([Enum]))) {            
                $optionList =             
                    if ($pipeworksDirectives.Options) {            
                        Invoke-Expression -Command "$($pipeworksDirectives.Options)" -ErrorAction SilentlyContinue            
                    } elseif ($ValidateSet) {            
                        $ValidateSet.ValidValues            
                    } elseif ($parameterType -and $parameterType.IsSubClassOf([Enum])) {            
                        [Enum]::GetValues($parameterType)            
                    }                        
            
            } else {            
                $optionList = @()            
            }            
            
                                           
            if  ($parameterInfo -and             
                                            
                $Request["TranscriptionText"]) {            
                # The person has supplied a value to a parameter, store it and move on            
                            
                if ($parameterInfo.ParameterType -eq [ScriptBlock]) {            
                    $parameterValues += try { [ScriptBlock]::Create($Request["TranscriptionText"]) } catch {}             
                } else {            
                    $parameterValues += ($Request["TranscriptionText"] -as $parameterInfo.ParameterType)            
                }            
                $parameterValues += $Request["TranscriptionText"]            
            
                $callStatusCookie["ParameterValue_$parameterInfo"]  =             
                    $Request["RecordingUrl"]            
            
                $parameterNumber++                                        
            } elseif  (            
                $Request["RecordingUrl"]) {            
                # A recording            
                $callStatusCookie["ParameterValue_$parameterInfo"]  =             
                    $Request["RecordingUrl"]            
                $parameterValues += $Request["RecordingUrl"]            
                $parameterNumber++            
            } elseif ($Request["Digits"]) {            
                # The person has supplied a value to a parameter, add it to the cookie and move on            
                $callStatusCookie["ParameterValue_$parameterInfo"]  =             
                    $request["Digits"].TrimEnd("#").TrimEnd("*")            
                $digit = $request["Digits"].TrimEnd("#").TrimEnd("*") -as [Uint32]            
                if ($optionList -and $optionList[$digit - 1]) {            
                    $parameterValues += $optionList[$digit - 1]            
                } else {             
                    $parameterValues += $digit            
                }            
            
                            
                $parameterNumber++                            
            } else {            
                if ($parameterNumber -eq 0 ) {            
            
                    $description  = if ($helpObj.Description) {            
                        $helpObj.Description[0].text.Replace('"',"'").Replace('<', '<').Replace('>', '>').Replace('$', '`$')                                    
                    } else {            
                        ""            
                    }            
            
                    if ($description) {            
                        if ($description -like "http://*") {            
                            $responseXml  += "<Play>$([Security.SecurityElement]::Escape($description))</Play>"                        
                        } else {            
                            $responseXml  += "<Say>$([Security.SecurityElement]::Escape($description))</Say>"                        
                        }            
                                    
                    }            
                                
                }            
            }            
            
            
            if ((-not $order.Count) -or ($parameterNumber -eq $order.Count)) {            
            
                $params = @{}            
            
                            
                for ($on = 0 ; $on -lt $order.count; $on++) {            
                    $paramInfo = $Command.Parameters[$order[$on]]            
                    if ($paramInfo.ParameterType -eq [switch]) {            
                        $params[$order[$on]] = if ($parameterValues[$on] -eq 0) { $false } else { $true }             
                    } else {            
                        $params[$order[$on]] = $parameterValues[$on]            
                    }            
                                
                }            
                            
            
                foreach ($p in $params.GetEnumerator()) {            
                    $cmdParams[$p.Key] = $p.Value            
                                
                }            
            
                foreach ($k in @($cmdParams.Keys)) {            
                    if (-not $command.Parameters.ContainsKey($k)) {            
                        $cmdParams.remove($k)# = $p.Value            
                    }            
                }            
                                
            
            
                $cmdResult = & $command @cmdParams            
                            
            
                if ($cmdResult -as [xml]) {            
                    $xml = ($cmdResult -as [xml])            
                    if ($xml.Response) {            
                        $responseXml += $xml.Response.InnerXml            
                    } else {            
                        $responseXml += $xml.InnerXml            
                    }                                
                } elseif ($cmdResult -like "http*") {            
                    if ($cmdResult -like "*.mp3") {            
                        $responseXml += "<Play>$([Security.SecurityElement]::Escape($cmdResult))</Play>"            
                    } elseif ($cmdResult -like "*.wav") {            
                        $responseXml += "<Play>$([Security.SecurityElement]::Escape($cmdResult))</Play>"            
                    } else {            
                        $responseXml += "<Redirect>$([Security.SecurityElement]::Escape($cmdResult))</Redirect>"            
                    }                                 
                                
                } else {            
                            
                    $responseXml += "<Say>$([Security.SecurityElement]::Escape($cmdResult))</Say>"            
                }            
            
            
                            
            } else {            
                $parameterInfo = $order[$parameterNumber]            
                $parameterInfo = $Command.Parameters[$parameterInfo]             
                $parameter = $parameterInfo.Name            
                $parameterType = $parameterInfo.ParameterType            
            
                # Combine the parameters here, so we can send the handler back to the right spot with all of the data intact            
                $ParameterData =             
                    if ($parameterValues.Count) {                                
                        for ($pN = 0; $pn -le $parameterValues.Count; $pn++) {            
                            "P$PN=$([web.httputility]::UrlEncode($parameterValues[$pn]))"            
                                
                        }            
                    } else {            
                        ""            
                    }            
                            
            
                $ParameterData = $ParameterData -join "&"            
            
                $actionUrl =             
                    if ($fullUrl.Contains("ParameterNumber=")) {            
                        # Replacing an existing parameter data            
                        $fullUrl ="$fullUrl".substring(0,"$fullUrl".IndexOf("ParameterNumber=") -1)            
                        if ($fullUrl.ToString().Contains("?")) {            
                            $fullUrl + "&ParameterNumber=$ParameterNumber&${ParameterData}"            
                        } else {                                    
                            "$fullUrl".TrimEnd("/") + "/" + "?ParameterNumber=$ParameterNumber&${ParameterData}"            
                        }            
                    } elseif ($fullUrl.ToString().Contains("?")) {            
                        $fullUrl + "&ParameterNumber=$ParameterNumber&${ParameterData}"            
                    } else {                                    
                        "$fullUrl".TrimEnd("/") + "/" + "?ParameterNumber=$ParameterNumber&${ParameterData}"            
                    }            
            
            
                            
            
            
                            
                # Request input for the parameter.            
                $parameterInfo = $order[$parameterNumber]            
                            
                $paramInput = Request-CommandInput -Platform TwilML -CommandMetaData $cmdMd -AllowedParameter $parameter -Action $actionUrl -DenyParameter $HideParameter            
            
                if ($paramInput -as [xml]) {            
                    $responseXml +=  ($paramInput -as [xml]).Response.innerXml            
                }            
                            
                
            }            
            
                        
            # If the parameter is a Number, have them enter it in on the keypad.            
            
                            
            # If the parameter is text, and named Recording* or *Recording, then record            
            
            # If the parameter is text, and named Trascribe* or *Transcript, then transcribe            
            
            # Otherwise, transcribe            
            
            # If the parameter is a PSObject, pass in the whole recording or transcription object            
            
                            
            
                            
                            
                            
            #$responseXml += "<Play>$([Security.SecurityElement]::Escape($ActionUrl))</Play>"            
                                                                     
                            
                            
            if ($callStatusCookie) {            
                $response.Cookies.Add($callStatusCookie)                                
            }            
            $responseXml += "</Response>"            
                            
            $strWrite = New-Object IO.StringWriter            
            ([xml]$responseXml).Save($strWrite)            
            $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
            if (-not $cmdOptions.ContentType) {            
                $response.ContentType ="text/xml"            
            }            
            $response.Write("$resultToOutput")                
                            
                            
        } elseif ($requestParameterNames."DownloadProxy") {            
            # Start with the core command,            
            . $getProxyCommand            
                        
if ($Request["AsHtml"]) {            
$webPage = Write-ScriptHtml ([ScriptBlock]::create($proxyCommandText))             
$webPage            
} elseif ($request["AsBase64"]) {            
$b64 = [Convert]::ToBase64String(([Text.Encoding]::Unicode.GetBytes($proxyCommandText)))            
    $response.ContentType = "text/plain"            
    $response.Write($b64)            
    $response.Flush()            
            
} else {            
    #$proxyCommandText            
    $response.ContentType = "text/plain"            
    $response.Write($proxyCommandText)            
    $response.Flush()            
}            
                        
        } else  {                        
            # Normal command handler            
                    
                    
                    
                    
            # If they want a link to run the command, instead of actually running it...            
            if ($Request -and ($Request['GetLink'] -or $request['-GetLink'])) {            
                # Get a link            
                $response.contentType = 'text/plain'            
                $responseString = $request.Url.ToString()            
                if ($responseString.Contains('?')) {            
                    $responseString = $responseString.Substring(0, $responseString.IndexOf("?"))            
                }            
                $responseString+='?'            
                foreach ($cp in $commandParameters.GetEnumerator()) {            
                    $b64 = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cp.Value))            
                    $responseString +="$($CmdMd.Name)_$($cp.Key)=${b64}&"            
                }            
                $responseString            
                return            
            }            
                        
            # If -Bare/Bare was specified, then do not output anything but the result            
            if ($Request -and (($request['Bare'] -ilike "$true") -or ($request['-Bare'] -ilike "$true"))) {            
                $cmdoptions.PlainOutput = $true            
            }                 
            
            $result = $null            
                   
            $runAnyways = ($request -and (            
                $request["RunItAnyway"] -or             
                $request["RunItAnyways"] -or             
                $request["RunAnyway"] -or             
                $request["RunAnyways"]))            
                        
            if ($cmdOptions.runWithoutInput -or             
                ($CommandParameters.Count -gt 0) -or             
                $runAnyways) {                                
                if ($cmdOptions.RequireAppKey) {            
                    $appKey = if ($session['User'].SecondaryApiKey -and             
                        -not $request['AppKey']) {            
                        $session['User'].SecondaryApiKey            
                    } elseif ($request['AppKey']) {            
                        $request['AppKey']            
                    } else {            
                        Write-Error "App Key is Required.  The user must be logged in, or a parameter named AppKey must be passed with the request"            
                        return            
                    }            
                                
                    Confirm-Person -ApiKey $appKey -StorageAccountSetting $storageAccountSetting -StorageKeySetting $storageKeySetting -WebsiteUrl $serviceUrl            
                    
                    <#
                    $storageAccount = Get-WebConfigurationSetting -Setting $cmdOptions.StorageAccountSetting
                    $storageKey = Get-WebConfigurationSetting -Setting $cmdOptions.StorageKeySetting
                    $userTableExists = Get-AzureTable -TableName $cmdOptions.UserTable -StorageAccount $storageAccount -StorageKey $storageKey
                    if (-not $userTableExists) { 
                        return
                    }
        
        
                    $userExists = Search-AzureTable -TableName $cmdOptions.UserTable -Filter "PartitionKey eq '$($cmdOptions.UserPartition)' and SecondaryApiKey eq '$appKey'"
                    if (-not $UserExists) {
                        Write-Error "User not found"
                        return
                    }
                    #>                            
                } elseif ($cmdOptions.RequireLogin) {            
                    $confirmHtml = Confirm-Person -WebsiteUrl $serviceUrl                            
                    if ($session["User"]) {            
                        $userExists = $session['User']            
                    } else {            
                        if ($confirmHtml) {            
                            $confirmHtml            
                        }            
                        return            
                    }            
                            
                }            
                
                
                # There are parameters, or the command knows it can run without them.            
            
                # First, clear out empty parameters from the structure            
                if ($mergedParameters.Count) {            
                    $toRemove = @()            
                    foreach ($kv in $mergedParameters.GetEnumerator()) {            
                        if (-not $kv.Value -and ($kv.Value -ne 0)) {             
                            $toRemove += $kv.Key             
                        }             
                    }            
                    foreach ($to in $toRemove) {            
                        $null = $mergedParameters.Remove($to)            
                    }            
                }                                
                     
                # Then, Enforce the Session Throttle            
                $doNotRunCommand = $true            
                if ($cmdOptions.SessionThrottle.TotalMilliseconds) {            
                    if (-not $session["$($cmdMd.Name)_LastRun"]) {            
                        $session["$($cmdMd.Name)_LastRun"] = Get-Date            
                        $doNotRunCommand = $false            
                    } elseif (($session["$($cmdMd.Name)_LastRun"] + $cmdOptions.SessionThrottle) -lt (Get-Date)) {            
                        $session["$($cmdMd.Name)_LastRun"] = Get-Date            
                        $doNotRunCommand = $false            
                    } else {            
                        $timeUntilICanRunAgain = (Get-Date) - ($session["$($cmdMd.Name)_LastRun"] + $cmdOptions.SessionThrottle)            
                        "<span style='color:red'>Can run the command again in $(-$timeUntilICanRunAgain.TotalSeconds) Seconds</span>"            
                        $doNotRunCommand = $true            
                    }                    
                } else {            
                    $doNotRunCommand = $false            
                }            
            
            
                if ($mergedParameters.Count -gt 0 -or $psBoundParameters.RunWithoutInput) {            
                            
                }            
            
                   
                # Default behavior, do not cache            
                if (-not $doNotRunCommand) {                                   
                    # Run the command            
                    $useId = [GUID]::NewGuid()            
                    if ($cmdOptions.ModeratedBy -and $cmdOptions.ExecutionQueueTable) {            
                        # If the command was moderated, 'running' the command is really putting            
                        # the parameters into table storage for someone to approve            
                        $subject = "Would you like to run $($cmdMd.Name)?"            
                        $confirmId = $useId            
                        $pendingExecutionRequest = New-Object PSObject -Property $commandParameters            
                        $requestAsString = $request.Url.ToString()            
                        $serviceUrl = $requestAsString.Substring(0,$requestAsString.LastIndexOf("/"))            
                                
                        $canReply = if ($session['User'].UserEmail) {            
                            "<a href='$serviceUrl?sendreply=$confirmId'>Reply</a>"            
                        } else {            
                            ""            
                        }            
                            
                            
                        $message = "
$userInfo has requested that you run $($cmdMd.Name) with the following parameters:

$($pendingExecutionRequest | Out-HTML) 

               
<a href='${finalUrl}?confirm=$confirmId'>Run this</a>
<a href='${finalUrl}?deny=$confirmId'>Don't run this</a>
$canReply
"            
            
                        $smtpEmail = Get-SecureSetting $cmdOptions.SmtpEmailSetting -ValueOnly            
                        $smtpPassword = Get-SecureSetting $cmdOptions.SmtpPasswordSetting -ValueOnly            
                        $smtpCred = New-Object Management.Automation.PSCredential ".\$smtpEmail", "$(ConvertTo-SecureString -AsPlainText -Force $smtpPassword)"            
                        Send-MailMessage -To $cmdOptions.ModeratedBy -UseWebConfiguration -Subject $subject -Body $Message -BodyAsHtml -AsJob                            
                            
                            
                        $pendingExecutionRequest |             
                            Set-AzureTable -TableName $cmdOptions.ExecutionQueueTable -PartitionKey $cmdMd.Name -RowKey $useId            
                            
                        $result = "Your request has been sent to the moderator"                                                                                        
                    } elseif (($PayNow -or $SubscribeNow) -and ($Request -and $Request["Confirmed"])) {            
                        # Calculate total payment and present with a bill and a pay now link.  When the payment is processed the command will be run            
                        . $ComputeTotalCost            
                                                 
                                    
                                              
                        $confirmLink = "$serviceUrl".Substring(0, "$serviceUrl".LastIndexOf("/")) + "/" + $Command + "/"             
            
                        if ($confirmLink.Contains("?")) {            
                            $confirmLink += "&"            
                        } else {            
                            $confirmLink = $confirmLink.TrimEnd("/") + "/?"            
                        }            
            
                        $costString = "$" + $totalCost            
            
                        $parameterConfirm = "
<span style='font-size:2em'>Are you sure you'd like to $($FriendlyName)?.  It will cost $costString .</span>                        
                        "            
                        $parameterConfirm += "<div style='margin-left:auto;margin-right:auto;width:66%'>
                        <table style='align:center'>
                            <tr>
                            <th style='font-size:1.6em;width:50%'>
                                Option
                            </th>
                            <th style='font-size:1.6em;width:50%'>
                                Value
                            </th>
                        </tr>"            
                        foreach ($pValue in $commandParameters.GetEnumerator()) {            
                            if (-not $pValue) { continue }            
                            $confirmLink += "&$($Command)_$($pValue.Key)=$([Web.HttpUtility]::UrlEncode($pValue.Value))"            
                            $parameterConfirm += "<tr><td><b>$($pValue.Key)</b><td><td>$($pValue.Value | Out-HTML)</td></tr>"            
                        }            
            
                        $confirmLink += "&Confirmed=true"            
            
                        $parameterConfirm +="</table></div>"            
                        $parameterConfirm += Write-Link -Url $confirmLink -Caption "OK" -Style @{'font-size' = '2.5em';float='right'}             
                                    
                        $parameterConfirm | New-WebPage | Out-HTML -WriteResponse             
                        return            
                                    
                    } elseif ((($PayNow -or $SubscribeNow) -and (-not ($Request -and $request["Confirmed"])))) {            
                        # Prompting for a pay link if -AsEmail is not provided.            
            
                                    
                        . $ComputeTotalCost            
            
            
                                    
            
                        $postPaymentCommand = $Command            
                        $session["PostPaymentCommand"] = $postPaymentCommand            
                        $session["PostPaymentParameter"] = $PostPaymentParameter =             
                            Write-PowerShellHashtable -InputObject $CommandParameters            
            
                        #$PostPaymentParameter  = [Web.HttpUtility]::UrlEncode($PostPaymentParameter)            
                        $payLink =             
                            if ($paynow) {            
                                "Purchase"            
                            } elseif ($SubscribeNow) {            
                                "Rent"            
                            }             
                        $payUrl  = $ServiceUrl.ToString() + "?$payLink=True&ItemName=$Command&ItemPrice=$TotalCost&$(if ($SubscribeNow) { "BillingFrequency=$BillingFrequency" })"            
                                    
                                    
                        #$PostPaymentParameter,$postPaymentCommand = $null            
                        $userPart = if ($pipeworksManifest.UserTable.Partition) {            
                            $pipeworksManifest.UserTable.Partition            
                        } else {            
                            "Users"            
                        }            
                        
                        $purchaseHistory = $userPart + "_Purchases"            
                        
                                    
                        $azureStorageAccount = Get-SecureSetting -Name $pipeworksManifest.UserTable.StorageAccountSetting -ValueOnly            
                        $azureStorageKey= Get-SecureSetting -Name $pipeworksManifest.UserTable.StorageKeySetting -ValueOnly            
            
                        $purchase = @()            
                        $payLinks = ""            
                        $fullPayLink = ""            
                        if (-not $listOfCosts) {            
                            $itemPrice = $TotalCost            
                            $purchaseId = [GUID]::NewGuid()            
                        
                        
                            $newpurchase = New-Object PSObject            
                            $newpurchase.pstypenames.clear()            
                            $newpurchase.pstypenames.add('http://shouldbeonschema.org/ReceiptItem')            
                            $itemNAme = $FriendlyName            
                            $Currency = if ($cmdOptions.Currency) {            
                                $cmdOptions.Currency            
                            } else {            
                                "USD"            
                            }            
                        
                            $newpurchase  = $newpurchase |            
                                Add-Member NoteProperty PurchaseId $purchaseId -PassThru |            
                                Add-Member NoteProperty ItemName $itemName -PassThru |            
                                Add-Member NoteProperty ItemPrice $itemPrice -PassThru |            
                                Add-Member NoteProperty Currency $currency -PassThru |                                        
                                Add-Member NoteProperty OrderTime $request["OrderTime"] -PassThru            
                                    
                            if ($session["User"]) {            
                                $newpurchase = $newpurchase |             
                                    Add-Member NoteProperty UserID $session["User"].UserID -PassThru            
                            }            
                            $isRental = if ($SubscribeNow) {            
                                $true            
                            } else {            
                                $false            
                            }            
            
                            $newpurchase = $newpurchase |             
                                Add-Member NoteProperty IsRental $isRental -Force -PassThru            
            
                                        
            
                            if ($postPaymentCommand) {            
                                $newpurchase  = $newpurchase  |            
                                    Add-Member NoteProperty PostPaymentCommand $postPaymentCommand -PassThru            
                            }            
            
                            if ($PostPaymentParameter) {            
                                $newpurchase = $newpurchase  |            
                                    Add-Member NoteProperty PostPaymentParameter $PostPaymentParameter -PassThru            
                            }            
            
                                        
            
                            $newpurchase |             
                                    Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -PartitionKey $purchaseHistory -RowKey $purchaseId -StorageAccount $azureStorageAccount  -StorageKey $azureStorageKey            
                        
                                        
                            $payLinks = ""            
                            $payLinks +=             
                                if ($pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -and             
                                    $pipeworksManifest.PaymentProcessing.AmazonAccessKey) {            
                                    $newpurchase |             
                                        Write-Link -AmazonPaymentsAccountId $pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -AmazonAccessKey $pipeworksManifest.PaymentProcessing.AmazonAccessKey            
                                }            
                            
                        
                            $payLinks +=             
                                if ($pipeworksManifest.PaymentProcessing.PaypalEmail) {                                                    
                                    Write-Link -ItemName $itemName -Currency $currency -ItemPrice $itemPrice -PaypalEmail $pipeworksManifest.PaymentProcessing.PaypalEmail -PaypalIPN "$ServiceUrl/?-PaypalIPN" -PaypalCustom $PurchaseId -Subscribe:$isRental -BillingFrequency $BillingFrequency             
                                }                                        
            
            
                            $payLinks +=             
                                if ($pipeworksManifest.PaymentProcessing.BuyCodeHandler) {            
                                    $newpurchase |             
                                        Write-Link -BuyCodeHandler $pipeworksManifest.PaymentProcessing.BuyCodeHandler -Subscribe:$isRental            
                                }            
            
                            $fullPayLink += "                                                    
                            <span style='font-size:1.3em'>$itemName</span>
                            <br/>
                            <span style='font-size:1.1em'>$itemPrice $currency $(if ($SubscribeNow) { " $BillingFrequency"})</span>
                            <br/>
                        
                            $($payLinks| Out-HTML)"            
            
                                        
                        } else {            
                            $lc = 0             
                            foreach ($loc in $listOfCosts) {            
                                $itemPrice = $loc            
                                $purchaseId = [GUID]::NewGuid()            
                        
                        
                                $newpurchase = New-Object PSObject            
                                $newpurchase.pstypenames.clear()            
                                $newpurchase.pstypenames.add('http://shouldbeonschema.org/ReceiptItem')            
                                $itemNAme = $FriendlyName            
                                                
                                $TheCurrency = if ($cmdOptions.Currency -and $cmdOptions.Currency.Count -ge $lc) {            
                                    $cmdOptions.Currency[$lc]            
                                } else {            
                                    $Currency[0]            
                                }            
            
                                $TheBillingFrequency= if ($cmdOptions.BillingFrequency -and $cmdOptions.BillingFrequency.Count -ge $lc) {            
                                    $cmdOptions.BillingFrequency[$lc]            
                                } else {            
                                    $BillingFrequency[0]            
                                }            
                                                
                        
                                $newpurchase  = $newpurchase |            
                                    Add-Member NoteProperty PurchaseId $purchaseId -PassThru |            
                                    Add-Member NoteProperty ItemName $itemName -PassThru |            
                                    Add-Member NoteProperty ItemPrice $itemPrice -PassThru |            
                                    Add-Member NoteProperty Currency $TheCurrency -PassThru |                                                                            
                                    Add-Member NoteProperty BillingFrequency $TheBillingFrequency -PassThru            
                                    
                                            
                                            
                                if ($session["User"]) {            
                                    $newpurchase = $newpurchase |             
                                        Add-Member NoteProperty UserID $session["User"].UserID -PassThru            
                                }            
                                $isRental = if ($SubscribeNow) {            
                                    $true            
                                } else {            
                                    $false            
                                }            
            
                                $newpurchase = $newpurchase |             
                                    Add-Member NoteProperty IsRental $isRental -Force -PassThru            
            
                                        
            
                                if ($postPaymentCommand) {            
                                    $newpurchase  = $newpurchase  |            
                                        Add-Member NoteProperty PostPaymentCommand $postPaymentCommand -PassThru            
                                }            
            
                                if ($PostPaymentParameter) {            
                                    $newpurchase = $newpurchase  |            
                                        Add-Member NoteProperty PostPaymentParameter $PostPaymentParameter -PassThru            
                                }            
            
                                $purchase += $newpurchase            
            
                                $itemPrice = $newpurchase.ItemPrice            
                                $TheCurrency = $newpurchase.Currency            
                                            
                                $TheBillingFrequency = $newpurchase.BillingFrequency            
                                $newpurchase |             
                                    Set-AzureTable -TableName $pipeworksManifest.UserTable.Name -PartitionKey $purchaseHistory -RowKey { $_.purchaseId } -StorageAccount $azureStorageAccount  -StorageKey $azureStorageKey            
                        
                                        
                                $payLinks = ""            
                                $payLinks +=             
                                    if ($pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -and             
                                        $pipeworksManifest.PaymentProcessing.AmazonAccessKey) {            
                                        $newpurchase |             
                                            Write-Link -AmazonPaymentsAccountId $pipeworksManifest.PaymentProcessing.AmazonPaymentsAccountId -AmazonAccessKey $pipeworksManifest.PaymentProcessing.AmazonAccessKey            
                                    }            
                            
                        
                                $payLinks +=             
                                    if ($pipeworksManifest.PaymentProcessing.PaypalEmail) {                                                    
                                        Write-Link -ItemName $itemName -Currency $TheCurrency -ItemPrice $itemPrice  -PaypalEmail $pipeworksManifest.PaymentProcessing.PaypalEmail -PaypalIPN "$ServiceUrl/?-PaypalIPN" -PaypalCustom $PurchaseId -Subscribe:$isRental -BillingFrequency:$TheBillingFrequency             
                                    }            
            
            
                                $payLinks +=             
                                    if ($pipeworksManifest.PaymentProcessing.BuyCodeHandler) {            
                                        $newpurchase |             
                                            Write-Link -BuyCodeHandler $pipeworksManifest.PaymentProcessing.BuyCodeHandler -Subscribe:$isRental            
                                    }            
                                $lc++            
                                $fullPayLink += "                                                                                
                            <span style='font-size:1.3em'>$itemName</span>
                            <br/>
                            <span style='font-size:1.1em'>$itemPrice $Thecurrency $(if ($SubscribeNow) { " $TheBillingFrequency"})</span>
                            <br/>
                        
                            $($payLinks| Out-HTML)"            
            
            
                            }            
                        }            
                        
                                    
            
                        if ($cmdOptions.PaymentProcessed) {            
                            try {            
                                        
                                if ($request -and ($Request["OutputParameter"] -eq 'true')) {            
                                    $result = $mergedParameters             
                                } else {            
                                            
                                    $result = & $command @mergedParameters -ErrorVariable AnyProblem            
                                                
                                }            
            
                                return ($result | Out-HTML)            
            
                                        
                            } catch {            
                                $commandError = $_            
                                    
                            }               
                        } else {            
                            return $fullPayLink            
                            
                                        
                        }            
                                    
                    } elseif ($promptForConfirmation -and -not $request["Confirmed"]) {            
                        # Prompt for the person's confirmation            
                        $confirmLink = "$fullUrl"            
            
                        if (-not $ConfirmationMessage) {            
                            $ConfirmationMessage= "Are you sure you'd like to $($FriendlyName)?."            
                        }             
                        $parameterConfirm = "
<span style='font-size:2em'>$ConfirmationMessage</span>                        
                        "            
                        $parameterConfirm += "<div style='margin-left:auto;margin-right:auto;width:66%'>
                        <table style='align:center'>
                            <tr>
                            <th style='font-size:1.6em;width:50%'>
                                Option
                            </th>
                            <th style='font-size:1.6em;width:50%'>
                                Value
                            </th>
                        </tr>"            
                        foreach ($pValue in $commandParameters.GetEnumerator()) {            
                            if (-not $pValue) { continue }            
                            $confirmLink += "&$($Command)_$($pValue.Key)=$([Web.HttpUtility]::UrlEncode($pValue.Value))"            
                            $parameterConfirm += "<tr><td><b>$($pValue.Key)</b><td><td>$($pValue.Value | Out-HTML)</td></tr>"            
                        }            
            
                        $confirmLink += "&Confirmed=true"            
            
                        $parameterConfirm +="</table></div>"            
                        $parameterConfirm  += Write-Link -Url $confirmLink -Caption "OK" -Style @{'font-size' = '2.5em';float='right';margin='100px'}             
            
                                    
                                    
                        $parameterConfirm | New-WebPage | Out-HTML -WriteResponse             
                        return            
            
                    } else {            
                        $anyProblem = ""            
                        $commandError  = $null                                                    
                                    
                        try {            
                                        
                            if ($request -and ($Request["OutputParameter"])) {            
                                $result = $mergedParameters             
                            } elseif ($request -and $request["OutputParameterType"]) {            
                                            
                                foreach ($mp in @($mergedParameters.GetEnumerator())) {            
                                    $mergedParameters[$mp.Key] = if ($mp.Value) {            
                                        $mp.Value.GetType()            
                                    }                
                                }            
                                $result = $mergedParameters            
                            } else {            
                                            
                                $result = & $command @mergedParameters -ErrorVariable AnyProblem            
                            }            
            
                            if ($request -and $request["OutputError"]) {            
                                $result = $anyProblem            
            
                            }            
            
                                        
                        } catch {            
                            $commandError = $_            
            
                            if ($manifestIsTemporary) {            
                                return            
                            }            
            
                            if ($PlainOutput) {            
                                return $commandError                                    
                            } else {            
                                $result = $commandError            
                            }            
                                        
                        }            
                    }                                    
                        
                             
                    $worked = $?            
                    $cmdresult = $result            
                        
            
                    $commandWasRun = $true            
                                    
                    # If it worked, charge them            
                    if ($worked -and $userExists -and ($cmdOptions.Cost -or $cmdOptions.CostFactor)) {            
                        $userRecord = Search-AzureTable -TableName $cmdOptions.UserTable -Filter "PartitionKey eq '$($cmdOptions.UserPartition)' and RowKey eq '$($userExists.UserId)'"             
            
                        if ($cmdOptions.Cost -and -not $PaymentProcessed) {            
                            # If there was a fixed cost, apply this cost to the user            
                            $balance =             
                                $userRecord.Balance -as [Double]            
                                    
                                    
                            $balance += $cmdOptions.Cost -as [Double]            
                            $userRecord  |            
                                Add-Member NoteProperty Balance $balance -Force -PassThru |                                    
                                Update-AzureTable -TableName $cmdOptions.UserTable -Value { $_ }             
                        }            
                            
                        if ($cmdOptions.CostFactor -and -not $PaymentProcessed) {            
                            $factoredCost = 0            
                                    
                            foreach ($kv in $cmdOptions.CostFactor.getEnumerator()) {                                    
                                        
                                $parameterValue = $mergedParameters["$($kv.Value.Parameter)"]            
                                if ($kv.Value.CostMap) {            
                                    $factoredCost += $kv.Value.CostMap[$parameterValue]            
                                } elseif ($kv.Value.CostPerValue) {            
                                    $factoredCost += $kv.Value.CostPerValue * $parameterValue            
                                }            
                                        
                            }            
            
                            # If there was a fixed cost, apply this cost to the user            
                            $balance =             
                                $userRecord.Balance -as [Double]            
                            if (-not $balance) {            
                                $balance = 0            
                            }             
                            $balance += $factoredCost            
                            $userRecord |            
                                Add-Member NoteProperty Balance $balance -Force -PassThru |                                    
                                Update-AzureTable -TableName $cmdOptions.UserTable -Value { $_ }            
                        }            
                            
                            
                    }            
                        
                        
                        
                # Immediately track its use before it is rendered, if the cmdoptions say so            
                if ($cmdOptions.UseTrackingTable) {            
                    $storageAccount = Get-WebConfigurationSetting -Setting $cmdOptions.StorageAccountSetting            
                    $storageKey = Get-WebConfigurationSetting -Setting $cmdOptions.StorageKeySetting            
                    $trackingTable = Get-AzureTable -TableName $cmdOptions.UseTrackingTable -StorageAccount $storageAccount -StorageKey $storageKey            
                    if (-not $trackingTable) {             
                        return            
                    }            
                            
                            
                    $useInfo = New-Object PSObject -Property @{            
                        UseId = $useID            
                        Worked = $worked            
                    }                                
                                
                                
                    if (-not $worked) {            
                        $ht = Write-PowerShellHashtable -InputObject $commandParameters            
                        $useInfo | Add-Member NoteProperty Parameters $ht -Force            
                    }            
                    if ($session['User'].UserId) {            
                        $useInfo | Add-Member NoteProperty UserId $session['User'].UserId -Force            
                    }            
                                
                    if ($appKey) {            
                        $useInfo | Add-Member NoteProperty AppKey $appKey -Force            
                    }            
                                
            
                                
                                
                                
                    $useInfo |             
                        Set-AzureTable -TableName $cmdoptions.UseTrackingTable -PartitionKey "$($cmdMd.Name)_TimesUsed" -RowKey $useId            
                                
                    if ($cmdOptions.TrackProperty) {            
                        $result |             
                            Select-Object $cmdOptions.TrackProperty |            
                            ForEach-Object { $_.psobject.properties } |            
                            ForEach-Object {            
                                $propName = $_.Name            
                                $md5 = [Security.Cryptography.MD5]::Create()            
                                $content = [Text.Encoding]::Unicode.GetBytes(("$($_.Value)"))            
                                $part = [BitConverter]::ToString($md5.ComputeHash($content))            
                                $useInfo |            
                                    Set-AzureTable -TableName $cmdoptions.UseTrackingTable -PartitionKey "$($cmdMd.Name)_$($propName)_${Part}" -RowKey $useID            
                            }            
                    }            
                                                                            
                            
                    if ($cmdOptions.TrackParameter) {            
                        New-Object PSObject -Property $commandParameters |                                
                            Select-Object $cmdOptions.TrackParameter |            
                            ForEach-Object { $_.psobject.properties } |            
                            ForEach-Object {            
                                $propName = $_.Name            
                                $md5 = [Security.Cryptography.MD5]::Create()            
                                $content = [Text.Encoding]::Unicode.GetBytes(("$($_.Value)"))            
                                $part = [BitConverter]::ToString($md5.ComputeHash($content))            
                                $useInfo |            
                                    Set-AzureTable -TableName $cmdoptions.UseTrackingTable -PartitionKey "$($cmdMd.Name)_$($propName)_Input_${Part}" -RowKey $useID            
                            }            
                    }            
                                
                    if ($cmdOptions.KeepResult -and $result) {            
                        if ($session['User'].UserId) {            
                            $result | Add-Member NoteProperty __UserId $session['User'].UserId -Force            
                        }            
                                    
                        if ($appKey) {            
                            $result | Add-Member NoteProperty __AppKey $appKey -Force            
                        }            
                                    
                        $result |             
                            Add-Member NoteProperty __UseId $useId -Force            
                                        
                        $result |            
                            Set-AzureTable -TableName $cmdoptions.UseTrackingTable -PartitionKey "$($cmdMd.Name)_Results" -RowKey $useID            
                    }            
                            
                            
                    if ($cmdOptions.KeepUserHistory) {            
                        $ht = Write-PowerShellHashtable -InputObject $commandParameters             
                        $md5 = [Security.Cryptography.MD5]::Create()            
                        $content = [Text.Encoding]::Unicode.GetBytes(("$($ht)"))            
                        $part = [BitConverter]::ToString($md5.ComputeHash($content))            
                        New-Object PSObject -Property @{            
                            UseId = $useID            
                            CompressedInput = Compress-Data -String $ht            
                        }            
                        $useInfo |            
                            Set-AzureTable -TableName $cmdoptions.UseTrackingTable -PartitionKey "$($cmdMd.Name)_$($propName)_Input_${Part}" -RowKey $useID            
                    }            
                            
                            
                    if ($cmdOptions.KeepHistory) {                                
                        $ht = Write-PowerShellHashtable -InputObject $commandParameters             
                        $md5 = [Security.Cryptography.MD5]::Create()            
                        $content = [Text.Encoding]::Unicode.GetBytes(("$($ht)"))            
                        $part = [BitConverter]::ToString($md5.ComputeHash($content))            
                        New-Object PSObject -Property @{            
                            UseId = $useID            
                            CompressedInput = Compress-Data -String $ht            
                            CompressedResult = Compress-Data -String ($result | ConvertTo-Xml)             
                        }            
                    }            
                                
                                
                                
                                                                
                }            
            
                if (-not $result -and $NoOutputMessage) {            
                    $result = $NoOutputMessage            
                } else {            
                    if ($OutputProperty) {            
                        $result = $result | Select-Object $OutputProperty            
                    }            
            
                }                
            
            
                if ($LinkTo) {            
                    $result = foreach ($r in $result) {            
                        if (-not $r) { continue }            
                        foreach ($lt in $linkTo.GetEnumerator()) {            
                            # The key of the link is the command / parameter, and the value is the property, for instance:            
                            # @{"Get-Employee/RowKey" = "Row"}            
                                        
                            if ($r.psobject.properties.($lt.Value)) {            
                                $propCaption = $r.($lt.Value)            
                                $moduleUrlRoot = $ServiceUrl.ToString().Substring(0, $ServiceUrl.ToString().LastIndexOf("/"))            
                                $link =             
                                    if ($lt.Key -like "*/*") {            
                                        $cmdName ,$paramName = $lt.Key -split "/"            
                                        "$moduleUrlRoot/$cmdName/?$($cmdname)_$($paramName)=$($r.($lt.Value))"            
                                    } else {            
                                        $cmdName = $lt.Key            
                                        "$moduleUrlRoot/$cmdName/$($lt.Key)"            
                                    }            
            
                                            
            
                                $linkHtml = Write-Link -Caption $propCaption -Url $link            
            
                                            
                                Add-Member -InputObject $r -Name $lt.Value -MemberType NoteProperty -Value $linkHtml  -Force            
                            }            
                        }            
                        $r            
            
                    }                                
                }            
                            
                if ($AsTypename) {            
                    $result = foreach ($r in $result) {            
                        if (-not $r) { continue }            
                        $r.pstypenames.clear()            
                        $R.pstypenames.add($AsTypename)            
                        $r            
                    }            
            
                }                        
                                                
                if ($Request -and (($request['AsXml'] -eq $true) -or ($request['-AsXml'] -eq $true))) {            
                    $response.contentType = 'text/xml'            
                    $result = [string]($result | ConvertTo-Xml -as String)            
                    $response.Write("$result     ")                                                    
                    return             
                }            
                        
                if ($Request -and (($request['AsCsv'] -eq $true) -or ($request['-AsCsv'] -eq $true))) {            
                    $response.contentType = 'text/csv'            
                    $csvFile = [io.path]::GetTempFileName() + ".csv"            
                    $result | Export-Csv -Path $csvFile                                             
                    $response.Write("$([IO.File]::ReadAllText($csvFile))")                                                    
                    Remove-Item -Path $csvFile -ErrorAction SilentlyContinue             
                    return             
                }            
                if ($Request -and (($request['AsJson'] -eq $true) -or ($request['-AsJson'] -eq $true))) {            
                    if ($PSVersionTable.PSVersion -ge '3.0') {            
                        $response.ContentType -eq 'application/json'            
                        $response.Write("$($result | ConvertTo-Json)")                                
                                    
                        return            
                    } else {            
                        throw "Not PS v3 or greater"            
                    }            
                }            
                            
                                                         
                # $result | Out-HTML -Id "${CommandId}Output" -Escape:$escape            
                if ($Request -and (($request['AsRss'] -eq $true) -or ($request['-AsRss'] -eq $true))) {            
                    $response.contentType = 'text/xml'            
                                
                    $requestAsString = $request.Url.ToString()             
                    $pageUrl = $requestAsString  -ireplace "AsRss=true", ""            
                    $pageUrl = $pageUrl.TrimEnd("&")            
                    $shorturl = $requestAsString.Substring(0, $requestAsString.IndexOf("?"))            
                    $description = (Get-Help $command.Name).Description            
                    if ($description) {            
                        $description = $description[0].text.Replace('"',"'").Replace('<', '<').Replace('>', '>').Replace('$', '`$')            
                    }            
                                            
                    $getDateScript = {            
                        if ($_.DatePublished) {            
                            [DateTime]$_.DatePublished            
                        } elseif ($_.TimeCreated) {            
                            [DateTime]$_.TimeCreated            
                        } elseif ($_.TimeGenerated) {            
                            [DateTime]$_.TimeGenerated            
                        } elseif ($_.Timestamp) {            
                            [DateTime]$_.Timestamp            
                        } else {            
                            Get-Date            
                        }            
                    }            
                            
                    # DCR: Make RSS support multiple results            
                    $resultFeed =             
                        $result |             
                            Sort-Object $getDateScript  -Descending |             
                            New-RssItem -DatePublished $getDateScript  -Author {             
                                if ($_.Author) { $_.Author } else { "$($command.Name)" }            
                            } -Link {            
                                $pageUrl             
                            } -Title {            
                                if ($_.Title) {             
                                    $_.Title             
                                } elseif ($_.Name) {             
                                    $_.Name             
                                } else {            
                                    "$($command.Name) - $(Get-Date)"            
                                }             
                            } -Description {            
                                if ($_.Description) {            
                                    $_.Description            
                                } elseif ($_.ArticleBody) {            
                                    $_.ArticleBody            
                                } elseif ($_.Readings) {            
                                    $_.Readings | Out-HTML            
                                } else {            
                                    $_  | Out-HTML            
                                }            
                            }  |            
                            Out-RssFeed -Link $shorturl -Title "$($command.Name)" -Description "$description"                                 
                    $response.Write("$resultFeed")                                
                    return             
                }             
            
                if ($cmdOptions.PlainOutput -or             
                    ($request -and ($request['Bare'] -like "$true")) -or             
                    ($request -and ($request['-Bare'] -like "$true"))) {            
                    if ($cmdOptions.ContentType -and $response) {            
                        $response.ContentType = $cmdOptions.ContentType            
                    }            
                    $resultAsBytes = $result -as [Byte[]]            
                    if ($resultAsBytes) {                                
                        if ($response) {            
                            # If the result was a set of bytes, flush them all as one so that the handler can produce a complex content type.            
                            $response.BufferOutput = $true            
                            $response.BinaryWrite($resultAsBytes )            
                            $response.Flush()            
                        } else {            
                            $resultAsBytes            
                        }            
                    } else {            
                        # If the result is an XmlDocument, then render it as XML.            
                        if ($result -is [xml]) {            
                            $strWrite = New-Object IO.StringWriter            
                            $result.Save($strWrite)            
                            $result  = "$strWrite"            
                            # And, if the content type hasn't been set, set the content type            
                            $resultToOutput  = "$strWrite" -replace "encoding=`"utf-16`"", "encoding=`"utf-8`""            
                            if (-not $cmdOptions.ContentType) {            
                                $response.ContentType ="text/xml"            
                                $response.write($resultToOutput)            
                            }                                        
                        } else {            
                            if ($cmdOptions.ContentType -and $commandWasRun -and $worked -and (-not $inputWasRequested) -and $response) {            
                                $response.ContentType =$cmdOptions.ContentType            
                                if ($global:ContentDisposition) {            
                                    $null = $response.Headers.Add('content-disposition', $global:ContentDisposition.ToString())            
                                    $global:ContentDisposition = $null            
                                }            
                                $response.write($result)            
                            } else {            
                                # The normal output, with plain output            
                                $result            
                            }            
                                        
                        }            
            
                                    
                    }            
            
                    if ($manifestIsTemporary) {            
                        $global:pipeworksManifest = $null             
                    }            
                                
                    return            
                }              
                                                        
                            
            
            
            if ($cmdOptons.showCode) {                            
                $result | Out-HTML             
                "
                $([Security.SecurityElement]::Escape($result))
                <hr/>
                Code
                <br/>
                <textarea cols='80' rows='30'>$([Security.SecurityElement]::Escape($result))</textarea>"                            
            }             
                        
                        
            if ($result) {            
                # Output page            
            
            
                # If there's a content type, and the output is that content type, then we want to write the output directly.            
                # This makes services that create images or other files possible            
            
            
            
                if ($cmdOptions.ContentType -and $commandWasRun -and $worked -and (-not $inputWasRequested)) {                                
                    $response.ContentType =$cmdOptions.ContentType            
                    if ($global:ContentDisposition) {            
                        $null = $response.Headers.Add('content-disposition', $global:ContentDisposition.ToString())            
                        $global:ContentDisposition = $null            
                    }            
                    $response.write($result)                                
                } else {            
                    $redirectPart =             
                    if ($RedirectTo -and $result) {            
    $redirectHref = "$RedirectTo"            
    if( $request["Snug"]) {            
        if ($redirectHref.Contains("?")) {            
            $redirectHref += "&snug=true"            
        } else {            
            $redirectHref += "?snug=true"            
        }            
            
    }            
                        if(-not $RedirectIn) {            
                            @"
    <a href='$redirectHref' style='display:none' id='redirectLink'>
    </a>
    <script type="text/javascript">
    setTimeout('document.getElementById("redirectLink").click()', 250)
    </script>
"@            
                        } else {            
                            @"
    <a href='$redirectHref' style='display:none' id='redirectLink'>
    </a>
    <script type="text/javascript">
    setTimeout('document.getElementById("redirectLink").click()', $($RedirectIn.TotalMilliseconds))
    </script>
"@                             
                        }                            
                    } else {            
                        ""            
                    }            
                    if ($request -and $request["Notify"]) {            
                        "$($result | Out-Html)
$redirectPart
<script type='text/javascript'>
    if (windows.external != null) {
        windows.external.notify('$($request["Notify"].Replace("'", "''"))');
    }
</script>
"            
                                
            
                    } elseif ($Notify) {            
                        "$($result | Out-Html)
$redirectPart
<script type='text/javascript'>
    if (windows.external != null) {
        windows.external.notify('$($notify.Replace("'", "''"))');
    }
</script>
"            
                    } else {            
                        "$($result | Out-Html)
$redirectPart"            
                    }            
                }            
                            
            }               
                                                   
                }                         
            }                        
                        
                        
            $depthChunk = if ($depth) {            
                "../" * $depth            
            } else {            
                ""            
            }            
            
            $useAjax = if ($Request -and $Request["Ajax"]) {            
                $true            
            }            
            if ((-not $result) -or ($commandError -or $validationErrors -or $anyProblem)) {            
                $embedded =  $request -and (($Request["Embed"] -ilike "$true") -or ($Request["Bare"] -ilike "$true"))            
                $allHiddenParameters =@() + $HideParameter            
                        
                if ($ParameterDefaultValue) {            
                    $allHiddenParameters += $ParameterDefaultValue.Keys            
                }            
                $useAjax =             
                    if ($pipeworksManifest.NoAjax -or $cmdOptions.NoAjax -or $cmdOptions.ContentType -or $cmdOptions.RedirectTo -or $cmdOptions.PlainOutput) {            
                        if ($request -and $request["Ajax"]) {            
                            $true            
                        } else {            
                            $false                                        
                                        
                        }            
                                    
                    } else {            
                        $true            
                    }            
            
                if ($anyProblem -or $validationErrors -or $commandError) {            
                                
                    $AnyProblem  = $AnyProblem | ForEach-Object { $_.Message  } | Select-Object -Unique            
                    $validationErrors = $validationErrors | ForEach-Object { $_ }             
                    $commandError = $commandError | ForEach-Object { $_ }             
            
            
                    $problemsPage=  $AnyProblem, $validationErrors, $commandError -ne $null |             
                        Select-Object -Unique |                                     
                        ForEach-Object { "<span class='ui-state-error' style='color:red;padding:15px;margin:10px;font-size:1.33em'>$($_)</span>" }|                                    
                        Out-HTML            
                                                    
                                
                    if (-not $embedded) {            
                        $problemsPage = $problemsPage |              
                            New-Region -Style @{} -LayerID CommandOutput            
            
                        $method = "POST"            
                        if ($request -and $request["Method"]) {            
                            $method = $request["Method"]            
                        }            
            
                        $problemsPage += Request-CommandInput -Action "${fullUrl}" -CommandMetaData $Command -DenyParameter $allHiddenParameters  -Method $method -Ajax:$useAjax |            
                            New-Region -Style @{} -LayerID CommandInput                 
                        $problemsPage  = $problemsPage             
                    }            
                                
                    "$problemsPage "            
                } else {            
                    $method = "POST"            
                    if ($request -and $request["Method"]) {            
                        $method = $request["Method"]            
                    }            
            
                    $inputWasRequested = $true            
            
            
                    $inputPage =             
                        Request-CommandInput -Action "$fullUrl" -CommandMetaData $Command -DenyParameter $allHiddenParameters -Method $method -Ajax:$useAjax              
                    if (-not $embedded) {                
                        $inputPage = $inputPage |            
                            New-Region -Style @{} -LayerID CommandInput             
                        "
                        
                        $inputPage
                        
                        "            
                    }            
                }            
                            
            }                
                    
                    
            if ($manifestIsTemporary) {            
                $global:pipeworksManifest = $null             
            }            
            return            
                        
        }            
        if ($manifestIsTemporary) {            
            $global:pipeworksManifest = $null             
        }                    
    }            
            
}