Public/SEPPmailAPI-Mailprocessing.ps1


<#
.SYNOPSIS
    Reads the active SEPPmail mail processing ruleset.
.DESCRIPTION
    Sends a GET request to the 'mailprocessing/ruleset' endpoint and returns the
    currently configured mail processing ruleset of the SEPPmail appliance.
.PARAMETER showRuleset
    Optional query parameter (boolean) that controls whether the generated
    ruleset content is included in the response.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the active mail processing ruleset as an object.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Update-SMAMailprocessingRuleset
.LINK
    Get-SMAMailprocessingRulesetMisc
.LINK
    Get-SMAMailprocessingRuleSetSettings
.EXAMPLE
    PS C:\> Get-SMAMailProcessingRuleSet
    Returns the active mail processing ruleset.
.EXAMPLE
    PS C:\> Get-SMAMailProcessingRuleSet -showRuleset $true
    Returns the active mail processing ruleset including the generated ruleset content.
#>

function Get-SMAMailProcessingRuleSet
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Apply sysconfig after change ?'
        )]
        [SMARestType('query')]
        [bool]$showRuleset,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'mailprocessing', 'ruleset'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -object
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}


<#
.SYNOPSIS
    Generates and activates the SEPPmail mail processing ruleset.
.DESCRIPTION
    Sends a PUT request to the 'mailprocessing/ruleset/generate' endpoint to
    (re)generate the mail processing ruleset from the current configuration.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the result of the ruleset generation as an object.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAMailProcessingRuleSet
.LINK
    Get-SMAMailprocessingRulesetMisc
.LINK
    Set-SMAMailProcessingRuleSetMisc
.EXAMPLE
    PS C:\> Update-SMAMailprocessingRuleset
    Generates and activates the mail processing ruleset.
#>

function Update-SMAMailprocessingRuleset
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'PUT'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing', 'ruleset', 'generate'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -Object
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }
}


<#
.SYNOPSIS
    Reads miscellaneous mail processing ruleset settings.
.DESCRIPTION
    Sends a GET request to the 'mailprocessing/ruleset/misc' endpoint and returns
    the miscellaneous settings of the mail processing ruleset.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the miscellaneous ruleset settings as an object.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Set-SMAMailProcessingRuleSetMisc
.LINK
    Get-SMAMailProcessingRuleSet
.LINK
    Get-SMAMailprocessingRuleSetSettings
.EXAMPLE
    PS C:\> Get-SMAMailprocessingRulesetMisc
    Returns the miscellaneous mail processing ruleset settings.
#>

function Get-SMAMailprocessingRulesetMisc
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing', 'ruleset', 'misc'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -Object
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Updates miscellaneous mail processing ruleset settings.
.DESCRIPTION
    Sends a PUT request to the 'mailprocessing/ruleset/misc' endpoint to update
    miscellaneous settings such as the LDAP server mode and OpenPGP key template
    behaviour of the mail processing ruleset.
.PARAMETER ldapServerMode
    Selected mode for the LDAP server on ports 388, 387 and 635 used to
    distribute collected S/MIME certificates to internal users.
    Valid values: 'off', 'server', 'interim'.
.PARAMETER enablePgpKeysTemplate
    Boolean that enables sending new OpenPGP public keys to users when a key is
    created with a specified template.
.PARAMETER pgpKeysTemplate
    Name of the template used when sending new OpenPGP public keys to users on
    key creation. The list of templates is available at mailsystem/template.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the API status message of the update operation.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm (ConfirmImpact = Medium).
.LINK
    Get-SMAMailprocessingRulesetMisc
.LINK
    Get-SMAMailProcessingRuleSet
.LINK
    Update-SMAMailprocessingRuleset
.EXAMPLE
    PS C:\> Set-SMAMailProcessingRuleSetMisc -ldapServerMode 'server'
    Sets the LDAP server mode to 'server'.
.EXAMPLE
    PS C:\> Set-SMAMailProcessingRuleSetMisc -enablePgpKeysTemplate $true -pgpKeysTemplate 'PGPKeyMail'
    Enables sending of new OpenPGP public keys using the 'PGPKeyMail' template.
#>

function Set-SMAMailProcessingRuleSetMisc
{
    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Medium'
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'selected mode for LDAP server on port 388, 387 and 635 to distribute collected S/MIME certificates to internal users'
        )]
        [ValidateSet('off','server','interim')]
        [SMARestType('body')]
        [string]$ldapServerMode,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Enable sending of new OpenPGP public keys to users when a key is created with a specified template'
        )]
        [SMARestType('body')]
        [boolean]$enablePgpKeysTemplate,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'specified template used when sending of new OpenPGP public keys to users when a key is created List of templates is available at mailsystem / template'
        )]
        [SMARestType('body')]
        [string]$pgpKeysTemplate,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'PUT'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing','ruleset','misc'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -StringPos2to6
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Reads the mail processing ruleset settings.
.DESCRIPTION
    Sends a GET request to the 'mailprocessing/ruleset/settings' endpoint and
    returns the settings of the mail processing ruleset.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the mail processing ruleset settings as an object.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAMailprocessingRulesetMisc
.LINK
    Get-SMAMailProcessingRuleSet
.LINK
    Update-SMAMailprocessingRuleset
.EXAMPLE
    PS C:\> Get-SMAMailprocessingRuleSetSettings
    Returns the mail processing ruleset settings.
#>

function Get-SMAMailprocessingRuleSetSettings
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'
        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing','ruleset','settings'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -object
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Lists mail processing extended fields.
.DESCRIPTION
    Sends a GET request to the 'mailprocessing/extendedfields' endpoint and
    returns the configured extended fields. The result can be filtered by name,
    domain or customer and limited in size.
.PARAMETER list
    Optional query parameter (boolean). When set, only the field names are listed.
.PARAMETER limit
    Optional query parameter that limits the number of returned entries.
.PARAMETER name
    Optional query parameter that specifies the extended field name to return.
.PARAMETER domainName
    Optional query parameter to limit the output to a specific domain name.
.PARAMETER customer
    Optional query parameter to limit the output to a specific customer.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns an array of mail processing extended field objects.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    New-SMAMailprocessingExtendedFields
.LINK
    Remove-SMAMailprocessingExtendedFields
.LINK
    Get-SMAMailprocessingSystemExtendedFields
.EXAMPLE
    PS C:\> Get-SMAMailprocessingExtendedFields
    Returns all mail processing extended fields.
.EXAMPLE
    PS C:\> Get-SMAMailprocessingExtendedFields -name 'priority' -domainName 'contoso.com'
    Returns the extended field 'priority' filtered to the domain 'contoso.com'.
#>

function Get-SMAMailprocessingExtendedFields
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'List fields only (true/false'
        )]
        [SMARestType('query')]
        [bool]$list,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit number of returned entries'
        )]
        [SMARestType('query')]
        [int]$limit,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Specifies the extended fields name'
        )]
        [SMARestType('query')]
        [string]$name,

                [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit output to a specific domainname'
        )]
        [SMARestType('query')]
        [string]$domainName,

                [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit output to a specific customer'
        )]
        [SMARestType('query')]
        [string]$customer,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'mailprocessing', 'extendedfields'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -objectArray
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Creates a new mail processing extended field.
.DESCRIPTION
    Sends a POST request to the 'mailprocessing/extendedfields' endpoint to
    create a new extended field with the specified name, data type, default
    value and optional domain/tenant assignments.
.PARAMETER name
    Mandatory. Name of the extended field.
.PARAMETER type
    Mandatory. Data type of the extended field.
    Valid values: 'boolean', 'hex', 'integer', 'number', 'string', 'generalized_time'.
.PARAMETER active
    Mandatory boolean that activates the extended field.
.PARAMETER default
    Mandatory. Default value of the extended field.
.PARAMETER comment
    Optional comment explaining the purpose of the extended field.
.PARAMETER domains
    Optional array of domains linked to this extended field.
.PARAMETER tenants
    Optional array of tenants (customers) linked to this extended field.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the API status message of the create operation.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm (ConfirmImpact = Medium).
.LINK
    Get-SMAMailprocessingExtendedFields
.LINK
    Remove-SMAMailprocessingExtendedFields
.EXAMPLE
    PS C:\> New-SMAMailprocessingExtendedFields -name 'priority' -type 'integer' -active $true -default '0'
    Creates a new active integer extended field 'priority' with default value 0.
.EXAMPLE
    PS C:\> New-SMAMailprocessingExtendedFields -name 'vip' -type 'boolean' -active $true -default 'false' -domains 'contoso.com'
    Creates a boolean extended field 'vip' linked to the domain 'contoso.com'.
#>

function New-SMAMailprocessingExtendedFields #:FIXME: Use gat-Date native as input and transform to (Get-Date -Format "yyyyMMdd'T'HHmmss'Z'")
{
    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Medium'
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Name of the extended field'
        )]
        [SMARestType('body')]
        [string]$name,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Data type of the extended field'
        )]
        [ValidateSet('boolean','hex','integer','number','string','generalized_time')]
        [SMARestType('body')]
        [string]$type,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Activate the extended field'
        )]
        [SMARestType('body')]
        [boolean]$active,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Default value of the extended fields'
        )]
        [SMARestType('body')]
        [string]$default,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Comments which explains the purpose of the extended field'
        )]
        [SMARestType('body')]
        [string]$comment,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Domains linked to thie exteded field'
        )]
        [SMARestType('body')]
        [string[]]$domains,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Tenants (customers) linked to thie exteded field'
        )]
        [SMARestType('body')]
        [string[]]$tenants,

        # for later use: tenant_values domain_values group_values user_values


        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'POST' #TODO: Change REST method

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'mailprocessing', 'extendedfields' #TODO: Change URL path

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -StringPos2to4 #TODO: object, StringPos3 -StringPos2to4, objectArray, nattiveJson
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }
}


<#
.SYNOPSIS
    Removes a mail processing extended field.
.DESCRIPTION
    Sends a DELETE request to the 'mailprocessing/extendedfields/{name}'
    endpoint to remove the extended field with the specified name.
.PARAMETER name
    Mandatory. Name of the extended field to remove.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the API status message of the delete operation.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAMailprocessingExtendedFields
.LINK
    New-SMAMailprocessingExtendedFields
.EXAMPLE
    PS C:\> Remove-SMAMailprocessingExtendedFields -name 'priority'
    Removes the extended field named 'priority'.
#>

function Remove-SMAMailprocessingExtendedFields
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Name of the extended field'
        )]
        [SMARestType('body')]
        [string]$name,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'DELETE'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing', 'extendedfields', $name

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -StringPos2to4
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Lists mail processing system extended fields.
.DESCRIPTION
    Sends a GET request to the 'mailprocessing/systemextendedfields' endpoint
    and returns the configured system extended fields. The result can be
    filtered by name, domain or customer and limited in size.
.PARAMETER list
    Optional query parameter (boolean). When set, only the field names are listed.
.PARAMETER limit
    Optional query parameter that limits the number of returned entries.
.PARAMETER name
    Optional query parameter that specifies the system extended field name to return.
.PARAMETER domainName
    Optional query parameter to limit the output to a specific domain name.
.PARAMETER customer
    Optional query parameter to limit the output to a specific customer.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns an array of mail processing system extended field objects.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Set-SMAMailprocessingSystemExtendedFields
.LINK
    Get-SMAMailprocessingExtendedFields
.EXAMPLE
    PS C:\> Get-SMAMailprocessingSystemExtendedFields
    Returns all mail processing system extended fields.
.EXAMPLE
    PS C:\> Get-SMAMailprocessingSystemExtendedFields -name 'sysflag'
    Returns the system extended field named 'sysflag'.
#>

function Get-SMAMailprocessingSystemExtendedFields
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'List fields only (true/false'
        )]
        [SMARestType('query')]
        [bool]$list,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit number of returned entries'
        )]
        [SMARestType('query')]
        [int]$limit,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Specifies the extended fields name'
        )]
        [SMARestType('query')]
        [string]$name,

                [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit output to a specific domainname'
        )]
        [SMARestType('query')]
        [string]$domainName,

                [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Limit output to a specific customer'
        )]
        [SMARestType('query')]
        [string]$customer,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'mailprocessing', 'systemextendedfields'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -objectArray
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }

}

<#
.SYNOPSIS
    Updates a mail processing system extended field.
.DESCRIPTION
    Sends a PUT request to the 'mailprocessing/systemextendedfields/{name}'
    endpoint to update the system extended field identified by its name with the
    specified data type, default value and optional domain/tenant values.
.PARAMETER name
    Mandatory. Name of the system extended field (part of the URI path).
.PARAMETER type
    Mandatory. Data type of the system extended field.
    Valid values: 'boolean', 'hex', 'integer', 'number', 'string', 'generalized_time'.
.PARAMETER active
    Mandatory boolean that activates the system extended field.
.PARAMETER default
    Mandatory. Default value of the system extended field.
.PARAMETER comment
    Optional comment explaining the purpose of the system extended field.
.PARAMETER domain_values
    Optional hashtable of domain-specific values.
.PARAMETER tenant_values
    Optional hashtable of tenant-specific values.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the API status message of the update operation.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm (ConfirmImpact = Medium).
.LINK
    Get-SMAMailprocessingSystemExtendedFields
.LINK
    Get-SMAMailprocessingExtendedFields
.EXAMPLE
    PS C:\> Set-SMAMailprocessingSystemExtendedFields -name 'sysflag' -type 'boolean' -active $true -default 'false'
    Updates the system extended field 'sysflag' as an active boolean with default value 'false'.
#>

function Set-SMAMailprocessingSystemExtendedFields
{
    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Medium'
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Name of the system extended field'
        )]
        [SMARestType('path')]
        [string]$name,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Data type of the system extended field'
        )]
        [ValidateSet('boolean','hex','integer','number','string','generalized_time')]
        [SMARestType('body')]
        [string]$type,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Activate the system extended field'
        )]
        [SMARestType('body')]
        [boolean]$active,

        [Parameter(
            Mandatory       = $true,
            HelpMessage     = 'Default value of the system extended fields'
        )]
        [SMARestType('body')]
        [string]$default,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Comments which explains the purpose of the system extended field'
        )]
        [SMARestType('body')]
        [string]$comment,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Domain values'
        )]
        [SMARestType('body')]
        [hashTable]$domain_values,

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'Tenant values'
        )]
        [SMARestType('body')]
        [hashTable]$tenant_values,

        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'PUT'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}/{2}" -f 'mailprocessing', 'systemextendedfields',$name 

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -StringPos2to4 #TODO: object, StringPos3 -StringPos2to4, objectArray, nattiveJson
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }
}



# SIG # Begin signature block
# MIIVyAYJKoZIhvcNAQcCoIIVuTCCFbUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAo3AboRB1lA8bB
# dme/8YkeiHqRBfhTyoUs4uHIfbsCd6CCEgQwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggZvMIIE16ADAgECAhBIqMP3CCLHOHtOKuaWNyeFMA0GCSqG
# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
# HhcNMjYwNDE1MDAwMDAwWhcNMjcwNzE0MjM1OTU5WjBmMQswCQYDVQQGEwJERTEP
# MA0GA1UECAwGQmF5ZXJuMSIwIAYDVQQKDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBH
# bWJIMSIwIAYDVQQDDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBHbWJIMIICIjANBgkq
# hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvAFzE8MbJpvQt+IdIh1M+bKYsJBFDk4b
# 9ySe25IrCi00B9o5XmQtIw42MqyIKbUq1tDARtp9KTQedEP9W+rflAF2l+0Z046J
# kiqumU9/enbqWLDyln1aS/p7HOgwZFMhnsR9zH0MfFckiklUmkzJO+vmzYAK7ZmD
# xajNLJs0gkGRU2/BecAx/TSvLXMaKONsKZCyMKQCnwo1mCY/tFl5EgUz7YQFrPOR
# BQGfQke/hkdBfQDqNRsi/J6+KhJWc6LvgQihdRg/INQbQsTxlow18NWvyFsjjueH
# 7kG6HR4YKfbv07xgrsIh8xvq9ZJ1SBhLXmkg4SdoQGASjqR6o3keAX+bDRFf+hml
# WWJp/FqVHR5QomF3vbK2/bbz4jAclYSPx/sPasNJ0YnKFkgmowZ7Ysa0KA0/egBg
# tI4gJ+8V7zrqIVEG3rMQh9KCdMnJqP2aM9o4gUzQvE1M4x606liX9EWwdLLS+fe7
# 9o+Fzo5oH4wBE/En6hQQkzseHHu+TXCDd6zUUZ/PlTK0gTaDIRXt6UzPNqJ4RiRC
# W2pNFcPt078qqVTuwKUXoE4ufxGgXKFrZlCYST/9eG1TnW2oq19nz8A333GCsL3g
# poNIKvfmDyGMMNzvx2aeqn2v6e75z8kH19iGSNZ51xT+WgS9F1aIvjz08/T7XAv7
# iDPF1/gPIp8CAwEAAaOCAakwggGlMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1Sm
# KaoXpM0MMB0GA1UdDgQWBBS30/Tq+alF3j2BY5up8n5zpAU23DAOBgNVHQ8BAf8E
# BAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAE
# QzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp
# Z28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2Ny
# bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmww
# eQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28u
# Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcw
# AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETc3VwcG9ydEBz
# ZXBwbWFpbC5jaDANBgkqhkiG9w0BAQwFAAOCAYEAi7fmb5UYoemWG3CC4K2UZWVr
# R6GOfi8gbJKgjPbKO4zrCrU/x6cOdyp6scKZfUEGFDf8KH6pP4pAQv1Hsbi49gU2
# kxoUWLlCiipn05qJY663DHx9hlStej/ZdEatou0wyCDiG5xD7kmG+1t6iLyyCBgE
# B88tJpzTjI61qXmBTS/FGEOAsB4SDEW1ngA7bc5FOv4IUKA43hp8M+N3GeYFzDqw
# JELYEfVVYheBW3o7q4VrCdfFEuaQihOtvfDfYpP6ANgekNn8HdsMT8rx9D1I50Rl
# i/qQFo2BOuPyb2SIQPzJvCs5wgi5qgp1nHiN6igumu2Cz7BmGjOazGUgCSUY5Qwy
# E8+F+R2tVM+2O15rfX01+e56ZfojBEiEjMwfPHs3fa3V3gokWWNwUMkton/v0R/n
# l2zjmOr2okohOINZEDh9frg21zUCN5ZD8Y4zQWuiJLCvvvBZs0JR4c9xl2k2wtw/
# QLPhGU69zM3smGpRoLE8M6zvUvSU7jXjvefazUniMYIDGjCCAxYCAQEwaDBUMQsw
# CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJT
# ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhBIqMP3CCLHOHtOKuaW
# NyeFMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICll1EHF++RudSGsu5/Cmzm1OmnU4tlG
# JGaZZteSXoVwMA0GCSqGSIb3DQEBAQUABIICAKVYll+Azr23XqfO0qVS+XKEA41J
# kOVW32oD/4+dKPFQdVq8O8nT/y9F6YdsJezO7wWiCodaGstr5nGVXUjGUgqOREEu
# ztDh6HXHlBJwmh67NnZ/vd0nyI4QoLDUWSLXI7xgxuvNhzqKr6lJxlILlUkQjCm/
# 74EhhQRsIxvpegKPGWroGwm3VhqHo3e7QNRD5FkMxQK7KqCMTY7jydLFovFmPgxC
# qXYXjIOVrrSMbIDrWdOZhCu6g8rwPEKlD+gCYiG00wc662mHcQYX1blyBGsQ4+df
# R6Of4siPnvCn4gDTWPmKoWZ9904nfBF1vAVrR3OHaKssUp/F4DjMKDYbtECtQrAh
# Wb8U3EX9k1OEDgdKipTuhZYz3S1+PERf8xmc0MJTAc14y1h23HXUU/6Y9xz6kCdN
# WCvYYG/Zk45LL52OUpPXe5hdHWDw4ni5njLUb+F3vMNtQe21EMqkMImQHpAvFv+i
# 9iFP8aaobi5aUKSgFUfXJC4N/Dnn76ZRzgpWLdPsvvckaW61gyDa9rv2iDOhH0QA
# tPyEavgr0JbdLPgOwTTbg/eov2wDvcq3N3U/C7LUH3c+grJYaIpRNwi2IZJPymi/
# ptPUK4mTxb7P78pLkSjERoRBdmdLEAR9GrBLpNqDeIB3N/ZNhzs9X6yrw7z4N4/x
# KoeF5hkL/VveWb0H
# SIG # End signature block